1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
67 [; Relocation specifiers
78 (UNSPEC_MACHOPIC_OFFSET 10)
81 (UNSPEC_STACK_ALLOC 11)
83 (UNSPEC_SSE_PROLOGUE_SAVE 13)
87 (UNSPEC_SET_GOT_OFFSET 17)
88 (UNSPEC_MEMORY_BLOCKAGE 18)
93 (UNSPEC_TLS_LD_BASE 22)
96 ; Other random patterns
101 (UNSPEC_ADD_CARRY 34)
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
107 ; For SSE/MMX support:
108 (UNSPEC_FIX_NOTRUNC 40)
125 (UNSPEC_MS_TO_SYSV_CALL 48)
127 ; Generic math support
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
152 ; x87 Double output FP
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
181 (UNSPEC_INSERTQI 132)
186 (UNSPEC_INSERTPS 135)
188 (UNSPEC_MOVNTDQA 137)
190 (UNSPEC_PHMINPOSUW 139)
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
200 (UNSPEC_FMA4_INTRINSIC 150)
201 (UNSPEC_FMA4_FMADDSUB 151)
202 (UNSPEC_FMA4_FMSUBADD 152)
203 (UNSPEC_XOP_UNSIGNED_CMP 151)
204 (UNSPEC_XOP_TRUEFALSE 152)
205 (UNSPEC_XOP_PERMUTE 153)
210 (UNSPEC_AESENCLAST 160)
212 (UNSPEC_AESDECLAST 162)
214 (UNSPEC_AESKEYGENASSIST 164)
222 (UNSPEC_VPERMIL2 168)
223 (UNSPEC_VPERMIL2F128 169)
224 (UNSPEC_MASKLOAD 170)
225 (UNSPEC_MASKSTORE 171)
231 [(UNSPECV_BLOCKAGE 0)
232 (UNSPECV_STACK_PROBE 1)
244 (UNSPECV_PROLOGUE_USE 14)
246 (UNSPECV_VZEROALL 16)
247 (UNSPECV_VZEROUPPER 17)
251 (UNSPECV_VSWAPMOV 21)
252 (UNSPECV_LLWP_INTRINSIC 22)
253 (UNSPECV_SLWP_INTRINSIC 23)
254 (UNSPECV_LWPVAL_INTRINSIC 24)
255 (UNSPECV_LWPINS_INTRINSIC 25)
258 ;; Constants to represent pcomtrue/pcomfalse variants
268 ;; Constants used in the XOP pperm instruction
270 [(PPERM_SRC 0x00) /* copy source */
271 (PPERM_INVERT 0x20) /* invert source */
272 (PPERM_REVERSE 0x40) /* bit reverse source */
273 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
274 (PPERM_ZERO 0x80) /* all 0's */
275 (PPERM_ONES 0xa0) /* all 1's */
276 (PPERM_SIGN 0xc0) /* propagate sign bit */
277 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
278 (PPERM_SRC1 0x00) /* use first source byte */
279 (PPERM_SRC2 0x10) /* use second source byte */
282 ;; Registers by name.
335 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
338 ;; In C guard expressions, put expressions which may be compile-time
339 ;; constants first. This allows for better optimization. For
340 ;; example, write "TARGET_64BIT && reload_completed", not
341 ;; "reload_completed && TARGET_64BIT".
345 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347 (const (symbol_ref "ix86_schedule")))
349 ;; A basic instruction type. Refinements due to arguments to be
350 ;; provided in other attributes.
353 alu,alu1,negnot,imov,imovx,lea,
354 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
355 icmp,test,ibr,setcc,icmov,
356 push,pop,call,callv,leave,
358 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
359 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
360 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
361 ssemuladd,sse4arg,lwp,
362 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
363 (const_string "other"))
365 ;; Main data type used by the insn
367 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
368 (const_string "unknown"))
370 ;; The CPU unit operations uses.
371 (define_attr "unit" "integer,i387,sse,mmx,unknown"
372 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
373 (const_string "i387")
374 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
375 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
376 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
378 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
380 (eq_attr "type" "other")
381 (const_string "unknown")]
382 (const_string "integer")))
384 ;; The (bounding maximum) length of an instruction immediate.
385 (define_attr "length_immediate" ""
386 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
389 (eq_attr "unit" "i387,sse,mmx")
391 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
393 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
394 (eq_attr "type" "imov,test")
395 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
396 (eq_attr "type" "call")
397 (if_then_else (match_operand 0 "constant_call_address_operand" "")
400 (eq_attr "type" "callv")
401 (if_then_else (match_operand 1 "constant_call_address_operand" "")
404 ;; We don't know the size before shorten_branches. Expect
405 ;; the instruction to fit for better scheduling.
406 (eq_attr "type" "ibr")
409 (symbol_ref "/* Update immediate_length and other attributes! */
410 gcc_unreachable (),1")))
412 ;; The (bounding maximum) length of an instruction address.
413 (define_attr "length_address" ""
414 (cond [(eq_attr "type" "str,other,multi,fxch")
416 (and (eq_attr "type" "call")
417 (match_operand 0 "constant_call_address_operand" ""))
419 (and (eq_attr "type" "callv")
420 (match_operand 1 "constant_call_address_operand" ""))
423 (symbol_ref "ix86_attr_length_address_default (insn)")))
425 ;; Set when length prefix is used.
426 (define_attr "prefix_data16" ""
427 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
429 (eq_attr "mode" "HI")
431 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
436 ;; Set when string REP prefix is used.
437 (define_attr "prefix_rep" ""
438 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
440 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
445 ;; Set when 0f opcode prefix is used.
446 (define_attr "prefix_0f" ""
448 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
449 (eq_attr "unit" "sse,mmx"))
453 ;; Set when REX opcode prefix is used.
454 (define_attr "prefix_rex" ""
455 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
457 (and (eq_attr "mode" "DI")
458 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
459 (eq_attr "unit" "!mmx")))
461 (and (eq_attr "mode" "QI")
462 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
465 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
468 (and (eq_attr "type" "imovx")
469 (match_operand:QI 1 "ext_QIreg_operand" ""))
474 ;; There are also additional prefixes in 3DNOW, SSSE3.
475 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
476 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
477 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
478 (define_attr "prefix_extra" ""
479 (cond [(eq_attr "type" "ssemuladd,sse4arg")
481 (eq_attr "type" "sseiadd1,ssecvt1")
486 ;; Prefix used: original, VEX or maybe VEX.
487 (define_attr "prefix" "orig,vex,maybe_vex"
488 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
490 (const_string "orig")))
492 ;; VEX W bit is used.
493 (define_attr "prefix_vex_w" "" (const_int 0))
495 ;; The length of VEX prefix
496 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
497 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
498 ;; still prefix_0f 1, with prefix_extra 1.
499 (define_attr "length_vex" ""
500 (if_then_else (and (eq_attr "prefix_0f" "1")
501 (eq_attr "prefix_extra" "0"))
502 (if_then_else (eq_attr "prefix_vex_w" "1")
503 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
504 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
505 (if_then_else (eq_attr "prefix_vex_w" "1")
506 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
507 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
509 ;; Set when modrm byte is used.
510 (define_attr "modrm" ""
511 (cond [(eq_attr "type" "str,leave")
513 (eq_attr "unit" "i387")
515 (and (eq_attr "type" "incdec")
516 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
517 (ior (match_operand:SI 1 "register_operand" "")
518 (match_operand:HI 1 "register_operand" ""))))
520 (and (eq_attr "type" "push")
521 (not (match_operand 1 "memory_operand" "")))
523 (and (eq_attr "type" "pop")
524 (not (match_operand 0 "memory_operand" "")))
526 (and (eq_attr "type" "imov")
527 (and (not (eq_attr "mode" "DI"))
528 (ior (and (match_operand 0 "register_operand" "")
529 (match_operand 1 "immediate_operand" ""))
530 (ior (and (match_operand 0 "ax_reg_operand" "")
531 (match_operand 1 "memory_displacement_only_operand" ""))
532 (and (match_operand 0 "memory_displacement_only_operand" "")
533 (match_operand 1 "ax_reg_operand" ""))))))
535 (and (eq_attr "type" "call")
536 (match_operand 0 "constant_call_address_operand" ""))
538 (and (eq_attr "type" "callv")
539 (match_operand 1 "constant_call_address_operand" ""))
541 (and (eq_attr "type" "alu,alu1,icmp,test")
542 (match_operand 0 "ax_reg_operand" ""))
543 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
547 ;; The (bounding maximum) length of an instruction in bytes.
548 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
549 ;; Later we may want to split them and compute proper length as for
551 (define_attr "length" ""
552 (cond [(eq_attr "type" "other,multi,fistp,frndint")
554 (eq_attr "type" "fcmp")
556 (eq_attr "unit" "i387")
558 (plus (attr "prefix_data16")
559 (attr "length_address")))
560 (ior (eq_attr "prefix" "vex")
561 (and (eq_attr "prefix" "maybe_vex")
562 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
563 (plus (attr "length_vex")
564 (plus (attr "length_immediate")
566 (attr "length_address"))))]
567 (plus (plus (attr "modrm")
568 (plus (attr "prefix_0f")
569 (plus (attr "prefix_rex")
570 (plus (attr "prefix_extra")
572 (plus (attr "prefix_rep")
573 (plus (attr "prefix_data16")
574 (plus (attr "length_immediate")
575 (attr "length_address")))))))
577 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
578 ;; `store' if there is a simple memory reference therein, or `unknown'
579 ;; if the instruction is complex.
581 (define_attr "memory" "none,load,store,both,unknown"
582 (cond [(eq_attr "type" "other,multi,str,lwp")
583 (const_string "unknown")
584 (eq_attr "type" "lea,fcmov,fpspc")
585 (const_string "none")
586 (eq_attr "type" "fistp,leave")
587 (const_string "both")
588 (eq_attr "type" "frndint")
589 (const_string "load")
590 (eq_attr "type" "push")
591 (if_then_else (match_operand 1 "memory_operand" "")
592 (const_string "both")
593 (const_string "store"))
594 (eq_attr "type" "pop")
595 (if_then_else (match_operand 0 "memory_operand" "")
596 (const_string "both")
597 (const_string "load"))
598 (eq_attr "type" "setcc")
599 (if_then_else (match_operand 0 "memory_operand" "")
600 (const_string "store")
601 (const_string "none"))
602 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
603 (if_then_else (ior (match_operand 0 "memory_operand" "")
604 (match_operand 1 "memory_operand" ""))
605 (const_string "load")
606 (const_string "none"))
607 (eq_attr "type" "ibr")
608 (if_then_else (match_operand 0 "memory_operand" "")
609 (const_string "load")
610 (const_string "none"))
611 (eq_attr "type" "call")
612 (if_then_else (match_operand 0 "constant_call_address_operand" "")
613 (const_string "none")
614 (const_string "load"))
615 (eq_attr "type" "callv")
616 (if_then_else (match_operand 1 "constant_call_address_operand" "")
617 (const_string "none")
618 (const_string "load"))
619 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
620 (match_operand 1 "memory_operand" ""))
621 (const_string "both")
622 (and (match_operand 0 "memory_operand" "")
623 (match_operand 1 "memory_operand" ""))
624 (const_string "both")
625 (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (match_operand 1 "memory_operand" "")
628 (const_string "load")
630 "!alu1,negnot,ishift1,
631 imov,imovx,icmp,test,bitmanip,
633 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
634 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
635 (match_operand 2 "memory_operand" ""))
636 (const_string "load")
637 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
638 (match_operand 3 "memory_operand" ""))
639 (const_string "load")
641 (const_string "none")))
643 ;; Indicates if an instruction has both an immediate and a displacement.
645 (define_attr "imm_disp" "false,true,unknown"
646 (cond [(eq_attr "type" "other,multi")
647 (const_string "unknown")
648 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
649 (and (match_operand 0 "memory_displacement_operand" "")
650 (match_operand 1 "immediate_operand" "")))
651 (const_string "true")
652 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
653 (and (match_operand 0 "memory_displacement_operand" "")
654 (match_operand 2 "immediate_operand" "")))
655 (const_string "true")
657 (const_string "false")))
659 ;; Indicates if an FP operation has an integer source.
661 (define_attr "fp_int_src" "false,true"
662 (const_string "false"))
664 ;; Defines rounding mode of an FP operation.
666 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
667 (const_string "any"))
669 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
670 (define_attr "use_carry" "0,1" (const_string "0"))
672 ;; Define attribute to indicate unaligned ssemov insns
673 (define_attr "movu" "0,1" (const_string "0"))
675 ;; Describe a user's asm statement.
676 (define_asm_attributes
677 [(set_attr "length" "128")
678 (set_attr "type" "multi")])
680 ;; All integer comparison codes.
681 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
683 ;; All floating-point comparison codes.
684 (define_code_iterator fp_cond [unordered ordered
685 uneq unge ungt unle unlt ltgt])
687 (define_code_iterator plusminus [plus minus])
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698 [(plus "add") (ss_plus "adds") (us_plus "addus")
699 (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701 [(plus "adc") (minus "sbb")])
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705 (minus "") (ss_minus "") (us_minus "")])
707 ;; Mapping of signed max and min
708 (define_code_iterator smaxmin [smax smin])
710 ;; Mapping of unsigned max and min
711 (define_code_iterator umaxmin [umax umin])
713 ;; Mapping of signed/unsigned max and min
714 (define_code_iterator maxmin [smax smin umax umin])
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
718 (umax "maxu") (umin "minu")])
719 (define_code_attr maxminfprefix [(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 logicprefix [(and "and") (ior "or") (xor "xor")])
728 ;; Mapping of abs neg operators
729 (define_code_iterator absneg [abs neg])
731 ;; Base name for x87 insn mnemonic.
732 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
734 ;; Used in signed and unsigned widening multiplications.
735 (define_code_iterator any_extend [sign_extend zero_extend])
737 ;; Various insn prefixes for signed and unsigned operations.
738 (define_code_attr u [(sign_extend "") (zero_extend "u")
739 (div "") (udiv "u")])
740 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
742 ;; Used in signed and unsigned divisions.
743 (define_code_iterator any_div [div udiv])
745 ;; Instruction prefix for signed and unsigned operations.
746 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
747 (div "i") (udiv "")])
749 ;; All single word integer modes.
750 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
752 ;; Single word integer modes without DImode.
753 (define_mode_iterator SWI124 [QI HI SI])
755 ;; Single word integer modes without QImode.
756 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
758 ;; Single word integer modes without QImode and HImode.
759 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
761 ;; All math-dependant single and double word integer modes.
762 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
763 (HI "TARGET_HIMODE_MATH")
764 SI DI (TI "TARGET_64BIT")])
766 ;; Math-dependant single word integer modes.
767 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
768 (HI "TARGET_HIMODE_MATH")
769 SI (DI "TARGET_64BIT")])
771 ;; Math-dependant single word integer modes without QImode.
772 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
773 SI (DI "TARGET_64BIT")])
775 ;; Half mode for double word integer modes.
776 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
777 (DI "TARGET_64BIT")])
779 ;; Double word integer modes.
780 (define_mode_attr DWI [(SI "DI") (DI "TI")])
781 (define_mode_attr dwi [(SI "di") (DI "ti")])
783 ;; Instruction suffix for integer modes.
784 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
786 ;; Register class for integer modes.
787 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
789 ;; Immediate operand constraint for integer modes.
790 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
792 ;; General operand constraint for word modes.
793 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
795 ;; Immediate operand constraint for double integer modes.
796 (define_mode_attr di [(SI "iF") (DI "e")])
798 ;; General operand predicate for integer modes.
799 (define_mode_attr general_operand
800 [(QI "general_operand")
801 (HI "general_operand")
802 (SI "general_operand")
803 (DI "x86_64_general_operand")
804 (TI "x86_64_general_operand")])
806 ;; General sign/zero extend operand predicate for integer modes.
807 (define_mode_attr general_szext_operand
808 [(QI "general_operand")
809 (HI "general_operand")
810 (SI "general_operand")
811 (DI "x86_64_szext_general_operand")])
813 ;; SSE and x87 SFmode and DFmode floating point modes
814 (define_mode_iterator MODEF [SF DF])
816 ;; All x87 floating point modes
817 (define_mode_iterator X87MODEF [SF DF XF])
819 ;; All integer modes handled by x87 fisttp operator.
820 (define_mode_iterator X87MODEI [HI SI DI])
822 ;; All integer modes handled by integer x87 operators.
823 (define_mode_iterator X87MODEI12 [HI SI])
825 ;; All integer modes handled by SSE cvtts?2si* operators.
826 (define_mode_iterator SSEMODEI24 [SI DI])
828 ;; SSE asm suffix for floating point modes
829 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
831 ;; SSE vector mode corresponding to a scalar mode
832 (define_mode_attr ssevecmode
833 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
835 ;; Instruction suffix for REX 64bit operators.
836 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
838 ;; This mode iterator allows :P to be used for patterns that operate on
839 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
840 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
842 ;; Scheduling descriptions
844 (include "pentium.md")
847 (include "athlon.md")
852 ;; Operand and operator predicates and constraints
854 (include "predicates.md")
855 (include "constraints.md")
858 ;; Compare and branch/compare and store instructions.
860 (define_expand "cbranch<mode>4"
861 [(set (reg:CC FLAGS_REG)
862 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
863 (match_operand:SDWIM 2 "<general_operand>" "")))
864 (set (pc) (if_then_else
865 (match_operator 0 "comparison_operator"
866 [(reg:CC FLAGS_REG) (const_int 0)])
867 (label_ref (match_operand 3 "" ""))
871 if (MEM_P (operands[1]) && MEM_P (operands[2]))
872 operands[1] = force_reg (<MODE>mode, operands[1]);
873 ix86_compare_op0 = operands[1];
874 ix86_compare_op1 = operands[2];
875 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
879 (define_expand "cstore<mode>4"
880 [(set (reg:CC FLAGS_REG)
881 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
882 (match_operand:SWIM 3 "<general_operand>" "")))
883 (set (match_operand:QI 0 "register_operand" "")
884 (match_operator 1 "comparison_operator"
885 [(reg:CC FLAGS_REG) (const_int 0)]))]
888 if (MEM_P (operands[2]) && MEM_P (operands[3]))
889 operands[2] = force_reg (<MODE>mode, operands[2]);
890 ix86_compare_op0 = operands[2];
891 ix86_compare_op1 = operands[3];
892 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
896 (define_expand "cmp<mode>_1"
897 [(set (reg:CC FLAGS_REG)
898 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
899 (match_operand:SWI48 1 "<general_operand>" "")))]
903 (define_insn "*cmp<mode>_ccno_1"
904 [(set (reg FLAGS_REG)
905 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
906 (match_operand:SWI 1 "const0_operand" "")))]
907 "ix86_match_ccmode (insn, CCNOmode)"
909 test{<imodesuffix>}\t%0, %0
910 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
911 [(set_attr "type" "test,icmp")
912 (set_attr "length_immediate" "0,1")
913 (set_attr "mode" "<MODE>")])
915 (define_insn "*cmp<mode>_1"
916 [(set (reg FLAGS_REG)
917 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
918 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
919 "ix86_match_ccmode (insn, CCmode)"
920 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
921 [(set_attr "type" "icmp")
922 (set_attr "mode" "<MODE>")])
924 (define_insn "*cmp<mode>_minus_1"
925 [(set (reg FLAGS_REG)
927 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
928 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
930 "ix86_match_ccmode (insn, CCGOCmode)"
931 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
932 [(set_attr "type" "icmp")
933 (set_attr "mode" "<MODE>")])
935 (define_insn "*cmpqi_ext_1"
936 [(set (reg FLAGS_REG)
938 (match_operand:QI 0 "general_operand" "Qm")
941 (match_operand 1 "ext_register_operand" "Q")
944 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
945 "cmp{b}\t{%h1, %0|%0, %h1}"
946 [(set_attr "type" "icmp")
947 (set_attr "mode" "QI")])
949 (define_insn "*cmpqi_ext_1_rex64"
950 [(set (reg FLAGS_REG)
952 (match_operand:QI 0 "register_operand" "Q")
955 (match_operand 1 "ext_register_operand" "Q")
958 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
959 "cmp{b}\t{%h1, %0|%0, %h1}"
960 [(set_attr "type" "icmp")
961 (set_attr "mode" "QI")])
963 (define_insn "*cmpqi_ext_2"
964 [(set (reg FLAGS_REG)
968 (match_operand 0 "ext_register_operand" "Q")
971 (match_operand:QI 1 "const0_operand" "")))]
972 "ix86_match_ccmode (insn, CCNOmode)"
974 [(set_attr "type" "test")
975 (set_attr "length_immediate" "0")
976 (set_attr "mode" "QI")])
978 (define_expand "cmpqi_ext_3"
979 [(set (reg:CC FLAGS_REG)
983 (match_operand 0 "ext_register_operand" "")
986 (match_operand:QI 1 "immediate_operand" "")))]
990 (define_insn "*cmpqi_ext_3_insn"
991 [(set (reg FLAGS_REG)
995 (match_operand 0 "ext_register_operand" "Q")
998 (match_operand:QI 1 "general_operand" "Qmn")))]
999 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1000 "cmp{b}\t{%1, %h0|%h0, %1}"
1001 [(set_attr "type" "icmp")
1002 (set_attr "modrm" "1")
1003 (set_attr "mode" "QI")])
1005 (define_insn "*cmpqi_ext_3_insn_rex64"
1006 [(set (reg FLAGS_REG)
1010 (match_operand 0 "ext_register_operand" "Q")
1013 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1014 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015 "cmp{b}\t{%1, %h0|%h0, %1}"
1016 [(set_attr "type" "icmp")
1017 (set_attr "modrm" "1")
1018 (set_attr "mode" "QI")])
1020 (define_insn "*cmpqi_ext_4"
1021 [(set (reg FLAGS_REG)
1025 (match_operand 0 "ext_register_operand" "Q")
1030 (match_operand 1 "ext_register_operand" "Q")
1032 (const_int 8)) 0)))]
1033 "ix86_match_ccmode (insn, CCmode)"
1034 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1035 [(set_attr "type" "icmp")
1036 (set_attr "mode" "QI")])
1038 ;; These implement float point compares.
1039 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1040 ;; which would allow mix and match FP modes on the compares. Which is what
1041 ;; the old patterns did, but with many more of them.
1043 (define_expand "cbranchxf4"
1044 [(set (reg:CC FLAGS_REG)
1045 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1046 (match_operand:XF 2 "nonmemory_operand" "")))
1047 (set (pc) (if_then_else
1048 (match_operator 0 "ix86_fp_comparison_operator"
1051 (label_ref (match_operand 3 "" ""))
1055 ix86_compare_op0 = operands[1];
1056 ix86_compare_op1 = operands[2];
1057 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1061 (define_expand "cstorexf4"
1062 [(set (reg:CC FLAGS_REG)
1063 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1064 (match_operand:XF 3 "nonmemory_operand" "")))
1065 (set (match_operand:QI 0 "register_operand" "")
1066 (match_operator 1 "ix86_fp_comparison_operator"
1071 ix86_compare_op0 = operands[2];
1072 ix86_compare_op1 = operands[3];
1073 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1077 (define_expand "cbranch<mode>4"
1078 [(set (reg:CC FLAGS_REG)
1079 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1080 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1081 (set (pc) (if_then_else
1082 (match_operator 0 "ix86_fp_comparison_operator"
1085 (label_ref (match_operand 3 "" ""))
1087 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1089 ix86_compare_op0 = operands[1];
1090 ix86_compare_op1 = operands[2];
1091 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1095 (define_expand "cstore<mode>4"
1096 [(set (reg:CC FLAGS_REG)
1097 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1098 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1099 (set (match_operand:QI 0 "register_operand" "")
1100 (match_operator 1 "ix86_fp_comparison_operator"
1103 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1105 ix86_compare_op0 = operands[2];
1106 ix86_compare_op1 = operands[3];
1107 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1111 (define_expand "cbranchcc4"
1112 [(set (pc) (if_then_else
1113 (match_operator 0 "comparison_operator"
1114 [(match_operand 1 "flags_reg_operand" "")
1115 (match_operand 2 "const0_operand" "")])
1116 (label_ref (match_operand 3 "" ""))
1120 ix86_compare_op0 = operands[1];
1121 ix86_compare_op1 = operands[2];
1122 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1126 (define_expand "cstorecc4"
1127 [(set (match_operand:QI 0 "register_operand" "")
1128 (match_operator 1 "comparison_operator"
1129 [(match_operand 2 "flags_reg_operand" "")
1130 (match_operand 3 "const0_operand" "")]))]
1133 ix86_compare_op0 = operands[2];
1134 ix86_compare_op1 = operands[3];
1135 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1140 ;; FP compares, step 1:
1141 ;; Set the FP condition codes.
1143 ;; CCFPmode compare with exceptions
1144 ;; CCFPUmode compare with no exceptions
1146 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1147 ;; used to manage the reg stack popping would not be preserved.
1149 (define_insn "*cmpfp_0"
1150 [(set (match_operand:HI 0 "register_operand" "=a")
1153 (match_operand 1 "register_operand" "f")
1154 (match_operand 2 "const0_operand" ""))]
1156 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1157 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1158 "* return output_fp_compare (insn, operands, 0, 0);"
1159 [(set_attr "type" "multi")
1160 (set_attr "unit" "i387")
1162 (cond [(match_operand:SF 1 "" "")
1164 (match_operand:DF 1 "" "")
1167 (const_string "XF")))])
1169 (define_insn_and_split "*cmpfp_0_cc"
1170 [(set (reg:CCFP FLAGS_REG)
1172 (match_operand 1 "register_operand" "f")
1173 (match_operand 2 "const0_operand" "")))
1174 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1175 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1176 && TARGET_SAHF && !TARGET_CMOVE
1177 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1179 "&& reload_completed"
1182 [(compare:CCFP (match_dup 1)(match_dup 2))]
1184 (set (reg:CC FLAGS_REG)
1185 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1187 [(set_attr "type" "multi")
1188 (set_attr "unit" "i387")
1190 (cond [(match_operand:SF 1 "" "")
1192 (match_operand:DF 1 "" "")
1195 (const_string "XF")))])
1197 (define_insn "*cmpfp_xf"
1198 [(set (match_operand:HI 0 "register_operand" "=a")
1201 (match_operand:XF 1 "register_operand" "f")
1202 (match_operand:XF 2 "register_operand" "f"))]
1205 "* return output_fp_compare (insn, operands, 0, 0);"
1206 [(set_attr "type" "multi")
1207 (set_attr "unit" "i387")
1208 (set_attr "mode" "XF")])
1210 (define_insn_and_split "*cmpfp_xf_cc"
1211 [(set (reg:CCFP FLAGS_REG)
1213 (match_operand:XF 1 "register_operand" "f")
1214 (match_operand:XF 2 "register_operand" "f")))
1215 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1217 && TARGET_SAHF && !TARGET_CMOVE"
1219 "&& reload_completed"
1222 [(compare:CCFP (match_dup 1)(match_dup 2))]
1224 (set (reg:CC FLAGS_REG)
1225 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1227 [(set_attr "type" "multi")
1228 (set_attr "unit" "i387")
1229 (set_attr "mode" "XF")])
1231 (define_insn "*cmpfp_<mode>"
1232 [(set (match_operand:HI 0 "register_operand" "=a")
1235 (match_operand:MODEF 1 "register_operand" "f")
1236 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1239 "* return output_fp_compare (insn, operands, 0, 0);"
1240 [(set_attr "type" "multi")
1241 (set_attr "unit" "i387")
1242 (set_attr "mode" "<MODE>")])
1244 (define_insn_and_split "*cmpfp_<mode>_cc"
1245 [(set (reg:CCFP FLAGS_REG)
1247 (match_operand:MODEF 1 "register_operand" "f")
1248 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1249 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1251 && TARGET_SAHF && !TARGET_CMOVE"
1253 "&& reload_completed"
1256 [(compare:CCFP (match_dup 1)(match_dup 2))]
1258 (set (reg:CC FLAGS_REG)
1259 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1261 [(set_attr "type" "multi")
1262 (set_attr "unit" "i387")
1263 (set_attr "mode" "<MODE>")])
1265 (define_insn "*cmpfp_u"
1266 [(set (match_operand:HI 0 "register_operand" "=a")
1269 (match_operand 1 "register_operand" "f")
1270 (match_operand 2 "register_operand" "f"))]
1272 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1273 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1274 "* return output_fp_compare (insn, operands, 0, 1);"
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1278 (cond [(match_operand:SF 1 "" "")
1280 (match_operand:DF 1 "" "")
1283 (const_string "XF")))])
1285 (define_insn_and_split "*cmpfp_u_cc"
1286 [(set (reg:CCFPU FLAGS_REG)
1288 (match_operand 1 "register_operand" "f")
1289 (match_operand 2 "register_operand" "f")))
1290 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1291 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1292 && TARGET_SAHF && !TARGET_CMOVE
1293 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1295 "&& reload_completed"
1298 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1300 (set (reg:CC FLAGS_REG)
1301 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1303 [(set_attr "type" "multi")
1304 (set_attr "unit" "i387")
1306 (cond [(match_operand:SF 1 "" "")
1308 (match_operand:DF 1 "" "")
1311 (const_string "XF")))])
1313 (define_insn "*cmpfp_<mode>"
1314 [(set (match_operand:HI 0 "register_operand" "=a")
1317 (match_operand 1 "register_operand" "f")
1318 (match_operator 3 "float_operator"
1319 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1321 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1322 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1323 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1324 "* return output_fp_compare (insn, operands, 0, 0);"
1325 [(set_attr "type" "multi")
1326 (set_attr "unit" "i387")
1327 (set_attr "fp_int_src" "true")
1328 (set_attr "mode" "<MODE>")])
1330 (define_insn_and_split "*cmpfp_<mode>_cc"
1331 [(set (reg:CCFP FLAGS_REG)
1333 (match_operand 1 "register_operand" "f")
1334 (match_operator 3 "float_operator"
1335 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1336 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1337 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1338 && TARGET_SAHF && !TARGET_CMOVE
1339 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1340 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1342 "&& reload_completed"
1347 (match_op_dup 3 [(match_dup 2)]))]
1349 (set (reg:CC FLAGS_REG)
1350 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1352 [(set_attr "type" "multi")
1353 (set_attr "unit" "i387")
1354 (set_attr "fp_int_src" "true")
1355 (set_attr "mode" "<MODE>")])
1357 ;; FP compares, step 2
1358 ;; Move the fpsw to ax.
1360 (define_insn "x86_fnstsw_1"
1361 [(set (match_operand:HI 0 "register_operand" "=a")
1362 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1365 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1366 (set_attr "mode" "SI")
1367 (set_attr "unit" "i387")])
1369 ;; FP compares, step 3
1370 ;; Get ax into flags, general case.
1372 (define_insn "x86_sahf_1"
1373 [(set (reg:CC FLAGS_REG)
1374 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1378 #ifdef HAVE_AS_IX86_SAHF
1381 return ASM_BYTE "0x9e";
1384 [(set_attr "length" "1")
1385 (set_attr "athlon_decode" "vector")
1386 (set_attr "amdfam10_decode" "direct")
1387 (set_attr "mode" "SI")])
1389 ;; Pentium Pro can do steps 1 through 3 in one go.
1390 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1391 (define_insn "*cmpfp_i_mixed"
1392 [(set (reg:CCFP FLAGS_REG)
1393 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1394 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1395 "TARGET_MIX_SSE_I387
1396 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1397 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1398 "* return output_fp_compare (insn, operands, 1, 0);"
1399 [(set_attr "type" "fcmp,ssecomi")
1400 (set_attr "prefix" "orig,maybe_vex")
1402 (if_then_else (match_operand:SF 1 "" "")
1404 (const_string "DF")))
1405 (set (attr "prefix_rep")
1406 (if_then_else (eq_attr "type" "ssecomi")
1408 (const_string "*")))
1409 (set (attr "prefix_data16")
1410 (cond [(eq_attr "type" "fcmp")
1412 (eq_attr "mode" "DF")
1415 (const_string "0")))
1416 (set_attr "athlon_decode" "vector")
1417 (set_attr "amdfam10_decode" "direct")])
1419 (define_insn "*cmpfp_i_sse"
1420 [(set (reg:CCFP FLAGS_REG)
1421 (compare:CCFP (match_operand 0 "register_operand" "x")
1422 (match_operand 1 "nonimmediate_operand" "xm")))]
1424 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1425 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426 "* return output_fp_compare (insn, operands, 1, 0);"
1427 [(set_attr "type" "ssecomi")
1428 (set_attr "prefix" "maybe_vex")
1430 (if_then_else (match_operand:SF 1 "" "")
1432 (const_string "DF")))
1433 (set_attr "prefix_rep" "0")
1434 (set (attr "prefix_data16")
1435 (if_then_else (eq_attr "mode" "DF")
1437 (const_string "0")))
1438 (set_attr "athlon_decode" "vector")
1439 (set_attr "amdfam10_decode" "direct")])
1441 (define_insn "*cmpfp_i_i387"
1442 [(set (reg:CCFP FLAGS_REG)
1443 (compare:CCFP (match_operand 0 "register_operand" "f")
1444 (match_operand 1 "register_operand" "f")))]
1445 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1447 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1448 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1449 "* return output_fp_compare (insn, operands, 1, 0);"
1450 [(set_attr "type" "fcmp")
1452 (cond [(match_operand:SF 1 "" "")
1454 (match_operand:DF 1 "" "")
1457 (const_string "XF")))
1458 (set_attr "athlon_decode" "vector")
1459 (set_attr "amdfam10_decode" "direct")])
1461 (define_insn "*cmpfp_iu_mixed"
1462 [(set (reg:CCFPU FLAGS_REG)
1463 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1464 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1465 "TARGET_MIX_SSE_I387
1466 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1467 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1468 "* return output_fp_compare (insn, operands, 1, 1);"
1469 [(set_attr "type" "fcmp,ssecomi")
1470 (set_attr "prefix" "orig,maybe_vex")
1472 (if_then_else (match_operand:SF 1 "" "")
1474 (const_string "DF")))
1475 (set (attr "prefix_rep")
1476 (if_then_else (eq_attr "type" "ssecomi")
1478 (const_string "*")))
1479 (set (attr "prefix_data16")
1480 (cond [(eq_attr "type" "fcmp")
1482 (eq_attr "mode" "DF")
1485 (const_string "0")))
1486 (set_attr "athlon_decode" "vector")
1487 (set_attr "amdfam10_decode" "direct")])
1489 (define_insn "*cmpfp_iu_sse"
1490 [(set (reg:CCFPU FLAGS_REG)
1491 (compare:CCFPU (match_operand 0 "register_operand" "x")
1492 (match_operand 1 "nonimmediate_operand" "xm")))]
1494 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1495 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1496 "* return output_fp_compare (insn, operands, 1, 1);"
1497 [(set_attr "type" "ssecomi")
1498 (set_attr "prefix" "maybe_vex")
1500 (if_then_else (match_operand:SF 1 "" "")
1502 (const_string "DF")))
1503 (set_attr "prefix_rep" "0")
1504 (set (attr "prefix_data16")
1505 (if_then_else (eq_attr "mode" "DF")
1507 (const_string "0")))
1508 (set_attr "athlon_decode" "vector")
1509 (set_attr "amdfam10_decode" "direct")])
1511 (define_insn "*cmpfp_iu_387"
1512 [(set (reg:CCFPU FLAGS_REG)
1513 (compare:CCFPU (match_operand 0 "register_operand" "f")
1514 (match_operand 1 "register_operand" "f")))]
1515 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1517 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1518 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1519 "* return output_fp_compare (insn, operands, 1, 1);"
1520 [(set_attr "type" "fcmp")
1522 (cond [(match_operand:SF 1 "" "")
1524 (match_operand:DF 1 "" "")
1527 (const_string "XF")))
1528 (set_attr "athlon_decode" "vector")
1529 (set_attr "amdfam10_decode" "direct")])
1531 ;; Move instructions.
1533 ;; General case of fullword move.
1535 (define_expand "movsi"
1536 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1537 (match_operand:SI 1 "general_operand" ""))]
1539 "ix86_expand_move (SImode, operands); DONE;")
1541 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1544 ;; %%% We don't use a post-inc memory reference because x86 is not a
1545 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1546 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1547 ;; targets without our curiosities, and it is just as easy to represent
1548 ;; this differently.
1550 (define_insn "*pushsi2"
1551 [(set (match_operand:SI 0 "push_operand" "=<")
1552 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1555 [(set_attr "type" "push")
1556 (set_attr "mode" "SI")])
1558 ;; For 64BIT abi we always round up to 8 bytes.
1559 (define_insn "*pushsi2_rex64"
1560 [(set (match_operand:SI 0 "push_operand" "=X")
1561 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1564 [(set_attr "type" "push")
1565 (set_attr "mode" "SI")])
1567 (define_insn "*pushsi2_prologue"
1568 [(set (match_operand:SI 0 "push_operand" "=<")
1569 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1570 (clobber (mem:BLK (scratch)))]
1573 [(set_attr "type" "push")
1574 (set_attr "mode" "SI")])
1576 (define_insn "*popsi1_epilogue"
1577 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1578 (mem:SI (reg:SI SP_REG)))
1579 (set (reg:SI SP_REG)
1580 (plus:SI (reg:SI SP_REG) (const_int 4)))
1581 (clobber (mem:BLK (scratch)))]
1584 [(set_attr "type" "pop")
1585 (set_attr "mode" "SI")])
1587 (define_insn "popsi1"
1588 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1589 (mem:SI (reg:SI SP_REG)))
1590 (set (reg:SI SP_REG)
1591 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1594 [(set_attr "type" "pop")
1595 (set_attr "mode" "SI")])
1597 (define_insn "*movsi_xor"
1598 [(set (match_operand:SI 0 "register_operand" "=r")
1599 (match_operand:SI 1 "const0_operand" ""))
1600 (clobber (reg:CC FLAGS_REG))]
1603 [(set_attr "type" "alu1")
1604 (set_attr "mode" "SI")
1605 (set_attr "length_immediate" "0")])
1607 (define_insn "*movsi_or"
1608 [(set (match_operand:SI 0 "register_operand" "=r")
1609 (match_operand:SI 1 "immediate_operand" "i"))
1610 (clobber (reg:CC FLAGS_REG))]
1612 && operands[1] == constm1_rtx"
1614 operands[1] = constm1_rtx;
1615 return "or{l}\t{%1, %0|%0, %1}";
1617 [(set_attr "type" "alu1")
1618 (set_attr "mode" "SI")
1619 (set_attr "length_immediate" "1")])
1621 (define_insn "*movsi_1"
1622 [(set (match_operand:SI 0 "nonimmediate_operand"
1623 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1624 (match_operand:SI 1 "general_operand"
1625 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1626 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1628 switch (get_attr_type (insn))
1631 if (get_attr_mode (insn) == MODE_TI)
1632 return "%vpxor\t%0, %d0";
1633 return "%vxorps\t%0, %d0";
1636 switch (get_attr_mode (insn))
1639 return "%vmovdqa\t{%1, %0|%0, %1}";
1641 return "%vmovaps\t{%1, %0|%0, %1}";
1643 return "%vmovd\t{%1, %0|%0, %1}";
1645 return "%vmovss\t{%1, %0|%0, %1}";
1651 return "pxor\t%0, %0";
1654 if (get_attr_mode (insn) == MODE_DI)
1655 return "movq\t{%1, %0|%0, %1}";
1656 return "movd\t{%1, %0|%0, %1}";
1659 return "lea{l}\t{%1, %0|%0, %1}";
1662 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1663 return "mov{l}\t{%1, %0|%0, %1}";
1667 (cond [(eq_attr "alternative" "2")
1668 (const_string "mmx")
1669 (eq_attr "alternative" "3,4,5")
1670 (const_string "mmxmov")
1671 (eq_attr "alternative" "6")
1672 (const_string "sselog1")
1673 (eq_attr "alternative" "7,8,9,10,11")
1674 (const_string "ssemov")
1675 (match_operand:DI 1 "pic_32bit_operand" "")
1676 (const_string "lea")
1678 (const_string "imov")))
1679 (set (attr "prefix")
1680 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1681 (const_string "orig")
1682 (const_string "maybe_vex")))
1683 (set (attr "prefix_data16")
1684 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1686 (const_string "*")))
1688 (cond [(eq_attr "alternative" "2,3")
1690 (eq_attr "alternative" "6,7")
1692 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1693 (const_string "V4SF")
1694 (const_string "TI"))
1695 (and (eq_attr "alternative" "8,9,10,11")
1696 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1699 (const_string "SI")))])
1701 ;; Stores and loads of ax to arbitrary constant address.
1702 ;; We fake an second form of instruction to force reload to load address
1703 ;; into register when rax is not available
1704 (define_insn "*movabssi_1_rex64"
1705 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1706 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1707 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1709 movabs{l}\t{%1, %P0|%P0, %1}
1710 mov{l}\t{%1, %a0|%a0, %1}"
1711 [(set_attr "type" "imov")
1712 (set_attr "modrm" "0,*")
1713 (set_attr "length_address" "8,0")
1714 (set_attr "length_immediate" "0,*")
1715 (set_attr "memory" "store")
1716 (set_attr "mode" "SI")])
1718 (define_insn "*movabssi_2_rex64"
1719 [(set (match_operand:SI 0 "register_operand" "=a,r")
1720 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1721 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1723 movabs{l}\t{%P1, %0|%0, %P1}
1724 mov{l}\t{%a1, %0|%0, %a1}"
1725 [(set_attr "type" "imov")
1726 (set_attr "modrm" "0,*")
1727 (set_attr "length_address" "8,0")
1728 (set_attr "length_immediate" "0")
1729 (set_attr "memory" "load")
1730 (set_attr "mode" "SI")])
1732 (define_insn "*swapsi"
1733 [(set (match_operand:SI 0 "register_operand" "+r")
1734 (match_operand:SI 1 "register_operand" "+r"))
1739 [(set_attr "type" "imov")
1740 (set_attr "mode" "SI")
1741 (set_attr "pent_pair" "np")
1742 (set_attr "athlon_decode" "vector")
1743 (set_attr "amdfam10_decode" "double")])
1745 (define_expand "movhi"
1746 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1747 (match_operand:HI 1 "general_operand" ""))]
1749 "ix86_expand_move (HImode, operands); DONE;")
1751 (define_insn "*pushhi2"
1752 [(set (match_operand:HI 0 "push_operand" "=X")
1753 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1756 [(set_attr "type" "push")
1757 (set_attr "mode" "SI")])
1759 ;; For 64BIT abi we always round up to 8 bytes.
1760 (define_insn "*pushhi2_rex64"
1761 [(set (match_operand:HI 0 "push_operand" "=X")
1762 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1765 [(set_attr "type" "push")
1766 (set_attr "mode" "DI")])
1768 (define_insn "*movhi_1"
1769 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1770 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1771 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1773 switch (get_attr_type (insn))
1776 /* movzwl is faster than movw on p2 due to partial word stalls,
1777 though not as fast as an aligned movl. */
1778 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1780 if (get_attr_mode (insn) == MODE_SI)
1781 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1783 return "mov{w}\t{%1, %0|%0, %1}";
1787 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1788 (const_string "imov")
1789 (and (eq_attr "alternative" "0")
1790 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1792 (eq (symbol_ref "TARGET_HIMODE_MATH")
1794 (const_string "imov")
1795 (and (eq_attr "alternative" "1,2")
1796 (match_operand:HI 1 "aligned_operand" ""))
1797 (const_string "imov")
1798 (and (ne (symbol_ref "TARGET_MOVX")
1800 (eq_attr "alternative" "0,2"))
1801 (const_string "imovx")
1803 (const_string "imov")))
1805 (cond [(eq_attr "type" "imovx")
1807 (and (eq_attr "alternative" "1,2")
1808 (match_operand:HI 1 "aligned_operand" ""))
1810 (and (eq_attr "alternative" "0")
1811 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1813 (eq (symbol_ref "TARGET_HIMODE_MATH")
1817 (const_string "HI")))])
1819 ;; Stores and loads of ax to arbitrary constant address.
1820 ;; We fake an second form of instruction to force reload to load address
1821 ;; into register when rax is not available
1822 (define_insn "*movabshi_1_rex64"
1823 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1824 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1825 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1827 movabs{w}\t{%1, %P0|%P0, %1}
1828 mov{w}\t{%1, %a0|%a0, %1}"
1829 [(set_attr "type" "imov")
1830 (set_attr "modrm" "0,*")
1831 (set_attr "length_address" "8,0")
1832 (set_attr "length_immediate" "0,*")
1833 (set_attr "memory" "store")
1834 (set_attr "mode" "HI")])
1836 (define_insn "*movabshi_2_rex64"
1837 [(set (match_operand:HI 0 "register_operand" "=a,r")
1838 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1839 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1841 movabs{w}\t{%P1, %0|%0, %P1}
1842 mov{w}\t{%a1, %0|%0, %a1}"
1843 [(set_attr "type" "imov")
1844 (set_attr "modrm" "0,*")
1845 (set_attr "length_address" "8,0")
1846 (set_attr "length_immediate" "0")
1847 (set_attr "memory" "load")
1848 (set_attr "mode" "HI")])
1850 (define_insn "*swaphi_1"
1851 [(set (match_operand:HI 0 "register_operand" "+r")
1852 (match_operand:HI 1 "register_operand" "+r"))
1855 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1857 [(set_attr "type" "imov")
1858 (set_attr "mode" "SI")
1859 (set_attr "pent_pair" "np")
1860 (set_attr "athlon_decode" "vector")
1861 (set_attr "amdfam10_decode" "double")])
1863 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1864 (define_insn "*swaphi_2"
1865 [(set (match_operand:HI 0 "register_operand" "+r")
1866 (match_operand:HI 1 "register_operand" "+r"))
1869 "TARGET_PARTIAL_REG_STALL"
1871 [(set_attr "type" "imov")
1872 (set_attr "mode" "HI")
1873 (set_attr "pent_pair" "np")
1874 (set_attr "athlon_decode" "vector")])
1876 (define_expand "movstricthi"
1877 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1878 (match_operand:HI 1 "general_operand" ""))]
1881 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1883 /* Don't generate memory->memory moves, go through a register */
1884 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1885 operands[1] = force_reg (HImode, operands[1]);
1888 (define_insn "*movstricthi_1"
1889 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1890 (match_operand:HI 1 "general_operand" "rn,m"))]
1891 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1892 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1893 "mov{w}\t{%1, %0|%0, %1}"
1894 [(set_attr "type" "imov")
1895 (set_attr "mode" "HI")])
1897 (define_insn "*movstricthi_xor"
1898 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1899 (match_operand:HI 1 "const0_operand" ""))
1900 (clobber (reg:CC FLAGS_REG))]
1903 [(set_attr "type" "alu1")
1904 (set_attr "mode" "HI")
1905 (set_attr "length_immediate" "0")])
1907 (define_expand "movqi"
1908 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1909 (match_operand:QI 1 "general_operand" ""))]
1911 "ix86_expand_move (QImode, operands); DONE;")
1913 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1914 ;; "push a byte". But actually we use pushl, which has the effect
1915 ;; of rounding the amount pushed up to a word.
1917 (define_insn "*pushqi2"
1918 [(set (match_operand:QI 0 "push_operand" "=X")
1919 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1922 [(set_attr "type" "push")
1923 (set_attr "mode" "SI")])
1925 ;; For 64BIT abi we always round up to 8 bytes.
1926 (define_insn "*pushqi2_rex64"
1927 [(set (match_operand:QI 0 "push_operand" "=X")
1928 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1931 [(set_attr "type" "push")
1932 (set_attr "mode" "DI")])
1934 ;; Situation is quite tricky about when to choose full sized (SImode) move
1935 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1936 ;; partial register dependency machines (such as AMD Athlon), where QImode
1937 ;; moves issue extra dependency and for partial register stalls machines
1938 ;; that don't use QImode patterns (and QImode move cause stall on the next
1941 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1942 ;; register stall machines with, where we use QImode instructions, since
1943 ;; partial register stall can be caused there. Then we use movzx.
1944 (define_insn "*movqi_1"
1945 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1946 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1947 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1949 switch (get_attr_type (insn))
1952 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1953 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1955 if (get_attr_mode (insn) == MODE_SI)
1956 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1958 return "mov{b}\t{%1, %0|%0, %1}";
1962 (cond [(and (eq_attr "alternative" "5")
1963 (not (match_operand:QI 1 "aligned_operand" "")))
1964 (const_string "imovx")
1965 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1966 (const_string "imov")
1967 (and (eq_attr "alternative" "3")
1968 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1970 (eq (symbol_ref "TARGET_QIMODE_MATH")
1972 (const_string "imov")
1973 (eq_attr "alternative" "3,5")
1974 (const_string "imovx")
1975 (and (ne (symbol_ref "TARGET_MOVX")
1977 (eq_attr "alternative" "2"))
1978 (const_string "imovx")
1980 (const_string "imov")))
1982 (cond [(eq_attr "alternative" "3,4,5")
1984 (eq_attr "alternative" "6")
1986 (eq_attr "type" "imovx")
1988 (and (eq_attr "type" "imov")
1989 (and (eq_attr "alternative" "0,1")
1990 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1992 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1994 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1997 ;; Avoid partial register stalls when not using QImode arithmetic
1998 (and (eq_attr "type" "imov")
1999 (and (eq_attr "alternative" "0,1")
2000 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2002 (eq (symbol_ref "TARGET_QIMODE_MATH")
2006 (const_string "QI")))])
2008 (define_insn "*swapqi_1"
2009 [(set (match_operand:QI 0 "register_operand" "+r")
2010 (match_operand:QI 1 "register_operand" "+r"))
2013 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2015 [(set_attr "type" "imov")
2016 (set_attr "mode" "SI")
2017 (set_attr "pent_pair" "np")
2018 (set_attr "athlon_decode" "vector")
2019 (set_attr "amdfam10_decode" "vector")])
2021 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2022 (define_insn "*swapqi_2"
2023 [(set (match_operand:QI 0 "register_operand" "+q")
2024 (match_operand:QI 1 "register_operand" "+q"))
2027 "TARGET_PARTIAL_REG_STALL"
2029 [(set_attr "type" "imov")
2030 (set_attr "mode" "QI")
2031 (set_attr "pent_pair" "np")
2032 (set_attr "athlon_decode" "vector")])
2034 (define_expand "movstrictqi"
2035 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2036 (match_operand:QI 1 "general_operand" ""))]
2039 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2041 /* Don't generate memory->memory moves, go through a register. */
2042 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2043 operands[1] = force_reg (QImode, operands[1]);
2046 (define_insn "*movstrictqi_1"
2047 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2048 (match_operand:QI 1 "general_operand" "*qn,m"))]
2049 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2050 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2051 "mov{b}\t{%1, %0|%0, %1}"
2052 [(set_attr "type" "imov")
2053 (set_attr "mode" "QI")])
2055 (define_insn "*movstrictqi_xor"
2056 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2057 (match_operand:QI 1 "const0_operand" ""))
2058 (clobber (reg:CC FLAGS_REG))]
2061 [(set_attr "type" "alu1")
2062 (set_attr "mode" "QI")
2063 (set_attr "length_immediate" "0")])
2065 (define_insn "*movsi_extv_1"
2066 [(set (match_operand:SI 0 "register_operand" "=R")
2067 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2071 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2072 [(set_attr "type" "imovx")
2073 (set_attr "mode" "SI")])
2075 (define_insn "*movhi_extv_1"
2076 [(set (match_operand:HI 0 "register_operand" "=R")
2077 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2081 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2082 [(set_attr "type" "imovx")
2083 (set_attr "mode" "SI")])
2085 (define_insn "*movqi_extv_1"
2086 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2087 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2092 switch (get_attr_type (insn))
2095 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2097 return "mov{b}\t{%h1, %0|%0, %h1}";
2101 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2102 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2103 (ne (symbol_ref "TARGET_MOVX")
2105 (const_string "imovx")
2106 (const_string "imov")))
2108 (if_then_else (eq_attr "type" "imovx")
2110 (const_string "QI")))])
2112 (define_insn "*movqi_extv_1_rex64"
2113 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2114 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2119 switch (get_attr_type (insn))
2122 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2124 return "mov{b}\t{%h1, %0|%0, %h1}";
2128 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2129 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2130 (ne (symbol_ref "TARGET_MOVX")
2132 (const_string "imovx")
2133 (const_string "imov")))
2135 (if_then_else (eq_attr "type" "imovx")
2137 (const_string "QI")))])
2139 ;; Stores and loads of ax to arbitrary constant address.
2140 ;; We fake an second form of instruction to force reload to load address
2141 ;; into register when rax is not available
2142 (define_insn "*movabsqi_1_rex64"
2143 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2144 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2145 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2147 movabs{b}\t{%1, %P0|%P0, %1}
2148 mov{b}\t{%1, %a0|%a0, %1}"
2149 [(set_attr "type" "imov")
2150 (set_attr "modrm" "0,*")
2151 (set_attr "length_address" "8,0")
2152 (set_attr "length_immediate" "0,*")
2153 (set_attr "memory" "store")
2154 (set_attr "mode" "QI")])
2156 (define_insn "*movabsqi_2_rex64"
2157 [(set (match_operand:QI 0 "register_operand" "=a,r")
2158 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2159 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2161 movabs{b}\t{%P1, %0|%0, %P1}
2162 mov{b}\t{%a1, %0|%0, %a1}"
2163 [(set_attr "type" "imov")
2164 (set_attr "modrm" "0,*")
2165 (set_attr "length_address" "8,0")
2166 (set_attr "length_immediate" "0")
2167 (set_attr "memory" "load")
2168 (set_attr "mode" "QI")])
2170 (define_insn "*movdi_extzv_1"
2171 [(set (match_operand:DI 0 "register_operand" "=R")
2172 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2176 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2177 [(set_attr "type" "imovx")
2178 (set_attr "mode" "SI")])
2180 (define_insn "*movsi_extzv_1"
2181 [(set (match_operand:SI 0 "register_operand" "=R")
2182 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2186 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2187 [(set_attr "type" "imovx")
2188 (set_attr "mode" "SI")])
2190 (define_insn "*movqi_extzv_2"
2191 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2192 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2197 switch (get_attr_type (insn))
2200 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2202 return "mov{b}\t{%h1, %0|%0, %h1}";
2206 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2207 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2208 (ne (symbol_ref "TARGET_MOVX")
2210 (const_string "imovx")
2211 (const_string "imov")))
2213 (if_then_else (eq_attr "type" "imovx")
2215 (const_string "QI")))])
2217 (define_insn "*movqi_extzv_2_rex64"
2218 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2219 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2224 switch (get_attr_type (insn))
2227 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2229 return "mov{b}\t{%h1, %0|%0, %h1}";
2233 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2234 (ne (symbol_ref "TARGET_MOVX")
2236 (const_string "imovx")
2237 (const_string "imov")))
2239 (if_then_else (eq_attr "type" "imovx")
2241 (const_string "QI")))])
2243 (define_insn "movsi_insv_1"
2244 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2247 (match_operand:SI 1 "general_operand" "Qmn"))]
2249 "mov{b}\t{%b1, %h0|%h0, %b1}"
2250 [(set_attr "type" "imov")
2251 (set_attr "mode" "QI")])
2253 (define_insn "*movsi_insv_1_rex64"
2254 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2257 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2259 "mov{b}\t{%b1, %h0|%h0, %b1}"
2260 [(set_attr "type" "imov")
2261 (set_attr "mode" "QI")])
2263 (define_insn "movdi_insv_1_rex64"
2264 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2267 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2269 "mov{b}\t{%b1, %h0|%h0, %b1}"
2270 [(set_attr "type" "imov")
2271 (set_attr "mode" "QI")])
2273 (define_insn "*movqi_insv_2"
2274 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2277 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2280 "mov{b}\t{%h1, %h0|%h0, %h1}"
2281 [(set_attr "type" "imov")
2282 (set_attr "mode" "QI")])
2284 (define_expand "movdi"
2285 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2286 (match_operand:DI 1 "general_operand" ""))]
2288 "ix86_expand_move (DImode, operands); DONE;")
2290 (define_insn "*pushdi"
2291 [(set (match_operand:DI 0 "push_operand" "=<")
2292 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2296 (define_insn "*pushdi2_rex64"
2297 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2298 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2303 [(set_attr "type" "push,multi")
2304 (set_attr "mode" "DI")])
2306 ;; Convert impossible pushes of immediate to existing instructions.
2307 ;; First try to get scratch register and go through it. In case this
2308 ;; fails, push sign extended lower part first and then overwrite
2309 ;; upper part by 32bit move.
2311 [(match_scratch:DI 2 "r")
2312 (set (match_operand:DI 0 "push_operand" "")
2313 (match_operand:DI 1 "immediate_operand" ""))]
2314 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2315 && !x86_64_immediate_operand (operands[1], DImode)"
2316 [(set (match_dup 2) (match_dup 1))
2317 (set (match_dup 0) (match_dup 2))]
2320 ;; We need to define this as both peepholer and splitter for case
2321 ;; peephole2 pass is not run.
2322 ;; "&& 1" is needed to keep it from matching the previous pattern.
2324 [(set (match_operand:DI 0 "push_operand" "")
2325 (match_operand:DI 1 "immediate_operand" ""))]
2326 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2327 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2328 [(set (match_dup 0) (match_dup 1))
2329 (set (match_dup 2) (match_dup 3))]
2330 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2331 operands[1] = gen_lowpart (DImode, operands[2]);
2332 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2337 [(set (match_operand:DI 0 "push_operand" "")
2338 (match_operand:DI 1 "immediate_operand" ""))]
2339 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2340 ? epilogue_completed : reload_completed)
2341 && !symbolic_operand (operands[1], DImode)
2342 && !x86_64_immediate_operand (operands[1], DImode)"
2343 [(set (match_dup 0) (match_dup 1))
2344 (set (match_dup 2) (match_dup 3))]
2345 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2346 operands[1] = gen_lowpart (DImode, operands[2]);
2347 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2351 (define_insn "*pushdi2_prologue_rex64"
2352 [(set (match_operand:DI 0 "push_operand" "=<")
2353 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2354 (clobber (mem:BLK (scratch)))]
2357 [(set_attr "type" "push")
2358 (set_attr "mode" "DI")])
2360 (define_insn "*popdi1_epilogue_rex64"
2361 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2362 (mem:DI (reg:DI SP_REG)))
2363 (set (reg:DI SP_REG)
2364 (plus:DI (reg:DI SP_REG) (const_int 8)))
2365 (clobber (mem:BLK (scratch)))]
2368 [(set_attr "type" "pop")
2369 (set_attr "mode" "DI")])
2371 (define_insn "popdi1"
2372 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2373 (mem:DI (reg:DI SP_REG)))
2374 (set (reg:DI SP_REG)
2375 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2378 [(set_attr "type" "pop")
2379 (set_attr "mode" "DI")])
2381 (define_insn "*movdi_xor_rex64"
2382 [(set (match_operand:DI 0 "register_operand" "=r")
2383 (match_operand:DI 1 "const0_operand" ""))
2384 (clobber (reg:CC FLAGS_REG))]
2386 && reload_completed"
2388 [(set_attr "type" "alu1")
2389 (set_attr "mode" "SI")
2390 (set_attr "length_immediate" "0")])
2392 (define_insn "*movdi_or_rex64"
2393 [(set (match_operand:DI 0 "register_operand" "=r")
2394 (match_operand:DI 1 "const_int_operand" "i"))
2395 (clobber (reg:CC FLAGS_REG))]
2398 && operands[1] == constm1_rtx"
2400 operands[1] = constm1_rtx;
2401 return "or{q}\t{%1, %0|%0, %1}";
2403 [(set_attr "type" "alu1")
2404 (set_attr "mode" "DI")
2405 (set_attr "length_immediate" "1")])
2407 (define_insn "*movdi_2"
2408 [(set (match_operand:DI 0 "nonimmediate_operand"
2409 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2410 (match_operand:DI 1 "general_operand"
2411 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2412 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2417 movq\t{%1, %0|%0, %1}
2418 movq\t{%1, %0|%0, %1}
2420 %vmovq\t{%1, %0|%0, %1}
2421 %vmovdqa\t{%1, %0|%0, %1}
2422 %vmovq\t{%1, %0|%0, %1}
2424 movlps\t{%1, %0|%0, %1}
2425 movaps\t{%1, %0|%0, %1}
2426 movlps\t{%1, %0|%0, %1}"
2427 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2428 (set (attr "prefix")
2429 (if_then_else (eq_attr "alternative" "5,6,7,8")
2430 (const_string "vex")
2431 (const_string "orig")))
2432 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2435 [(set (match_operand:DI 0 "push_operand" "")
2436 (match_operand:DI 1 "general_operand" ""))]
2437 "!TARGET_64BIT && reload_completed
2438 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2440 "ix86_split_long_move (operands); DONE;")
2442 ;; %%% This multiword shite has got to go.
2444 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2445 (match_operand:DI 1 "general_operand" ""))]
2446 "!TARGET_64BIT && reload_completed
2447 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2448 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2450 "ix86_split_long_move (operands); DONE;")
2452 (define_insn "*movdi_1_rex64"
2453 [(set (match_operand:DI 0 "nonimmediate_operand"
2454 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2455 (match_operand:DI 1 "general_operand"
2456 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2457 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2459 switch (get_attr_type (insn))
2462 if (SSE_REG_P (operands[0]))
2463 return "movq2dq\t{%1, %0|%0, %1}";
2465 return "movdq2q\t{%1, %0|%0, %1}";
2470 if (get_attr_mode (insn) == MODE_TI)
2471 return "vmovdqa\t{%1, %0|%0, %1}";
2473 return "vmovq\t{%1, %0|%0, %1}";
2476 if (get_attr_mode (insn) == MODE_TI)
2477 return "movdqa\t{%1, %0|%0, %1}";
2481 /* Moves from and into integer register is done using movd
2482 opcode with REX prefix. */
2483 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2484 return "movd\t{%1, %0|%0, %1}";
2485 return "movq\t{%1, %0|%0, %1}";
2488 return "%vpxor\t%0, %d0";
2491 return "pxor\t%0, %0";
2497 return "lea{q}\t{%a1, %0|%0, %a1}";
2500 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2501 if (get_attr_mode (insn) == MODE_SI)
2502 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2503 else if (which_alternative == 2)
2504 return "movabs{q}\t{%1, %0|%0, %1}";
2506 return "mov{q}\t{%1, %0|%0, %1}";
2510 (cond [(eq_attr "alternative" "5")
2511 (const_string "mmx")
2512 (eq_attr "alternative" "6,7,8,9,10")
2513 (const_string "mmxmov")
2514 (eq_attr "alternative" "11")
2515 (const_string "sselog1")
2516 (eq_attr "alternative" "12,13,14,15,16")
2517 (const_string "ssemov")
2518 (eq_attr "alternative" "17,18")
2519 (const_string "ssecvt")
2520 (eq_attr "alternative" "4")
2521 (const_string "multi")
2522 (match_operand:DI 1 "pic_32bit_operand" "")
2523 (const_string "lea")
2525 (const_string "imov")))
2528 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2530 (const_string "*")))
2531 (set (attr "length_immediate")
2533 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2535 (const_string "*")))
2536 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2537 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2538 (set (attr "prefix")
2539 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2540 (const_string "maybe_vex")
2541 (const_string "orig")))
2542 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2544 ;; Stores and loads of ax to arbitrary constant address.
2545 ;; We fake an second form of instruction to force reload to load address
2546 ;; into register when rax is not available
2547 (define_insn "*movabsdi_1_rex64"
2548 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2549 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2550 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2552 movabs{q}\t{%1, %P0|%P0, %1}
2553 mov{q}\t{%1, %a0|%a0, %1}"
2554 [(set_attr "type" "imov")
2555 (set_attr "modrm" "0,*")
2556 (set_attr "length_address" "8,0")
2557 (set_attr "length_immediate" "0,*")
2558 (set_attr "memory" "store")
2559 (set_attr "mode" "DI")])
2561 (define_insn "*movabsdi_2_rex64"
2562 [(set (match_operand:DI 0 "register_operand" "=a,r")
2563 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2564 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2566 movabs{q}\t{%P1, %0|%0, %P1}
2567 mov{q}\t{%a1, %0|%0, %a1}"
2568 [(set_attr "type" "imov")
2569 (set_attr "modrm" "0,*")
2570 (set_attr "length_address" "8,0")
2571 (set_attr "length_immediate" "0")
2572 (set_attr "memory" "load")
2573 (set_attr "mode" "DI")])
2575 ;; Convert impossible stores of immediate to existing instructions.
2576 ;; First try to get scratch register and go through it. In case this
2577 ;; fails, move by 32bit parts.
2579 [(match_scratch:DI 2 "r")
2580 (set (match_operand:DI 0 "memory_operand" "")
2581 (match_operand:DI 1 "immediate_operand" ""))]
2582 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2583 && !x86_64_immediate_operand (operands[1], DImode)"
2584 [(set (match_dup 2) (match_dup 1))
2585 (set (match_dup 0) (match_dup 2))]
2588 ;; We need to define this as both peepholer and splitter for case
2589 ;; peephole2 pass is not run.
2590 ;; "&& 1" is needed to keep it from matching the previous pattern.
2592 [(set (match_operand:DI 0 "memory_operand" "")
2593 (match_operand:DI 1 "immediate_operand" ""))]
2594 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2595 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2596 [(set (match_dup 2) (match_dup 3))
2597 (set (match_dup 4) (match_dup 5))]
2598 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2601 [(set (match_operand:DI 0 "memory_operand" "")
2602 (match_operand:DI 1 "immediate_operand" ""))]
2603 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2604 ? epilogue_completed : reload_completed)
2605 && !symbolic_operand (operands[1], DImode)
2606 && !x86_64_immediate_operand (operands[1], DImode)"
2607 [(set (match_dup 2) (match_dup 3))
2608 (set (match_dup 4) (match_dup 5))]
2609 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2611 (define_insn "*swapdi_rex64"
2612 [(set (match_operand:DI 0 "register_operand" "+r")
2613 (match_operand:DI 1 "register_operand" "+r"))
2618 [(set_attr "type" "imov")
2619 (set_attr "mode" "DI")
2620 (set_attr "pent_pair" "np")
2621 (set_attr "athlon_decode" "vector")
2622 (set_attr "amdfam10_decode" "double")])
2624 (define_expand "movoi"
2625 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2626 (match_operand:OI 1 "general_operand" ""))]
2628 "ix86_expand_move (OImode, operands); DONE;")
2630 (define_insn "*movoi_internal"
2631 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2632 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2634 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2636 switch (which_alternative)
2639 return "vxorps\t%0, %0, %0";
2642 if (misaligned_operand (operands[0], OImode)
2643 || misaligned_operand (operands[1], OImode))
2644 return "vmovdqu\t{%1, %0|%0, %1}";
2646 return "vmovdqa\t{%1, %0|%0, %1}";
2651 [(set_attr "type" "sselog1,ssemov,ssemov")
2652 (set_attr "prefix" "vex")
2653 (set_attr "mode" "OI")])
2655 (define_expand "movti"
2656 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2657 (match_operand:TI 1 "nonimmediate_operand" ""))]
2658 "TARGET_SSE || TARGET_64BIT"
2661 ix86_expand_move (TImode, operands);
2662 else if (push_operand (operands[0], TImode))
2663 ix86_expand_push (TImode, operands[1]);
2665 ix86_expand_vector_move (TImode, operands);
2669 (define_insn "*movti_internal"
2670 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2671 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2672 "TARGET_SSE && !TARGET_64BIT
2673 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2675 switch (which_alternative)
2678 if (get_attr_mode (insn) == MODE_V4SF)
2679 return "%vxorps\t%0, %d0";
2681 return "%vpxor\t%0, %d0";
2684 /* TDmode values are passed as TImode on the stack. Moving them
2685 to stack may result in unaligned memory access. */
2686 if (misaligned_operand (operands[0], TImode)
2687 || misaligned_operand (operands[1], TImode))
2689 if (get_attr_mode (insn) == MODE_V4SF)
2690 return "%vmovups\t{%1, %0|%0, %1}";
2692 return "%vmovdqu\t{%1, %0|%0, %1}";
2696 if (get_attr_mode (insn) == MODE_V4SF)
2697 return "%vmovaps\t{%1, %0|%0, %1}";
2699 return "%vmovdqa\t{%1, %0|%0, %1}";
2705 [(set_attr "type" "sselog1,ssemov,ssemov")
2706 (set_attr "prefix" "maybe_vex")
2708 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2709 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2710 (const_string "V4SF")
2711 (and (eq_attr "alternative" "2")
2712 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2714 (const_string "V4SF")]
2715 (const_string "TI")))])
2717 (define_insn "*movti_rex64"
2718 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2719 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2721 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2723 switch (which_alternative)
2729 if (get_attr_mode (insn) == MODE_V4SF)
2730 return "%vxorps\t%0, %d0";
2732 return "%vpxor\t%0, %d0";
2735 /* TDmode values are passed as TImode on the stack. Moving them
2736 to stack may result in unaligned memory access. */
2737 if (misaligned_operand (operands[0], TImode)
2738 || misaligned_operand (operands[1], TImode))
2740 if (get_attr_mode (insn) == MODE_V4SF)
2741 return "%vmovups\t{%1, %0|%0, %1}";
2743 return "%vmovdqu\t{%1, %0|%0, %1}";
2747 if (get_attr_mode (insn) == MODE_V4SF)
2748 return "%vmovaps\t{%1, %0|%0, %1}";
2750 return "%vmovdqa\t{%1, %0|%0, %1}";
2756 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2757 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2759 (cond [(eq_attr "alternative" "2,3")
2761 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2763 (const_string "V4SF")
2764 (const_string "TI"))
2765 (eq_attr "alternative" "4")
2767 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2769 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2771 (const_string "V4SF")
2772 (const_string "TI"))]
2773 (const_string "DI")))])
2776 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2777 (match_operand:TI 1 "general_operand" ""))]
2778 "reload_completed && !SSE_REG_P (operands[0])
2779 && !SSE_REG_P (operands[1])"
2781 "ix86_split_long_move (operands); DONE;")
2783 ;; This expands to what emit_move_complex would generate if we didn't
2784 ;; have a movti pattern. Having this avoids problems with reload on
2785 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2786 ;; to have around all the time.
2787 (define_expand "movcdi"
2788 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2789 (match_operand:CDI 1 "general_operand" ""))]
2792 if (push_operand (operands[0], CDImode))
2793 emit_move_complex_push (CDImode, operands[0], operands[1]);
2795 emit_move_complex_parts (operands[0], operands[1]);
2799 (define_expand "movsf"
2800 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2801 (match_operand:SF 1 "general_operand" ""))]
2803 "ix86_expand_move (SFmode, operands); DONE;")
2805 (define_insn "*pushsf"
2806 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2807 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2810 /* Anything else should be already split before reg-stack. */
2811 gcc_assert (which_alternative == 1);
2812 return "push{l}\t%1";
2814 [(set_attr "type" "multi,push,multi")
2815 (set_attr "unit" "i387,*,*")
2816 (set_attr "mode" "SF,SI,SF")])
2818 (define_insn "*pushsf_rex64"
2819 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2820 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2823 /* Anything else should be already split before reg-stack. */
2824 gcc_assert (which_alternative == 1);
2825 return "push{q}\t%q1";
2827 [(set_attr "type" "multi,push,multi")
2828 (set_attr "unit" "i387,*,*")
2829 (set_attr "mode" "SF,DI,SF")])
2832 [(set (match_operand:SF 0 "push_operand" "")
2833 (match_operand:SF 1 "memory_operand" ""))]
2835 && MEM_P (operands[1])
2836 && (operands[2] = find_constant_src (insn))"
2840 ;; %%% Kill this when call knows how to work this out.
2842 [(set (match_operand:SF 0 "push_operand" "")
2843 (match_operand:SF 1 "any_fp_register_operand" ""))]
2845 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2846 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2849 [(set (match_operand:SF 0 "push_operand" "")
2850 (match_operand:SF 1 "any_fp_register_operand" ""))]
2852 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2853 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2855 (define_insn "*movsf_1"
2856 [(set (match_operand:SF 0 "nonimmediate_operand"
2857 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2858 (match_operand:SF 1 "general_operand"
2859 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2860 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2861 && (reload_in_progress || reload_completed
2862 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2863 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2864 && standard_80387_constant_p (operands[1]))
2865 || GET_CODE (operands[1]) != CONST_DOUBLE
2866 || memory_operand (operands[0], SFmode))"
2868 switch (which_alternative)
2872 return output_387_reg_move (insn, operands);
2875 return standard_80387_constant_opcode (operands[1]);
2879 return "mov{l}\t{%1, %0|%0, %1}";
2881 if (get_attr_mode (insn) == MODE_TI)
2882 return "%vpxor\t%0, %d0";
2884 return "%vxorps\t%0, %d0";
2886 if (get_attr_mode (insn) == MODE_V4SF)
2887 return "%vmovaps\t{%1, %0|%0, %1}";
2889 return "%vmovss\t{%1, %d0|%d0, %1}";
2892 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2893 : "vmovss\t{%1, %0|%0, %1}";
2895 return "movss\t{%1, %0|%0, %1}";
2897 return "%vmovss\t{%1, %0|%0, %1}";
2899 case 9: case 10: case 14: case 15:
2900 return "movd\t{%1, %0|%0, %1}";
2902 return "%vmovd\t{%1, %0|%0, %1}";
2905 return "movq\t{%1, %0|%0, %1}";
2911 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2912 (set (attr "prefix")
2913 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2914 (const_string "maybe_vex")
2915 (const_string "orig")))
2917 (cond [(eq_attr "alternative" "3,4,9,10")
2919 (eq_attr "alternative" "5")
2921 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2923 (ne (symbol_ref "TARGET_SSE2")
2925 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2928 (const_string "V4SF"))
2929 /* For architectures resolving dependencies on
2930 whole SSE registers use APS move to break dependency
2931 chains, otherwise use short move to avoid extra work.
2933 Do the same for architectures resolving dependencies on
2934 the parts. While in DF mode it is better to always handle
2935 just register parts, the SF mode is different due to lack
2936 of instructions to load just part of the register. It is
2937 better to maintain the whole registers in single format
2938 to avoid problems on using packed logical operations. */
2939 (eq_attr "alternative" "6")
2941 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2943 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2945 (const_string "V4SF")
2946 (const_string "SF"))
2947 (eq_attr "alternative" "11")
2948 (const_string "DI")]
2949 (const_string "SF")))])
2951 (define_insn "*swapsf"
2952 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2953 (match_operand:SF 1 "fp_register_operand" "+f"))
2956 "reload_completed || TARGET_80387"
2958 if (STACK_TOP_P (operands[0]))
2963 [(set_attr "type" "fxch")
2964 (set_attr "mode" "SF")])
2966 (define_expand "movdf"
2967 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2968 (match_operand:DF 1 "general_operand" ""))]
2970 "ix86_expand_move (DFmode, operands); DONE;")
2972 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2973 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2974 ;; On the average, pushdf using integers can be still shorter. Allow this
2975 ;; pattern for optimize_size too.
2977 (define_insn "*pushdf_nointeger"
2978 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2979 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2980 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2982 /* This insn should be already split before reg-stack. */
2985 [(set_attr "type" "multi")
2986 (set_attr "unit" "i387,*,*,*")
2987 (set_attr "mode" "DF,SI,SI,DF")])
2989 (define_insn "*pushdf_integer"
2990 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2991 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2992 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2994 /* This insn should be already split before reg-stack. */
2997 [(set_attr "type" "multi")
2998 (set_attr "unit" "i387,*,*")
2999 (set_attr "mode" "DF,SI,DF")])
3001 ;; %%% Kill this when call knows how to work this out.
3003 [(set (match_operand:DF 0 "push_operand" "")
3004 (match_operand:DF 1 "any_fp_register_operand" ""))]
3006 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3007 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3011 [(set (match_operand:DF 0 "push_operand" "")
3012 (match_operand:DF 1 "general_operand" ""))]
3015 "ix86_split_long_move (operands); DONE;")
3017 ;; Moving is usually shorter when only FP registers are used. This separate
3018 ;; movdf pattern avoids the use of integer registers for FP operations
3019 ;; when optimizing for size.
3021 (define_insn "*movdf_nointeger"
3022 [(set (match_operand:DF 0 "nonimmediate_operand"
3023 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3024 (match_operand:DF 1 "general_operand"
3025 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3026 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3027 && ((optimize_function_for_size_p (cfun)
3028 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3029 && (reload_in_progress || reload_completed
3030 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3031 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3032 && optimize_function_for_size_p (cfun)
3033 && !memory_operand (operands[0], DFmode)
3034 && standard_80387_constant_p (operands[1]))
3035 || GET_CODE (operands[1]) != CONST_DOUBLE
3036 || ((optimize_function_for_size_p (cfun)
3037 || !TARGET_MEMORY_MISMATCH_STALL
3038 || reload_in_progress || reload_completed)
3039 && memory_operand (operands[0], DFmode)))"
3041 switch (which_alternative)
3045 return output_387_reg_move (insn, operands);
3048 return standard_80387_constant_opcode (operands[1]);
3054 switch (get_attr_mode (insn))
3057 return "%vxorps\t%0, %d0";
3059 return "%vxorpd\t%0, %d0";
3061 return "%vpxor\t%0, %d0";
3068 switch (get_attr_mode (insn))
3071 return "%vmovaps\t{%1, %0|%0, %1}";
3073 return "%vmovapd\t{%1, %0|%0, %1}";
3075 return "%vmovdqa\t{%1, %0|%0, %1}";
3077 return "%vmovq\t{%1, %0|%0, %1}";
3081 if (REG_P (operands[0]) && REG_P (operands[1]))
3082 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3084 return "vmovsd\t{%1, %0|%0, %1}";
3087 return "movsd\t{%1, %0|%0, %1}";
3091 if (REG_P (operands[0]))
3092 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3094 return "vmovlpd\t{%1, %0|%0, %1}";
3097 return "movlpd\t{%1, %0|%0, %1}";
3101 if (REG_P (operands[0]))
3102 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3104 return "vmovlps\t{%1, %0|%0, %1}";
3107 return "movlps\t{%1, %0|%0, %1}";
3116 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3117 (set (attr "prefix")
3118 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3119 (const_string "orig")
3120 (const_string "maybe_vex")))
3121 (set (attr "prefix_data16")
3122 (if_then_else (eq_attr "mode" "V1DF")
3124 (const_string "*")))
3126 (cond [(eq_attr "alternative" "0,1,2")
3128 (eq_attr "alternative" "3,4")
3131 /* For SSE1, we have many fewer alternatives. */
3132 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3133 (cond [(eq_attr "alternative" "5,6")
3134 (const_string "V4SF")
3136 (const_string "V2SF"))
3138 /* xorps is one byte shorter. */
3139 (eq_attr "alternative" "5")
3140 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3142 (const_string "V4SF")
3143 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3147 (const_string "V2DF"))
3149 /* For architectures resolving dependencies on
3150 whole SSE registers use APD move to break dependency
3151 chains, otherwise use short move to avoid extra work.
3153 movaps encodes one byte shorter. */
3154 (eq_attr "alternative" "6")
3156 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3158 (const_string "V4SF")
3159 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3161 (const_string "V2DF")
3163 (const_string "DF"))
3164 /* For architectures resolving dependencies on register
3165 parts we may avoid extra work to zero out upper part
3167 (eq_attr "alternative" "7")
3169 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3171 (const_string "V1DF")
3172 (const_string "DF"))
3174 (const_string "DF")))])
3176 (define_insn "*movdf_integer_rex64"
3177 [(set (match_operand:DF 0 "nonimmediate_operand"
3178 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3179 (match_operand:DF 1 "general_operand"
3180 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3181 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3182 && (reload_in_progress || reload_completed
3183 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3184 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3185 && optimize_function_for_size_p (cfun)
3186 && standard_80387_constant_p (operands[1]))
3187 || GET_CODE (operands[1]) != CONST_DOUBLE
3188 || memory_operand (operands[0], DFmode))"
3190 switch (which_alternative)
3194 return output_387_reg_move (insn, operands);
3197 return standard_80387_constant_opcode (operands[1]);
3204 switch (get_attr_mode (insn))
3207 return "%vxorps\t%0, %d0";
3209 return "%vxorpd\t%0, %d0";
3211 return "%vpxor\t%0, %d0";
3218 switch (get_attr_mode (insn))
3221 return "%vmovaps\t{%1, %0|%0, %1}";
3223 return "%vmovapd\t{%1, %0|%0, %1}";
3225 return "%vmovdqa\t{%1, %0|%0, %1}";
3227 return "%vmovq\t{%1, %0|%0, %1}";
3231 if (REG_P (operands[0]) && REG_P (operands[1]))
3232 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3234 return "vmovsd\t{%1, %0|%0, %1}";
3237 return "movsd\t{%1, %0|%0, %1}";
3239 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3241 return "%vmovlps\t{%1, %d0|%d0, %1}";
3248 return "%vmovd\t{%1, %0|%0, %1}";
3254 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3255 (set (attr "prefix")
3256 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3257 (const_string "orig")
3258 (const_string "maybe_vex")))
3259 (set (attr "prefix_data16")
3260 (if_then_else (eq_attr "mode" "V1DF")
3262 (const_string "*")))
3264 (cond [(eq_attr "alternative" "0,1,2")
3266 (eq_attr "alternative" "3,4,9,10")
3269 /* For SSE1, we have many fewer alternatives. */
3270 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3271 (cond [(eq_attr "alternative" "5,6")
3272 (const_string "V4SF")
3274 (const_string "V2SF"))
3276 /* xorps is one byte shorter. */
3277 (eq_attr "alternative" "5")
3278 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3280 (const_string "V4SF")
3281 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3285 (const_string "V2DF"))
3287 /* For architectures resolving dependencies on
3288 whole SSE registers use APD move to break dependency
3289 chains, otherwise use short move to avoid extra work.
3291 movaps encodes one byte shorter. */
3292 (eq_attr "alternative" "6")
3294 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3296 (const_string "V4SF")
3297 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3299 (const_string "V2DF")
3301 (const_string "DF"))
3302 /* For architectures resolving dependencies on register
3303 parts we may avoid extra work to zero out upper part
3305 (eq_attr "alternative" "7")
3307 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3309 (const_string "V1DF")
3310 (const_string "DF"))
3312 (const_string "DF")))])
3314 (define_insn "*movdf_integer"
3315 [(set (match_operand:DF 0 "nonimmediate_operand"
3316 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3317 (match_operand:DF 1 "general_operand"
3318 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3319 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3320 && optimize_function_for_speed_p (cfun)
3321 && TARGET_INTEGER_DFMODE_MOVES
3322 && (reload_in_progress || reload_completed
3323 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3324 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3325 && optimize_function_for_size_p (cfun)
3326 && standard_80387_constant_p (operands[1]))
3327 || GET_CODE (operands[1]) != CONST_DOUBLE
3328 || memory_operand (operands[0], DFmode))"
3330 switch (which_alternative)
3334 return output_387_reg_move (insn, operands);
3337 return standard_80387_constant_opcode (operands[1]);
3344 switch (get_attr_mode (insn))
3347 return "xorps\t%0, %0";
3349 return "xorpd\t%0, %0";
3351 return "pxor\t%0, %0";
3358 switch (get_attr_mode (insn))
3361 return "movaps\t{%1, %0|%0, %1}";
3363 return "movapd\t{%1, %0|%0, %1}";
3365 return "movdqa\t{%1, %0|%0, %1}";
3367 return "movq\t{%1, %0|%0, %1}";
3369 return "movsd\t{%1, %0|%0, %1}";
3371 return "movlpd\t{%1, %0|%0, %1}";
3373 return "movlps\t{%1, %0|%0, %1}";
3382 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3383 (set (attr "prefix_data16")
3384 (if_then_else (eq_attr "mode" "V1DF")
3386 (const_string "*")))
3388 (cond [(eq_attr "alternative" "0,1,2")
3390 (eq_attr "alternative" "3,4")
3393 /* For SSE1, we have many fewer alternatives. */
3394 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3395 (cond [(eq_attr "alternative" "5,6")
3396 (const_string "V4SF")
3398 (const_string "V2SF"))
3400 /* xorps is one byte shorter. */
3401 (eq_attr "alternative" "5")
3402 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3404 (const_string "V4SF")
3405 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3409 (const_string "V2DF"))
3411 /* For architectures resolving dependencies on
3412 whole SSE registers use APD move to break dependency
3413 chains, otherwise use short move to avoid extra work.
3415 movaps encodes one byte shorter. */
3416 (eq_attr "alternative" "6")
3418 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3420 (const_string "V4SF")
3421 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3423 (const_string "V2DF")
3425 (const_string "DF"))
3426 /* For architectures resolving dependencies on register
3427 parts we may avoid extra work to zero out upper part
3429 (eq_attr "alternative" "7")
3431 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3433 (const_string "V1DF")
3434 (const_string "DF"))
3436 (const_string "DF")))])
3439 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3440 (match_operand:DF 1 "general_operand" ""))]
3442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3443 && ! (ANY_FP_REG_P (operands[0]) ||
3444 (GET_CODE (operands[0]) == SUBREG
3445 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3446 && ! (ANY_FP_REG_P (operands[1]) ||
3447 (GET_CODE (operands[1]) == SUBREG
3448 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3450 "ix86_split_long_move (operands); DONE;")
3452 (define_insn "*swapdf"
3453 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3454 (match_operand:DF 1 "fp_register_operand" "+f"))
3457 "reload_completed || TARGET_80387"
3459 if (STACK_TOP_P (operands[0]))
3464 [(set_attr "type" "fxch")
3465 (set_attr "mode" "DF")])
3467 (define_expand "movxf"
3468 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3469 (match_operand:XF 1 "general_operand" ""))]
3471 "ix86_expand_move (XFmode, operands); DONE;")
3473 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3474 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3475 ;; Pushing using integer instructions is longer except for constants
3476 ;; and direct memory references.
3477 ;; (assuming that any given constant is pushed only once, but this ought to be
3478 ;; handled elsewhere).
3480 (define_insn "*pushxf_nointeger"
3481 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3482 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3483 "optimize_function_for_size_p (cfun)"
3485 /* This insn should be already split before reg-stack. */
3488 [(set_attr "type" "multi")
3489 (set_attr "unit" "i387,*,*")
3490 (set_attr "mode" "XF,SI,SI")])
3492 (define_insn "*pushxf_integer"
3493 [(set (match_operand:XF 0 "push_operand" "=<,<")
3494 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3495 "optimize_function_for_speed_p (cfun)"
3497 /* This insn should be already split before reg-stack. */
3500 [(set_attr "type" "multi")
3501 (set_attr "unit" "i387,*")
3502 (set_attr "mode" "XF,SI")])
3505 [(set (match_operand 0 "push_operand" "")
3506 (match_operand 1 "general_operand" ""))]
3508 && (GET_MODE (operands[0]) == XFmode
3509 || GET_MODE (operands[0]) == DFmode)
3510 && !ANY_FP_REG_P (operands[1])"
3512 "ix86_split_long_move (operands); DONE;")
3515 [(set (match_operand:XF 0 "push_operand" "")
3516 (match_operand:XF 1 "any_fp_register_operand" ""))]
3518 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3519 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3520 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3522 ;; Do not use integer registers when optimizing for size
3523 (define_insn "*movxf_nointeger"
3524 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3525 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3526 "optimize_function_for_size_p (cfun)
3527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528 && (reload_in_progress || reload_completed
3529 || standard_80387_constant_p (operands[1])
3530 || GET_CODE (operands[1]) != CONST_DOUBLE
3531 || memory_operand (operands[0], XFmode))"
3533 switch (which_alternative)
3537 return output_387_reg_move (insn, operands);
3540 return standard_80387_constant_opcode (operands[1]);
3548 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3549 (set_attr "mode" "XF,XF,XF,SI,SI")])
3551 (define_insn "*movxf_integer"
3552 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3553 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3554 "optimize_function_for_speed_p (cfun)
3555 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3556 && (reload_in_progress || reload_completed
3557 || GET_CODE (operands[1]) != CONST_DOUBLE
3558 || memory_operand (operands[0], XFmode))"
3560 switch (which_alternative)
3564 return output_387_reg_move (insn, operands);
3567 return standard_80387_constant_opcode (operands[1]);
3576 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3577 (set_attr "mode" "XF,XF,XF,SI,SI")])
3579 (define_expand "movtf"
3580 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3581 (match_operand:TF 1 "nonimmediate_operand" ""))]
3584 ix86_expand_move (TFmode, operands);
3588 (define_insn "*movtf_internal"
3589 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3590 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3592 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3594 switch (which_alternative)
3598 if (get_attr_mode (insn) == MODE_V4SF)
3599 return "%vmovaps\t{%1, %0|%0, %1}";
3601 return "%vmovdqa\t{%1, %0|%0, %1}";
3603 if (get_attr_mode (insn) == MODE_V4SF)
3604 return "%vxorps\t%0, %d0";
3606 return "%vpxor\t%0, %d0";
3614 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3615 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3617 (cond [(eq_attr "alternative" "0,2")
3619 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3621 (const_string "V4SF")
3622 (const_string "TI"))
3623 (eq_attr "alternative" "1")
3625 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3627 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3629 (const_string "V4SF")
3630 (const_string "TI"))]
3631 (const_string "DI")))])
3633 (define_insn "*pushtf_sse"
3634 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3635 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3638 /* This insn should be already split before reg-stack. */
3641 [(set_attr "type" "multi")
3642 (set_attr "unit" "sse,*,*")
3643 (set_attr "mode" "TF,SI,SI")])
3646 [(set (match_operand:TF 0 "push_operand" "")
3647 (match_operand:TF 1 "general_operand" ""))]
3648 "TARGET_SSE2 && reload_completed
3649 && !SSE_REG_P (operands[1])"
3651 "ix86_split_long_move (operands); DONE;")
3654 [(set (match_operand:TF 0 "push_operand" "")
3655 (match_operand:TF 1 "any_fp_register_operand" ""))]
3657 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3658 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3662 [(set (match_operand 0 "nonimmediate_operand" "")
3663 (match_operand 1 "general_operand" ""))]
3665 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3666 && GET_MODE (operands[0]) == XFmode
3667 && ! (ANY_FP_REG_P (operands[0]) ||
3668 (GET_CODE (operands[0]) == SUBREG
3669 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3670 && ! (ANY_FP_REG_P (operands[1]) ||
3671 (GET_CODE (operands[1]) == SUBREG
3672 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3674 "ix86_split_long_move (operands); DONE;")
3677 [(set (match_operand 0 "register_operand" "")
3678 (match_operand 1 "memory_operand" ""))]
3680 && MEM_P (operands[1])
3681 && (GET_MODE (operands[0]) == TFmode
3682 || GET_MODE (operands[0]) == XFmode
3683 || GET_MODE (operands[0]) == SFmode
3684 || GET_MODE (operands[0]) == DFmode)
3685 && (operands[2] = find_constant_src (insn))"
3686 [(set (match_dup 0) (match_dup 2))]
3688 rtx c = operands[2];
3689 rtx r = operands[0];
3691 if (GET_CODE (r) == SUBREG)
3696 if (!standard_sse_constant_p (c))
3699 else if (FP_REG_P (r))
3701 if (!standard_80387_constant_p (c))
3704 else if (MMX_REG_P (r))
3709 [(set (match_operand 0 "register_operand" "")
3710 (float_extend (match_operand 1 "memory_operand" "")))]
3712 && MEM_P (operands[1])
3713 && (GET_MODE (operands[0]) == TFmode
3714 || GET_MODE (operands[0]) == XFmode
3715 || GET_MODE (operands[0]) == SFmode
3716 || GET_MODE (operands[0]) == DFmode)
3717 && (operands[2] = find_constant_src (insn))"
3718 [(set (match_dup 0) (match_dup 2))]
3720 rtx c = operands[2];
3721 rtx r = operands[0];
3723 if (GET_CODE (r) == SUBREG)
3728 if (!standard_sse_constant_p (c))
3731 else if (FP_REG_P (r))
3733 if (!standard_80387_constant_p (c))
3736 else if (MMX_REG_P (r))
3740 (define_insn "swapxf"
3741 [(set (match_operand:XF 0 "register_operand" "+f")
3742 (match_operand:XF 1 "register_operand" "+f"))
3747 if (STACK_TOP_P (operands[0]))
3752 [(set_attr "type" "fxch")
3753 (set_attr "mode" "XF")])
3755 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3757 [(set (match_operand:X87MODEF 0 "register_operand" "")
3758 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3759 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3760 && (standard_80387_constant_p (operands[1]) == 8
3761 || standard_80387_constant_p (operands[1]) == 9)"
3762 [(set (match_dup 0)(match_dup 1))
3764 (neg:X87MODEF (match_dup 0)))]
3768 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3769 if (real_isnegzero (&r))
3770 operands[1] = CONST0_RTX (<MODE>mode);
3772 operands[1] = CONST1_RTX (<MODE>mode);
3776 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3777 (match_operand:TF 1 "general_operand" ""))]
3779 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3781 "ix86_split_long_move (operands); DONE;")
3783 ;; Zero extension instructions
3785 (define_expand "zero_extendhisi2"
3786 [(set (match_operand:SI 0 "register_operand" "")
3787 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3790 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3792 operands[1] = force_reg (HImode, operands[1]);
3793 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3798 (define_insn "zero_extendhisi2_and"
3799 [(set (match_operand:SI 0 "register_operand" "=r")
3800 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3801 (clobber (reg:CC FLAGS_REG))]
3802 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3804 [(set_attr "type" "alu1")
3805 (set_attr "mode" "SI")])
3808 [(set (match_operand:SI 0 "register_operand" "")
3809 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3810 (clobber (reg:CC FLAGS_REG))]
3811 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3812 && optimize_function_for_speed_p (cfun)"
3813 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3814 (clobber (reg:CC FLAGS_REG))])]
3817 (define_insn "*zero_extendhisi2_movzwl"
3818 [(set (match_operand:SI 0 "register_operand" "=r")
3819 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3820 "!TARGET_ZERO_EXTEND_WITH_AND
3821 || optimize_function_for_size_p (cfun)"
3822 "movz{wl|x}\t{%1, %0|%0, %1}"
3823 [(set_attr "type" "imovx")
3824 (set_attr "mode" "SI")])
3826 (define_expand "zero_extendqihi2"
3828 [(set (match_operand:HI 0 "register_operand" "")
3829 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3830 (clobber (reg:CC FLAGS_REG))])]
3834 (define_insn "*zero_extendqihi2_and"
3835 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3836 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3837 (clobber (reg:CC FLAGS_REG))]
3838 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3840 [(set_attr "type" "alu1")
3841 (set_attr "mode" "HI")])
3843 (define_insn "*zero_extendqihi2_movzbw_and"
3844 [(set (match_operand:HI 0 "register_operand" "=r,r")
3845 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3846 (clobber (reg:CC FLAGS_REG))]
3847 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3849 [(set_attr "type" "imovx,alu1")
3850 (set_attr "mode" "HI")])
3852 ; zero extend to SImode here to avoid partial register stalls
3853 (define_insn "*zero_extendqihi2_movzbl"
3854 [(set (match_operand:HI 0 "register_operand" "=r")
3855 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3856 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3857 && reload_completed"
3858 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3859 [(set_attr "type" "imovx")
3860 (set_attr "mode" "SI")])
3862 ;; For the movzbw case strip only the clobber
3864 [(set (match_operand:HI 0 "register_operand" "")
3865 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3866 (clobber (reg:CC FLAGS_REG))]
3868 && (!TARGET_ZERO_EXTEND_WITH_AND
3869 || optimize_function_for_size_p (cfun))
3870 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3871 [(set (match_operand:HI 0 "register_operand" "")
3872 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3874 ;; When source and destination does not overlap, clear destination
3875 ;; first and then do the movb
3877 [(set (match_operand:HI 0 "register_operand" "")
3878 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3879 (clobber (reg:CC FLAGS_REG))]
3881 && ANY_QI_REG_P (operands[0])
3882 && (TARGET_ZERO_EXTEND_WITH_AND
3883 && optimize_function_for_speed_p (cfun))
3884 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3885 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3887 operands[2] = gen_lowpart (QImode, operands[0]);
3888 ix86_expand_clear (operands[0]);
3891 ;; Rest is handled by single and.
3893 [(set (match_operand:HI 0 "register_operand" "")
3894 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3895 (clobber (reg:CC FLAGS_REG))]
3897 && true_regnum (operands[0]) == true_regnum (operands[1])"
3898 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3899 (clobber (reg:CC FLAGS_REG))])]
3902 (define_expand "zero_extendqisi2"
3904 [(set (match_operand:SI 0 "register_operand" "")
3905 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3906 (clobber (reg:CC FLAGS_REG))])]
3910 (define_insn "*zero_extendqisi2_and"
3911 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3912 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3913 (clobber (reg:CC FLAGS_REG))]
3914 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3916 [(set_attr "type" "alu1")
3917 (set_attr "mode" "SI")])
3919 (define_insn "*zero_extendqisi2_movzbl_and"
3920 [(set (match_operand:SI 0 "register_operand" "=r,r")
3921 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3922 (clobber (reg:CC FLAGS_REG))]
3923 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3925 [(set_attr "type" "imovx,alu1")
3926 (set_attr "mode" "SI")])
3928 (define_insn "*zero_extendqisi2_movzbl"
3929 [(set (match_operand:SI 0 "register_operand" "=r")
3930 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3931 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3932 && reload_completed"
3933 "movz{bl|x}\t{%1, %0|%0, %1}"
3934 [(set_attr "type" "imovx")
3935 (set_attr "mode" "SI")])
3937 ;; For the movzbl case strip only the clobber
3939 [(set (match_operand:SI 0 "register_operand" "")
3940 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3941 (clobber (reg:CC FLAGS_REG))]
3943 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3944 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3946 (zero_extend:SI (match_dup 1)))])
3948 ;; When source and destination does not overlap, clear destination
3949 ;; first and then do the movb
3951 [(set (match_operand:SI 0 "register_operand" "")
3952 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3953 (clobber (reg:CC FLAGS_REG))]
3955 && ANY_QI_REG_P (operands[0])
3956 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3957 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3958 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3959 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3961 operands[2] = gen_lowpart (QImode, operands[0]);
3962 ix86_expand_clear (operands[0]);
3965 ;; Rest is handled by single and.
3967 [(set (match_operand:SI 0 "register_operand" "")
3968 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3969 (clobber (reg:CC FLAGS_REG))]
3971 && true_regnum (operands[0]) == true_regnum (operands[1])"
3972 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3973 (clobber (reg:CC FLAGS_REG))])]
3976 ;; %%% Kill me once multi-word ops are sane.
3977 (define_expand "zero_extendsidi2"
3978 [(set (match_operand:DI 0 "register_operand" "")
3979 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3984 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3989 (define_insn "zero_extendsidi2_32"
3990 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3992 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3993 (clobber (reg:CC FLAGS_REG))]
3999 movd\t{%1, %0|%0, %1}
4000 movd\t{%1, %0|%0, %1}
4001 %vmovd\t{%1, %0|%0, %1}
4002 %vmovd\t{%1, %0|%0, %1}"
4003 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4004 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4005 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4007 (define_insn "zero_extendsidi2_rex64"
4008 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4010 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4013 mov\t{%k1, %k0|%k0, %k1}
4015 movd\t{%1, %0|%0, %1}
4016 movd\t{%1, %0|%0, %1}
4017 %vmovd\t{%1, %0|%0, %1}
4018 %vmovd\t{%1, %0|%0, %1}"
4019 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4020 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4021 (set_attr "prefix_0f" "0,*,*,*,*,*")
4022 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4025 [(set (match_operand:DI 0 "memory_operand" "")
4026 (zero_extend:DI (match_dup 0)))]
4028 [(set (match_dup 4) (const_int 0))]
4029 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4032 [(set (match_operand:DI 0 "register_operand" "")
4033 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4034 (clobber (reg:CC FLAGS_REG))]
4035 "!TARGET_64BIT && reload_completed
4036 && true_regnum (operands[0]) == true_regnum (operands[1])"
4037 [(set (match_dup 4) (const_int 0))]
4038 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4041 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4042 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4043 (clobber (reg:CC FLAGS_REG))]
4044 "!TARGET_64BIT && reload_completed
4045 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4046 [(set (match_dup 3) (match_dup 1))
4047 (set (match_dup 4) (const_int 0))]
4048 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4050 (define_insn "zero_extendhidi2"
4051 [(set (match_operand:DI 0 "register_operand" "=r")
4052 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4054 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4055 [(set_attr "type" "imovx")
4056 (set_attr "mode" "SI")])
4058 (define_insn "zero_extendqidi2"
4059 [(set (match_operand:DI 0 "register_operand" "=r")
4060 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4062 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4063 [(set_attr "type" "imovx")
4064 (set_attr "mode" "SI")])
4066 ;; Sign extension instructions
4068 (define_expand "extendsidi2"
4069 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4070 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4071 (clobber (reg:CC FLAGS_REG))
4072 (clobber (match_scratch:SI 2 ""))])]
4077 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4082 (define_insn "*extendsidi2_1"
4083 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4084 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4085 (clobber (reg:CC FLAGS_REG))
4086 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4090 (define_insn "extendsidi2_rex64"
4091 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4092 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4096 movs{lq|x}\t{%1, %0|%0, %1}"
4097 [(set_attr "type" "imovx")
4098 (set_attr "mode" "DI")
4099 (set_attr "prefix_0f" "0")
4100 (set_attr "modrm" "0,1")])
4102 (define_insn "extendhidi2"
4103 [(set (match_operand:DI 0 "register_operand" "=r")
4104 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4106 "movs{wq|x}\t{%1, %0|%0, %1}"
4107 [(set_attr "type" "imovx")
4108 (set_attr "mode" "DI")])
4110 (define_insn "extendqidi2"
4111 [(set (match_operand:DI 0 "register_operand" "=r")
4112 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4114 "movs{bq|x}\t{%1, %0|%0, %1}"
4115 [(set_attr "type" "imovx")
4116 (set_attr "mode" "DI")])
4118 ;; Extend to memory case when source register does die.
4120 [(set (match_operand:DI 0 "memory_operand" "")
4121 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4122 (clobber (reg:CC FLAGS_REG))
4123 (clobber (match_operand:SI 2 "register_operand" ""))]
4125 && dead_or_set_p (insn, operands[1])
4126 && !reg_mentioned_p (operands[1], operands[0]))"
4127 [(set (match_dup 3) (match_dup 1))
4128 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4129 (clobber (reg:CC FLAGS_REG))])
4130 (set (match_dup 4) (match_dup 1))]
4131 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4133 ;; Extend to memory case when source register does not die.
4135 [(set (match_operand:DI 0 "memory_operand" "")
4136 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4137 (clobber (reg:CC FLAGS_REG))
4138 (clobber (match_operand:SI 2 "register_operand" ""))]
4142 split_di (&operands[0], 1, &operands[3], &operands[4]);
4144 emit_move_insn (operands[3], operands[1]);
4146 /* Generate a cltd if possible and doing so it profitable. */
4147 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4148 && true_regnum (operands[1]) == AX_REG
4149 && true_regnum (operands[2]) == DX_REG)
4151 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4155 emit_move_insn (operands[2], operands[1]);
4156 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4158 emit_move_insn (operands[4], operands[2]);
4162 ;; Extend to register case. Optimize case where source and destination
4163 ;; registers match and cases where we can use cltd.
4165 [(set (match_operand:DI 0 "register_operand" "")
4166 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4167 (clobber (reg:CC FLAGS_REG))
4168 (clobber (match_scratch:SI 2 ""))]
4172 split_di (&operands[0], 1, &operands[3], &operands[4]);
4174 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4175 emit_move_insn (operands[3], operands[1]);
4177 /* Generate a cltd if possible and doing so it profitable. */
4178 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4179 && true_regnum (operands[3]) == AX_REG)
4181 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4185 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4186 emit_move_insn (operands[4], operands[1]);
4188 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4192 (define_insn "extendhisi2"
4193 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4194 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4197 switch (get_attr_prefix_0f (insn))
4200 return "{cwtl|cwde}";
4202 return "movs{wl|x}\t{%1, %0|%0, %1}";
4205 [(set_attr "type" "imovx")
4206 (set_attr "mode" "SI")
4207 (set (attr "prefix_0f")
4208 ;; movsx is short decodable while cwtl is vector decoded.
4209 (if_then_else (and (eq_attr "cpu" "!k6")
4210 (eq_attr "alternative" "0"))
4212 (const_string "1")))
4214 (if_then_else (eq_attr "prefix_0f" "0")
4216 (const_string "1")))])
4218 (define_insn "*extendhisi2_zext"
4219 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4221 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4224 switch (get_attr_prefix_0f (insn))
4227 return "{cwtl|cwde}";
4229 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4232 [(set_attr "type" "imovx")
4233 (set_attr "mode" "SI")
4234 (set (attr "prefix_0f")
4235 ;; movsx is short decodable while cwtl is vector decoded.
4236 (if_then_else (and (eq_attr "cpu" "!k6")
4237 (eq_attr "alternative" "0"))
4239 (const_string "1")))
4241 (if_then_else (eq_attr "prefix_0f" "0")
4243 (const_string "1")))])
4245 (define_insn "extendqihi2"
4246 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4247 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4250 switch (get_attr_prefix_0f (insn))
4253 return "{cbtw|cbw}";
4255 return "movs{bw|x}\t{%1, %0|%0, %1}";
4258 [(set_attr "type" "imovx")
4259 (set_attr "mode" "HI")
4260 (set (attr "prefix_0f")
4261 ;; movsx is short decodable while cwtl is vector decoded.
4262 (if_then_else (and (eq_attr "cpu" "!k6")
4263 (eq_attr "alternative" "0"))
4265 (const_string "1")))
4267 (if_then_else (eq_attr "prefix_0f" "0")
4269 (const_string "1")))])
4271 (define_insn "extendqisi2"
4272 [(set (match_operand:SI 0 "register_operand" "=r")
4273 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4275 "movs{bl|x}\t{%1, %0|%0, %1}"
4276 [(set_attr "type" "imovx")
4277 (set_attr "mode" "SI")])
4279 (define_insn "*extendqisi2_zext"
4280 [(set (match_operand:DI 0 "register_operand" "=r")
4282 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4284 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4285 [(set_attr "type" "imovx")
4286 (set_attr "mode" "SI")])
4288 ;; Conversions between float and double.
4290 ;; These are all no-ops in the model used for the 80387. So just
4293 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4294 (define_insn "*dummy_extendsfdf2"
4295 [(set (match_operand:DF 0 "push_operand" "=<")
4296 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4301 [(set (match_operand:DF 0 "push_operand" "")
4302 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4304 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4305 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4307 (define_insn "*dummy_extendsfxf2"
4308 [(set (match_operand:XF 0 "push_operand" "=<")
4309 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4314 [(set (match_operand:XF 0 "push_operand" "")
4315 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4317 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4318 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4319 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4322 [(set (match_operand:XF 0 "push_operand" "")
4323 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4325 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4326 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4327 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4329 (define_expand "extendsfdf2"
4330 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4331 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4332 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4334 /* ??? Needed for compress_float_constant since all fp constants
4335 are LEGITIMATE_CONSTANT_P. */
4336 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4338 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4339 && standard_80387_constant_p (operands[1]) > 0)
4341 operands[1] = simplify_const_unary_operation
4342 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4343 emit_move_insn_1 (operands[0], operands[1]);
4346 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4350 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4352 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4354 We do the conversion post reload to avoid producing of 128bit spills
4355 that might lead to ICE on 32bit target. The sequence unlikely combine
4358 [(set (match_operand:DF 0 "register_operand" "")
4360 (match_operand:SF 1 "nonimmediate_operand" "")))]
4361 "TARGET_USE_VECTOR_FP_CONVERTS
4362 && optimize_insn_for_speed_p ()
4363 && reload_completed && SSE_REG_P (operands[0])"
4368 (parallel [(const_int 0) (const_int 1)]))))]
4370 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4371 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4372 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4373 Try to avoid move when unpacking can be done in source. */
4374 if (REG_P (operands[1]))
4376 /* If it is unsafe to overwrite upper half of source, we need
4377 to move to destination and unpack there. */
4378 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4379 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4380 && true_regnum (operands[0]) != true_regnum (operands[1]))
4382 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4383 emit_move_insn (tmp, operands[1]);
4386 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4387 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4391 emit_insn (gen_vec_setv4sf_0 (operands[3],
4392 CONST0_RTX (V4SFmode), operands[1]));
4395 (define_insn "*extendsfdf2_mixed"
4396 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4398 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4399 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4401 switch (which_alternative)
4405 return output_387_reg_move (insn, operands);
4408 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4414 [(set_attr "type" "fmov,fmov,ssecvt")
4415 (set_attr "prefix" "orig,orig,maybe_vex")
4416 (set_attr "mode" "SF,XF,DF")])
4418 (define_insn "*extendsfdf2_sse"
4419 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4420 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4421 "TARGET_SSE2 && TARGET_SSE_MATH"
4422 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4423 [(set_attr "type" "ssecvt")
4424 (set_attr "prefix" "maybe_vex")
4425 (set_attr "mode" "DF")])
4427 (define_insn "*extendsfdf2_i387"
4428 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4429 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4431 "* return output_387_reg_move (insn, operands);"
4432 [(set_attr "type" "fmov")
4433 (set_attr "mode" "SF,XF")])
4435 (define_expand "extend<mode>xf2"
4436 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4437 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4440 /* ??? Needed for compress_float_constant since all fp constants
4441 are LEGITIMATE_CONSTANT_P. */
4442 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4444 if (standard_80387_constant_p (operands[1]) > 0)
4446 operands[1] = simplify_const_unary_operation
4447 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4448 emit_move_insn_1 (operands[0], operands[1]);
4451 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4455 (define_insn "*extend<mode>xf2_i387"
4456 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4458 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4460 "* return output_387_reg_move (insn, operands);"
4461 [(set_attr "type" "fmov")
4462 (set_attr "mode" "<MODE>,XF")])
4464 ;; %%% This seems bad bad news.
4465 ;; This cannot output into an f-reg because there is no way to be sure
4466 ;; of truncating in that case. Otherwise this is just like a simple move
4467 ;; insn. So we pretend we can output to a reg in order to get better
4468 ;; register preferencing, but we really use a stack slot.
4470 ;; Conversion from DFmode to SFmode.
4472 (define_expand "truncdfsf2"
4473 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4475 (match_operand:DF 1 "nonimmediate_operand" "")))]
4476 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4478 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4480 else if (flag_unsafe_math_optimizations)
4484 enum ix86_stack_slot slot = (virtuals_instantiated
4487 rtx temp = assign_386_stack_local (SFmode, slot);
4488 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4493 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4495 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4497 We do the conversion post reload to avoid producing of 128bit spills
4498 that might lead to ICE on 32bit target. The sequence unlikely combine
4501 [(set (match_operand:SF 0 "register_operand" "")
4503 (match_operand:DF 1 "nonimmediate_operand" "")))]
4504 "TARGET_USE_VECTOR_FP_CONVERTS
4505 && optimize_insn_for_speed_p ()
4506 && reload_completed && SSE_REG_P (operands[0])"
4509 (float_truncate:V2SF
4513 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4514 operands[3] = CONST0_RTX (V2SFmode);
4515 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4516 /* Use movsd for loading from memory, unpcklpd for registers.
4517 Try to avoid move when unpacking can be done in source, or SSE3
4518 movddup is available. */
4519 if (REG_P (operands[1]))
4522 && true_regnum (operands[0]) != true_regnum (operands[1])
4523 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4524 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4526 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4527 emit_move_insn (tmp, operands[1]);
4530 else if (!TARGET_SSE3)
4531 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4532 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4535 emit_insn (gen_sse2_loadlpd (operands[4],
4536 CONST0_RTX (V2DFmode), operands[1]));
4539 (define_expand "truncdfsf2_with_temp"
4540 [(parallel [(set (match_operand:SF 0 "" "")
4541 (float_truncate:SF (match_operand:DF 1 "" "")))
4542 (clobber (match_operand:SF 2 "" ""))])]
4545 (define_insn "*truncdfsf_fast_mixed"
4546 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4548 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4549 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4551 switch (which_alternative)
4554 return output_387_reg_move (insn, operands);
4556 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4561 [(set_attr "type" "fmov,ssecvt")
4562 (set_attr "prefix" "orig,maybe_vex")
4563 (set_attr "mode" "SF")])
4565 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4566 ;; because nothing we do here is unsafe.
4567 (define_insn "*truncdfsf_fast_sse"
4568 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4570 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4571 "TARGET_SSE2 && TARGET_SSE_MATH"
4572 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4573 [(set_attr "type" "ssecvt")
4574 (set_attr "prefix" "maybe_vex")
4575 (set_attr "mode" "SF")])
4577 (define_insn "*truncdfsf_fast_i387"
4578 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4580 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4581 "TARGET_80387 && flag_unsafe_math_optimizations"
4582 "* return output_387_reg_move (insn, operands);"
4583 [(set_attr "type" "fmov")
4584 (set_attr "mode" "SF")])
4586 (define_insn "*truncdfsf_mixed"
4587 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4589 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4590 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4591 "TARGET_MIX_SSE_I387"
4593 switch (which_alternative)
4596 return output_387_reg_move (insn, operands);
4598 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4604 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4605 (set_attr "unit" "*,*,i387,i387,i387")
4606 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4607 (set_attr "mode" "SF")])
4609 (define_insn "*truncdfsf_i387"
4610 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4612 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4613 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4616 switch (which_alternative)
4619 return output_387_reg_move (insn, operands);
4625 [(set_attr "type" "fmov,multi,multi,multi")
4626 (set_attr "unit" "*,i387,i387,i387")
4627 (set_attr "mode" "SF")])
4629 (define_insn "*truncdfsf2_i387_1"
4630 [(set (match_operand:SF 0 "memory_operand" "=m")
4632 (match_operand:DF 1 "register_operand" "f")))]
4634 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4635 && !TARGET_MIX_SSE_I387"
4636 "* return output_387_reg_move (insn, operands);"
4637 [(set_attr "type" "fmov")
4638 (set_attr "mode" "SF")])
4641 [(set (match_operand:SF 0 "register_operand" "")
4643 (match_operand:DF 1 "fp_register_operand" "")))
4644 (clobber (match_operand 2 "" ""))]
4646 [(set (match_dup 2) (match_dup 1))
4647 (set (match_dup 0) (match_dup 2))]
4649 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4652 ;; Conversion from XFmode to {SF,DF}mode
4654 (define_expand "truncxf<mode>2"
4655 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4656 (float_truncate:MODEF
4657 (match_operand:XF 1 "register_operand" "")))
4658 (clobber (match_dup 2))])]
4661 if (flag_unsafe_math_optimizations)
4663 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4664 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4665 if (reg != operands[0])
4666 emit_move_insn (operands[0], reg);
4671 enum ix86_stack_slot slot = (virtuals_instantiated
4674 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4678 (define_insn "*truncxfsf2_mixed"
4679 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4681 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4682 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4685 gcc_assert (!which_alternative);
4686 return output_387_reg_move (insn, operands);
4688 [(set_attr "type" "fmov,multi,multi,multi")
4689 (set_attr "unit" "*,i387,i387,i387")
4690 (set_attr "mode" "SF")])
4692 (define_insn "*truncxfdf2_mixed"
4693 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4695 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4696 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4699 gcc_assert (!which_alternative);
4700 return output_387_reg_move (insn, operands);
4702 [(set_attr "type" "fmov,multi,multi,multi")
4703 (set_attr "unit" "*,i387,i387,i387")
4704 (set_attr "mode" "DF")])
4706 (define_insn "truncxf<mode>2_i387_noop"
4707 [(set (match_operand:MODEF 0 "register_operand" "=f")
4708 (float_truncate:MODEF
4709 (match_operand:XF 1 "register_operand" "f")))]
4710 "TARGET_80387 && flag_unsafe_math_optimizations"
4711 "* return output_387_reg_move (insn, operands);"
4712 [(set_attr "type" "fmov")
4713 (set_attr "mode" "<MODE>")])
4715 (define_insn "*truncxf<mode>2_i387"
4716 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4717 (float_truncate:MODEF
4718 (match_operand:XF 1 "register_operand" "f")))]
4720 "* return output_387_reg_move (insn, operands);"
4721 [(set_attr "type" "fmov")
4722 (set_attr "mode" "<MODE>")])
4725 [(set (match_operand:MODEF 0 "register_operand" "")
4726 (float_truncate:MODEF
4727 (match_operand:XF 1 "register_operand" "")))
4728 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4729 "TARGET_80387 && reload_completed"
4730 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4731 (set (match_dup 0) (match_dup 2))]
4735 [(set (match_operand:MODEF 0 "memory_operand" "")
4736 (float_truncate:MODEF
4737 (match_operand:XF 1 "register_operand" "")))
4738 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4740 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4743 ;; Signed conversion to DImode.
4745 (define_expand "fix_truncxfdi2"
4746 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4747 (fix:DI (match_operand:XF 1 "register_operand" "")))
4748 (clobber (reg:CC FLAGS_REG))])]
4753 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4758 (define_expand "fix_trunc<mode>di2"
4759 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4760 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4761 (clobber (reg:CC FLAGS_REG))])]
4762 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4765 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4767 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4770 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4772 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4773 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4774 if (out != operands[0])
4775 emit_move_insn (operands[0], out);
4780 ;; Signed conversion to SImode.
4782 (define_expand "fix_truncxfsi2"
4783 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4784 (fix:SI (match_operand:XF 1 "register_operand" "")))
4785 (clobber (reg:CC FLAGS_REG))])]
4790 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4795 (define_expand "fix_trunc<mode>si2"
4796 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4797 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4798 (clobber (reg:CC FLAGS_REG))])]
4799 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4802 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4804 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4807 if (SSE_FLOAT_MODE_P (<MODE>mode))
4809 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4810 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4811 if (out != operands[0])
4812 emit_move_insn (operands[0], out);
4817 ;; Signed conversion to HImode.
4819 (define_expand "fix_trunc<mode>hi2"
4820 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4821 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4822 (clobber (reg:CC FLAGS_REG))])]
4824 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4828 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4833 ;; Unsigned conversion to SImode.
4835 (define_expand "fixuns_trunc<mode>si2"
4837 [(set (match_operand:SI 0 "register_operand" "")
4839 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4841 (clobber (match_scratch:<ssevecmode> 3 ""))
4842 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4843 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4845 enum machine_mode mode = <MODE>mode;
4846 enum machine_mode vecmode = <ssevecmode>mode;
4847 REAL_VALUE_TYPE TWO31r;
4850 if (optimize_insn_for_size_p ())
4853 real_ldexp (&TWO31r, &dconst1, 31);
4854 two31 = const_double_from_real_value (TWO31r, mode);
4855 two31 = ix86_build_const_vector (mode, true, two31);
4856 operands[2] = force_reg (vecmode, two31);
4859 (define_insn_and_split "*fixuns_trunc<mode>_1"
4860 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4862 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4863 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4864 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4865 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4866 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4867 && optimize_function_for_speed_p (cfun)"
4869 "&& reload_completed"
4872 ix86_split_convert_uns_si_sse (operands);
4876 ;; Unsigned conversion to HImode.
4877 ;; Without these patterns, we'll try the unsigned SI conversion which
4878 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4880 (define_expand "fixuns_trunc<mode>hi2"
4882 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4883 (set (match_operand:HI 0 "nonimmediate_operand" "")
4884 (subreg:HI (match_dup 2) 0))]
4885 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4886 "operands[2] = gen_reg_rtx (SImode);")
4888 ;; When SSE is available, it is always faster to use it!
4889 (define_insn "fix_trunc<mode>di_sse"
4890 [(set (match_operand:DI 0 "register_operand" "=r,r")
4891 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4892 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4893 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4894 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4895 [(set_attr "type" "sseicvt")
4896 (set_attr "prefix" "maybe_vex")
4897 (set_attr "prefix_rex" "1")
4898 (set_attr "mode" "<MODE>")
4899 (set_attr "athlon_decode" "double,vector")
4900 (set_attr "amdfam10_decode" "double,double")])
4902 (define_insn "fix_trunc<mode>si_sse"
4903 [(set (match_operand:SI 0 "register_operand" "=r,r")
4904 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4905 "SSE_FLOAT_MODE_P (<MODE>mode)
4906 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4907 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4908 [(set_attr "type" "sseicvt")
4909 (set_attr "prefix" "maybe_vex")
4910 (set_attr "mode" "<MODE>")
4911 (set_attr "athlon_decode" "double,vector")
4912 (set_attr "amdfam10_decode" "double,double")])
4914 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4916 [(set (match_operand:MODEF 0 "register_operand" "")
4917 (match_operand:MODEF 1 "memory_operand" ""))
4918 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4919 (fix:SSEMODEI24 (match_dup 0)))]
4920 "TARGET_SHORTEN_X87_SSE
4921 && peep2_reg_dead_p (2, operands[0])"
4922 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4925 ;; Avoid vector decoded forms of the instruction.
4927 [(match_scratch:DF 2 "Y2")
4928 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4929 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4930 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4931 [(set (match_dup 2) (match_dup 1))
4932 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4936 [(match_scratch:SF 2 "x")
4937 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4938 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4939 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4940 [(set (match_dup 2) (match_dup 1))
4941 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4944 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4945 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4946 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4947 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4949 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4950 && (TARGET_64BIT || <MODE>mode != DImode))
4952 && can_create_pseudo_p ()"
4957 if (memory_operand (operands[0], VOIDmode))
4958 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4961 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4962 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4968 [(set_attr "type" "fisttp")
4969 (set_attr "mode" "<MODE>")])
4971 (define_insn "fix_trunc<mode>_i387_fisttp"
4972 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4973 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4974 (clobber (match_scratch:XF 2 "=&1f"))]
4975 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4978 && (TARGET_64BIT || <MODE>mode != DImode))
4979 && TARGET_SSE_MATH)"
4980 "* return output_fix_trunc (insn, operands, 1);"
4981 [(set_attr "type" "fisttp")
4982 (set_attr "mode" "<MODE>")])
4984 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4985 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4986 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4987 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4988 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4989 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4991 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4992 && (TARGET_64BIT || <MODE>mode != DImode))
4993 && TARGET_SSE_MATH)"
4995 [(set_attr "type" "fisttp")
4996 (set_attr "mode" "<MODE>")])
4999 [(set (match_operand:X87MODEI 0 "register_operand" "")
5000 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5001 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5002 (clobber (match_scratch 3 ""))]
5004 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5005 (clobber (match_dup 3))])
5006 (set (match_dup 0) (match_dup 2))]
5010 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5011 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5012 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5013 (clobber (match_scratch 3 ""))]
5015 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5016 (clobber (match_dup 3))])]
5019 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5020 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5021 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5022 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5023 ;; function in i386.c.
5024 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5025 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5026 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5027 (clobber (reg:CC FLAGS_REG))]
5028 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5030 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5031 && (TARGET_64BIT || <MODE>mode != DImode))
5032 && can_create_pseudo_p ()"
5037 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5039 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5040 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5041 if (memory_operand (operands[0], VOIDmode))
5042 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5043 operands[2], operands[3]));
5046 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5047 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5048 operands[2], operands[3],
5053 [(set_attr "type" "fistp")
5054 (set_attr "i387_cw" "trunc")
5055 (set_attr "mode" "<MODE>")])
5057 (define_insn "fix_truncdi_i387"
5058 [(set (match_operand:DI 0 "memory_operand" "=m")
5059 (fix:DI (match_operand 1 "register_operand" "f")))
5060 (use (match_operand:HI 2 "memory_operand" "m"))
5061 (use (match_operand:HI 3 "memory_operand" "m"))
5062 (clobber (match_scratch:XF 4 "=&1f"))]
5063 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5065 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5066 "* return output_fix_trunc (insn, operands, 0);"
5067 [(set_attr "type" "fistp")
5068 (set_attr "i387_cw" "trunc")
5069 (set_attr "mode" "DI")])
5071 (define_insn "fix_truncdi_i387_with_temp"
5072 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5073 (fix:DI (match_operand 1 "register_operand" "f,f")))
5074 (use (match_operand:HI 2 "memory_operand" "m,m"))
5075 (use (match_operand:HI 3 "memory_operand" "m,m"))
5076 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5077 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5078 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5080 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5082 [(set_attr "type" "fistp")
5083 (set_attr "i387_cw" "trunc")
5084 (set_attr "mode" "DI")])
5087 [(set (match_operand:DI 0 "register_operand" "")
5088 (fix:DI (match_operand 1 "register_operand" "")))
5089 (use (match_operand:HI 2 "memory_operand" ""))
5090 (use (match_operand:HI 3 "memory_operand" ""))
5091 (clobber (match_operand:DI 4 "memory_operand" ""))
5092 (clobber (match_scratch 5 ""))]
5094 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5097 (clobber (match_dup 5))])
5098 (set (match_dup 0) (match_dup 4))]
5102 [(set (match_operand:DI 0 "memory_operand" "")
5103 (fix:DI (match_operand 1 "register_operand" "")))
5104 (use (match_operand:HI 2 "memory_operand" ""))
5105 (use (match_operand:HI 3 "memory_operand" ""))
5106 (clobber (match_operand:DI 4 "memory_operand" ""))
5107 (clobber (match_scratch 5 ""))]
5109 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5112 (clobber (match_dup 5))])]
5115 (define_insn "fix_trunc<mode>_i387"
5116 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5117 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5118 (use (match_operand:HI 2 "memory_operand" "m"))
5119 (use (match_operand:HI 3 "memory_operand" "m"))]
5120 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5122 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5123 "* return output_fix_trunc (insn, operands, 0);"
5124 [(set_attr "type" "fistp")
5125 (set_attr "i387_cw" "trunc")
5126 (set_attr "mode" "<MODE>")])
5128 (define_insn "fix_trunc<mode>_i387_with_temp"
5129 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5130 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5131 (use (match_operand:HI 2 "memory_operand" "m,m"))
5132 (use (match_operand:HI 3 "memory_operand" "m,m"))
5133 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5134 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5136 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5138 [(set_attr "type" "fistp")
5139 (set_attr "i387_cw" "trunc")
5140 (set_attr "mode" "<MODE>")])
5143 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5144 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5145 (use (match_operand:HI 2 "memory_operand" ""))
5146 (use (match_operand:HI 3 "memory_operand" ""))
5147 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5149 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5151 (use (match_dup 3))])
5152 (set (match_dup 0) (match_dup 4))]
5156 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5157 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5158 (use (match_operand:HI 2 "memory_operand" ""))
5159 (use (match_operand:HI 3 "memory_operand" ""))
5160 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5162 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5164 (use (match_dup 3))])]
5167 (define_insn "x86_fnstcw_1"
5168 [(set (match_operand:HI 0 "memory_operand" "=m")
5169 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5172 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5173 (set_attr "mode" "HI")
5174 (set_attr "unit" "i387")])
5176 (define_insn "x86_fldcw_1"
5177 [(set (reg:HI FPCR_REG)
5178 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5181 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5182 (set_attr "mode" "HI")
5183 (set_attr "unit" "i387")
5184 (set_attr "athlon_decode" "vector")
5185 (set_attr "amdfam10_decode" "vector")])
5187 ;; Conversion between fixed point and floating point.
5189 ;; Even though we only accept memory inputs, the backend _really_
5190 ;; wants to be able to do this between registers.
5192 (define_expand "floathi<mode>2"
5193 [(set (match_operand:X87MODEF 0 "register_operand" "")
5194 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5196 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5197 || TARGET_MIX_SSE_I387)"
5200 ;; Pre-reload splitter to add memory clobber to the pattern.
5201 (define_insn_and_split "*floathi<mode>2_1"
5202 [(set (match_operand:X87MODEF 0 "register_operand" "")
5203 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5206 || TARGET_MIX_SSE_I387)
5207 && can_create_pseudo_p ()"
5210 [(parallel [(set (match_dup 0)
5211 (float:X87MODEF (match_dup 1)))
5212 (clobber (match_dup 2))])]
5213 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5215 (define_insn "*floathi<mode>2_i387_with_temp"
5216 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5217 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5218 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5220 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5221 || TARGET_MIX_SSE_I387)"
5223 [(set_attr "type" "fmov,multi")
5224 (set_attr "mode" "<MODE>")
5225 (set_attr "unit" "*,i387")
5226 (set_attr "fp_int_src" "true")])
5228 (define_insn "*floathi<mode>2_i387"
5229 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5230 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5232 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5233 || TARGET_MIX_SSE_I387)"
5235 [(set_attr "type" "fmov")
5236 (set_attr "mode" "<MODE>")
5237 (set_attr "fp_int_src" "true")])
5240 [(set (match_operand:X87MODEF 0 "register_operand" "")
5241 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5242 (clobber (match_operand:HI 2 "memory_operand" ""))]
5244 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5245 || TARGET_MIX_SSE_I387)
5246 && reload_completed"
5247 [(set (match_dup 2) (match_dup 1))
5248 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5252 [(set (match_operand:X87MODEF 0 "register_operand" "")
5253 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5254 (clobber (match_operand:HI 2 "memory_operand" ""))]
5256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5257 || TARGET_MIX_SSE_I387)
5258 && reload_completed"
5259 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5262 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5263 [(set (match_operand:X87MODEF 0 "register_operand" "")
5265 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5267 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5268 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5270 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5271 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5272 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5274 rtx reg = gen_reg_rtx (XFmode);
5277 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5279 if (<X87MODEF:MODE>mode == SFmode)
5280 insn = gen_truncxfsf2 (operands[0], reg);
5281 else if (<X87MODEF:MODE>mode == DFmode)
5282 insn = gen_truncxfdf2 (operands[0], reg);
5291 ;; Pre-reload splitter to add memory clobber to the pattern.
5292 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5293 [(set (match_operand:X87MODEF 0 "register_operand" "")
5294 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5296 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5297 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5298 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5299 || TARGET_MIX_SSE_I387))
5300 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5301 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5302 && ((<SSEMODEI24:MODE>mode == SImode
5303 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5304 && optimize_function_for_speed_p (cfun)
5305 && flag_trapping_math)
5306 || !(TARGET_INTER_UNIT_CONVERSIONS
5307 || optimize_function_for_size_p (cfun)))))
5308 && can_create_pseudo_p ()"
5311 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5312 (clobber (match_dup 2))])]
5314 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5316 /* Avoid store forwarding (partial memory) stall penalty
5317 by passing DImode value through XMM registers. */
5318 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5319 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5320 && optimize_function_for_speed_p (cfun))
5322 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5329 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5330 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5332 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5333 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5334 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5335 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5337 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5338 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5339 (set_attr "unit" "*,i387,*,*,*")
5340 (set_attr "athlon_decode" "*,*,double,direct,double")
5341 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5342 (set_attr "fp_int_src" "true")])
5344 (define_insn "*floatsi<mode>2_vector_mixed"
5345 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5346 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5347 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5348 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5352 [(set_attr "type" "fmov,sseicvt")
5353 (set_attr "mode" "<MODE>,<ssevecmode>")
5354 (set_attr "unit" "i387,*")
5355 (set_attr "athlon_decode" "*,direct")
5356 (set_attr "amdfam10_decode" "*,double")
5357 (set_attr "fp_int_src" "true")])
5359 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5360 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5362 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5363 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5364 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5367 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5368 (set_attr "mode" "<MODEF:MODE>")
5369 (set_attr "unit" "*,i387,*,*")
5370 (set_attr "athlon_decode" "*,*,double,direct")
5371 (set_attr "amdfam10_decode" "*,*,vector,double")
5372 (set_attr "fp_int_src" "true")])
5375 [(set (match_operand:MODEF 0 "register_operand" "")
5376 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5377 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5378 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5379 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5380 && TARGET_INTER_UNIT_CONVERSIONS
5382 && (SSE_REG_P (operands[0])
5383 || (GET_CODE (operands[0]) == SUBREG
5384 && SSE_REG_P (operands[0])))"
5385 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5389 [(set (match_operand:MODEF 0 "register_operand" "")
5390 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5391 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5392 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5393 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5394 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5396 && (SSE_REG_P (operands[0])
5397 || (GET_CODE (operands[0]) == SUBREG
5398 && SSE_REG_P (operands[0])))"
5399 [(set (match_dup 2) (match_dup 1))
5400 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5403 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5404 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5406 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5407 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5408 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5409 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5412 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5413 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5414 [(set_attr "type" "fmov,sseicvt,sseicvt")
5415 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5416 (set_attr "mode" "<MODEF:MODE>")
5417 (set (attr "prefix_rex")
5419 (and (eq_attr "prefix" "maybe_vex")
5420 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5422 (const_string "*")))
5423 (set_attr "unit" "i387,*,*")
5424 (set_attr "athlon_decode" "*,double,direct")
5425 (set_attr "amdfam10_decode" "*,vector,double")
5426 (set_attr "fp_int_src" "true")])
5428 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5429 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5431 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5432 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5433 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5434 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5437 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5438 [(set_attr "type" "fmov,sseicvt")
5439 (set_attr "prefix" "orig,maybe_vex")
5440 (set_attr "mode" "<MODEF:MODE>")
5441 (set (attr "prefix_rex")
5443 (and (eq_attr "prefix" "maybe_vex")
5444 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5446 (const_string "*")))
5447 (set_attr "athlon_decode" "*,direct")
5448 (set_attr "amdfam10_decode" "*,double")
5449 (set_attr "fp_int_src" "true")])
5451 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5452 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5454 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5455 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5456 "TARGET_SSE2 && TARGET_SSE_MATH
5457 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5459 [(set_attr "type" "sseicvt")
5460 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5461 (set_attr "athlon_decode" "double,direct,double")
5462 (set_attr "amdfam10_decode" "vector,double,double")
5463 (set_attr "fp_int_src" "true")])
5465 (define_insn "*floatsi<mode>2_vector_sse"
5466 [(set (match_operand:MODEF 0 "register_operand" "=x")
5467 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5468 "TARGET_SSE2 && TARGET_SSE_MATH
5469 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5471 [(set_attr "type" "sseicvt")
5472 (set_attr "mode" "<MODE>")
5473 (set_attr "athlon_decode" "direct")
5474 (set_attr "amdfam10_decode" "double")
5475 (set_attr "fp_int_src" "true")])
5478 [(set (match_operand:MODEF 0 "register_operand" "")
5479 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5480 (clobber (match_operand:SI 2 "memory_operand" ""))]
5481 "TARGET_SSE2 && TARGET_SSE_MATH
5482 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5484 && (SSE_REG_P (operands[0])
5485 || (GET_CODE (operands[0]) == SUBREG
5486 && SSE_REG_P (operands[0])))"
5489 rtx op1 = operands[1];
5491 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5493 if (GET_CODE (op1) == SUBREG)
5494 op1 = SUBREG_REG (op1);
5496 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5498 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5499 emit_insn (gen_sse2_loadld (operands[4],
5500 CONST0_RTX (V4SImode), operands[1]));
5502 /* We can ignore possible trapping value in the
5503 high part of SSE register for non-trapping math. */
5504 else if (SSE_REG_P (op1) && !flag_trapping_math)
5505 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5508 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5509 emit_move_insn (operands[2], operands[1]);
5510 emit_insn (gen_sse2_loadld (operands[4],
5511 CONST0_RTX (V4SImode), operands[2]));
5514 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5519 [(set (match_operand:MODEF 0 "register_operand" "")
5520 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5521 (clobber (match_operand:SI 2 "memory_operand" ""))]
5522 "TARGET_SSE2 && TARGET_SSE_MATH
5523 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5525 && (SSE_REG_P (operands[0])
5526 || (GET_CODE (operands[0]) == SUBREG
5527 && SSE_REG_P (operands[0])))"
5530 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5532 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5534 emit_insn (gen_sse2_loadld (operands[4],
5535 CONST0_RTX (V4SImode), operands[1]));
5537 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5542 [(set (match_operand:MODEF 0 "register_operand" "")
5543 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5544 "TARGET_SSE2 && TARGET_SSE_MATH
5545 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5547 && (SSE_REG_P (operands[0])
5548 || (GET_CODE (operands[0]) == SUBREG
5549 && SSE_REG_P (operands[0])))"
5552 rtx op1 = operands[1];
5554 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5556 if (GET_CODE (op1) == SUBREG)
5557 op1 = SUBREG_REG (op1);
5559 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5561 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5562 emit_insn (gen_sse2_loadld (operands[4],
5563 CONST0_RTX (V4SImode), operands[1]));
5565 /* We can ignore possible trapping value in the
5566 high part of SSE register for non-trapping math. */
5567 else if (SSE_REG_P (op1) && !flag_trapping_math)
5568 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5572 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5577 [(set (match_operand:MODEF 0 "register_operand" "")
5578 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5579 "TARGET_SSE2 && TARGET_SSE_MATH
5580 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5582 && (SSE_REG_P (operands[0])
5583 || (GET_CODE (operands[0]) == SUBREG
5584 && SSE_REG_P (operands[0])))"
5587 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5589 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5591 emit_insn (gen_sse2_loadld (operands[4],
5592 CONST0_RTX (V4SImode), operands[1]));
5594 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5598 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5599 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5601 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5602 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5603 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5604 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5606 [(set_attr "type" "sseicvt")
5607 (set_attr "mode" "<MODEF:MODE>")
5608 (set_attr "athlon_decode" "double,direct")
5609 (set_attr "amdfam10_decode" "vector,double")
5610 (set_attr "fp_int_src" "true")])
5612 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5613 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5615 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5616 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5617 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5618 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5619 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5620 [(set_attr "type" "sseicvt")
5621 (set_attr "prefix" "maybe_vex")
5622 (set_attr "mode" "<MODEF:MODE>")
5623 (set (attr "prefix_rex")
5625 (and (eq_attr "prefix" "maybe_vex")
5626 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5628 (const_string "*")))
5629 (set_attr "athlon_decode" "double,direct")
5630 (set_attr "amdfam10_decode" "vector,double")
5631 (set_attr "fp_int_src" "true")])
5634 [(set (match_operand:MODEF 0 "register_operand" "")
5635 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5636 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5637 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5638 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5639 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5641 && (SSE_REG_P (operands[0])
5642 || (GET_CODE (operands[0]) == SUBREG
5643 && SSE_REG_P (operands[0])))"
5644 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5647 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5648 [(set (match_operand:MODEF 0 "register_operand" "=x")
5650 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5651 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5652 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5653 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5654 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5655 [(set_attr "type" "sseicvt")
5656 (set_attr "prefix" "maybe_vex")
5657 (set_attr "mode" "<MODEF:MODE>")
5658 (set (attr "prefix_rex")
5660 (and (eq_attr "prefix" "maybe_vex")
5661 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5663 (const_string "*")))
5664 (set_attr "athlon_decode" "direct")
5665 (set_attr "amdfam10_decode" "double")
5666 (set_attr "fp_int_src" "true")])
5669 [(set (match_operand:MODEF 0 "register_operand" "")
5670 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5671 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5672 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5673 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5674 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5676 && (SSE_REG_P (operands[0])
5677 || (GET_CODE (operands[0]) == SUBREG
5678 && SSE_REG_P (operands[0])))"
5679 [(set (match_dup 2) (match_dup 1))
5680 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5684 [(set (match_operand:MODEF 0 "register_operand" "")
5685 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5686 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5687 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5688 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5690 && (SSE_REG_P (operands[0])
5691 || (GET_CODE (operands[0]) == SUBREG
5692 && SSE_REG_P (operands[0])))"
5693 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5696 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5697 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5699 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5700 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5702 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5706 [(set_attr "type" "fmov,multi")
5707 (set_attr "mode" "<X87MODEF:MODE>")
5708 (set_attr "unit" "*,i387")
5709 (set_attr "fp_int_src" "true")])
5711 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5712 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5714 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5716 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5718 [(set_attr "type" "fmov")
5719 (set_attr "mode" "<X87MODEF:MODE>")
5720 (set_attr "fp_int_src" "true")])
5723 [(set (match_operand:X87MODEF 0 "register_operand" "")
5724 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5725 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5727 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5729 && FP_REG_P (operands[0])"
5730 [(set (match_dup 2) (match_dup 1))
5731 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5735 [(set (match_operand:X87MODEF 0 "register_operand" "")
5736 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5737 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5739 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5741 && FP_REG_P (operands[0])"
5742 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5745 ;; Avoid store forwarding (partial memory) stall penalty
5746 ;; by passing DImode value through XMM registers. */
5748 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5749 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5751 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5752 (clobber (match_scratch:V4SI 3 "=X,x"))
5753 (clobber (match_scratch:V4SI 4 "=X,x"))
5754 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5755 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5756 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5757 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5759 [(set_attr "type" "multi")
5760 (set_attr "mode" "<X87MODEF:MODE>")
5761 (set_attr "unit" "i387")
5762 (set_attr "fp_int_src" "true")])
5765 [(set (match_operand:X87MODEF 0 "register_operand" "")
5766 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5767 (clobber (match_scratch:V4SI 3 ""))
5768 (clobber (match_scratch:V4SI 4 ""))
5769 (clobber (match_operand:DI 2 "memory_operand" ""))]
5770 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5771 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5772 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5774 && FP_REG_P (operands[0])"
5775 [(set (match_dup 2) (match_dup 3))
5776 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5778 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5779 Assemble the 64-bit DImode value in an xmm register. */
5780 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5781 gen_rtx_SUBREG (SImode, operands[1], 0)));
5782 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5783 gen_rtx_SUBREG (SImode, operands[1], 4)));
5784 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5787 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5791 [(set (match_operand:X87MODEF 0 "register_operand" "")
5792 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5793 (clobber (match_scratch:V4SI 3 ""))
5794 (clobber (match_scratch:V4SI 4 ""))
5795 (clobber (match_operand:DI 2 "memory_operand" ""))]
5796 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5797 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5798 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5800 && FP_REG_P (operands[0])"
5801 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5804 ;; Avoid store forwarding (partial memory) stall penalty by extending
5805 ;; SImode value to DImode through XMM register instead of pushing two
5806 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5807 ;; targets benefit from this optimization. Also note that fild
5808 ;; loads from memory only.
5810 (define_insn "*floatunssi<mode>2_1"
5811 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5812 (unsigned_float:X87MODEF
5813 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5814 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5815 (clobber (match_scratch:SI 3 "=X,x"))]
5817 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5820 [(set_attr "type" "multi")
5821 (set_attr "mode" "<MODE>")])
5824 [(set (match_operand:X87MODEF 0 "register_operand" "")
5825 (unsigned_float:X87MODEF
5826 (match_operand:SI 1 "register_operand" "")))
5827 (clobber (match_operand:DI 2 "memory_operand" ""))
5828 (clobber (match_scratch:SI 3 ""))]
5830 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5832 && reload_completed"
5833 [(set (match_dup 2) (match_dup 1))
5835 (float:X87MODEF (match_dup 2)))]
5836 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5839 [(set (match_operand:X87MODEF 0 "register_operand" "")
5840 (unsigned_float:X87MODEF
5841 (match_operand:SI 1 "memory_operand" "")))
5842 (clobber (match_operand:DI 2 "memory_operand" ""))
5843 (clobber (match_scratch:SI 3 ""))]
5845 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5847 && reload_completed"
5848 [(set (match_dup 2) (match_dup 3))
5850 (float:X87MODEF (match_dup 2)))]
5852 emit_move_insn (operands[3], operands[1]);
5853 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5856 (define_expand "floatunssi<mode>2"
5858 [(set (match_operand:X87MODEF 0 "register_operand" "")
5859 (unsigned_float:X87MODEF
5860 (match_operand:SI 1 "nonimmediate_operand" "")))
5861 (clobber (match_dup 2))
5862 (clobber (match_scratch:SI 3 ""))])]
5864 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5866 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5868 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5870 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5875 enum ix86_stack_slot slot = (virtuals_instantiated
5878 operands[2] = assign_386_stack_local (DImode, slot);
5882 (define_expand "floatunsdisf2"
5883 [(use (match_operand:SF 0 "register_operand" ""))
5884 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5885 "TARGET_64BIT && TARGET_SSE_MATH"
5886 "x86_emit_floatuns (operands); DONE;")
5888 (define_expand "floatunsdidf2"
5889 [(use (match_operand:DF 0 "register_operand" ""))
5890 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5891 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5892 && TARGET_SSE2 && TARGET_SSE_MATH"
5895 x86_emit_floatuns (operands);
5897 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5903 (define_expand "add<mode>3"
5904 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5905 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5906 (match_operand:SDWIM 2 "<general_operand>" "")))]
5908 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5910 (define_insn_and_split "*add<dwi>3_doubleword"
5911 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5913 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5914 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5915 (clobber (reg:CC FLAGS_REG))]
5916 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5919 [(parallel [(set (reg:CC FLAGS_REG)
5920 (unspec:CC [(match_dup 1) (match_dup 2)]
5923 (plus:DWIH (match_dup 1) (match_dup 2)))])
5924 (parallel [(set (match_dup 3)
5928 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5930 (clobber (reg:CC FLAGS_REG))])]
5931 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5933 (define_insn "*add<mode>3_cc"
5934 [(set (reg:CC FLAGS_REG)
5936 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5937 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5939 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5940 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5941 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5942 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5943 [(set_attr "type" "alu")
5944 (set_attr "mode" "<MODE>")])
5946 (define_insn "addqi3_cc"
5947 [(set (reg:CC FLAGS_REG)
5949 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5950 (match_operand:QI 2 "general_operand" "qn,qm")]
5952 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5953 (plus:QI (match_dup 1) (match_dup 2)))]
5954 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5955 "add{b}\t{%2, %0|%0, %2}"
5956 [(set_attr "type" "alu")
5957 (set_attr "mode" "QI")])
5959 (define_insn "*lea_1"
5960 [(set (match_operand:DWIH 0 "register_operand" "=r")
5961 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5963 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5964 [(set_attr "type" "lea")
5965 (set_attr "mode" "<MODE>")])
5967 (define_insn "*lea_2"
5968 [(set (match_operand:SI 0 "register_operand" "=r")
5969 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5971 "lea{l}\t{%a1, %0|%0, %a1}"
5972 [(set_attr "type" "lea")
5973 (set_attr "mode" "SI")])
5975 (define_insn "*lea_2_zext"
5976 [(set (match_operand:DI 0 "register_operand" "=r")
5978 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5980 "lea{l}\t{%a1, %k0|%k0, %a1}"
5981 [(set_attr "type" "lea")
5982 (set_attr "mode" "SI")])
5984 (define_insn "*add<mode>_1"
5985 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5987 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5988 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5989 (clobber (reg:CC FLAGS_REG))]
5990 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5992 switch (get_attr_type (insn))
5995 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5996 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5999 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6000 if (operands[2] == const1_rtx)
6001 return "inc{<imodesuffix>}\t%0";
6004 gcc_assert (operands[2] == constm1_rtx);
6005 return "dec{<imodesuffix>}\t%0";
6009 /* Use add as much as possible to replace lea for AGU optimization. */
6010 if (which_alternative == 2 && TARGET_OPT_AGU)
6011 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6013 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6015 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6016 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6017 if (CONST_INT_P (operands[2])
6018 /* Avoid overflows. */
6019 && (<MODE>mode != DImode
6020 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6021 && (INTVAL (operands[2]) == 128
6022 || (INTVAL (operands[2]) < 0
6023 && INTVAL (operands[2]) != -128)))
6025 operands[2] = GEN_INT (-INTVAL (operands[2]));
6026 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6028 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6032 (cond [(and (eq_attr "alternative" "2")
6033 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6034 (const_string "lea")
6035 (eq_attr "alternative" "3")
6036 (const_string "lea")
6037 ; Current assemblers are broken and do not allow @GOTOFF in
6038 ; ought but a memory context.
6039 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6040 (const_string "lea")
6041 (match_operand:SWI48 2 "incdec_operand" "")
6042 (const_string "incdec")
6044 (const_string "alu")))
6045 (set (attr "length_immediate")
6047 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6049 (const_string "*")))
6050 (set_attr "mode" "<MODE>")])
6052 ;; It may seem that nonimmediate operand is proper one for operand 1.
6053 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6054 ;; we take care in ix86_binary_operator_ok to not allow two memory
6055 ;; operands so proper swapping will be done in reload. This allow
6056 ;; patterns constructed from addsi_1 to match.
6058 (define_insn "*addsi_1_zext"
6059 [(set (match_operand:DI 0 "register_operand" "=r,r")
6061 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6062 (match_operand:SI 2 "general_operand" "g,li"))))
6063 (clobber (reg:CC FLAGS_REG))]
6064 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6066 switch (get_attr_type (insn))
6069 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6070 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6073 if (operands[2] == const1_rtx)
6074 return "inc{l}\t%k0";
6077 gcc_assert (operands[2] == constm1_rtx);
6078 return "dec{l}\t%k0";
6082 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6083 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6084 if (CONST_INT_P (operands[2])
6085 && (INTVAL (operands[2]) == 128
6086 || (INTVAL (operands[2]) < 0
6087 && INTVAL (operands[2]) != -128)))
6089 operands[2] = GEN_INT (-INTVAL (operands[2]));
6090 return "sub{l}\t{%2, %k0|%k0, %2}";
6092 return "add{l}\t{%2, %k0|%k0, %2}";
6096 (cond [(eq_attr "alternative" "1")
6097 (const_string "lea")
6098 ; Current assemblers are broken and do not allow @GOTOFF in
6099 ; ought but a memory context.
6100 (match_operand:SI 2 "pic_symbolic_operand" "")
6101 (const_string "lea")
6102 (match_operand:SI 2 "incdec_operand" "")
6103 (const_string "incdec")
6105 (const_string "alu")))
6106 (set (attr "length_immediate")
6108 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6110 (const_string "*")))
6111 (set_attr "mode" "SI")])
6113 (define_insn "*addhi_1"
6114 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6115 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6116 (match_operand:HI 2 "general_operand" "rn,rm")))
6117 (clobber (reg:CC FLAGS_REG))]
6118 "TARGET_PARTIAL_REG_STALL
6119 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6121 switch (get_attr_type (insn))
6124 if (operands[2] == const1_rtx)
6125 return "inc{w}\t%0";
6128 gcc_assert (operands[2] == constm1_rtx);
6129 return "dec{w}\t%0";
6133 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6134 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6135 if (CONST_INT_P (operands[2])
6136 && (INTVAL (operands[2]) == 128
6137 || (INTVAL (operands[2]) < 0
6138 && INTVAL (operands[2]) != -128)))
6140 operands[2] = GEN_INT (-INTVAL (operands[2]));
6141 return "sub{w}\t{%2, %0|%0, %2}";
6143 return "add{w}\t{%2, %0|%0, %2}";
6147 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu")))
6150 (set (attr "length_immediate")
6152 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6154 (const_string "*")))
6155 (set_attr "mode" "HI")])
6157 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6158 ;; type optimizations enabled by define-splits. This is not important
6159 ;; for PII, and in fact harmful because of partial register stalls.
6161 (define_insn "*addhi_1_lea"
6162 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6163 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6164 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6165 (clobber (reg:CC FLAGS_REG))]
6166 "!TARGET_PARTIAL_REG_STALL
6167 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6169 switch (get_attr_type (insn))
6174 if (operands[2] == const1_rtx)
6175 return "inc{w}\t%0";
6178 gcc_assert (operands[2] == constm1_rtx);
6179 return "dec{w}\t%0";
6183 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6184 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6185 if (CONST_INT_P (operands[2])
6186 && (INTVAL (operands[2]) == 128
6187 || (INTVAL (operands[2]) < 0
6188 && INTVAL (operands[2]) != -128)))
6190 operands[2] = GEN_INT (-INTVAL (operands[2]));
6191 return "sub{w}\t{%2, %0|%0, %2}";
6193 return "add{w}\t{%2, %0|%0, %2}";
6197 (if_then_else (eq_attr "alternative" "2")
6198 (const_string "lea")
6199 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6200 (const_string "incdec")
6201 (const_string "alu"))))
6202 (set (attr "length_immediate")
6204 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6206 (const_string "*")))
6207 (set_attr "mode" "HI,HI,SI")])
6209 (define_insn "*addqi_1"
6210 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6211 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6212 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6213 (clobber (reg:CC FLAGS_REG))]
6214 "TARGET_PARTIAL_REG_STALL
6215 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6217 int widen = (which_alternative == 2);
6218 switch (get_attr_type (insn))
6221 if (operands[2] == const1_rtx)
6222 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6225 gcc_assert (operands[2] == constm1_rtx);
6226 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6230 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6231 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6232 if (CONST_INT_P (operands[2])
6233 && (INTVAL (operands[2]) == 128
6234 || (INTVAL (operands[2]) < 0
6235 && INTVAL (operands[2]) != -128)))
6237 operands[2] = GEN_INT (-INTVAL (operands[2]));
6239 return "sub{l}\t{%2, %k0|%k0, %2}";
6241 return "sub{b}\t{%2, %0|%0, %2}";
6244 return "add{l}\t{%k2, %k0|%k0, %k2}";
6246 return "add{b}\t{%2, %0|%0, %2}";
6250 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6251 (const_string "incdec")
6252 (const_string "alu")))
6253 (set (attr "length_immediate")
6255 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6257 (const_string "*")))
6258 (set_attr "mode" "QI,QI,SI")])
6260 ;; %%% Potential partial reg stall on alternative 2. What to do?
6261 (define_insn "*addqi_1_lea"
6262 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6263 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6264 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6265 (clobber (reg:CC FLAGS_REG))]
6266 "!TARGET_PARTIAL_REG_STALL
6267 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6269 int widen = (which_alternative == 2);
6270 switch (get_attr_type (insn))
6275 if (operands[2] == const1_rtx)
6276 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6279 gcc_assert (operands[2] == constm1_rtx);
6280 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6284 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6285 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6286 if (CONST_INT_P (operands[2])
6287 && (INTVAL (operands[2]) == 128
6288 || (INTVAL (operands[2]) < 0
6289 && INTVAL (operands[2]) != -128)))
6291 operands[2] = GEN_INT (-INTVAL (operands[2]));
6293 return "sub{l}\t{%2, %k0|%k0, %2}";
6295 return "sub{b}\t{%2, %0|%0, %2}";
6298 return "add{l}\t{%k2, %k0|%k0, %k2}";
6300 return "add{b}\t{%2, %0|%0, %2}";
6304 (if_then_else (eq_attr "alternative" "3")
6305 (const_string "lea")
6306 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6307 (const_string "incdec")
6308 (const_string "alu"))))
6309 (set (attr "length_immediate")
6311 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6313 (const_string "*")))
6314 (set_attr "mode" "QI,QI,SI,SI")])
6316 (define_insn "*addqi_1_slp"
6317 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6318 (plus:QI (match_dup 0)
6319 (match_operand:QI 1 "general_operand" "qn,qnm")))
6320 (clobber (reg:CC FLAGS_REG))]
6321 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6322 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6324 switch (get_attr_type (insn))
6327 if (operands[1] == const1_rtx)
6328 return "inc{b}\t%0";
6331 gcc_assert (operands[1] == constm1_rtx);
6332 return "dec{b}\t%0";
6336 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6337 if (CONST_INT_P (operands[1])
6338 && INTVAL (operands[1]) < 0)
6340 operands[1] = GEN_INT (-INTVAL (operands[1]));
6341 return "sub{b}\t{%1, %0|%0, %1}";
6343 return "add{b}\t{%1, %0|%0, %1}";
6347 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6348 (const_string "incdec")
6349 (const_string "alu1")))
6350 (set (attr "memory")
6351 (if_then_else (match_operand 1 "memory_operand" "")
6352 (const_string "load")
6353 (const_string "none")))
6354 (set_attr "mode" "QI")])
6356 (define_insn "*add<mode>_2"
6357 [(set (reg FLAGS_REG)
6360 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6361 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6363 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6364 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6365 "ix86_match_ccmode (insn, CCGOCmode)
6366 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6367 /* Current assemblers are broken and do not allow @GOTOFF in
6368 ought but a memory context. */
6369 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6371 switch (get_attr_type (insn))
6374 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6375 if (operands[2] == const1_rtx)
6376 return "inc{<imodesuffix>}\t%0";
6379 gcc_assert (operands[2] == constm1_rtx);
6380 return "dec{<imodesuffix>}\t%0";
6384 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6385 /* ???? In DImode, we ought to handle there the 32bit case too
6386 - do we need new constraint? */
6387 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6388 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6389 if (CONST_INT_P (operands[2])
6390 /* Avoid overflows. */
6391 && (<MODE>mode != DImode
6392 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6393 && (INTVAL (operands[2]) == 128
6394 || (INTVAL (operands[2]) < 0
6395 && INTVAL (operands[2]) != -128)))
6397 operands[2] = GEN_INT (-INTVAL (operands[2]));
6398 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6400 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6404 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6405 (const_string "incdec")
6406 (const_string "alu")))
6407 (set (attr "length_immediate")
6409 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6411 (const_string "*")))
6412 (set_attr "mode" "<MODE>")])
6414 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6415 (define_insn "*addsi_2_zext"
6416 [(set (reg FLAGS_REG)
6418 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6419 (match_operand:SI 2 "general_operand" "g"))
6421 (set (match_operand:DI 0 "register_operand" "=r")
6422 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6423 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6424 && ix86_binary_operator_ok (PLUS, SImode, operands)
6425 /* Current assemblers are broken and do not allow @GOTOFF in
6426 ought but a memory context. */
6427 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6429 switch (get_attr_type (insn))
6432 if (operands[2] == const1_rtx)
6433 return "inc{l}\t%k0";
6436 gcc_assert (operands[2] == constm1_rtx);
6437 return "dec{l}\t%k0";
6441 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6442 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6443 if (CONST_INT_P (operands[2])
6444 && (INTVAL (operands[2]) == 128
6445 || (INTVAL (operands[2]) < 0
6446 && INTVAL (operands[2]) != -128)))
6448 operands[2] = GEN_INT (-INTVAL (operands[2]));
6449 return "sub{l}\t{%2, %k0|%k0, %2}";
6451 return "add{l}\t{%2, %k0|%k0, %2}";
6455 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6456 (const_string "incdec")
6457 (const_string "alu")))
6458 (set (attr "length_immediate")
6460 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6462 (const_string "*")))
6463 (set_attr "mode" "SI")])
6465 (define_insn "*addhi_2"
6466 [(set (reg FLAGS_REG)
6468 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6469 (match_operand:HI 2 "general_operand" "rmn,rn"))
6471 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6472 (plus:HI (match_dup 1) (match_dup 2)))]
6473 "ix86_match_ccmode (insn, CCGOCmode)
6474 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6476 switch (get_attr_type (insn))
6479 if (operands[2] == const1_rtx)
6480 return "inc{w}\t%0";
6483 gcc_assert (operands[2] == constm1_rtx);
6484 return "dec{w}\t%0";
6488 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6489 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6490 if (CONST_INT_P (operands[2])
6491 && (INTVAL (operands[2]) == 128
6492 || (INTVAL (operands[2]) < 0
6493 && INTVAL (operands[2]) != -128)))
6495 operands[2] = GEN_INT (-INTVAL (operands[2]));
6496 return "sub{w}\t{%2, %0|%0, %2}";
6498 return "add{w}\t{%2, %0|%0, %2}";
6502 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6503 (const_string "incdec")
6504 (const_string "alu")))
6505 (set (attr "length_immediate")
6507 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6509 (const_string "*")))
6510 (set_attr "mode" "HI")])
6512 (define_insn "*addqi_2"
6513 [(set (reg FLAGS_REG)
6515 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6516 (match_operand:QI 2 "general_operand" "qmn,qn"))
6518 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6519 (plus:QI (match_dup 1) (match_dup 2)))]
6520 "ix86_match_ccmode (insn, CCGOCmode)
6521 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6523 switch (get_attr_type (insn))
6526 if (operands[2] == const1_rtx)
6527 return "inc{b}\t%0";
6530 gcc_assert (operands[2] == constm1_rtx
6531 || (CONST_INT_P (operands[2])
6532 && INTVAL (operands[2]) == 255));
6533 return "dec{b}\t%0";
6537 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6538 if (CONST_INT_P (operands[2])
6539 && INTVAL (operands[2]) < 0)
6541 operands[2] = GEN_INT (-INTVAL (operands[2]));
6542 return "sub{b}\t{%2, %0|%0, %2}";
6544 return "add{b}\t{%2, %0|%0, %2}";
6548 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6549 (const_string "incdec")
6550 (const_string "alu")))
6551 (set_attr "mode" "QI")])
6553 (define_insn "*add<mode>_3"
6554 [(set (reg FLAGS_REG)
6556 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6557 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6558 (clobber (match_scratch:SWI48 0 "=r"))]
6559 "ix86_match_ccmode (insn, CCZmode)
6560 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6561 /* Current assemblers are broken and do not allow @GOTOFF in
6562 ought but a memory context. */
6563 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6565 switch (get_attr_type (insn))
6568 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6569 if (operands[2] == const1_rtx)
6570 return "inc{<imodesuffix>}\t%0";
6573 gcc_assert (operands[2] == constm1_rtx);
6574 return "dec{<imodesuffix>}\t%0";
6578 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6579 /* ???? In DImode, we ought to handle there the 32bit case too
6580 - do we need new constraint? */
6581 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6582 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6583 if (CONST_INT_P (operands[2])
6584 /* Avoid overflows. */
6585 && (<MODE>mode != DImode
6586 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6587 && (INTVAL (operands[2]) == 128
6588 || (INTVAL (operands[2]) < 0
6589 && INTVAL (operands[2]) != -128)))
6591 operands[2] = GEN_INT (-INTVAL (operands[2]));
6592 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6594 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6598 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6599 (const_string "incdec")
6600 (const_string "alu")))
6601 (set (attr "length_immediate")
6603 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6605 (const_string "*")))
6606 (set_attr "mode" "<MODE>")])
6608 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6609 (define_insn "*addsi_3_zext"
6610 [(set (reg FLAGS_REG)
6612 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6613 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6614 (set (match_operand:DI 0 "register_operand" "=r")
6615 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6616 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6617 && ix86_binary_operator_ok (PLUS, SImode, operands)
6618 /* Current assemblers are broken and do not allow @GOTOFF in
6619 ought but a memory context. */
6620 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6622 switch (get_attr_type (insn))
6625 if (operands[2] == const1_rtx)
6626 return "inc{l}\t%k0";
6629 gcc_assert (operands[2] == constm1_rtx);
6630 return "dec{l}\t%k0";
6634 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6635 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6636 if (CONST_INT_P (operands[2])
6637 && (INTVAL (operands[2]) == 128
6638 || (INTVAL (operands[2]) < 0
6639 && INTVAL (operands[2]) != -128)))
6641 operands[2] = GEN_INT (-INTVAL (operands[2]));
6642 return "sub{l}\t{%2, %k0|%k0, %2}";
6644 return "add{l}\t{%2, %k0|%k0, %2}";
6648 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6649 (const_string "incdec")
6650 (const_string "alu")))
6651 (set (attr "length_immediate")
6653 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6655 (const_string "*")))
6656 (set_attr "mode" "SI")])
6658 (define_insn "*addhi_3"
6659 [(set (reg FLAGS_REG)
6661 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6662 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6663 (clobber (match_scratch:HI 0 "=r"))]
6664 "ix86_match_ccmode (insn, CCZmode)
6665 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6667 switch (get_attr_type (insn))
6670 if (operands[2] == const1_rtx)
6671 return "inc{w}\t%0";
6674 gcc_assert (operands[2] == constm1_rtx);
6675 return "dec{w}\t%0";
6679 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6680 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6681 if (CONST_INT_P (operands[2])
6682 && (INTVAL (operands[2]) == 128
6683 || (INTVAL (operands[2]) < 0
6684 && INTVAL (operands[2]) != -128)))
6686 operands[2] = GEN_INT (-INTVAL (operands[2]));
6687 return "sub{w}\t{%2, %0|%0, %2}";
6689 return "add{w}\t{%2, %0|%0, %2}";
6693 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6694 (const_string "incdec")
6695 (const_string "alu")))
6696 (set (attr "length_immediate")
6698 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6700 (const_string "*")))
6701 (set_attr "mode" "HI")])
6703 (define_insn "*addqi_3"
6704 [(set (reg FLAGS_REG)
6706 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6707 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6708 (clobber (match_scratch:QI 0 "=q"))]
6709 "ix86_match_ccmode (insn, CCZmode)
6710 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6712 switch (get_attr_type (insn))
6715 if (operands[2] == const1_rtx)
6716 return "inc{b}\t%0";
6719 gcc_assert (operands[2] == constm1_rtx
6720 || (CONST_INT_P (operands[2])
6721 && INTVAL (operands[2]) == 255));
6722 return "dec{b}\t%0";
6726 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6727 if (CONST_INT_P (operands[2])
6728 && INTVAL (operands[2]) < 0)
6730 operands[2] = GEN_INT (-INTVAL (operands[2]));
6731 return "sub{b}\t{%2, %0|%0, %2}";
6733 return "add{b}\t{%2, %0|%0, %2}";
6737 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6738 (const_string "incdec")
6739 (const_string "alu")))
6740 (set_attr "mode" "QI")])
6742 ; For comparisons against 1, -1 and 128, we may generate better code
6743 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6744 ; is matched then. We can't accept general immediate, because for
6745 ; case of overflows, the result is messed up.
6746 ; This pattern also don't hold of 0x8000000000000000, since the value
6747 ; overflows when negated.
6748 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6749 ; only for comparisons not depending on it.
6751 (define_insn "*adddi_4"
6752 [(set (reg FLAGS_REG)
6754 (match_operand:DI 1 "nonimmediate_operand" "0")
6755 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6756 (clobber (match_scratch:DI 0 "=rm"))]
6758 && ix86_match_ccmode (insn, CCGCmode)"
6760 switch (get_attr_type (insn))
6763 if (operands[2] == constm1_rtx)
6764 return "inc{q}\t%0";
6767 gcc_assert (operands[2] == const1_rtx);
6768 return "dec{q}\t%0";
6772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6773 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6774 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6775 if ((INTVAL (operands[2]) == -128
6776 || (INTVAL (operands[2]) > 0
6777 && INTVAL (operands[2]) != 128))
6778 /* Avoid overflows. */
6779 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6780 return "sub{q}\t{%2, %0|%0, %2}";
6781 operands[2] = GEN_INT (-INTVAL (operands[2]));
6782 return "add{q}\t{%2, %0|%0, %2}";
6786 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6787 (const_string "incdec")
6788 (const_string "alu")))
6789 (set (attr "length_immediate")
6791 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6793 (const_string "*")))
6794 (set_attr "mode" "DI")])
6796 ; For comparisons against 1, -1 and 128, we may generate better code
6797 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6798 ; is matched then. We can't accept general immediate, because for
6799 ; case of overflows, the result is messed up.
6800 ; This pattern also don't hold of 0x80000000, since the value overflows
6802 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6803 ; only for comparisons not depending on it.
6805 (define_insn "*addsi_4"
6806 [(set (reg FLAGS_REG)
6808 (match_operand:SI 1 "nonimmediate_operand" "0")
6809 (match_operand:SI 2 "const_int_operand" "n")))
6810 (clobber (match_scratch:SI 0 "=rm"))]
6811 "ix86_match_ccmode (insn, CCGCmode)
6812 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6814 switch (get_attr_type (insn))
6817 if (operands[2] == constm1_rtx)
6818 return "inc{l}\t%0";
6821 gcc_assert (operands[2] == const1_rtx);
6822 return "dec{l}\t%0";
6826 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6827 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6828 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6829 if ((INTVAL (operands[2]) == -128
6830 || (INTVAL (operands[2]) > 0
6831 && INTVAL (operands[2]) != 128)))
6832 return "sub{l}\t{%2, %0|%0, %2}";
6833 operands[2] = GEN_INT (-INTVAL (operands[2]));
6834 return "add{l}\t{%2, %0|%0, %2}";
6838 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6839 (const_string "incdec")
6840 (const_string "alu")))
6841 (set (attr "length_immediate")
6843 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6845 (const_string "*")))
6846 (set_attr "mode" "SI")])
6848 ; See comments above addsi_4 for details.
6850 (define_insn "*addhi_4"
6851 [(set (reg FLAGS_REG)
6853 (match_operand:HI 1 "nonimmediate_operand" "0")
6854 (match_operand:HI 2 "const_int_operand" "n")))
6855 (clobber (match_scratch:HI 0 "=rm"))]
6856 "ix86_match_ccmode (insn, CCGCmode)
6857 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6859 switch (get_attr_type (insn))
6862 if (operands[2] == constm1_rtx)
6863 return "inc{w}\t%0";
6866 gcc_assert (operands[2] == const1_rtx);
6867 return "dec{w}\t%0";
6871 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6872 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6873 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6874 if ((INTVAL (operands[2]) == -128
6875 || (INTVAL (operands[2]) > 0
6876 && INTVAL (operands[2]) != 128)))
6877 return "sub{w}\t{%2, %0|%0, %2}";
6878 operands[2] = GEN_INT (-INTVAL (operands[2]));
6879 return "add{w}\t{%2, %0|%0, %2}";
6883 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6884 (const_string "incdec")
6885 (const_string "alu")))
6886 (set (attr "length_immediate")
6888 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6890 (const_string "*")))
6891 (set_attr "mode" "HI")])
6893 ; See comments above addsi_4 for details.
6895 (define_insn "*addqi_4"
6896 [(set (reg FLAGS_REG)
6898 (match_operand:QI 1 "nonimmediate_operand" "0")
6899 (match_operand:QI 2 "const_int_operand" "n")))
6900 (clobber (match_scratch:QI 0 "=qm"))]
6901 "ix86_match_ccmode (insn, CCGCmode)
6902 && (INTVAL (operands[2]) & 0xff) != 0x80"
6904 switch (get_attr_type (insn))
6907 if (operands[2] == constm1_rtx
6908 || (CONST_INT_P (operands[2])
6909 && INTVAL (operands[2]) == 255))
6910 return "inc{b}\t%0";
6913 gcc_assert (operands[2] == const1_rtx);
6914 return "dec{b}\t%0";
6918 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6919 if (INTVAL (operands[2]) < 0)
6921 operands[2] = GEN_INT (-INTVAL (operands[2]));
6922 return "add{b}\t{%2, %0|%0, %2}";
6924 return "sub{b}\t{%2, %0|%0, %2}";
6928 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6929 (const_string "incdec")
6930 (const_string "alu")))
6931 (set_attr "mode" "QI")])
6933 (define_insn "*add<mode>_5"
6934 [(set (reg FLAGS_REG)
6937 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6938 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6940 (clobber (match_scratch:SWI48 0 "=r"))]
6941 "ix86_match_ccmode (insn, CCGOCmode)
6942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6943 /* Current assemblers are broken and do not allow @GOTOFF in
6944 ought but a memory context. */
6945 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6947 switch (get_attr_type (insn))
6950 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6951 if (operands[2] == const1_rtx)
6952 return "inc{<imodesuffix>}\t%0";
6955 gcc_assert (operands[2] == constm1_rtx);
6956 return "dec{<imodesuffix>}\t%0";
6960 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6961 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6962 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6963 if (CONST_INT_P (operands[2])
6964 /* Avoid overflows. */
6965 && (<MODE>mode != DImode
6966 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6967 && (INTVAL (operands[2]) == 128
6968 || (INTVAL (operands[2]) < 0
6969 && INTVAL (operands[2]) != -128)))
6971 operands[2] = GEN_INT (-INTVAL (operands[2]));
6972 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6974 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6978 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6979 (const_string "incdec")
6980 (const_string "alu")))
6981 (set (attr "length_immediate")
6983 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6985 (const_string "*")))
6986 (set_attr "mode" "<MODE>")])
6988 (define_insn "*addhi_5"
6989 [(set (reg FLAGS_REG)
6991 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6992 (match_operand:HI 2 "general_operand" "rmn"))
6994 (clobber (match_scratch:HI 0 "=r"))]
6995 "ix86_match_ccmode (insn, CCGOCmode)
6996 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998 switch (get_attr_type (insn))
7001 if (operands[2] == const1_rtx)
7002 return "inc{w}\t%0";
7005 gcc_assert (operands[2] == constm1_rtx);
7006 return "dec{w}\t%0";
7010 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7011 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7012 if (CONST_INT_P (operands[2])
7013 && (INTVAL (operands[2]) == 128
7014 || (INTVAL (operands[2]) < 0
7015 && INTVAL (operands[2]) != -128)))
7017 operands[2] = GEN_INT (-INTVAL (operands[2]));
7018 return "sub{w}\t{%2, %0|%0, %2}";
7020 return "add{w}\t{%2, %0|%0, %2}";
7024 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7025 (const_string "incdec")
7026 (const_string "alu")))
7027 (set (attr "length_immediate")
7029 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7031 (const_string "*")))
7032 (set_attr "mode" "HI")])
7034 (define_insn "*addqi_5"
7035 [(set (reg FLAGS_REG)
7037 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7038 (match_operand:QI 2 "general_operand" "qmn"))
7040 (clobber (match_scratch:QI 0 "=q"))]
7041 "ix86_match_ccmode (insn, CCGOCmode)
7042 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7044 switch (get_attr_type (insn))
7047 if (operands[2] == const1_rtx)
7048 return "inc{b}\t%0";
7051 gcc_assert (operands[2] == constm1_rtx
7052 || (CONST_INT_P (operands[2])
7053 && INTVAL (operands[2]) == 255));
7054 return "dec{b}\t%0";
7058 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
7059 if (CONST_INT_P (operands[2])
7060 && INTVAL (operands[2]) < 0)
7062 operands[2] = GEN_INT (-INTVAL (operands[2]));
7063 return "sub{b}\t{%2, %0|%0, %2}";
7065 return "add{b}\t{%2, %0|%0, %2}";
7069 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7070 (const_string "incdec")
7071 (const_string "alu")))
7072 (set_attr "mode" "QI")])
7074 (define_insn "*addqi_ext_1_rex64"
7075 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7080 (match_operand 1 "ext_register_operand" "0")
7083 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7084 (clobber (reg:CC FLAGS_REG))]
7087 switch (get_attr_type (insn))
7090 if (operands[2] == const1_rtx)
7091 return "inc{b}\t%h0";
7094 gcc_assert (operands[2] == constm1_rtx
7095 || (CONST_INT_P (operands[2])
7096 && INTVAL (operands[2]) == 255));
7097 return "dec{b}\t%h0";
7101 return "add{b}\t{%2, %h0|%h0, %2}";
7105 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7106 (const_string "incdec")
7107 (const_string "alu")))
7108 (set_attr "modrm" "1")
7109 (set_attr "mode" "QI")])
7111 (define_insn "addqi_ext_1"
7112 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7117 (match_operand 1 "ext_register_operand" "0")
7120 (match_operand:QI 2 "general_operand" "Qmn")))
7121 (clobber (reg:CC FLAGS_REG))]
7124 switch (get_attr_type (insn))
7127 if (operands[2] == const1_rtx)
7128 return "inc{b}\t%h0";
7131 gcc_assert (operands[2] == constm1_rtx
7132 || (CONST_INT_P (operands[2])
7133 && INTVAL (operands[2]) == 255));
7134 return "dec{b}\t%h0";
7138 return "add{b}\t{%2, %h0|%h0, %2}";
7142 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7143 (const_string "incdec")
7144 (const_string "alu")))
7145 (set_attr "modrm" "1")
7146 (set_attr "mode" "QI")])
7148 (define_insn "*addqi_ext_2"
7149 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7154 (match_operand 1 "ext_register_operand" "%0")
7158 (match_operand 2 "ext_register_operand" "Q")
7161 (clobber (reg:CC FLAGS_REG))]
7163 "add{b}\t{%h2, %h0|%h0, %h2}"
7164 [(set_attr "type" "alu")
7165 (set_attr "mode" "QI")])
7167 ;; The lea patterns for non-Pmodes needs to be matched by
7168 ;; several insns converted to real lea by splitters.
7170 (define_insn_and_split "*lea_general_1"
7171 [(set (match_operand 0 "register_operand" "=r")
7172 (plus (plus (match_operand 1 "index_register_operand" "l")
7173 (match_operand 2 "register_operand" "r"))
7174 (match_operand 3 "immediate_operand" "i")))]
7175 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7176 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7177 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7178 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7179 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7180 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7181 || GET_MODE (operands[3]) == VOIDmode)"
7183 "&& reload_completed"
7187 operands[0] = gen_lowpart (SImode, operands[0]);
7188 operands[1] = gen_lowpart (Pmode, operands[1]);
7189 operands[2] = gen_lowpart (Pmode, operands[2]);
7190 operands[3] = gen_lowpart (Pmode, operands[3]);
7191 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7193 if (Pmode != SImode)
7194 pat = gen_rtx_SUBREG (SImode, pat, 0);
7195 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7198 [(set_attr "type" "lea")
7199 (set_attr "mode" "SI")])
7201 (define_insn_and_split "*lea_general_1_zext"
7202 [(set (match_operand:DI 0 "register_operand" "=r")
7205 (match_operand:SI 1 "index_register_operand" "l")
7206 (match_operand:SI 2 "register_operand" "r"))
7207 (match_operand:SI 3 "immediate_operand" "i"))))]
7210 "&& reload_completed"
7212 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7214 (match_dup 3)) 0)))]
7216 operands[1] = gen_lowpart (Pmode, operands[1]);
7217 operands[2] = gen_lowpart (Pmode, operands[2]);
7218 operands[3] = gen_lowpart (Pmode, operands[3]);
7220 [(set_attr "type" "lea")
7221 (set_attr "mode" "SI")])
7223 (define_insn_and_split "*lea_general_2"
7224 [(set (match_operand 0 "register_operand" "=r")
7225 (plus (mult (match_operand 1 "index_register_operand" "l")
7226 (match_operand 2 "const248_operand" "i"))
7227 (match_operand 3 "nonmemory_operand" "ri")))]
7228 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7229 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7230 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7231 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7232 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7233 || GET_MODE (operands[3]) == VOIDmode)"
7235 "&& reload_completed"
7239 operands[0] = gen_lowpart (SImode, operands[0]);
7240 operands[1] = gen_lowpart (Pmode, operands[1]);
7241 operands[3] = gen_lowpart (Pmode, operands[3]);
7242 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7244 if (Pmode != SImode)
7245 pat = gen_rtx_SUBREG (SImode, pat, 0);
7246 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7249 [(set_attr "type" "lea")
7250 (set_attr "mode" "SI")])
7252 (define_insn_and_split "*lea_general_2_zext"
7253 [(set (match_operand:DI 0 "register_operand" "=r")
7256 (match_operand:SI 1 "index_register_operand" "l")
7257 (match_operand:SI 2 "const248_operand" "n"))
7258 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7261 "&& reload_completed"
7263 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7265 (match_dup 3)) 0)))]
7267 operands[1] = gen_lowpart (Pmode, operands[1]);
7268 operands[3] = gen_lowpart (Pmode, operands[3]);
7270 [(set_attr "type" "lea")
7271 (set_attr "mode" "SI")])
7273 (define_insn_and_split "*lea_general_3"
7274 [(set (match_operand 0 "register_operand" "=r")
7275 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7276 (match_operand 2 "const248_operand" "i"))
7277 (match_operand 3 "register_operand" "r"))
7278 (match_operand 4 "immediate_operand" "i")))]
7279 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7280 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7281 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7282 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7283 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7285 "&& reload_completed"
7289 operands[0] = gen_lowpart (SImode, operands[0]);
7290 operands[1] = gen_lowpart (Pmode, operands[1]);
7291 operands[3] = gen_lowpart (Pmode, operands[3]);
7292 operands[4] = gen_lowpart (Pmode, operands[4]);
7293 pat = gen_rtx_PLUS (Pmode,
7294 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7298 if (Pmode != SImode)
7299 pat = gen_rtx_SUBREG (SImode, pat, 0);
7300 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7303 [(set_attr "type" "lea")
7304 (set_attr "mode" "SI")])
7306 (define_insn_and_split "*lea_general_3_zext"
7307 [(set (match_operand:DI 0 "register_operand" "=r")
7311 (match_operand:SI 1 "index_register_operand" "l")
7312 (match_operand:SI 2 "const248_operand" "n"))
7313 (match_operand:SI 3 "register_operand" "r"))
7314 (match_operand:SI 4 "immediate_operand" "i"))))]
7317 "&& reload_completed"
7319 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7322 (match_dup 4)) 0)))]
7324 operands[1] = gen_lowpart (Pmode, operands[1]);
7325 operands[3] = gen_lowpart (Pmode, operands[3]);
7326 operands[4] = gen_lowpart (Pmode, operands[4]);
7328 [(set_attr "type" "lea")
7329 (set_attr "mode" "SI")])
7331 ;; Convert lea to the lea pattern to avoid flags dependency.
7333 [(set (match_operand:DI 0 "register_operand" "")
7334 (plus:DI (match_operand:DI 1 "register_operand" "")
7335 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7336 (clobber (reg:CC FLAGS_REG))]
7337 "TARGET_64BIT && reload_completed
7338 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7340 (plus:DI (match_dup 1)
7344 ;; Convert lea to the lea pattern to avoid flags dependency.
7346 [(set (match_operand 0 "register_operand" "")
7347 (plus (match_operand 1 "register_operand" "")
7348 (match_operand 2 "nonmemory_operand" "")))
7349 (clobber (reg:CC FLAGS_REG))]
7350 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7354 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7355 may confuse gen_lowpart. */
7356 if (GET_MODE (operands[0]) != Pmode)
7358 operands[1] = gen_lowpart (Pmode, operands[1]);
7359 operands[2] = gen_lowpart (Pmode, operands[2]);
7361 operands[0] = gen_lowpart (SImode, operands[0]);
7362 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7363 if (Pmode != SImode)
7364 pat = gen_rtx_SUBREG (SImode, pat, 0);
7365 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7369 ;; Convert lea to the lea pattern to avoid flags dependency.
7371 [(set (match_operand:DI 0 "register_operand" "")
7373 (plus:SI (match_operand:SI 1 "register_operand" "")
7374 (match_operand:SI 2 "nonmemory_operand" ""))))
7375 (clobber (reg:CC FLAGS_REG))]
7376 "TARGET_64BIT && reload_completed
7377 && true_regnum (operands[0]) != true_regnum (operands[1])"
7379 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7381 operands[1] = gen_lowpart (Pmode, operands[1]);
7382 operands[2] = gen_lowpart (Pmode, operands[2]);
7385 ;; Subtract instructions
7387 (define_expand "sub<mode>3"
7388 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7389 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7390 (match_operand:SDWIM 2 "<general_operand>" "")))]
7392 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7394 (define_insn_and_split "*sub<dwi>3_doubleword"
7395 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7397 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7398 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7399 (clobber (reg:CC FLAGS_REG))]
7400 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7403 [(parallel [(set (reg:CC FLAGS_REG)
7404 (compare:CC (match_dup 1) (match_dup 2)))
7406 (minus:DWIH (match_dup 1) (match_dup 2)))])
7407 (parallel [(set (match_dup 3)
7411 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7413 (clobber (reg:CC FLAGS_REG))])]
7414 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7416 (define_insn "*sub<mode>_1"
7417 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7419 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7420 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7421 (clobber (reg:CC FLAGS_REG))]
7422 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7423 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7424 [(set_attr "type" "alu")
7425 (set_attr "mode" "<MODE>")])
7427 (define_insn "*subsi_1_zext"
7428 [(set (match_operand:DI 0 "register_operand" "=r")
7430 (minus:SI (match_operand:SI 1 "register_operand" "0")
7431 (match_operand:SI 2 "general_operand" "g"))))
7432 (clobber (reg:CC FLAGS_REG))]
7433 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7434 "sub{l}\t{%2, %k0|%k0, %2}"
7435 [(set_attr "type" "alu")
7436 (set_attr "mode" "SI")])
7438 (define_insn "*subqi_1_slp"
7439 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7440 (minus:QI (match_dup 0)
7441 (match_operand:QI 1 "general_operand" "qn,qm")))
7442 (clobber (reg:CC FLAGS_REG))]
7443 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7444 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7445 "sub{b}\t{%1, %0|%0, %1}"
7446 [(set_attr "type" "alu1")
7447 (set_attr "mode" "QI")])
7449 (define_insn "*sub<mode>_2"
7450 [(set (reg FLAGS_REG)
7453 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7454 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7456 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7457 (minus:SWI (match_dup 1) (match_dup 2)))]
7458 "ix86_match_ccmode (insn, CCGOCmode)
7459 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7460 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7461 [(set_attr "type" "alu")
7462 (set_attr "mode" "<MODE>")])
7464 (define_insn "*subsi_2_zext"
7465 [(set (reg FLAGS_REG)
7467 (minus:SI (match_operand:SI 1 "register_operand" "0")
7468 (match_operand:SI 2 "general_operand" "g"))
7470 (set (match_operand:DI 0 "register_operand" "=r")
7472 (minus:SI (match_dup 1)
7474 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7475 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7476 "sub{l}\t{%2, %k0|%k0, %2}"
7477 [(set_attr "type" "alu")
7478 (set_attr "mode" "SI")])
7480 (define_insn "*sub<mode>_3"
7481 [(set (reg FLAGS_REG)
7482 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7483 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7484 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7485 (minus:SWI (match_dup 1) (match_dup 2)))]
7486 "ix86_match_ccmode (insn, CCmode)
7487 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7488 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7489 [(set_attr "type" "alu")
7490 (set_attr "mode" "<MODE>")])
7492 (define_insn "*subsi_3_zext"
7493 [(set (reg FLAGS_REG)
7494 (compare (match_operand:SI 1 "register_operand" "0")
7495 (match_operand:SI 2 "general_operand" "g")))
7496 (set (match_operand:DI 0 "register_operand" "=r")
7498 (minus:SI (match_dup 1)
7500 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7501 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7502 "sub{l}\t{%2, %1|%1, %2}"
7503 [(set_attr "type" "alu")
7504 (set_attr "mode" "SI")])
7506 ;; Add with carry and subtract with borrow
7508 (define_expand "<plusminus_insn><mode>3_carry"
7510 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7512 (match_operand:SWI 1 "nonimmediate_operand" "")
7513 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7514 [(match_operand 3 "flags_reg_operand" "")
7516 (match_operand:SWI 2 "<general_operand>" ""))))
7517 (clobber (reg:CC FLAGS_REG))])]
7518 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7521 (define_insn "*<plusminus_insn><mode>3_carry"
7522 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7524 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7526 (match_operator 3 "ix86_carry_flag_operator"
7527 [(reg FLAGS_REG) (const_int 0)])
7528 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7529 (clobber (reg:CC FLAGS_REG))]
7530 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7531 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7532 [(set_attr "type" "alu")
7533 (set_attr "use_carry" "1")
7534 (set_attr "pent_pair" "pu")
7535 (set_attr "mode" "<MODE>")])
7537 (define_insn "*addsi3_carry_zext"
7538 [(set (match_operand:DI 0 "register_operand" "=r")
7540 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7541 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7542 [(reg FLAGS_REG) (const_int 0)])
7543 (match_operand:SI 2 "general_operand" "g")))))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7546 "adc{l}\t{%2, %k0|%k0, %2}"
7547 [(set_attr "type" "alu")
7548 (set_attr "use_carry" "1")
7549 (set_attr "pent_pair" "pu")
7550 (set_attr "mode" "SI")])
7552 (define_insn "*subsi3_carry_zext"
7553 [(set (match_operand:DI 0 "register_operand" "=r")
7555 (minus:SI (match_operand:SI 1 "register_operand" "0")
7556 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7557 [(reg FLAGS_REG) (const_int 0)])
7558 (match_operand:SI 2 "general_operand" "g")))))
7559 (clobber (reg:CC FLAGS_REG))]
7560 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7561 "sbb{l}\t{%2, %k0|%k0, %2}"
7562 [(set_attr "type" "alu")
7563 (set_attr "pent_pair" "pu")
7564 (set_attr "mode" "SI")])
7566 ;; Overflow setting add and subtract instructions
7568 (define_insn "*add<mode>3_cconly_overflow"
7569 [(set (reg:CCC FLAGS_REG)
7572 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7573 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7575 (clobber (match_scratch:SWI 0 "=<r>"))]
7576 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7577 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7578 [(set_attr "type" "alu")
7579 (set_attr "mode" "<MODE>")])
7581 (define_insn "*sub<mode>3_cconly_overflow"
7582 [(set (reg:CCC FLAGS_REG)
7585 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7586 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7589 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7590 [(set_attr "type" "icmp")
7591 (set_attr "mode" "<MODE>")])
7593 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7594 [(set (reg:CCC FLAGS_REG)
7597 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7598 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7600 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7601 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7602 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7603 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7604 [(set_attr "type" "alu")
7605 (set_attr "mode" "<MODE>")])
7607 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7608 [(set (reg:CCC FLAGS_REG)
7611 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7612 (match_operand:SI 2 "general_operand" "g"))
7614 (set (match_operand:DI 0 "register_operand" "=r")
7615 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7616 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7617 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7618 [(set_attr "type" "alu")
7619 (set_attr "mode" "SI")])
7621 ;; The patterns that match these are at the end of this file.
7623 (define_expand "<plusminus_insn>xf3"
7624 [(set (match_operand:XF 0 "register_operand" "")
7626 (match_operand:XF 1 "register_operand" "")
7627 (match_operand:XF 2 "register_operand" "")))]
7631 (define_expand "<plusminus_insn><mode>3"
7632 [(set (match_operand:MODEF 0 "register_operand" "")
7634 (match_operand:MODEF 1 "register_operand" "")
7635 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7636 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7637 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7640 ;; Multiply instructions
7642 (define_expand "mul<mode>3"
7643 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7645 (match_operand:SWIM248 1 "register_operand" "")
7646 (match_operand:SWIM248 2 "<general_operand>" "")))
7647 (clobber (reg:CC FLAGS_REG))])]
7651 (define_expand "mulqi3"
7652 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7654 (match_operand:QI 1 "register_operand" "")
7655 (match_operand:QI 2 "nonimmediate_operand" "")))
7656 (clobber (reg:CC FLAGS_REG))])]
7657 "TARGET_QIMODE_MATH"
7661 ;; IMUL reg32/64, reg32/64, imm8 Direct
7662 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7663 ;; IMUL reg32/64, reg32/64, imm32 Direct
7664 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7665 ;; IMUL reg32/64, reg32/64 Direct
7666 ;; IMUL reg32/64, mem32/64 Direct
7668 (define_insn "*mul<mode>3_1"
7669 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7671 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7672 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7673 (clobber (reg:CC FLAGS_REG))]
7674 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7676 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7677 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7678 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7679 [(set_attr "type" "imul")
7680 (set_attr "prefix_0f" "0,0,1")
7681 (set (attr "athlon_decode")
7682 (cond [(eq_attr "cpu" "athlon")
7683 (const_string "vector")
7684 (eq_attr "alternative" "1")
7685 (const_string "vector")
7686 (and (eq_attr "alternative" "2")
7687 (match_operand 1 "memory_operand" ""))
7688 (const_string "vector")]
7689 (const_string "direct")))
7690 (set (attr "amdfam10_decode")
7691 (cond [(and (eq_attr "alternative" "0,1")
7692 (match_operand 1 "memory_operand" ""))
7693 (const_string "vector")]
7694 (const_string "direct")))
7695 (set_attr "mode" "<MODE>")])
7697 (define_insn "*mulsi3_1_zext"
7698 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7700 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7701 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7702 (clobber (reg:CC FLAGS_REG))]
7704 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7706 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7707 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7708 imul{l}\t{%2, %k0|%k0, %2}"
7709 [(set_attr "type" "imul")
7710 (set_attr "prefix_0f" "0,0,1")
7711 (set (attr "athlon_decode")
7712 (cond [(eq_attr "cpu" "athlon")
7713 (const_string "vector")
7714 (eq_attr "alternative" "1")
7715 (const_string "vector")
7716 (and (eq_attr "alternative" "2")
7717 (match_operand 1 "memory_operand" ""))
7718 (const_string "vector")]
7719 (const_string "direct")))
7720 (set (attr "amdfam10_decode")
7721 (cond [(and (eq_attr "alternative" "0,1")
7722 (match_operand 1 "memory_operand" ""))
7723 (const_string "vector")]
7724 (const_string "direct")))
7725 (set_attr "mode" "SI")])
7728 ;; IMUL reg16, reg16, imm8 VectorPath
7729 ;; IMUL reg16, mem16, imm8 VectorPath
7730 ;; IMUL reg16, reg16, imm16 VectorPath
7731 ;; IMUL reg16, mem16, imm16 VectorPath
7732 ;; IMUL reg16, reg16 Direct
7733 ;; IMUL reg16, mem16 Direct
7735 (define_insn "*mulhi3_1"
7736 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7737 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7738 (match_operand:HI 2 "general_operand" "K,n,mr")))
7739 (clobber (reg:CC FLAGS_REG))]
7741 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7743 imul{w}\t{%2, %1, %0|%0, %1, %2}
7744 imul{w}\t{%2, %1, %0|%0, %1, %2}
7745 imul{w}\t{%2, %0|%0, %2}"
7746 [(set_attr "type" "imul")
7747 (set_attr "prefix_0f" "0,0,1")
7748 (set (attr "athlon_decode")
7749 (cond [(eq_attr "cpu" "athlon")
7750 (const_string "vector")
7751 (eq_attr "alternative" "1,2")
7752 (const_string "vector")]
7753 (const_string "direct")))
7754 (set (attr "amdfam10_decode")
7755 (cond [(eq_attr "alternative" "0,1")
7756 (const_string "vector")]
7757 (const_string "direct")))
7758 (set_attr "mode" "HI")])
7764 (define_insn "*mulqi3_1"
7765 [(set (match_operand:QI 0 "register_operand" "=a")
7766 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7767 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7768 (clobber (reg:CC FLAGS_REG))]
7770 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7772 [(set_attr "type" "imul")
7773 (set_attr "length_immediate" "0")
7774 (set (attr "athlon_decode")
7775 (if_then_else (eq_attr "cpu" "athlon")
7776 (const_string "vector")
7777 (const_string "direct")))
7778 (set_attr "amdfam10_decode" "direct")
7779 (set_attr "mode" "QI")])
7781 (define_expand "<u>mul<mode><dwi>3"
7782 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7785 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7787 (match_operand:DWIH 2 "register_operand" ""))))
7788 (clobber (reg:CC FLAGS_REG))])]
7792 (define_expand "<u>mulqihi3"
7793 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7796 (match_operand:QI 1 "nonimmediate_operand" ""))
7798 (match_operand:QI 2 "register_operand" ""))))
7799 (clobber (reg:CC FLAGS_REG))])]
7800 "TARGET_QIMODE_MATH"
7803 (define_insn "*<u>mul<mode><dwi>3_1"
7804 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7807 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7809 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7812 "<sgnprefix>mul{<imodesuffix>}\t%2"
7813 [(set_attr "type" "imul")
7814 (set_attr "length_immediate" "0")
7815 (set (attr "athlon_decode")
7816 (if_then_else (eq_attr "cpu" "athlon")
7817 (const_string "vector")
7818 (const_string "double")))
7819 (set_attr "amdfam10_decode" "double")
7820 (set_attr "mode" "<MODE>")])
7822 (define_insn "*<u>mulqihi3_1"
7823 [(set (match_operand:HI 0 "register_operand" "=a")
7826 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7828 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7829 (clobber (reg:CC FLAGS_REG))]
7831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7832 "<sgnprefix>mul{b}\t%2"
7833 [(set_attr "type" "imul")
7834 (set_attr "length_immediate" "0")
7835 (set (attr "athlon_decode")
7836 (if_then_else (eq_attr "cpu" "athlon")
7837 (const_string "vector")
7838 (const_string "direct")))
7839 (set_attr "amdfam10_decode" "direct")
7840 (set_attr "mode" "QI")])
7842 (define_expand "<s>mul<mode>3_highpart"
7843 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7848 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7850 (match_operand:SWI48 2 "register_operand" "")))
7852 (clobber (match_scratch:SWI48 3 ""))
7853 (clobber (reg:CC FLAGS_REG))])]
7855 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7857 (define_insn "*<s>muldi3_highpart_1"
7858 [(set (match_operand:DI 0 "register_operand" "=d")
7863 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7865 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7867 (clobber (match_scratch:DI 3 "=1"))
7868 (clobber (reg:CC FLAGS_REG))]
7870 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7871 "<sgnprefix>mul{q}\t%2"
7872 [(set_attr "type" "imul")
7873 (set_attr "length_immediate" "0")
7874 (set (attr "athlon_decode")
7875 (if_then_else (eq_attr "cpu" "athlon")
7876 (const_string "vector")
7877 (const_string "double")))
7878 (set_attr "amdfam10_decode" "double")
7879 (set_attr "mode" "DI")])
7881 (define_insn "*<s>mulsi3_highpart_1"
7882 [(set (match_operand:SI 0 "register_operand" "=d")
7887 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7889 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7891 (clobber (match_scratch:SI 3 "=1"))
7892 (clobber (reg:CC FLAGS_REG))]
7893 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7894 "<sgnprefix>mul{l}\t%2"
7895 [(set_attr "type" "imul")
7896 (set_attr "length_immediate" "0")
7897 (set (attr "athlon_decode")
7898 (if_then_else (eq_attr "cpu" "athlon")
7899 (const_string "vector")
7900 (const_string "double")))
7901 (set_attr "amdfam10_decode" "double")
7902 (set_attr "mode" "SI")])
7904 (define_insn "*<s>mulsi3_highpart_zext"
7905 [(set (match_operand:DI 0 "register_operand" "=d")
7906 (zero_extend:DI (truncate:SI
7908 (mult:DI (any_extend:DI
7909 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7911 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7913 (clobber (match_scratch:SI 3 "=1"))
7914 (clobber (reg:CC FLAGS_REG))]
7916 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7917 "<sgnprefix>mul{l}\t%2"
7918 [(set_attr "type" "imul")
7919 (set_attr "length_immediate" "0")
7920 (set (attr "athlon_decode")
7921 (if_then_else (eq_attr "cpu" "athlon")
7922 (const_string "vector")
7923 (const_string "double")))
7924 (set_attr "amdfam10_decode" "double")
7925 (set_attr "mode" "SI")])
7927 ;; The patterns that match these are at the end of this file.
7929 (define_expand "mulxf3"
7930 [(set (match_operand:XF 0 "register_operand" "")
7931 (mult:XF (match_operand:XF 1 "register_operand" "")
7932 (match_operand:XF 2 "register_operand" "")))]
7936 (define_expand "mul<mode>3"
7937 [(set (match_operand:MODEF 0 "register_operand" "")
7938 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7939 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7940 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7941 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7944 ;; Divide instructions
7946 (define_insn "<u>divqi3"
7947 [(set (match_operand:QI 0 "register_operand" "=a")
7949 (match_operand:HI 1 "register_operand" "0")
7950 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7951 (clobber (reg:CC FLAGS_REG))]
7952 "TARGET_QIMODE_MATH"
7953 "<sgnprefix>div{b}\t%2"
7954 [(set_attr "type" "idiv")
7955 (set_attr "mode" "QI")])
7957 ;; The patterns that match these are at the end of this file.
7959 (define_expand "divxf3"
7960 [(set (match_operand:XF 0 "register_operand" "")
7961 (div:XF (match_operand:XF 1 "register_operand" "")
7962 (match_operand:XF 2 "register_operand" "")))]
7966 (define_expand "divdf3"
7967 [(set (match_operand:DF 0 "register_operand" "")
7968 (div:DF (match_operand:DF 1 "register_operand" "")
7969 (match_operand:DF 2 "nonimmediate_operand" "")))]
7970 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7971 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7974 (define_expand "divsf3"
7975 [(set (match_operand:SF 0 "register_operand" "")
7976 (div:SF (match_operand:SF 1 "register_operand" "")
7977 (match_operand:SF 2 "nonimmediate_operand" "")))]
7978 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7981 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7982 && flag_finite_math_only && !flag_trapping_math
7983 && flag_unsafe_math_optimizations)
7985 ix86_emit_swdivsf (operands[0], operands[1],
7986 operands[2], SFmode);
7991 ;; Divmod instructions.
7993 (define_expand "divmod<mode>4"
7994 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7996 (match_operand:SWIM248 1 "register_operand" "")
7997 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7998 (set (match_operand:SWIM248 3 "register_operand" "")
7999 (mod:SWIM248 (match_dup 1) (match_dup 2)))
8000 (clobber (reg:CC FLAGS_REG))])]
8004 (define_insn_and_split "*divmod<mode>4"
8005 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8006 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8007 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8008 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8009 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8010 (clobber (reg:CC FLAGS_REG))]
8013 "&& reload_completed"
8014 [(parallel [(set (match_dup 1)
8015 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8016 (clobber (reg:CC FLAGS_REG))])
8017 (parallel [(set (match_dup 0)
8018 (div:SWIM248 (match_dup 2) (match_dup 3)))
8020 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8022 (clobber (reg:CC FLAGS_REG))])]
8024 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8026 if (<MODE>mode != HImode
8027 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8028 operands[4] = operands[2];
8031 /* Avoid use of cltd in favor of a mov+shift. */
8032 emit_move_insn (operands[1], operands[2]);
8033 operands[4] = operands[1];
8036 [(set_attr "type" "multi")
8037 (set_attr "mode" "<MODE>")])
8039 (define_insn "*divmod<mode>4_noext"
8040 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8041 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8042 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8043 (set (match_operand:SWIM248 1 "register_operand" "=d")
8044 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8045 (use (match_operand:SWIM248 4 "register_operand" "1"))
8046 (clobber (reg:CC FLAGS_REG))]
8048 "idiv{<imodesuffix>}\t%3"
8049 [(set_attr "type" "idiv")
8050 (set_attr "mode" "<MODE>")])
8052 (define_expand "udivmod<mode>4"
8053 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8055 (match_operand:SWIM248 1 "register_operand" "")
8056 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8057 (set (match_operand:SWIM248 3 "register_operand" "")
8058 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8059 (clobber (reg:CC FLAGS_REG))])]
8063 (define_insn_and_split "*udivmod<mode>4"
8064 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8065 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8066 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8067 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8068 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8069 (clobber (reg:CC FLAGS_REG))]
8072 "&& reload_completed"
8073 [(set (match_dup 1) (const_int 0))
8074 (parallel [(set (match_dup 0)
8075 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8077 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8079 (clobber (reg:CC FLAGS_REG))])]
8081 [(set_attr "type" "multi")
8082 (set_attr "mode" "<MODE>")])
8084 (define_insn "*udivmod<mode>4_noext"
8085 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8086 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8087 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8088 (set (match_operand:SWIM248 1 "register_operand" "=d")
8089 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8090 (use (match_operand:SWIM248 4 "register_operand" "1"))
8091 (clobber (reg:CC FLAGS_REG))]
8093 "div{<imodesuffix>}\t%3"
8094 [(set_attr "type" "idiv")
8095 (set_attr "mode" "<MODE>")])
8097 ;; We cannot use div/idiv for double division, because it causes
8098 ;; "division by zero" on the overflow and that's not what we expect
8099 ;; from truncate. Because true (non truncating) double division is
8100 ;; never generated, we can't create this insn anyway.
8103 ; [(set (match_operand:SI 0 "register_operand" "=a")
8105 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8107 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8108 ; (set (match_operand:SI 3 "register_operand" "=d")
8110 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8111 ; (clobber (reg:CC FLAGS_REG))]
8113 ; "div{l}\t{%2, %0|%0, %2}"
8114 ; [(set_attr "type" "idiv")])
8116 ;;- Logical AND instructions
8118 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8119 ;; Note that this excludes ah.
8121 (define_expand "testsi_ccno_1"
8122 [(set (reg:CCNO FLAGS_REG)
8124 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8125 (match_operand:SI 1 "nonmemory_operand" ""))
8130 (define_expand "testqi_ccz_1"
8131 [(set (reg:CCZ FLAGS_REG)
8132 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8133 (match_operand:QI 1 "nonmemory_operand" ""))
8138 (define_insn "*testdi_1"
8139 [(set (reg FLAGS_REG)
8142 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8143 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8145 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8146 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8148 test{l}\t{%k1, %k0|%k0, %k1}
8149 test{l}\t{%k1, %k0|%k0, %k1}
8150 test{q}\t{%1, %0|%0, %1}
8151 test{q}\t{%1, %0|%0, %1}
8152 test{q}\t{%1, %0|%0, %1}"
8153 [(set_attr "type" "test")
8154 (set_attr "modrm" "0,1,0,1,1")
8155 (set_attr "mode" "SI,SI,DI,DI,DI")])
8157 (define_insn "*testqi_1_maybe_si"
8158 [(set (reg FLAGS_REG)
8161 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8162 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8164 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8165 && ix86_match_ccmode (insn,
8166 CONST_INT_P (operands[1])
8167 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8169 if (which_alternative == 3)
8171 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8172 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8173 return "test{l}\t{%1, %k0|%k0, %1}";
8175 return "test{b}\t{%1, %0|%0, %1}";
8177 [(set_attr "type" "test")
8178 (set_attr "modrm" "0,1,1,1")
8179 (set_attr "mode" "QI,QI,QI,SI")
8180 (set_attr "pent_pair" "uv,np,uv,np")])
8182 (define_insn "*test<mode>_1"
8183 [(set (reg FLAGS_REG)
8186 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8187 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8189 "ix86_match_ccmode (insn, CCNOmode)
8190 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8191 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8192 [(set_attr "type" "test")
8193 (set_attr "modrm" "0,1,1")
8194 (set_attr "mode" "<MODE>")
8195 (set_attr "pent_pair" "uv,np,uv")])
8197 (define_expand "testqi_ext_ccno_0"
8198 [(set (reg:CCNO FLAGS_REG)
8202 (match_operand 0 "ext_register_operand" "")
8205 (match_operand 1 "const_int_operand" ""))
8210 (define_insn "*testqi_ext_0"
8211 [(set (reg FLAGS_REG)
8215 (match_operand 0 "ext_register_operand" "Q")
8218 (match_operand 1 "const_int_operand" "n"))
8220 "ix86_match_ccmode (insn, CCNOmode)"
8221 "test{b}\t{%1, %h0|%h0, %1}"
8222 [(set_attr "type" "test")
8223 (set_attr "mode" "QI")
8224 (set_attr "length_immediate" "1")
8225 (set_attr "modrm" "1")
8226 (set_attr "pent_pair" "np")])
8228 (define_insn "*testqi_ext_1_rex64"
8229 [(set (reg FLAGS_REG)
8233 (match_operand 0 "ext_register_operand" "Q")
8237 (match_operand:QI 1 "register_operand" "Q")))
8239 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8240 "test{b}\t{%1, %h0|%h0, %1}"
8241 [(set_attr "type" "test")
8242 (set_attr "mode" "QI")])
8244 (define_insn "*testqi_ext_1"
8245 [(set (reg FLAGS_REG)
8249 (match_operand 0 "ext_register_operand" "Q")
8253 (match_operand:QI 1 "general_operand" "Qm")))
8255 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8256 "test{b}\t{%1, %h0|%h0, %1}"
8257 [(set_attr "type" "test")
8258 (set_attr "mode" "QI")])
8260 (define_insn "*testqi_ext_2"
8261 [(set (reg FLAGS_REG)
8265 (match_operand 0 "ext_register_operand" "Q")
8269 (match_operand 1 "ext_register_operand" "Q")
8273 "ix86_match_ccmode (insn, CCNOmode)"
8274 "test{b}\t{%h1, %h0|%h0, %h1}"
8275 [(set_attr "type" "test")
8276 (set_attr "mode" "QI")])
8278 (define_insn "*testqi_ext_3_rex64"
8279 [(set (reg FLAGS_REG)
8280 (compare (zero_extract:DI
8281 (match_operand 0 "nonimmediate_operand" "rm")
8282 (match_operand:DI 1 "const_int_operand" "")
8283 (match_operand:DI 2 "const_int_operand" ""))
8286 && ix86_match_ccmode (insn, CCNOmode)
8287 && INTVAL (operands[1]) > 0
8288 && INTVAL (operands[2]) >= 0
8289 /* Ensure that resulting mask is zero or sign extended operand. */
8290 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8291 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8292 && INTVAL (operands[1]) > 32))
8293 && (GET_MODE (operands[0]) == SImode
8294 || GET_MODE (operands[0]) == DImode
8295 || GET_MODE (operands[0]) == HImode
8296 || GET_MODE (operands[0]) == QImode)"
8299 ;; Combine likes to form bit extractions for some tests. Humor it.
8300 (define_insn "*testqi_ext_3"
8301 [(set (reg FLAGS_REG)
8302 (compare (zero_extract:SI
8303 (match_operand 0 "nonimmediate_operand" "rm")
8304 (match_operand:SI 1 "const_int_operand" "")
8305 (match_operand:SI 2 "const_int_operand" ""))
8307 "ix86_match_ccmode (insn, CCNOmode)
8308 && INTVAL (operands[1]) > 0
8309 && INTVAL (operands[2]) >= 0
8310 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8311 && (GET_MODE (operands[0]) == SImode
8312 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8313 || GET_MODE (operands[0]) == HImode
8314 || GET_MODE (operands[0]) == QImode)"
8318 [(set (match_operand 0 "flags_reg_operand" "")
8319 (match_operator 1 "compare_operator"
8321 (match_operand 2 "nonimmediate_operand" "")
8322 (match_operand 3 "const_int_operand" "")
8323 (match_operand 4 "const_int_operand" ""))
8325 "ix86_match_ccmode (insn, CCNOmode)"
8326 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8328 rtx val = operands[2];
8329 HOST_WIDE_INT len = INTVAL (operands[3]);
8330 HOST_WIDE_INT pos = INTVAL (operands[4]);
8332 enum machine_mode mode, submode;
8334 mode = GET_MODE (val);
8337 /* ??? Combine likes to put non-volatile mem extractions in QImode
8338 no matter the size of the test. So find a mode that works. */
8339 if (! MEM_VOLATILE_P (val))
8341 mode = smallest_mode_for_size (pos + len, MODE_INT);
8342 val = adjust_address (val, mode, 0);
8345 else if (GET_CODE (val) == SUBREG
8346 && (submode = GET_MODE (SUBREG_REG (val)),
8347 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8348 && pos + len <= GET_MODE_BITSIZE (submode)
8349 && GET_MODE_CLASS (submode) == MODE_INT)
8351 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8353 val = SUBREG_REG (val);
8355 else if (mode == HImode && pos + len <= 8)
8357 /* Small HImode tests can be converted to QImode. */
8359 val = gen_lowpart (QImode, val);
8362 if (len == HOST_BITS_PER_WIDE_INT)
8365 mask = ((HOST_WIDE_INT)1 << len) - 1;
8368 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8371 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8372 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8373 ;; this is relatively important trick.
8374 ;; Do the conversion only post-reload to avoid limiting of the register class
8377 [(set (match_operand 0 "flags_reg_operand" "")
8378 (match_operator 1 "compare_operator"
8379 [(and (match_operand 2 "register_operand" "")
8380 (match_operand 3 "const_int_operand" ""))
8383 && QI_REG_P (operands[2])
8384 && GET_MODE (operands[2]) != QImode
8385 && ((ix86_match_ccmode (insn, CCZmode)
8386 && !(INTVAL (operands[3]) & ~(255 << 8)))
8387 || (ix86_match_ccmode (insn, CCNOmode)
8388 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8391 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8394 "operands[2] = gen_lowpart (SImode, operands[2]);
8395 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8398 [(set (match_operand 0 "flags_reg_operand" "")
8399 (match_operator 1 "compare_operator"
8400 [(and (match_operand 2 "nonimmediate_operand" "")
8401 (match_operand 3 "const_int_operand" ""))
8404 && GET_MODE (operands[2]) != QImode
8405 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8406 && ((ix86_match_ccmode (insn, CCZmode)
8407 && !(INTVAL (operands[3]) & ~255))
8408 || (ix86_match_ccmode (insn, CCNOmode)
8409 && !(INTVAL (operands[3]) & ~127)))"
8411 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8413 "operands[2] = gen_lowpart (QImode, operands[2]);
8414 operands[3] = gen_lowpart (QImode, operands[3]);")
8416 ;; %%% This used to optimize known byte-wide and operations to memory,
8417 ;; and sometimes to QImode registers. If this is considered useful,
8418 ;; it should be done with splitters.
8420 (define_expand "and<mode>3"
8421 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8422 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8423 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8425 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8427 (define_insn "*anddi_1"
8428 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8430 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8431 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8435 switch (get_attr_type (insn))
8439 enum machine_mode mode;
8441 gcc_assert (CONST_INT_P (operands[2]));
8442 if (INTVAL (operands[2]) == 0xff)
8446 gcc_assert (INTVAL (operands[2]) == 0xffff);
8450 operands[1] = gen_lowpart (mode, operands[1]);
8452 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8454 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8458 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8459 if (get_attr_mode (insn) == MODE_SI)
8460 return "and{l}\t{%k2, %k0|%k0, %k2}";
8462 return "and{q}\t{%2, %0|%0, %2}";
8465 [(set_attr "type" "alu,alu,alu,imovx")
8466 (set_attr "length_immediate" "*,*,*,0")
8467 (set (attr "prefix_rex")
8469 (and (eq_attr "type" "imovx")
8470 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8471 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8473 (const_string "*")))
8474 (set_attr "mode" "SI,DI,DI,SI")])
8476 (define_insn "*andsi_1"
8477 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8478 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8479 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8480 (clobber (reg:CC FLAGS_REG))]
8481 "ix86_binary_operator_ok (AND, SImode, operands)"
8483 switch (get_attr_type (insn))
8487 enum machine_mode mode;
8489 gcc_assert (CONST_INT_P (operands[2]));
8490 if (INTVAL (operands[2]) == 0xff)
8494 gcc_assert (INTVAL (operands[2]) == 0xffff);
8498 operands[1] = gen_lowpart (mode, operands[1]);
8500 return "movz{bl|x}\t{%1, %0|%0, %1}";
8502 return "movz{wl|x}\t{%1, %0|%0, %1}";
8506 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8507 return "and{l}\t{%2, %0|%0, %2}";
8510 [(set_attr "type" "alu,alu,imovx")
8511 (set (attr "prefix_rex")
8513 (and (eq_attr "type" "imovx")
8514 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8515 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8517 (const_string "*")))
8518 (set_attr "length_immediate" "*,*,0")
8519 (set_attr "mode" "SI")])
8521 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8522 (define_insn "*andsi_1_zext"
8523 [(set (match_operand:DI 0 "register_operand" "=r")
8525 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8526 (match_operand:SI 2 "general_operand" "g"))))
8527 (clobber (reg:CC FLAGS_REG))]
8528 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8529 "and{l}\t{%2, %k0|%k0, %2}"
8530 [(set_attr "type" "alu")
8531 (set_attr "mode" "SI")])
8533 (define_insn "*andhi_1"
8534 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8535 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8536 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8537 (clobber (reg:CC FLAGS_REG))]
8538 "ix86_binary_operator_ok (AND, HImode, operands)"
8540 switch (get_attr_type (insn))
8543 gcc_assert (CONST_INT_P (operands[2]));
8544 gcc_assert (INTVAL (operands[2]) == 0xff);
8545 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8548 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8550 return "and{w}\t{%2, %0|%0, %2}";
8553 [(set_attr "type" "alu,alu,imovx")
8554 (set_attr "length_immediate" "*,*,0")
8555 (set (attr "prefix_rex")
8557 (and (eq_attr "type" "imovx")
8558 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8560 (const_string "*")))
8561 (set_attr "mode" "HI,HI,SI")])
8563 ;; %%% Potential partial reg stall on alternative 2. What to do?
8564 (define_insn "*andqi_1"
8565 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8566 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8567 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "ix86_binary_operator_ok (AND, QImode, operands)"
8571 and{b}\t{%2, %0|%0, %2}
8572 and{b}\t{%2, %0|%0, %2}
8573 and{l}\t{%k2, %k0|%k0, %k2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "mode" "QI,QI,SI")])
8577 (define_insn "*andqi_1_slp"
8578 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8579 (and:QI (match_dup 0)
8580 (match_operand:QI 1 "general_operand" "qn,qmn")))
8581 (clobber (reg:CC FLAGS_REG))]
8582 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8584 "and{b}\t{%1, %0|%0, %1}"
8585 [(set_attr "type" "alu1")
8586 (set_attr "mode" "QI")])
8589 [(set (match_operand 0 "register_operand" "")
8591 (const_int -65536)))
8592 (clobber (reg:CC FLAGS_REG))]
8593 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8594 || optimize_function_for_size_p (cfun)"
8595 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8596 "operands[1] = gen_lowpart (HImode, operands[0]);")
8599 [(set (match_operand 0 "ext_register_operand" "")
8602 (clobber (reg:CC FLAGS_REG))]
8603 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8604 && reload_completed"
8605 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8606 "operands[1] = gen_lowpart (QImode, operands[0]);")
8609 [(set (match_operand 0 "ext_register_operand" "")
8611 (const_int -65281)))
8612 (clobber (reg:CC FLAGS_REG))]
8613 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8614 && reload_completed"
8615 [(parallel [(set (zero_extract:SI (match_dup 0)
8619 (zero_extract:SI (match_dup 0)
8622 (zero_extract:SI (match_dup 0)
8625 (clobber (reg:CC FLAGS_REG))])]
8626 "operands[0] = gen_lowpart (SImode, operands[0]);")
8628 (define_insn "*anddi_2"
8629 [(set (reg FLAGS_REG)
8632 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8633 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8635 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8636 (and:DI (match_dup 1) (match_dup 2)))]
8637 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8638 && ix86_binary_operator_ok (AND, DImode, operands)"
8640 and{l}\t{%k2, %k0|%k0, %k2}
8641 and{q}\t{%2, %0|%0, %2}
8642 and{q}\t{%2, %0|%0, %2}"
8643 [(set_attr "type" "alu")
8644 (set_attr "mode" "SI,DI,DI")])
8646 (define_insn "*andqi_2_maybe_si"
8647 [(set (reg FLAGS_REG)
8649 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8652 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653 (and:QI (match_dup 1) (match_dup 2)))]
8654 "ix86_binary_operator_ok (AND, QImode, operands)
8655 && ix86_match_ccmode (insn,
8656 CONST_INT_P (operands[2])
8657 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8659 if (which_alternative == 2)
8661 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663 return "and{l}\t{%2, %k0|%k0, %2}";
8665 return "and{b}\t{%2, %0|%0, %2}";
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "QI,QI,SI")])
8670 (define_insn "*and<mode>_2"
8671 [(set (reg FLAGS_REG)
8672 (compare (and:SWI124
8673 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8674 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8676 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8677 (and:SWI124 (match_dup 1) (match_dup 2)))]
8678 "ix86_match_ccmode (insn, CCNOmode)
8679 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8680 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8681 [(set_attr "type" "alu")
8682 (set_attr "mode" "<MODE>")])
8684 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8685 (define_insn "*andsi_2_zext"
8686 [(set (reg FLAGS_REG)
8688 (match_operand:SI 1 "nonimmediate_operand" "%0")
8689 (match_operand:SI 2 "general_operand" "g"))
8691 (set (match_operand:DI 0 "register_operand" "=r")
8692 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8693 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8694 && ix86_binary_operator_ok (AND, SImode, operands)"
8695 "and{l}\t{%2, %k0|%k0, %2}"
8696 [(set_attr "type" "alu")
8697 (set_attr "mode" "SI")])
8699 (define_insn "*andqi_2_slp"
8700 [(set (reg FLAGS_REG)
8702 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8703 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8705 (set (strict_low_part (match_dup 0))
8706 (and:QI (match_dup 0) (match_dup 1)))]
8707 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8708 && ix86_match_ccmode (insn, CCNOmode)
8709 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8710 "and{b}\t{%1, %0|%0, %1}"
8711 [(set_attr "type" "alu1")
8712 (set_attr "mode" "QI")])
8714 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8715 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8716 ;; for a QImode operand, which of course failed.
8717 (define_insn "andqi_ext_0"
8718 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8723 (match_operand 1 "ext_register_operand" "0")
8726 (match_operand 2 "const_int_operand" "n")))
8727 (clobber (reg:CC FLAGS_REG))]
8729 "and{b}\t{%2, %h0|%h0, %2}"
8730 [(set_attr "type" "alu")
8731 (set_attr "length_immediate" "1")
8732 (set_attr "modrm" "1")
8733 (set_attr "mode" "QI")])
8735 ;; Generated by peephole translating test to and. This shows up
8736 ;; often in fp comparisons.
8737 (define_insn "*andqi_ext_0_cc"
8738 [(set (reg FLAGS_REG)
8742 (match_operand 1 "ext_register_operand" "0")
8745 (match_operand 2 "const_int_operand" "n"))
8747 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8756 "ix86_match_ccmode (insn, CCNOmode)"
8757 "and{b}\t{%2, %h0|%h0, %2}"
8758 [(set_attr "type" "alu")
8759 (set_attr "length_immediate" "1")
8760 (set_attr "modrm" "1")
8761 (set_attr "mode" "QI")])
8763 (define_insn "*andqi_ext_1_rex64"
8764 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8769 (match_operand 1 "ext_register_operand" "0")
8773 (match_operand 2 "ext_register_operand" "Q"))))
8774 (clobber (reg:CC FLAGS_REG))]
8776 "and{b}\t{%2, %h0|%h0, %2}"
8777 [(set_attr "type" "alu")
8778 (set_attr "length_immediate" "0")
8779 (set_attr "mode" "QI")])
8781 (define_insn "*andqi_ext_1"
8782 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8787 (match_operand 1 "ext_register_operand" "0")
8791 (match_operand:QI 2 "general_operand" "Qm"))))
8792 (clobber (reg:CC FLAGS_REG))]
8794 "and{b}\t{%2, %h0|%h0, %2}"
8795 [(set_attr "type" "alu")
8796 (set_attr "length_immediate" "0")
8797 (set_attr "mode" "QI")])
8799 (define_insn "*andqi_ext_2"
8800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8805 (match_operand 1 "ext_register_operand" "%0")
8809 (match_operand 2 "ext_register_operand" "Q")
8812 (clobber (reg:CC FLAGS_REG))]
8814 "and{b}\t{%h2, %h0|%h0, %h2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "length_immediate" "0")
8817 (set_attr "mode" "QI")])
8819 ;; Convert wide AND instructions with immediate operand to shorter QImode
8820 ;; equivalents when possible.
8821 ;; Don't do the splitting with memory operands, since it introduces risk
8822 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8823 ;; for size, but that can (should?) be handled by generic code instead.
8825 [(set (match_operand 0 "register_operand" "")
8826 (and (match_operand 1 "register_operand" "")
8827 (match_operand 2 "const_int_operand" "")))
8828 (clobber (reg:CC FLAGS_REG))]
8830 && QI_REG_P (operands[0])
8831 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8832 && !(~INTVAL (operands[2]) & ~(255 << 8))
8833 && GET_MODE (operands[0]) != QImode"
8834 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8835 (and:SI (zero_extract:SI (match_dup 1)
8836 (const_int 8) (const_int 8))
8838 (clobber (reg:CC FLAGS_REG))])]
8839 "operands[0] = gen_lowpart (SImode, operands[0]);
8840 operands[1] = gen_lowpart (SImode, operands[1]);
8841 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8843 ;; Since AND can be encoded with sign extended immediate, this is only
8844 ;; profitable when 7th bit is not set.
8846 [(set (match_operand 0 "register_operand" "")
8847 (and (match_operand 1 "general_operand" "")
8848 (match_operand 2 "const_int_operand" "")))
8849 (clobber (reg:CC FLAGS_REG))]
8851 && ANY_QI_REG_P (operands[0])
8852 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8853 && !(~INTVAL (operands[2]) & ~255)
8854 && !(INTVAL (operands[2]) & 128)
8855 && GET_MODE (operands[0]) != QImode"
8856 [(parallel [(set (strict_low_part (match_dup 0))
8857 (and:QI (match_dup 1)
8859 (clobber (reg:CC FLAGS_REG))])]
8860 "operands[0] = gen_lowpart (QImode, operands[0]);
8861 operands[1] = gen_lowpart (QImode, operands[1]);
8862 operands[2] = gen_lowpart (QImode, operands[2]);")
8864 ;; Logical inclusive and exclusive OR instructions
8866 ;; %%% This used to optimize known byte-wide and operations to memory.
8867 ;; If this is considered useful, it should be done with splitters.
8869 (define_expand "<code><mode>3"
8870 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8871 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8872 (match_operand:SWIM 2 "<general_operand>" "")))]
8874 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8876 (define_insn "*<code><mode>_1"
8877 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8879 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8880 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8881 (clobber (reg:CC FLAGS_REG))]
8882 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8883 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8884 [(set_attr "type" "alu")
8885 (set_attr "mode" "<MODE>")])
8887 ;; %%% Potential partial reg stall on alternative 2. What to do?
8888 (define_insn "*<code>qi_1"
8889 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8890 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8891 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8892 (clobber (reg:CC FLAGS_REG))]
8893 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8895 <logicprefix>{b}\t{%2, %0|%0, %2}
8896 <logicprefix>{b}\t{%2, %0|%0, %2}
8897 <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8898 [(set_attr "type" "alu")
8899 (set_attr "mode" "QI,QI,SI")])
8901 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8902 (define_insn "*<code>si_1_zext"
8903 [(set (match_operand:DI 0 "register_operand" "=r")
8905 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8906 (match_operand:SI 2 "general_operand" "g"))))
8907 (clobber (reg:CC FLAGS_REG))]
8908 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8909 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8910 [(set_attr "type" "alu")
8911 (set_attr "mode" "SI")])
8913 (define_insn "*<code>si_1_zext_imm"
8914 [(set (match_operand:DI 0 "register_operand" "=r")
8916 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8917 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8918 (clobber (reg:CC FLAGS_REG))]
8919 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8920 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "SI")])
8924 (define_insn "*<code>qi_1_slp"
8925 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8926 (any_or:QI (match_dup 0)
8927 (match_operand:QI 1 "general_operand" "qmn,qn")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8930 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8931 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8932 [(set_attr "type" "alu1")
8933 (set_attr "mode" "QI")])
8935 (define_insn "*<code><mode>_2"
8936 [(set (reg FLAGS_REG)
8937 (compare (any_or:SWI
8938 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8939 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8941 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8942 (any_or:SWI (match_dup 1) (match_dup 2)))]
8943 "ix86_match_ccmode (insn, CCNOmode)
8944 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8945 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8946 [(set_attr "type" "alu")
8947 (set_attr "mode" "<MODE>")])
8949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8950 ;; ??? Special case for immediate operand is missing - it is tricky.
8951 (define_insn "*<code>si_2_zext"
8952 [(set (reg FLAGS_REG)
8953 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8954 (match_operand:SI 2 "general_operand" "g"))
8956 (set (match_operand:DI 0 "register_operand" "=r")
8957 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8958 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8959 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8960 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8961 [(set_attr "type" "alu")
8962 (set_attr "mode" "SI")])
8964 (define_insn "*<code>si_2_zext_imm"
8965 [(set (reg FLAGS_REG)
8967 (match_operand:SI 1 "nonimmediate_operand" "%0")
8968 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8970 (set (match_operand:DI 0 "register_operand" "=r")
8971 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8972 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8973 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8974 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8975 [(set_attr "type" "alu")
8976 (set_attr "mode" "SI")])
8978 (define_insn "*<code>qi_2_slp"
8979 [(set (reg FLAGS_REG)
8980 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8981 (match_operand:QI 1 "general_operand" "qmn,qn"))
8983 (set (strict_low_part (match_dup 0))
8984 (any_or:QI (match_dup 0) (match_dup 1)))]
8985 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8986 && ix86_match_ccmode (insn, CCNOmode)
8987 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8988 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8989 [(set_attr "type" "alu1")
8990 (set_attr "mode" "QI")])
8992 (define_insn "*<code><mode>_3"
8993 [(set (reg FLAGS_REG)
8994 (compare (any_or:SWI
8995 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8996 (match_operand:SWI 2 "<general_operand>" "<g>"))
8998 (clobber (match_scratch:SWI 0 "=<r>"))]
8999 "ix86_match_ccmode (insn, CCNOmode)
9000 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9001 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
9002 [(set_attr "type" "alu")
9003 (set_attr "mode" "<MODE>")])
9005 (define_insn "*<code>qi_ext_0"
9006 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9011 (match_operand 1 "ext_register_operand" "0")
9014 (match_operand 2 "const_int_operand" "n")))
9015 (clobber (reg:CC FLAGS_REG))]
9016 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9017 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9018 [(set_attr "type" "alu")
9019 (set_attr "length_immediate" "1")
9020 (set_attr "modrm" "1")
9021 (set_attr "mode" "QI")])
9023 (define_insn "*<code>qi_ext_1_rex64"
9024 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9029 (match_operand 1 "ext_register_operand" "0")
9033 (match_operand 2 "ext_register_operand" "Q"))))
9034 (clobber (reg:CC FLAGS_REG))]
9036 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9037 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "length_immediate" "0")
9040 (set_attr "mode" "QI")])
9042 (define_insn "*<code>qi_ext_1"
9043 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9048 (match_operand 1 "ext_register_operand" "0")
9052 (match_operand:QI 2 "general_operand" "Qm"))))
9053 (clobber (reg:CC FLAGS_REG))]
9055 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9056 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9057 [(set_attr "type" "alu")
9058 (set_attr "length_immediate" "0")
9059 (set_attr "mode" "QI")])
9061 (define_insn "*<code>qi_ext_2"
9062 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9066 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9069 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9072 (clobber (reg:CC FLAGS_REG))]
9073 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9074 "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
9075 [(set_attr "type" "alu")
9076 (set_attr "length_immediate" "0")
9077 (set_attr "mode" "QI")])
9080 [(set (match_operand 0 "register_operand" "")
9081 (any_or (match_operand 1 "register_operand" "")
9082 (match_operand 2 "const_int_operand" "")))
9083 (clobber (reg:CC FLAGS_REG))]
9085 && QI_REG_P (operands[0])
9086 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9087 && !(INTVAL (operands[2]) & ~(255 << 8))
9088 && GET_MODE (operands[0]) != QImode"
9089 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9090 (any_or:SI (zero_extract:SI (match_dup 1)
9091 (const_int 8) (const_int 8))
9093 (clobber (reg:CC FLAGS_REG))])]
9094 "operands[0] = gen_lowpart (SImode, operands[0]);
9095 operands[1] = gen_lowpart (SImode, operands[1]);
9096 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9098 ;; Since OR can be encoded with sign extended immediate, this is only
9099 ;; profitable when 7th bit is set.
9101 [(set (match_operand 0 "register_operand" "")
9102 (any_or (match_operand 1 "general_operand" "")
9103 (match_operand 2 "const_int_operand" "")))
9104 (clobber (reg:CC FLAGS_REG))]
9106 && ANY_QI_REG_P (operands[0])
9107 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9108 && !(INTVAL (operands[2]) & ~255)
9109 && (INTVAL (operands[2]) & 128)
9110 && GET_MODE (operands[0]) != QImode"
9111 [(parallel [(set (strict_low_part (match_dup 0))
9112 (any_or:QI (match_dup 1)
9114 (clobber (reg:CC FLAGS_REG))])]
9115 "operands[0] = gen_lowpart (QImode, operands[0]);
9116 operands[1] = gen_lowpart (QImode, operands[1]);
9117 operands[2] = gen_lowpart (QImode, operands[2]);")
9119 (define_expand "xorqi_cc_ext_1"
9121 (set (reg:CCNO FLAGS_REG)
9125 (match_operand 1 "ext_register_operand" "")
9128 (match_operand:QI 2 "general_operand" ""))
9130 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9142 (define_insn "*xorqi_cc_ext_1_rex64"
9143 [(set (reg FLAGS_REG)
9147 (match_operand 1 "ext_register_operand" "0")
9150 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9152 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9161 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9162 "xor{b}\t{%2, %h0|%h0, %2}"
9163 [(set_attr "type" "alu")
9164 (set_attr "modrm" "1")
9165 (set_attr "mode" "QI")])
9167 (define_insn "*xorqi_cc_ext_1"
9168 [(set (reg FLAGS_REG)
9172 (match_operand 1 "ext_register_operand" "0")
9175 (match_operand:QI 2 "general_operand" "qmn"))
9177 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9186 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9187 "xor{b}\t{%2, %h0|%h0, %2}"
9188 [(set_attr "type" "alu")
9189 (set_attr "modrm" "1")
9190 (set_attr "mode" "QI")])
9192 ;; Negation instructions
9194 (define_expand "neg<mode>2"
9195 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9196 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9198 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9200 (define_insn_and_split "*neg<dwi>2_doubleword"
9201 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9202 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9203 (clobber (reg:CC FLAGS_REG))]
9204 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9208 [(set (reg:CCZ FLAGS_REG)
9209 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9210 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9213 (plus:DWIH (match_dup 3)
9214 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9216 (clobber (reg:CC FLAGS_REG))])
9219 (neg:DWIH (match_dup 2)))
9220 (clobber (reg:CC FLAGS_REG))])]
9221 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9223 (define_insn "*neg<mode>2_1"
9224 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9225 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9228 "neg{<imodesuffix>}\t%0"
9229 [(set_attr "type" "negnot")
9230 (set_attr "mode" "<MODE>")])
9232 ;; Combine is quite creative about this pattern.
9233 (define_insn "*negsi2_1_zext"
9234 [(set (match_operand:DI 0 "register_operand" "=r")
9236 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9239 (clobber (reg:CC FLAGS_REG))]
9240 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9242 [(set_attr "type" "negnot")
9243 (set_attr "mode" "SI")])
9245 ;; The problem with neg is that it does not perform (compare x 0),
9246 ;; it really performs (compare 0 x), which leaves us with the zero
9247 ;; flag being the only useful item.
9249 (define_insn "*neg<mode>2_cmpz"
9250 [(set (reg:CCZ FLAGS_REG)
9252 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9254 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9255 (neg:SWI (match_dup 1)))]
9256 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9257 "neg{<imodesuffix>}\t%0"
9258 [(set_attr "type" "negnot")
9259 (set_attr "mode" "<MODE>")])
9261 (define_insn "*negsi2_cmpz_zext"
9262 [(set (reg:CCZ FLAGS_REG)
9266 (match_operand:DI 1 "register_operand" "0")
9270 (set (match_operand:DI 0 "register_operand" "=r")
9271 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9274 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9276 [(set_attr "type" "negnot")
9277 (set_attr "mode" "SI")])
9279 ;; Changing of sign for FP values is doable using integer unit too.
9281 (define_expand "<code><mode>2"
9282 [(set (match_operand:X87MODEF 0 "register_operand" "")
9283 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9284 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9285 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9287 (define_insn "*absneg<mode>2_mixed"
9288 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9289 (match_operator:MODEF 3 "absneg_operator"
9290 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9291 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9292 (clobber (reg:CC FLAGS_REG))]
9293 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9296 (define_insn "*absneg<mode>2_sse"
9297 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9298 (match_operator:MODEF 3 "absneg_operator"
9299 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9300 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9301 (clobber (reg:CC FLAGS_REG))]
9302 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9305 (define_insn "*absneg<mode>2_i387"
9306 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9307 (match_operator:X87MODEF 3 "absneg_operator"
9308 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9309 (use (match_operand 2 "" ""))
9310 (clobber (reg:CC FLAGS_REG))]
9311 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9314 (define_expand "<code>tf2"
9315 [(set (match_operand:TF 0 "register_operand" "")
9316 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9318 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9320 (define_insn "*absnegtf2_sse"
9321 [(set (match_operand:TF 0 "register_operand" "=x,x")
9322 (match_operator:TF 3 "absneg_operator"
9323 [(match_operand:TF 1 "register_operand" "0,x")]))
9324 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9325 (clobber (reg:CC FLAGS_REG))]
9329 ;; Splitters for fp abs and neg.
9332 [(set (match_operand 0 "fp_register_operand" "")
9333 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9334 (use (match_operand 2 "" ""))
9335 (clobber (reg:CC FLAGS_REG))]
9337 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9340 [(set (match_operand 0 "register_operand" "")
9341 (match_operator 3 "absneg_operator"
9342 [(match_operand 1 "register_operand" "")]))
9343 (use (match_operand 2 "nonimmediate_operand" ""))
9344 (clobber (reg:CC FLAGS_REG))]
9345 "reload_completed && SSE_REG_P (operands[0])"
9346 [(set (match_dup 0) (match_dup 3))]
9348 enum machine_mode mode = GET_MODE (operands[0]);
9349 enum machine_mode vmode = GET_MODE (operands[2]);
9352 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9353 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9354 if (operands_match_p (operands[0], operands[2]))
9357 operands[1] = operands[2];
9360 if (GET_CODE (operands[3]) == ABS)
9361 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9363 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9368 [(set (match_operand:SF 0 "register_operand" "")
9369 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9370 (use (match_operand:V4SF 2 "" ""))
9371 (clobber (reg:CC FLAGS_REG))]
9373 [(parallel [(set (match_dup 0) (match_dup 1))
9374 (clobber (reg:CC FLAGS_REG))])]
9377 operands[0] = gen_lowpart (SImode, operands[0]);
9378 if (GET_CODE (operands[1]) == ABS)
9380 tmp = gen_int_mode (0x7fffffff, SImode);
9381 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9385 tmp = gen_int_mode (0x80000000, SImode);
9386 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9392 [(set (match_operand:DF 0 "register_operand" "")
9393 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9394 (use (match_operand 2 "" ""))
9395 (clobber (reg:CC FLAGS_REG))]
9397 [(parallel [(set (match_dup 0) (match_dup 1))
9398 (clobber (reg:CC FLAGS_REG))])]
9403 tmp = gen_lowpart (DImode, operands[0]);
9404 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9407 if (GET_CODE (operands[1]) == ABS)
9410 tmp = gen_rtx_NOT (DImode, tmp);
9414 operands[0] = gen_highpart (SImode, operands[0]);
9415 if (GET_CODE (operands[1]) == ABS)
9417 tmp = gen_int_mode (0x7fffffff, SImode);
9418 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9422 tmp = gen_int_mode (0x80000000, SImode);
9423 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9430 [(set (match_operand:XF 0 "register_operand" "")
9431 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9432 (use (match_operand 2 "" ""))
9433 (clobber (reg:CC FLAGS_REG))]
9435 [(parallel [(set (match_dup 0) (match_dup 1))
9436 (clobber (reg:CC FLAGS_REG))])]
9439 operands[0] = gen_rtx_REG (SImode,
9440 true_regnum (operands[0])
9441 + (TARGET_64BIT ? 1 : 2));
9442 if (GET_CODE (operands[1]) == ABS)
9444 tmp = GEN_INT (0x7fff);
9445 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9449 tmp = GEN_INT (0x8000);
9450 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9455 ;; Conditionalize these after reload. If they match before reload, we
9456 ;; lose the clobber and ability to use integer instructions.
9458 (define_insn "*<code><mode>2_1"
9459 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9460 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9462 && (reload_completed
9463 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9465 [(set_attr "type" "fsgn")
9466 (set_attr "mode" "<MODE>")])
9468 (define_insn "*<code>extendsfdf2"
9469 [(set (match_operand:DF 0 "register_operand" "=f")
9470 (absneg:DF (float_extend:DF
9471 (match_operand:SF 1 "register_operand" "0"))))]
9472 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9474 [(set_attr "type" "fsgn")
9475 (set_attr "mode" "DF")])
9477 (define_insn "*<code>extendsfxf2"
9478 [(set (match_operand:XF 0 "register_operand" "=f")
9479 (absneg:XF (float_extend:XF
9480 (match_operand:SF 1 "register_operand" "0"))))]
9483 [(set_attr "type" "fsgn")
9484 (set_attr "mode" "XF")])
9486 (define_insn "*<code>extenddfxf2"
9487 [(set (match_operand:XF 0 "register_operand" "=f")
9488 (absneg:XF (float_extend:XF
9489 (match_operand:DF 1 "register_operand" "0"))))]
9492 [(set_attr "type" "fsgn")
9493 (set_attr "mode" "XF")])
9495 ;; Copysign instructions
9497 (define_mode_iterator CSGNMODE [SF DF TF])
9498 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9500 (define_expand "copysign<mode>3"
9501 [(match_operand:CSGNMODE 0 "register_operand" "")
9502 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9503 (match_operand:CSGNMODE 2 "register_operand" "")]
9504 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9505 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9507 ix86_expand_copysign (operands);
9511 (define_insn_and_split "copysign<mode>3_const"
9512 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9514 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9515 (match_operand:CSGNMODE 2 "register_operand" "0")
9516 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9518 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9519 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9521 "&& reload_completed"
9524 ix86_split_copysign_const (operands);
9528 (define_insn "copysign<mode>3_var"
9529 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9531 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9532 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9533 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9534 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9536 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9537 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9538 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9542 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9544 [(match_operand:CSGNMODE 2 "register_operand" "")
9545 (match_operand:CSGNMODE 3 "register_operand" "")
9546 (match_operand:<CSGNVMODE> 4 "" "")
9547 (match_operand:<CSGNVMODE> 5 "" "")]
9549 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9550 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9551 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9552 && reload_completed"
9555 ix86_split_copysign_var (operands);
9559 ;; One complement instructions
9561 (define_expand "one_cmpl<mode>2"
9562 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9563 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9565 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9567 (define_insn "*one_cmpl<mode>2_1"
9568 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9569 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9570 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9571 "not{<imodesuffix>}\t%0"
9572 [(set_attr "type" "negnot")
9573 (set_attr "mode" "<MODE>")])
9575 ;; %%% Potential partial reg stall on alternative 1. What to do?
9576 (define_insn "*one_cmplqi2_1"
9577 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9578 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9579 "ix86_unary_operator_ok (NOT, QImode, operands)"
9583 [(set_attr "type" "negnot")
9584 (set_attr "mode" "QI,SI")])
9586 ;; ??? Currently never generated - xor is used instead.
9587 (define_insn "*one_cmplsi2_1_zext"
9588 [(set (match_operand:DI 0 "register_operand" "=r")
9590 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9591 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9593 [(set_attr "type" "negnot")
9594 (set_attr "mode" "SI")])
9596 (define_insn "*one_cmpl<mode>2_2"
9597 [(set (reg FLAGS_REG)
9598 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9600 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9601 (not:SWI (match_dup 1)))]
9602 "ix86_match_ccmode (insn, CCNOmode)
9603 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9605 [(set_attr "type" "alu1")
9606 (set_attr "mode" "<MODE>")])
9609 [(set (match_operand 0 "flags_reg_operand" "")
9610 (match_operator 2 "compare_operator"
9611 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9613 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9614 (not:SWI (match_dup 3)))]
9615 "ix86_match_ccmode (insn, CCNOmode)"
9616 [(parallel [(set (match_dup 0)
9617 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9620 (xor:SWI (match_dup 3) (const_int -1)))])]
9623 ;; ??? Currently never generated - xor is used instead.
9624 (define_insn "*one_cmplsi2_2_zext"
9625 [(set (reg FLAGS_REG)
9626 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9628 (set (match_operand:DI 0 "register_operand" "=r")
9629 (zero_extend:DI (not:SI (match_dup 1))))]
9630 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9631 && ix86_unary_operator_ok (NOT, SImode, operands)"
9633 [(set_attr "type" "alu1")
9634 (set_attr "mode" "SI")])
9637 [(set (match_operand 0 "flags_reg_operand" "")
9638 (match_operator 2 "compare_operator"
9639 [(not:SI (match_operand:SI 3 "register_operand" ""))
9641 (set (match_operand:DI 1 "register_operand" "")
9642 (zero_extend:DI (not:SI (match_dup 3))))]
9643 "ix86_match_ccmode (insn, CCNOmode)"
9644 [(parallel [(set (match_dup 0)
9645 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9648 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9651 ;; Arithmetic shift instructions
9653 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9654 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9655 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9656 ;; from the assembler input.
9658 ;; This instruction shifts the target reg/mem as usual, but instead of
9659 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9660 ;; is a left shift double, bits are taken from the high order bits of
9661 ;; reg, else if the insn is a shift right double, bits are taken from the
9662 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9663 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9665 ;; Since sh[lr]d does not change the `reg' operand, that is done
9666 ;; separately, making all shifts emit pairs of shift double and normal
9667 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9668 ;; support a 63 bit shift, each shift where the count is in a reg expands
9669 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9671 ;; If the shift count is a constant, we need never emit more than one
9672 ;; shift pair, instead using moves and sign extension for counts greater
9675 (define_expand "ashlti3"
9676 [(set (match_operand:TI 0 "register_operand" "")
9677 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9678 (match_operand:QI 2 "nonmemory_operand" "")))]
9680 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9682 (define_insn "*ashlti3_1"
9683 [(set (match_operand:TI 0 "register_operand" "=&r,r")
9684 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9685 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9686 (clobber (reg:CC FLAGS_REG))]
9689 [(set_attr "type" "multi")])
9692 [(match_scratch:DI 3 "r")
9693 (parallel [(set (match_operand:TI 0 "register_operand" "")
9694 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9695 (match_operand:QI 2 "nonmemory_operand" "")))
9696 (clobber (reg:CC FLAGS_REG))])
9700 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9703 [(set (match_operand:TI 0 "register_operand" "")
9704 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9705 (match_operand:QI 2 "nonmemory_operand" "")))
9706 (clobber (reg:CC FLAGS_REG))]
9707 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9708 ? epilogue_completed : reload_completed)"
9710 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9712 (define_insn "x86_64_shld"
9713 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9714 (ior:DI (ashift:DI (match_dup 0)
9715 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9716 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9717 (minus:QI (const_int 64) (match_dup 2)))))
9718 (clobber (reg:CC FLAGS_REG))]
9720 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9721 [(set_attr "type" "ishift")
9722 (set_attr "prefix_0f" "1")
9723 (set_attr "mode" "DI")
9724 (set_attr "athlon_decode" "vector")
9725 (set_attr "amdfam10_decode" "vector")])
9727 (define_expand "x86_64_shift_adj_1"
9728 [(set (reg:CCZ FLAGS_REG)
9729 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9732 (set (match_operand:DI 0 "register_operand" "")
9733 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9734 (match_operand:DI 1 "register_operand" "")
9737 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9738 (match_operand:DI 3 "register_operand" "r")
9743 (define_expand "x86_64_shift_adj_2"
9744 [(use (match_operand:DI 0 "register_operand" ""))
9745 (use (match_operand:DI 1 "register_operand" ""))
9746 (use (match_operand:QI 2 "register_operand" ""))]
9749 rtx label = gen_label_rtx ();
9752 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
9754 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9755 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9756 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9757 gen_rtx_LABEL_REF (VOIDmode, label),
9759 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9760 JUMP_LABEL (tmp) = label;
9762 emit_move_insn (operands[0], operands[1]);
9763 ix86_expand_clear (operands[1]);
9766 LABEL_NUSES (label) = 1;
9771 (define_expand "ashldi3"
9772 [(set (match_operand:DI 0 "shiftdi_operand" "")
9773 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
9774 (match_operand:QI 2 "nonmemory_operand" "")))]
9776 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
9778 (define_insn "*ashldi3_1_rex64"
9779 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9780 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
9781 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
9782 (clobber (reg:CC FLAGS_REG))]
9783 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9785 switch (get_attr_type (insn))
9788 gcc_assert (operands[2] == const1_rtx);
9789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9790 return "add{q}\t%0, %0";
9793 gcc_assert (CONST_INT_P (operands[2]));
9794 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
9795 operands[1] = gen_rtx_MULT (DImode, operands[1],
9796 GEN_INT (1 << INTVAL (operands[2])));
9797 return "lea{q}\t{%a1, %0|%0, %a1}";
9800 if (REG_P (operands[2]))
9801 return "sal{q}\t{%b2, %0|%0, %b2}";
9802 else if (operands[2] == const1_rtx
9803 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9804 return "sal{q}\t%0";
9806 return "sal{q}\t{%2, %0|%0, %2}";
9810 (cond [(eq_attr "alternative" "1")
9811 (const_string "lea")
9812 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9814 (match_operand 0 "register_operand" ""))
9815 (match_operand 2 "const1_operand" ""))
9816 (const_string "alu")
9818 (const_string "ishift")))
9819 (set (attr "length_immediate")
9821 (ior (eq_attr "type" "alu")
9822 (and (eq_attr "type" "ishift")
9823 (and (match_operand 2 "const1_operand" "")
9824 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9827 (const_string "*")))
9828 (set_attr "mode" "DI")])
9830 ;; Convert lea to the lea pattern to avoid flags dependency.
9832 [(set (match_operand:DI 0 "register_operand" "")
9833 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9834 (match_operand:QI 2 "immediate_operand" "")))
9835 (clobber (reg:CC FLAGS_REG))]
9836 "TARGET_64BIT && reload_completed
9837 && true_regnum (operands[0]) != true_regnum (operands[1])"
9839 (mult:DI (match_dup 1)
9841 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9843 ;; This pattern can't accept a variable shift count, since shifts by
9844 ;; zero don't affect the flags. We assume that shifts by constant
9845 ;; zero are optimized away.
9846 (define_insn "*ashldi3_cmp_rex64"
9847 [(set (reg FLAGS_REG)
9849 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9850 (match_operand:QI 2 "const_1_to_63_operand" "J"))
9852 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9853 (ashift:DI (match_dup 1) (match_dup 2)))]
9855 && (optimize_function_for_size_p (cfun)
9856 || !TARGET_PARTIAL_FLAG_REG_STALL
9857 || (operands[2] == const1_rtx
9859 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9860 && ix86_match_ccmode (insn, CCGOCmode)
9861 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9863 switch (get_attr_type (insn))
9866 gcc_assert (operands[2] == const1_rtx);
9867 return "add{q}\t%0, %0";
9870 if (REG_P (operands[2]))
9871 return "sal{q}\t{%b2, %0|%0, %b2}";
9872 else if (operands[2] == const1_rtx
9873 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9874 return "sal{q}\t%0";
9876 return "sal{q}\t{%2, %0|%0, %2}";
9880 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9882 (match_operand 0 "register_operand" ""))
9883 (match_operand 2 "const1_operand" ""))
9884 (const_string "alu")
9886 (const_string "ishift")))
9887 (set (attr "length_immediate")
9889 (ior (eq_attr "type" "alu")
9890 (and (eq_attr "type" "ishift")
9891 (and (match_operand 2 "const1_operand" "")
9892 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9895 (const_string "*")))
9896 (set_attr "mode" "DI")])
9898 (define_insn "*ashldi3_cconly_rex64"
9899 [(set (reg FLAGS_REG)
9901 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9902 (match_operand:QI 2 "const_1_to_63_operand" "J"))
9904 (clobber (match_scratch:DI 0 "=r"))]
9906 && (optimize_function_for_size_p (cfun)
9907 || !TARGET_PARTIAL_FLAG_REG_STALL
9908 || (operands[2] == const1_rtx
9910 || TARGET_DOUBLE_WITH_ADD)))
9911 && ix86_match_ccmode (insn, CCGOCmode)
9912 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9914 switch (get_attr_type (insn))
9917 gcc_assert (operands[2] == const1_rtx);
9918 return "add{q}\t%0, %0";
9921 if (REG_P (operands[2]))
9922 return "sal{q}\t{%b2, %0|%0, %b2}";
9923 else if (operands[2] == const1_rtx
9924 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9925 return "sal{q}\t%0";
9927 return "sal{q}\t{%2, %0|%0, %2}";
9931 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9933 (match_operand 0 "register_operand" ""))
9934 (match_operand 2 "const1_operand" ""))
9935 (const_string "alu")
9937 (const_string "ishift")))
9938 (set (attr "length_immediate")
9940 (ior (eq_attr "type" "alu")
9941 (and (eq_attr "type" "ishift")
9942 (and (match_operand 2 "const1_operand" "")
9943 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9946 (const_string "*")))
9947 (set_attr "mode" "DI")])
9949 (define_insn "*ashldi3_1"
9950 [(set (match_operand:DI 0 "register_operand" "=&r,r")
9951 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
9952 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
9953 (clobber (reg:CC FLAGS_REG))]
9956 [(set_attr "type" "multi")])
9958 ;; By default we don't ask for a scratch register, because when DImode
9959 ;; values are manipulated, registers are already at a premium. But if
9960 ;; we have one handy, we won't turn it away.
9962 [(match_scratch:SI 3 "r")
9963 (parallel [(set (match_operand:DI 0 "register_operand" "")
9964 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9965 (match_operand:QI 2 "nonmemory_operand" "")))
9966 (clobber (reg:CC FLAGS_REG))])
9968 "!TARGET_64BIT && TARGET_CMOVE"
9970 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
9973 [(set (match_operand:DI 0 "register_operand" "")
9974 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9975 (match_operand:QI 2 "nonmemory_operand" "")))
9976 (clobber (reg:CC FLAGS_REG))]
9977 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9978 ? epilogue_completed : reload_completed)"
9980 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
9982 (define_insn "x86_shld"
9983 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9984 (ior:SI (ashift:SI (match_dup 0)
9985 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9986 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9987 (minus:QI (const_int 32) (match_dup 2)))))
9988 (clobber (reg:CC FLAGS_REG))]
9990 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9991 [(set_attr "type" "ishift")
9992 (set_attr "prefix_0f" "1")
9993 (set_attr "mode" "SI")
9994 (set_attr "pent_pair" "np")
9995 (set_attr "athlon_decode" "vector")
9996 (set_attr "amdfam10_decode" "vector")])
9998 (define_expand "x86_shift_adj_1"
9999 [(set (reg:CCZ FLAGS_REG)
10000 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10003 (set (match_operand:SI 0 "register_operand" "")
10004 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10005 (match_operand:SI 1 "register_operand" "")
10008 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10009 (match_operand:SI 3 "register_operand" "r")
10014 (define_expand "x86_shift_adj_2"
10015 [(use (match_operand:SI 0 "register_operand" ""))
10016 (use (match_operand:SI 1 "register_operand" ""))
10017 (use (match_operand:QI 2 "register_operand" ""))]
10020 rtx label = gen_label_rtx ();
10023 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10025 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10026 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10027 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10028 gen_rtx_LABEL_REF (VOIDmode, label),
10030 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10031 JUMP_LABEL (tmp) = label;
10033 emit_move_insn (operands[0], operands[1]);
10034 ix86_expand_clear (operands[1]);
10036 emit_label (label);
10037 LABEL_NUSES (label) = 1;
10042 (define_expand "ashlsi3"
10043 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10044 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10045 (match_operand:QI 2 "nonmemory_operand" "")))]
10047 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10049 (define_insn "*ashlsi3_1"
10050 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10051 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10052 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10053 (clobber (reg:CC FLAGS_REG))]
10054 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10056 switch (get_attr_type (insn))
10059 gcc_assert (operands[2] == const1_rtx);
10060 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10061 return "add{l}\t%0, %0";
10067 if (REG_P (operands[2]))
10068 return "sal{l}\t{%b2, %0|%0, %b2}";
10069 else if (operands[2] == const1_rtx
10070 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10071 return "sal{l}\t%0";
10073 return "sal{l}\t{%2, %0|%0, %2}";
10076 [(set (attr "type")
10077 (cond [(eq_attr "alternative" "1")
10078 (const_string "lea")
10079 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10081 (match_operand 0 "register_operand" ""))
10082 (match_operand 2 "const1_operand" ""))
10083 (const_string "alu")
10085 (const_string "ishift")))
10086 (set (attr "length_immediate")
10088 (ior (eq_attr "type" "alu")
10089 (and (eq_attr "type" "ishift")
10090 (and (match_operand 2 "const1_operand" "")
10091 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10094 (const_string "*")))
10095 (set_attr "mode" "SI")])
10097 ;; Convert lea to the lea pattern to avoid flags dependency.
10099 [(set (match_operand 0 "register_operand" "")
10100 (ashift (match_operand 1 "index_register_operand" "")
10101 (match_operand:QI 2 "const_int_operand" "")))
10102 (clobber (reg:CC FLAGS_REG))]
10104 && true_regnum (operands[0]) != true_regnum (operands[1])
10105 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10109 enum machine_mode mode = GET_MODE (operands[0]);
10111 if (GET_MODE_SIZE (mode) < 4)
10112 operands[0] = gen_lowpart (SImode, operands[0]);
10114 operands[1] = gen_lowpart (Pmode, operands[1]);
10115 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10117 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10118 if (Pmode != SImode)
10119 pat = gen_rtx_SUBREG (SImode, pat, 0);
10120 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10124 ;; Rare case of shifting RSP is handled by generating move and shift
10126 [(set (match_operand 0 "register_operand" "")
10127 (ashift (match_operand 1 "register_operand" "")
10128 (match_operand:QI 2 "const_int_operand" "")))
10129 (clobber (reg:CC FLAGS_REG))]
10131 && true_regnum (operands[0]) != true_regnum (operands[1])"
10135 emit_move_insn (operands[0], operands[1]);
10136 pat = gen_rtx_SET (VOIDmode, operands[0],
10137 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10138 operands[0], operands[2]));
10139 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10140 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10144 (define_insn "*ashlsi3_1_zext"
10145 [(set (match_operand:DI 0 "register_operand" "=r,r")
10146 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10147 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10148 (clobber (reg:CC FLAGS_REG))]
10149 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10151 switch (get_attr_type (insn))
10154 gcc_assert (operands[2] == const1_rtx);
10155 return "add{l}\t%k0, %k0";
10161 if (REG_P (operands[2]))
10162 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10163 else if (operands[2] == const1_rtx
10164 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165 return "sal{l}\t%k0";
10167 return "sal{l}\t{%2, %k0|%k0, %2}";
10170 [(set (attr "type")
10171 (cond [(eq_attr "alternative" "1")
10172 (const_string "lea")
10173 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10175 (match_operand 2 "const1_operand" ""))
10176 (const_string "alu")
10178 (const_string "ishift")))
10179 (set (attr "length_immediate")
10181 (ior (eq_attr "type" "alu")
10182 (and (eq_attr "type" "ishift")
10183 (and (match_operand 2 "const1_operand" "")
10184 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10187 (const_string "*")))
10188 (set_attr "mode" "SI")])
10190 ;; Convert lea to the lea pattern to avoid flags dependency.
10192 [(set (match_operand:DI 0 "register_operand" "")
10193 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10194 (match_operand:QI 2 "const_int_operand" ""))))
10195 (clobber (reg:CC FLAGS_REG))]
10196 "TARGET_64BIT && reload_completed
10197 && true_regnum (operands[0]) != true_regnum (operands[1])"
10198 [(set (match_dup 0) (zero_extend:DI
10199 (subreg:SI (mult:SI (match_dup 1)
10200 (match_dup 2)) 0)))]
10202 operands[1] = gen_lowpart (Pmode, operands[1]);
10203 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10206 ;; This pattern can't accept a variable shift count, since shifts by
10207 ;; zero don't affect the flags. We assume that shifts by constant
10208 ;; zero are optimized away.
10209 (define_insn "*ashlsi3_cmp"
10210 [(set (reg FLAGS_REG)
10212 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10213 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10215 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10216 (ashift:SI (match_dup 1) (match_dup 2)))]
10217 "(optimize_function_for_size_p (cfun)
10218 || !TARGET_PARTIAL_FLAG_REG_STALL
10219 || (operands[2] == const1_rtx
10221 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10222 && ix86_match_ccmode (insn, CCGOCmode)
10223 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10225 switch (get_attr_type (insn))
10228 gcc_assert (operands[2] == const1_rtx);
10229 return "add{l}\t%0, %0";
10232 if (REG_P (operands[2]))
10233 return "sal{l}\t{%b2, %0|%0, %b2}";
10234 else if (operands[2] == const1_rtx
10235 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10236 return "sal{l}\t%0";
10238 return "sal{l}\t{%2, %0|%0, %2}";
10241 [(set (attr "type")
10242 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10244 (match_operand 0 "register_operand" ""))
10245 (match_operand 2 "const1_operand" ""))
10246 (const_string "alu")
10248 (const_string "ishift")))
10249 (set (attr "length_immediate")
10251 (ior (eq_attr "type" "alu")
10252 (and (eq_attr "type" "ishift")
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 "*ashlsi3_cconly"
10261 [(set (reg FLAGS_REG)
10263 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10264 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10266 (clobber (match_scratch:SI 0 "=r"))]
10267 "(optimize_function_for_size_p (cfun)
10268 || !TARGET_PARTIAL_FLAG_REG_STALL
10269 || (operands[2] == const1_rtx
10271 || TARGET_DOUBLE_WITH_ADD)))
10272 && ix86_match_ccmode (insn, CCGOCmode)
10273 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10275 switch (get_attr_type (insn))
10278 gcc_assert (operands[2] == const1_rtx);
10279 return "add{l}\t%0, %0";
10282 if (REG_P (operands[2]))
10283 return "sal{l}\t{%b2, %0|%0, %b2}";
10284 else if (operands[2] == const1_rtx
10285 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10286 return "sal{l}\t%0";
10288 return "sal{l}\t{%2, %0|%0, %2}";
10291 [(set (attr "type")
10292 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10294 (match_operand 0 "register_operand" ""))
10295 (match_operand 2 "const1_operand" ""))
10296 (const_string "alu")
10298 (const_string "ishift")))
10299 (set (attr "length_immediate")
10301 (ior (eq_attr "type" "alu")
10302 (and (eq_attr "type" "ishift")
10303 (and (match_operand 2 "const1_operand" "")
10304 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10307 (const_string "*")))
10308 (set_attr "mode" "SI")])
10310 (define_insn "*ashlsi3_cmp_zext"
10311 [(set (reg FLAGS_REG)
10313 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10314 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10316 (set (match_operand:DI 0 "register_operand" "=r")
10317 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10319 && (optimize_function_for_size_p (cfun)
10320 || !TARGET_PARTIAL_FLAG_REG_STALL
10321 || (operands[2] == const1_rtx
10323 || TARGET_DOUBLE_WITH_ADD)))
10324 && ix86_match_ccmode (insn, CCGOCmode)
10325 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10327 switch (get_attr_type (insn))
10330 gcc_assert (operands[2] == const1_rtx);
10331 return "add{l}\t%k0, %k0";
10334 if (REG_P (operands[2]))
10335 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10336 else if (operands[2] == const1_rtx
10337 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10338 return "sal{l}\t%k0";
10340 return "sal{l}\t{%2, %k0|%k0, %2}";
10343 [(set (attr "type")
10344 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10346 (match_operand 2 "const1_operand" ""))
10347 (const_string "alu")
10349 (const_string "ishift")))
10350 (set (attr "length_immediate")
10352 (ior (eq_attr "type" "alu")
10353 (and (eq_attr "type" "ishift")
10354 (and (match_operand 2 "const1_operand" "")
10355 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10358 (const_string "*")))
10359 (set_attr "mode" "SI")])
10361 (define_expand "ashlhi3"
10362 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10363 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10364 (match_operand:QI 2 "nonmemory_operand" "")))]
10365 "TARGET_HIMODE_MATH"
10366 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10368 (define_insn "*ashlhi3_1_lea"
10369 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10370 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10371 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10372 (clobber (reg:CC FLAGS_REG))]
10373 "!TARGET_PARTIAL_REG_STALL
10374 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10376 switch (get_attr_type (insn))
10381 gcc_assert (operands[2] == const1_rtx);
10382 return "add{w}\t%0, %0";
10385 if (REG_P (operands[2]))
10386 return "sal{w}\t{%b2, %0|%0, %b2}";
10387 else if (operands[2] == const1_rtx
10388 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10389 return "sal{w}\t%0";
10391 return "sal{w}\t{%2, %0|%0, %2}";
10394 [(set (attr "type")
10395 (cond [(eq_attr "alternative" "1")
10396 (const_string "lea")
10397 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10399 (match_operand 0 "register_operand" ""))
10400 (match_operand 2 "const1_operand" ""))
10401 (const_string "alu")
10403 (const_string "ishift")))
10404 (set (attr "length_immediate")
10406 (ior (eq_attr "type" "alu")
10407 (and (eq_attr "type" "ishift")
10408 (and (match_operand 2 "const1_operand" "")
10409 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10412 (const_string "*")))
10413 (set_attr "mode" "HI,SI")])
10415 (define_insn "*ashlhi3_1"
10416 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10417 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10418 (match_operand:QI 2 "nonmemory_operand" "cI")))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_PARTIAL_REG_STALL
10421 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10423 switch (get_attr_type (insn))
10426 gcc_assert (operands[2] == const1_rtx);
10427 return "add{w}\t%0, %0";
10430 if (REG_P (operands[2]))
10431 return "sal{w}\t{%b2, %0|%0, %b2}";
10432 else if (operands[2] == const1_rtx
10433 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10434 return "sal{w}\t%0";
10436 return "sal{w}\t{%2, %0|%0, %2}";
10439 [(set (attr "type")
10440 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10442 (match_operand 0 "register_operand" ""))
10443 (match_operand 2 "const1_operand" ""))
10444 (const_string "alu")
10446 (const_string "ishift")))
10447 (set (attr "length_immediate")
10449 (ior (eq_attr "type" "alu")
10450 (and (eq_attr "type" "ishift")
10451 (and (match_operand 2 "const1_operand" "")
10452 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10455 (const_string "*")))
10456 (set_attr "mode" "HI")])
10458 ;; This pattern can't accept a variable shift count, since shifts by
10459 ;; zero don't affect the flags. We assume that shifts by constant
10460 ;; zero are optimized away.
10461 (define_insn "*ashlhi3_cmp"
10462 [(set (reg FLAGS_REG)
10464 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10465 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10467 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10468 (ashift:HI (match_dup 1) (match_dup 2)))]
10469 "(optimize_function_for_size_p (cfun)
10470 || !TARGET_PARTIAL_FLAG_REG_STALL
10471 || (operands[2] == const1_rtx
10473 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10474 && ix86_match_ccmode (insn, CCGOCmode)
10475 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10477 switch (get_attr_type (insn))
10480 gcc_assert (operands[2] == const1_rtx);
10481 return "add{w}\t%0, %0";
10484 if (REG_P (operands[2]))
10485 return "sal{w}\t{%b2, %0|%0, %b2}";
10486 else if (operands[2] == const1_rtx
10487 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10488 return "sal{w}\t%0";
10490 return "sal{w}\t{%2, %0|%0, %2}";
10493 [(set (attr "type")
10494 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10496 (match_operand 0 "register_operand" ""))
10497 (match_operand 2 "const1_operand" ""))
10498 (const_string "alu")
10500 (const_string "ishift")))
10501 (set (attr "length_immediate")
10503 (ior (eq_attr "type" "alu")
10504 (and (eq_attr "type" "ishift")
10505 (and (match_operand 2 "const1_operand" "")
10506 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10509 (const_string "*")))
10510 (set_attr "mode" "HI")])
10512 (define_insn "*ashlhi3_cconly"
10513 [(set (reg FLAGS_REG)
10515 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10516 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10518 (clobber (match_scratch:HI 0 "=r"))]
10519 "(optimize_function_for_size_p (cfun)
10520 || !TARGET_PARTIAL_FLAG_REG_STALL
10521 || (operands[2] == const1_rtx
10523 || TARGET_DOUBLE_WITH_ADD)))
10524 && ix86_match_ccmode (insn, CCGOCmode)
10525 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10527 switch (get_attr_type (insn))
10530 gcc_assert (operands[2] == const1_rtx);
10531 return "add{w}\t%0, %0";
10534 if (REG_P (operands[2]))
10535 return "sal{w}\t{%b2, %0|%0, %b2}";
10536 else if (operands[2] == const1_rtx
10537 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10538 return "sal{w}\t%0";
10540 return "sal{w}\t{%2, %0|%0, %2}";
10543 [(set (attr "type")
10544 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10546 (match_operand 0 "register_operand" ""))
10547 (match_operand 2 "const1_operand" ""))
10548 (const_string "alu")
10550 (const_string "ishift")))
10551 (set (attr "length_immediate")
10553 (ior (eq_attr "type" "alu")
10554 (and (eq_attr "type" "ishift")
10555 (and (match_operand 2 "const1_operand" "")
10556 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10559 (const_string "*")))
10560 (set_attr "mode" "HI")])
10562 (define_expand "ashlqi3"
10563 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10564 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10565 (match_operand:QI 2 "nonmemory_operand" "")))]
10566 "TARGET_QIMODE_MATH"
10567 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10569 ;; %%% Potential partial reg stall on alternative 2. What to do?
10571 (define_insn "*ashlqi3_1_lea"
10572 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10573 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10574 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10575 (clobber (reg:CC FLAGS_REG))]
10576 "!TARGET_PARTIAL_REG_STALL
10577 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10579 switch (get_attr_type (insn))
10584 gcc_assert (operands[2] == const1_rtx);
10585 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10586 return "add{l}\t%k0, %k0";
10588 return "add{b}\t%0, %0";
10591 if (REG_P (operands[2]))
10593 if (get_attr_mode (insn) == MODE_SI)
10594 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10596 return "sal{b}\t{%b2, %0|%0, %b2}";
10598 else if (operands[2] == const1_rtx
10599 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10601 if (get_attr_mode (insn) == MODE_SI)
10602 return "sal{l}\t%0";
10604 return "sal{b}\t%0";
10608 if (get_attr_mode (insn) == MODE_SI)
10609 return "sal{l}\t{%2, %k0|%k0, %2}";
10611 return "sal{b}\t{%2, %0|%0, %2}";
10615 [(set (attr "type")
10616 (cond [(eq_attr "alternative" "2")
10617 (const_string "lea")
10618 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10620 (match_operand 0 "register_operand" ""))
10621 (match_operand 2 "const1_operand" ""))
10622 (const_string "alu")
10624 (const_string "ishift")))
10625 (set (attr "length_immediate")
10627 (ior (eq_attr "type" "alu")
10628 (and (eq_attr "type" "ishift")
10629 (and (match_operand 2 "const1_operand" "")
10630 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10633 (const_string "*")))
10634 (set_attr "mode" "QI,SI,SI")])
10636 (define_insn "*ashlqi3_1"
10637 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10638 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10639 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10640 (clobber (reg:CC FLAGS_REG))]
10641 "TARGET_PARTIAL_REG_STALL
10642 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10644 switch (get_attr_type (insn))
10647 gcc_assert (operands[2] == const1_rtx);
10648 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10649 return "add{l}\t%k0, %k0";
10651 return "add{b}\t%0, %0";
10654 if (REG_P (operands[2]))
10656 if (get_attr_mode (insn) == MODE_SI)
10657 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10659 return "sal{b}\t{%b2, %0|%0, %b2}";
10661 else if (operands[2] == const1_rtx
10662 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10664 if (get_attr_mode (insn) == MODE_SI)
10665 return "sal{l}\t%0";
10667 return "sal{b}\t%0";
10671 if (get_attr_mode (insn) == MODE_SI)
10672 return "sal{l}\t{%2, %k0|%k0, %2}";
10674 return "sal{b}\t{%2, %0|%0, %2}";
10678 [(set (attr "type")
10679 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10681 (match_operand 0 "register_operand" ""))
10682 (match_operand 2 "const1_operand" ""))
10683 (const_string "alu")
10685 (const_string "ishift")))
10686 (set (attr "length_immediate")
10688 (ior (eq_attr "type" "alu")
10689 (and (eq_attr "type" "ishift")
10690 (and (match_operand 2 "const1_operand" "")
10691 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10694 (const_string "*")))
10695 (set_attr "mode" "QI,SI")])
10697 ;; This pattern can't accept a variable shift count, since shifts by
10698 ;; zero don't affect the flags. We assume that shifts by constant
10699 ;; zero are optimized away.
10700 (define_insn "*ashlqi3_cmp"
10701 [(set (reg FLAGS_REG)
10703 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10704 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10706 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10707 (ashift:QI (match_dup 1) (match_dup 2)))]
10708 "(optimize_function_for_size_p (cfun)
10709 || !TARGET_PARTIAL_FLAG_REG_STALL
10710 || (operands[2] == const1_rtx
10712 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10713 && ix86_match_ccmode (insn, CCGOCmode)
10714 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10716 switch (get_attr_type (insn))
10719 gcc_assert (operands[2] == const1_rtx);
10720 return "add{b}\t%0, %0";
10723 if (REG_P (operands[2]))
10724 return "sal{b}\t{%b2, %0|%0, %b2}";
10725 else if (operands[2] == const1_rtx
10726 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10727 return "sal{b}\t%0";
10729 return "sal{b}\t{%2, %0|%0, %2}";
10732 [(set (attr "type")
10733 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10735 (match_operand 0 "register_operand" ""))
10736 (match_operand 2 "const1_operand" ""))
10737 (const_string "alu")
10739 (const_string "ishift")))
10740 (set (attr "length_immediate")
10742 (ior (eq_attr "type" "alu")
10743 (and (eq_attr "type" "ishift")
10744 (and (match_operand 2 "const1_operand" "")
10745 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10748 (const_string "*")))
10749 (set_attr "mode" "QI")])
10751 (define_insn "*ashlqi3_cconly"
10752 [(set (reg FLAGS_REG)
10754 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10755 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10757 (clobber (match_scratch:QI 0 "=q"))]
10758 "(optimize_function_for_size_p (cfun)
10759 || !TARGET_PARTIAL_FLAG_REG_STALL
10760 || (operands[2] == const1_rtx
10762 || TARGET_DOUBLE_WITH_ADD)))
10763 && ix86_match_ccmode (insn, CCGOCmode)
10764 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10766 switch (get_attr_type (insn))
10769 gcc_assert (operands[2] == const1_rtx);
10770 return "add{b}\t%0, %0";
10773 if (REG_P (operands[2]))
10774 return "sal{b}\t{%b2, %0|%0, %b2}";
10775 else if (operands[2] == const1_rtx
10776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10777 return "sal{b}\t%0";
10779 return "sal{b}\t{%2, %0|%0, %2}";
10782 [(set (attr "type")
10783 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10785 (match_operand 0 "register_operand" ""))
10786 (match_operand 2 "const1_operand" ""))
10787 (const_string "alu")
10789 (const_string "ishift")))
10790 (set (attr "length_immediate")
10792 (ior (eq_attr "type" "alu")
10793 (and (eq_attr "type" "ishift")
10794 (and (match_operand 2 "const1_operand" "")
10795 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10798 (const_string "*")))
10799 (set_attr "mode" "QI")])
10801 ;; See comment above `ashldi3' about how this works.
10803 (define_expand "ashrti3"
10804 [(set (match_operand:TI 0 "register_operand" "")
10805 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10806 (match_operand:QI 2 "nonmemory_operand" "")))]
10808 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10810 (define_insn "*ashrti3_1"
10811 [(set (match_operand:TI 0 "register_operand" "=r")
10812 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10813 (match_operand:QI 2 "nonmemory_operand" "Oc")))
10814 (clobber (reg:CC FLAGS_REG))]
10817 [(set_attr "type" "multi")])
10820 [(match_scratch:DI 3 "r")
10821 (parallel [(set (match_operand:TI 0 "register_operand" "")
10822 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10823 (match_operand:QI 2 "nonmemory_operand" "")))
10824 (clobber (reg:CC FLAGS_REG))])
10828 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10831 [(set (match_operand:TI 0 "register_operand" "")
10832 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10833 (match_operand:QI 2 "nonmemory_operand" "")))
10834 (clobber (reg:CC FLAGS_REG))]
10835 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10836 ? epilogue_completed : reload_completed)"
10838 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10840 (define_insn "x86_64_shrd"
10841 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10842 (ior:DI (ashiftrt:DI (match_dup 0)
10843 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10844 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10845 (minus:QI (const_int 64) (match_dup 2)))))
10846 (clobber (reg:CC FLAGS_REG))]
10848 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10849 [(set_attr "type" "ishift")
10850 (set_attr "prefix_0f" "1")
10851 (set_attr "mode" "DI")
10852 (set_attr "athlon_decode" "vector")
10853 (set_attr "amdfam10_decode" "vector")])
10855 (define_expand "ashrdi3"
10856 [(set (match_operand:DI 0 "shiftdi_operand" "")
10857 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10858 (match_operand:QI 2 "nonmemory_operand" "")))]
10860 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10862 (define_expand "x86_64_shift_adj_3"
10863 [(use (match_operand:DI 0 "register_operand" ""))
10864 (use (match_operand:DI 1 "register_operand" ""))
10865 (use (match_operand:QI 2 "register_operand" ""))]
10868 rtx label = gen_label_rtx ();
10871 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10873 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10874 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10875 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10876 gen_rtx_LABEL_REF (VOIDmode, label),
10878 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10879 JUMP_LABEL (tmp) = label;
10881 emit_move_insn (operands[0], operands[1]);
10882 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10884 emit_label (label);
10885 LABEL_NUSES (label) = 1;
10890 (define_insn "ashrdi3_63_rex64"
10891 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10892 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10893 (match_operand:DI 2 "const_int_operand" "i,i")))
10894 (clobber (reg:CC FLAGS_REG))]
10895 "TARGET_64BIT && INTVAL (operands[2]) == 63
10896 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10897 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10900 sar{q}\t{%2, %0|%0, %2}"
10901 [(set_attr "type" "imovx,ishift")
10902 (set_attr "prefix_0f" "0,*")
10903 (set_attr "length_immediate" "0,*")
10904 (set_attr "modrm" "0,1")
10905 (set_attr "mode" "DI")])
10907 (define_insn "*ashrdi3_1_one_bit_rex64"
10908 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10909 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10910 (match_operand:QI 2 "const1_operand" "")))
10911 (clobber (reg:CC FLAGS_REG))]
10913 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10914 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10916 [(set_attr "type" "ishift")
10917 (set_attr "length_immediate" "0")
10918 (set_attr "mode" "DI")])
10920 (define_insn "*ashrdi3_1_rex64"
10921 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10922 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10923 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10924 (clobber (reg:CC FLAGS_REG))]
10925 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10927 sar{q}\t{%2, %0|%0, %2}
10928 sar{q}\t{%b2, %0|%0, %b2}"
10929 [(set_attr "type" "ishift")
10930 (set_attr "mode" "DI")])
10932 ;; This pattern can't accept a variable shift count, since shifts by
10933 ;; zero don't affect the flags. We assume that shifts by constant
10934 ;; zero are optimized away.
10935 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10936 [(set (reg FLAGS_REG)
10938 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10939 (match_operand:QI 2 "const1_operand" ""))
10941 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10942 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10944 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10945 && ix86_match_ccmode (insn, CCGOCmode)
10946 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10948 [(set_attr "type" "ishift")
10949 (set_attr "length_immediate" "0")
10950 (set_attr "mode" "DI")])
10952 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10953 [(set (reg FLAGS_REG)
10955 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10956 (match_operand:QI 2 "const1_operand" ""))
10958 (clobber (match_scratch:DI 0 "=r"))]
10960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10961 && ix86_match_ccmode (insn, CCGOCmode)
10962 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10964 [(set_attr "type" "ishift")
10965 (set_attr "length_immediate" "0")
10966 (set_attr "mode" "DI")])
10968 ;; This pattern can't accept a variable shift count, since shifts by
10969 ;; zero don't affect the flags. We assume that shifts by constant
10970 ;; zero are optimized away.
10971 (define_insn "*ashrdi3_cmp_rex64"
10972 [(set (reg FLAGS_REG)
10974 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10975 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10977 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10978 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10980 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10981 && ix86_match_ccmode (insn, CCGOCmode)
10982 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10983 "sar{q}\t{%2, %0|%0, %2}"
10984 [(set_attr "type" "ishift")
10985 (set_attr "mode" "DI")])
10987 (define_insn "*ashrdi3_cconly_rex64"
10988 [(set (reg FLAGS_REG)
10990 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10991 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10993 (clobber (match_scratch:DI 0 "=r"))]
10995 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10996 && ix86_match_ccmode (insn, CCGOCmode)
10997 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10998 "sar{q}\t{%2, %0|%0, %2}"
10999 [(set_attr "type" "ishift")
11000 (set_attr "mode" "DI")])
11002 (define_insn "*ashrdi3_1"
11003 [(set (match_operand:DI 0 "register_operand" "=r")
11004 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11005 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11006 (clobber (reg:CC FLAGS_REG))]
11009 [(set_attr "type" "multi")])
11011 ;; By default we don't ask for a scratch register, because when DImode
11012 ;; values are manipulated, registers are already at a premium. But if
11013 ;; we have one handy, we won't turn it away.
11015 [(match_scratch:SI 3 "r")
11016 (parallel [(set (match_operand:DI 0 "register_operand" "")
11017 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11018 (match_operand:QI 2 "nonmemory_operand" "")))
11019 (clobber (reg:CC FLAGS_REG))])
11021 "!TARGET_64BIT && TARGET_CMOVE"
11023 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11026 [(set (match_operand:DI 0 "register_operand" "")
11027 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11028 (match_operand:QI 2 "nonmemory_operand" "")))
11029 (clobber (reg:CC FLAGS_REG))]
11030 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11031 ? epilogue_completed : reload_completed)"
11033 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11035 (define_insn "x86_shrd"
11036 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11037 (ior:SI (ashiftrt:SI (match_dup 0)
11038 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11039 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11040 (minus:QI (const_int 32) (match_dup 2)))))
11041 (clobber (reg:CC FLAGS_REG))]
11043 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11044 [(set_attr "type" "ishift")
11045 (set_attr "prefix_0f" "1")
11046 (set_attr "pent_pair" "np")
11047 (set_attr "mode" "SI")])
11049 (define_expand "x86_shift_adj_3"
11050 [(use (match_operand:SI 0 "register_operand" ""))
11051 (use (match_operand:SI 1 "register_operand" ""))
11052 (use (match_operand:QI 2 "register_operand" ""))]
11055 rtx label = gen_label_rtx ();
11058 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11060 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11061 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11062 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11063 gen_rtx_LABEL_REF (VOIDmode, label),
11065 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11066 JUMP_LABEL (tmp) = label;
11068 emit_move_insn (operands[0], operands[1]);
11069 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11071 emit_label (label);
11072 LABEL_NUSES (label) = 1;
11077 (define_expand "ashrsi3_31"
11078 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11079 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11080 (match_operand:SI 2 "const_int_operand" "i,i")))
11081 (clobber (reg:CC FLAGS_REG))])]
11084 (define_insn "*ashrsi3_31"
11085 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11086 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11087 (match_operand:SI 2 "const_int_operand" "i,i")))
11088 (clobber (reg:CC FLAGS_REG))]
11089 "INTVAL (operands[2]) == 31
11090 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11091 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11094 sar{l}\t{%2, %0|%0, %2}"
11095 [(set_attr "type" "imovx,ishift")
11096 (set_attr "prefix_0f" "0,*")
11097 (set_attr "length_immediate" "0,*")
11098 (set_attr "modrm" "0,1")
11099 (set_attr "mode" "SI")])
11101 (define_insn "*ashrsi3_31_zext"
11102 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11103 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11104 (match_operand:SI 2 "const_int_operand" "i,i"))))
11105 (clobber (reg:CC FLAGS_REG))]
11106 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11107 && INTVAL (operands[2]) == 31
11108 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11111 sar{l}\t{%2, %k0|%k0, %2}"
11112 [(set_attr "type" "imovx,ishift")
11113 (set_attr "prefix_0f" "0,*")
11114 (set_attr "length_immediate" "0,*")
11115 (set_attr "modrm" "0,1")
11116 (set_attr "mode" "SI")])
11118 (define_expand "ashrsi3"
11119 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11120 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11121 (match_operand:QI 2 "nonmemory_operand" "")))]
11123 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11125 (define_insn "*ashrsi3_1_one_bit"
11126 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11127 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11128 (match_operand:QI 2 "const1_operand" "")))
11129 (clobber (reg:CC FLAGS_REG))]
11130 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11131 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11133 [(set_attr "type" "ishift")
11134 (set_attr "length_immediate" "0")
11135 (set_attr "mode" "SI")])
11137 (define_insn "*ashrsi3_1_one_bit_zext"
11138 [(set (match_operand:DI 0 "register_operand" "=r")
11139 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11140 (match_operand:QI 2 "const1_operand" ""))))
11141 (clobber (reg:CC FLAGS_REG))]
11143 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11144 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11146 [(set_attr "type" "ishift")
11147 (set_attr "length_immediate" "0")
11148 (set_attr "mode" "SI")])
11150 (define_insn "*ashrsi3_1"
11151 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11152 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11153 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11154 (clobber (reg:CC FLAGS_REG))]
11155 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11157 sar{l}\t{%2, %0|%0, %2}
11158 sar{l}\t{%b2, %0|%0, %b2}"
11159 [(set_attr "type" "ishift")
11160 (set_attr "mode" "SI")])
11162 (define_insn "*ashrsi3_1_zext"
11163 [(set (match_operand:DI 0 "register_operand" "=r,r")
11164 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11165 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11166 (clobber (reg:CC FLAGS_REG))]
11167 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11169 sar{l}\t{%2, %k0|%k0, %2}
11170 sar{l}\t{%b2, %k0|%k0, %b2}"
11171 [(set_attr "type" "ishift")
11172 (set_attr "mode" "SI")])
11174 ;; This pattern can't accept a variable shift count, since shifts by
11175 ;; zero don't affect the flags. We assume that shifts by constant
11176 ;; zero are optimized away.
11177 (define_insn "*ashrsi3_one_bit_cmp"
11178 [(set (reg FLAGS_REG)
11180 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11181 (match_operand:QI 2 "const1_operand" ""))
11183 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11184 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11185 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11186 && ix86_match_ccmode (insn, CCGOCmode)
11187 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11189 [(set_attr "type" "ishift")
11190 (set_attr "length_immediate" "0")
11191 (set_attr "mode" "SI")])
11193 (define_insn "*ashrsi3_one_bit_cconly"
11194 [(set (reg FLAGS_REG)
11196 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11197 (match_operand:QI 2 "const1_operand" ""))
11199 (clobber (match_scratch:SI 0 "=r"))]
11200 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11201 && ix86_match_ccmode (insn, CCGOCmode)
11202 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11204 [(set_attr "type" "ishift")
11205 (set_attr "length_immediate" "0")
11206 (set_attr "mode" "SI")])
11208 (define_insn "*ashrsi3_one_bit_cmp_zext"
11209 [(set (reg FLAGS_REG)
11211 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11212 (match_operand:QI 2 "const1_operand" ""))
11214 (set (match_operand:DI 0 "register_operand" "=r")
11215 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11217 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11218 && ix86_match_ccmode (insn, CCmode)
11219 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11221 [(set_attr "type" "ishift")
11222 (set_attr "length_immediate" "0")
11223 (set_attr "mode" "SI")])
11225 ;; This pattern can't accept a variable shift count, since shifts by
11226 ;; zero don't affect the flags. We assume that shifts by constant
11227 ;; zero are optimized away.
11228 (define_insn "*ashrsi3_cmp"
11229 [(set (reg FLAGS_REG)
11231 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11232 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11234 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11235 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11236 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11237 && ix86_match_ccmode (insn, CCGOCmode)
11238 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11239 "sar{l}\t{%2, %0|%0, %2}"
11240 [(set_attr "type" "ishift")
11241 (set_attr "mode" "SI")])
11243 (define_insn "*ashrsi3_cconly"
11244 [(set (reg FLAGS_REG)
11246 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11247 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11249 (clobber (match_scratch:SI 0 "=r"))]
11250 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11251 && ix86_match_ccmode (insn, CCGOCmode)
11252 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11253 "sar{l}\t{%2, %0|%0, %2}"
11254 [(set_attr "type" "ishift")
11255 (set_attr "mode" "SI")])
11257 (define_insn "*ashrsi3_cmp_zext"
11258 [(set (reg FLAGS_REG)
11260 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11261 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11263 (set (match_operand:DI 0 "register_operand" "=r")
11264 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11266 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11267 && ix86_match_ccmode (insn, CCGOCmode)
11268 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11269 "sar{l}\t{%2, %k0|%k0, %2}"
11270 [(set_attr "type" "ishift")
11271 (set_attr "mode" "SI")])
11273 (define_expand "ashrhi3"
11274 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11275 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11276 (match_operand:QI 2 "nonmemory_operand" "")))]
11277 "TARGET_HIMODE_MATH"
11278 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11280 (define_insn "*ashrhi3_1_one_bit"
11281 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11282 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11283 (match_operand:QI 2 "const1_operand" "")))
11284 (clobber (reg:CC FLAGS_REG))]
11285 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11286 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11288 [(set_attr "type" "ishift")
11289 (set_attr "length_immediate" "0")
11290 (set_attr "mode" "HI")])
11292 (define_insn "*ashrhi3_1"
11293 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11294 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11295 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11296 (clobber (reg:CC FLAGS_REG))]
11297 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11299 sar{w}\t{%2, %0|%0, %2}
11300 sar{w}\t{%b2, %0|%0, %b2}"
11301 [(set_attr "type" "ishift")
11302 (set_attr "mode" "HI")])
11304 ;; This pattern can't accept a variable shift count, since shifts by
11305 ;; zero don't affect the flags. We assume that shifts by constant
11306 ;; zero are optimized away.
11307 (define_insn "*ashrhi3_one_bit_cmp"
11308 [(set (reg FLAGS_REG)
11310 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11311 (match_operand:QI 2 "const1_operand" ""))
11313 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11314 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11315 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11316 && ix86_match_ccmode (insn, CCGOCmode)
11317 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11319 [(set_attr "type" "ishift")
11320 (set_attr "length_immediate" "0")
11321 (set_attr "mode" "HI")])
11323 (define_insn "*ashrhi3_one_bit_cconly"
11324 [(set (reg FLAGS_REG)
11326 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11327 (match_operand:QI 2 "const1_operand" ""))
11329 (clobber (match_scratch:HI 0 "=r"))]
11330 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11331 && ix86_match_ccmode (insn, CCGOCmode)
11332 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11334 [(set_attr "type" "ishift")
11335 (set_attr "length_immediate" "0")
11336 (set_attr "mode" "HI")])
11338 ;; This pattern can't accept a variable shift count, since shifts by
11339 ;; zero don't affect the flags. We assume that shifts by constant
11340 ;; zero are optimized away.
11341 (define_insn "*ashrhi3_cmp"
11342 [(set (reg FLAGS_REG)
11344 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11345 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11347 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11348 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11349 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11350 && ix86_match_ccmode (insn, CCGOCmode)
11351 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11352 "sar{w}\t{%2, %0|%0, %2}"
11353 [(set_attr "type" "ishift")
11354 (set_attr "mode" "HI")])
11356 (define_insn "*ashrhi3_cconly"
11357 [(set (reg FLAGS_REG)
11359 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11360 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11362 (clobber (match_scratch:HI 0 "=r"))]
11363 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11364 && ix86_match_ccmode (insn, CCGOCmode)
11365 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11366 "sar{w}\t{%2, %0|%0, %2}"
11367 [(set_attr "type" "ishift")
11368 (set_attr "mode" "HI")])
11370 (define_expand "ashrqi3"
11371 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11372 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11373 (match_operand:QI 2 "nonmemory_operand" "")))]
11374 "TARGET_QIMODE_MATH"
11375 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11377 (define_insn "*ashrqi3_1_one_bit"
11378 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11379 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11380 (match_operand:QI 2 "const1_operand" "")))
11381 (clobber (reg:CC FLAGS_REG))]
11382 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11383 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11385 [(set_attr "type" "ishift")
11386 (set_attr "length_immediate" "0")
11387 (set_attr "mode" "QI")])
11389 (define_insn "*ashrqi3_1_one_bit_slp"
11390 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11391 (ashiftrt:QI (match_dup 0)
11392 (match_operand:QI 1 "const1_operand" "")))
11393 (clobber (reg:CC FLAGS_REG))]
11394 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11395 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11396 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11398 [(set_attr "type" "ishift1")
11399 (set_attr "length_immediate" "0")
11400 (set_attr "mode" "QI")])
11402 (define_insn "*ashrqi3_1"
11403 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11404 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11405 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11406 (clobber (reg:CC FLAGS_REG))]
11407 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11409 sar{b}\t{%2, %0|%0, %2}
11410 sar{b}\t{%b2, %0|%0, %b2}"
11411 [(set_attr "type" "ishift")
11412 (set_attr "mode" "QI")])
11414 (define_insn "*ashrqi3_1_slp"
11415 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11416 (ashiftrt:QI (match_dup 0)
11417 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11418 (clobber (reg:CC FLAGS_REG))]
11419 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11422 sar{b}\t{%1, %0|%0, %1}
11423 sar{b}\t{%b1, %0|%0, %b1}"
11424 [(set_attr "type" "ishift1")
11425 (set_attr "mode" "QI")])
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags. We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*ashrqi3_one_bit_cmp"
11431 [(set (reg FLAGS_REG)
11433 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11434 (match_operand:QI 2 "const1_operand" "I"))
11436 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11437 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11438 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11439 && ix86_match_ccmode (insn, CCGOCmode)
11440 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11442 [(set_attr "type" "ishift")
11443 (set_attr "length_immediate" "0")
11444 (set_attr "mode" "QI")])
11446 (define_insn "*ashrqi3_one_bit_cconly"
11447 [(set (reg FLAGS_REG)
11449 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11450 (match_operand:QI 2 "const1_operand" ""))
11452 (clobber (match_scratch:QI 0 "=q"))]
11453 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11454 && ix86_match_ccmode (insn, CCGOCmode)
11455 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11457 [(set_attr "type" "ishift")
11458 (set_attr "length_immediate" "0")
11459 (set_attr "mode" "QI")])
11461 ;; This pattern can't accept a variable shift count, since shifts by
11462 ;; zero don't affect the flags. We assume that shifts by constant
11463 ;; zero are optimized away.
11464 (define_insn "*ashrqi3_cmp"
11465 [(set (reg FLAGS_REG)
11467 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11468 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11470 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11471 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11472 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11473 && ix86_match_ccmode (insn, CCGOCmode)
11474 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11475 "sar{b}\t{%2, %0|%0, %2}"
11476 [(set_attr "type" "ishift")
11477 (set_attr "mode" "QI")])
11479 (define_insn "*ashrqi3_cconly"
11480 [(set (reg FLAGS_REG)
11482 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11483 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11485 (clobber (match_scratch:QI 0 "=q"))]
11486 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11487 && ix86_match_ccmode (insn, CCGOCmode)
11488 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11489 "sar{b}\t{%2, %0|%0, %2}"
11490 [(set_attr "type" "ishift")
11491 (set_attr "mode" "QI")])
11494 ;; Logical shift instructions
11496 ;; See comment above `ashldi3' about how this works.
11498 (define_expand "lshrti3"
11499 [(set (match_operand:TI 0 "register_operand" "")
11500 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11501 (match_operand:QI 2 "nonmemory_operand" "")))]
11503 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11505 (define_insn "*lshrti3_1"
11506 [(set (match_operand:TI 0 "register_operand" "=r")
11507 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11508 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11509 (clobber (reg:CC FLAGS_REG))]
11512 [(set_attr "type" "multi")])
11515 [(match_scratch:DI 3 "r")
11516 (parallel [(set (match_operand:TI 0 "register_operand" "")
11517 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11518 (match_operand:QI 2 "nonmemory_operand" "")))
11519 (clobber (reg:CC FLAGS_REG))])
11523 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11526 [(set (match_operand:TI 0 "register_operand" "")
11527 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11528 (match_operand:QI 2 "nonmemory_operand" "")))
11529 (clobber (reg:CC FLAGS_REG))]
11530 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11531 ? epilogue_completed : reload_completed)"
11533 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11535 (define_expand "lshrdi3"
11536 [(set (match_operand:DI 0 "shiftdi_operand" "")
11537 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11538 (match_operand:QI 2 "nonmemory_operand" "")))]
11540 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11542 (define_insn "*lshrdi3_1_one_bit_rex64"
11543 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11544 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11545 (match_operand:QI 2 "const1_operand" "")))
11546 (clobber (reg:CC FLAGS_REG))]
11548 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11549 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11551 [(set_attr "type" "ishift")
11552 (set_attr "length_immediate" "0")
11553 (set_attr "mode" "DI")])
11555 (define_insn "*lshrdi3_1_rex64"
11556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11557 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11558 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11559 (clobber (reg:CC FLAGS_REG))]
11560 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11562 shr{q}\t{%2, %0|%0, %2}
11563 shr{q}\t{%b2, %0|%0, %b2}"
11564 [(set_attr "type" "ishift")
11565 (set_attr "mode" "DI")])
11567 ;; This pattern can't accept a variable shift count, since shifts by
11568 ;; zero don't affect the flags. We assume that shifts by constant
11569 ;; zero are optimized away.
11570 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11571 [(set (reg FLAGS_REG)
11573 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11574 (match_operand:QI 2 "const1_operand" ""))
11576 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11577 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11579 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11580 && ix86_match_ccmode (insn, CCGOCmode)
11581 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11583 [(set_attr "type" "ishift")
11584 (set_attr "length_immediate" "0")
11585 (set_attr "mode" "DI")])
11587 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11588 [(set (reg FLAGS_REG)
11590 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11591 (match_operand:QI 2 "const1_operand" ""))
11593 (clobber (match_scratch:DI 0 "=r"))]
11595 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11596 && ix86_match_ccmode (insn, CCGOCmode)
11597 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11599 [(set_attr "type" "ishift")
11600 (set_attr "length_immediate" "0")
11601 (set_attr "mode" "DI")])
11603 ;; This pattern can't accept a variable shift count, since shifts by
11604 ;; zero don't affect the flags. We assume that shifts by constant
11605 ;; zero are optimized away.
11606 (define_insn "*lshrdi3_cmp_rex64"
11607 [(set (reg FLAGS_REG)
11609 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11610 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11612 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11613 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11615 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11616 && ix86_match_ccmode (insn, CCGOCmode)
11617 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11618 "shr{q}\t{%2, %0|%0, %2}"
11619 [(set_attr "type" "ishift")
11620 (set_attr "mode" "DI")])
11622 (define_insn "*lshrdi3_cconly_rex64"
11623 [(set (reg FLAGS_REG)
11625 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11626 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11628 (clobber (match_scratch:DI 0 "=r"))]
11630 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11631 && ix86_match_ccmode (insn, CCGOCmode)
11632 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11633 "shr{q}\t{%2, %0|%0, %2}"
11634 [(set_attr "type" "ishift")
11635 (set_attr "mode" "DI")])
11637 (define_insn "*lshrdi3_1"
11638 [(set (match_operand:DI 0 "register_operand" "=r")
11639 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11640 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11641 (clobber (reg:CC FLAGS_REG))]
11644 [(set_attr "type" "multi")])
11646 ;; By default we don't ask for a scratch register, because when DImode
11647 ;; values are manipulated, registers are already at a premium. But if
11648 ;; we have one handy, we won't turn it away.
11650 [(match_scratch:SI 3 "r")
11651 (parallel [(set (match_operand:DI 0 "register_operand" "")
11652 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11653 (match_operand:QI 2 "nonmemory_operand" "")))
11654 (clobber (reg:CC FLAGS_REG))])
11656 "!TARGET_64BIT && TARGET_CMOVE"
11658 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11661 [(set (match_operand:DI 0 "register_operand" "")
11662 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11663 (match_operand:QI 2 "nonmemory_operand" "")))
11664 (clobber (reg:CC FLAGS_REG))]
11665 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11666 ? epilogue_completed : reload_completed)"
11668 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11670 (define_expand "lshrsi3"
11671 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11672 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11673 (match_operand:QI 2 "nonmemory_operand" "")))]
11675 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11677 (define_insn "*lshrsi3_1_one_bit"
11678 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11679 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11680 (match_operand:QI 2 "const1_operand" "")))
11681 (clobber (reg:CC FLAGS_REG))]
11682 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11683 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11685 [(set_attr "type" "ishift")
11686 (set_attr "length_immediate" "0")
11687 (set_attr "mode" "SI")])
11689 (define_insn "*lshrsi3_1_one_bit_zext"
11690 [(set (match_operand:DI 0 "register_operand" "=r")
11691 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11692 (match_operand:QI 2 "const1_operand" "")))
11693 (clobber (reg:CC FLAGS_REG))]
11695 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11696 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11698 [(set_attr "type" "ishift")
11699 (set_attr "length_immediate" "0")
11700 (set_attr "mode" "SI")])
11702 (define_insn "*lshrsi3_1"
11703 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11704 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11705 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11706 (clobber (reg:CC FLAGS_REG))]
11707 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11709 shr{l}\t{%2, %0|%0, %2}
11710 shr{l}\t{%b2, %0|%0, %b2}"
11711 [(set_attr "type" "ishift")
11712 (set_attr "mode" "SI")])
11714 (define_insn "*lshrsi3_1_zext"
11715 [(set (match_operand:DI 0 "register_operand" "=r,r")
11717 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11718 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11719 (clobber (reg:CC FLAGS_REG))]
11720 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11722 shr{l}\t{%2, %k0|%k0, %2}
11723 shr{l}\t{%b2, %k0|%k0, %b2}"
11724 [(set_attr "type" "ishift")
11725 (set_attr "mode" "SI")])
11727 ;; This pattern can't accept a variable shift count, since shifts by
11728 ;; zero don't affect the flags. We assume that shifts by constant
11729 ;; zero are optimized away.
11730 (define_insn "*lshrsi3_one_bit_cmp"
11731 [(set (reg FLAGS_REG)
11733 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11734 (match_operand:QI 2 "const1_operand" ""))
11736 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11737 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11738 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11739 && ix86_match_ccmode (insn, CCGOCmode)
11740 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11742 [(set_attr "type" "ishift")
11743 (set_attr "length_immediate" "0")
11744 (set_attr "mode" "SI")])
11746 (define_insn "*lshrsi3_one_bit_cconly"
11747 [(set (reg FLAGS_REG)
11749 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11750 (match_operand:QI 2 "const1_operand" ""))
11752 (clobber (match_scratch:SI 0 "=r"))]
11753 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11754 && ix86_match_ccmode (insn, CCGOCmode)
11755 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11757 [(set_attr "type" "ishift")
11758 (set_attr "length_immediate" "0")
11759 (set_attr "mode" "SI")])
11761 (define_insn "*lshrsi3_cmp_one_bit_zext"
11762 [(set (reg FLAGS_REG)
11764 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11765 (match_operand:QI 2 "const1_operand" ""))
11767 (set (match_operand:DI 0 "register_operand" "=r")
11768 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11770 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11771 && ix86_match_ccmode (insn, CCGOCmode)
11772 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11774 [(set_attr "type" "ishift")
11775 (set_attr "length_immediate" "0")
11776 (set_attr "mode" "SI")])
11778 ;; This pattern can't accept a variable shift count, since shifts by
11779 ;; zero don't affect the flags. We assume that shifts by constant
11780 ;; zero are optimized away.
11781 (define_insn "*lshrsi3_cmp"
11782 [(set (reg FLAGS_REG)
11784 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11785 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11787 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11788 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11789 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11790 && ix86_match_ccmode (insn, CCGOCmode)
11791 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11792 "shr{l}\t{%2, %0|%0, %2}"
11793 [(set_attr "type" "ishift")
11794 (set_attr "mode" "SI")])
11796 (define_insn "*lshrsi3_cconly"
11797 [(set (reg FLAGS_REG)
11799 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11800 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11802 (clobber (match_scratch:SI 0 "=r"))]
11803 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11804 && ix86_match_ccmode (insn, CCGOCmode)
11805 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11806 "shr{l}\t{%2, %0|%0, %2}"
11807 [(set_attr "type" "ishift")
11808 (set_attr "mode" "SI")])
11810 (define_insn "*lshrsi3_cmp_zext"
11811 [(set (reg FLAGS_REG)
11813 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11814 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11816 (set (match_operand:DI 0 "register_operand" "=r")
11817 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11819 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11820 && ix86_match_ccmode (insn, CCGOCmode)
11821 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822 "shr{l}\t{%2, %k0|%k0, %2}"
11823 [(set_attr "type" "ishift")
11824 (set_attr "mode" "SI")])
11826 (define_expand "lshrhi3"
11827 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11828 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11829 (match_operand:QI 2 "nonmemory_operand" "")))]
11830 "TARGET_HIMODE_MATH"
11831 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11833 (define_insn "*lshrhi3_1_one_bit"
11834 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11835 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11836 (match_operand:QI 2 "const1_operand" "")))
11837 (clobber (reg:CC FLAGS_REG))]
11838 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11839 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11841 [(set_attr "type" "ishift")
11842 (set_attr "length_immediate" "0")
11843 (set_attr "mode" "HI")])
11845 (define_insn "*lshrhi3_1"
11846 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11847 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11848 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11849 (clobber (reg:CC FLAGS_REG))]
11850 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11852 shr{w}\t{%2, %0|%0, %2}
11853 shr{w}\t{%b2, %0|%0, %b2}"
11854 [(set_attr "type" "ishift")
11855 (set_attr "mode" "HI")])
11857 ;; This pattern can't accept a variable shift count, since shifts by
11858 ;; zero don't affect the flags. We assume that shifts by constant
11859 ;; zero are optimized away.
11860 (define_insn "*lshrhi3_one_bit_cmp"
11861 [(set (reg FLAGS_REG)
11863 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11864 (match_operand:QI 2 "const1_operand" ""))
11866 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11867 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11868 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11869 && ix86_match_ccmode (insn, CCGOCmode)
11870 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11872 [(set_attr "type" "ishift")
11873 (set_attr "length_immediate" "0")
11874 (set_attr "mode" "HI")])
11876 (define_insn "*lshrhi3_one_bit_cconly"
11877 [(set (reg FLAGS_REG)
11879 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11880 (match_operand:QI 2 "const1_operand" ""))
11882 (clobber (match_scratch:HI 0 "=r"))]
11883 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11884 && ix86_match_ccmode (insn, CCGOCmode)
11885 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11887 [(set_attr "type" "ishift")
11888 (set_attr "length_immediate" "0")
11889 (set_attr "mode" "HI")])
11891 ;; This pattern can't accept a variable shift count, since shifts by
11892 ;; zero don't affect the flags. We assume that shifts by constant
11893 ;; zero are optimized away.
11894 (define_insn "*lshrhi3_cmp"
11895 [(set (reg FLAGS_REG)
11897 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11898 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11900 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11901 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11902 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11903 && ix86_match_ccmode (insn, CCGOCmode)
11904 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11905 "shr{w}\t{%2, %0|%0, %2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "HI")])
11909 (define_insn "*lshrhi3_cconly"
11910 [(set (reg FLAGS_REG)
11912 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11913 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11915 (clobber (match_scratch:HI 0 "=r"))]
11916 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11917 && ix86_match_ccmode (insn, CCGOCmode)
11918 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11919 "shr{w}\t{%2, %0|%0, %2}"
11920 [(set_attr "type" "ishift")
11921 (set_attr "mode" "HI")])
11923 (define_expand "lshrqi3"
11924 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11925 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11926 (match_operand:QI 2 "nonmemory_operand" "")))]
11927 "TARGET_QIMODE_MATH"
11928 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11930 (define_insn "*lshrqi3_1_one_bit"
11931 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11932 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11933 (match_operand:QI 2 "const1_operand" "")))
11934 (clobber (reg:CC FLAGS_REG))]
11935 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11936 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11938 [(set_attr "type" "ishift")
11939 (set_attr "length_immediate" "0")
11940 (set_attr "mode" "QI")])
11942 (define_insn "*lshrqi3_1_one_bit_slp"
11943 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11944 (lshiftrt:QI (match_dup 0)
11945 (match_operand:QI 1 "const1_operand" "")))
11946 (clobber (reg:CC FLAGS_REG))]
11947 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11948 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11950 [(set_attr "type" "ishift1")
11951 (set_attr "length_immediate" "0")
11952 (set_attr "mode" "QI")])
11954 (define_insn "*lshrqi3_1"
11955 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11956 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11957 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11958 (clobber (reg:CC FLAGS_REG))]
11959 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11961 shr{b}\t{%2, %0|%0, %2}
11962 shr{b}\t{%b2, %0|%0, %b2}"
11963 [(set_attr "type" "ishift")
11964 (set_attr "mode" "QI")])
11966 (define_insn "*lshrqi3_1_slp"
11967 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11968 (lshiftrt:QI (match_dup 0)
11969 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11970 (clobber (reg:CC FLAGS_REG))]
11971 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11972 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11974 shr{b}\t{%1, %0|%0, %1}
11975 shr{b}\t{%b1, %0|%0, %b1}"
11976 [(set_attr "type" "ishift1")
11977 (set_attr "mode" "QI")])
11979 ;; This pattern can't accept a variable shift count, since shifts by
11980 ;; zero don't affect the flags. We assume that shifts by constant
11981 ;; zero are optimized away.
11982 (define_insn "*lshrqi2_one_bit_cmp"
11983 [(set (reg FLAGS_REG)
11985 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11986 (match_operand:QI 2 "const1_operand" ""))
11988 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11989 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11990 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11991 && ix86_match_ccmode (insn, CCGOCmode)
11992 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11994 [(set_attr "type" "ishift")
11995 (set_attr "length_immediate" "0")
11996 (set_attr "mode" "QI")])
11998 (define_insn "*lshrqi2_one_bit_cconly"
11999 [(set (reg FLAGS_REG)
12001 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12002 (match_operand:QI 2 "const1_operand" ""))
12004 (clobber (match_scratch:QI 0 "=q"))]
12005 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12006 && ix86_match_ccmode (insn, CCGOCmode)
12007 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12009 [(set_attr "type" "ishift")
12010 (set_attr "length_immediate" "0")
12011 (set_attr "mode" "QI")])
12013 ;; This pattern can't accept a variable shift count, since shifts by
12014 ;; zero don't affect the flags. We assume that shifts by constant
12015 ;; zero are optimized away.
12016 (define_insn "*lshrqi2_cmp"
12017 [(set (reg FLAGS_REG)
12019 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12020 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12022 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12023 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12024 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12025 && ix86_match_ccmode (insn, CCGOCmode)
12026 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12027 "shr{b}\t{%2, %0|%0, %2}"
12028 [(set_attr "type" "ishift")
12029 (set_attr "mode" "QI")])
12031 (define_insn "*lshrqi2_cconly"
12032 [(set (reg FLAGS_REG)
12034 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12035 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12037 (clobber (match_scratch:QI 0 "=q"))]
12038 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12039 && ix86_match_ccmode (insn, CCGOCmode)
12040 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12041 "shr{b}\t{%2, %0|%0, %2}"
12042 [(set_attr "type" "ishift")
12043 (set_attr "mode" "QI")])
12045 ;; Rotate instructions
12047 (define_expand "rotldi3"
12048 [(set (match_operand:DI 0 "shiftdi_operand" "")
12049 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12050 (match_operand:QI 2 "nonmemory_operand" "")))]
12055 ix86_expand_binary_operator (ROTATE, DImode, operands);
12058 if (!const_1_to_31_operand (operands[2], VOIDmode))
12060 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12064 ;; Implement rotation using two double-precision shift instructions
12065 ;; and a scratch register.
12066 (define_insn_and_split "ix86_rotldi3"
12067 [(set (match_operand:DI 0 "register_operand" "=r")
12068 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12069 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12070 (clobber (reg:CC FLAGS_REG))
12071 (clobber (match_scratch:SI 3 "=&r"))]
12074 "&& reload_completed"
12075 [(set (match_dup 3) (match_dup 4))
12077 [(set (match_dup 4)
12078 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12079 (lshiftrt:SI (match_dup 5)
12080 (minus:QI (const_int 32) (match_dup 2)))))
12081 (clobber (reg:CC FLAGS_REG))])
12083 [(set (match_dup 5)
12084 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12085 (lshiftrt:SI (match_dup 3)
12086 (minus:QI (const_int 32) (match_dup 2)))))
12087 (clobber (reg:CC FLAGS_REG))])]
12088 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12090 (define_insn "*rotlsi3_1_one_bit_rex64"
12091 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12092 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12093 (match_operand:QI 2 "const1_operand" "")))
12094 (clobber (reg:CC FLAGS_REG))]
12096 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12097 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12099 [(set_attr "type" "rotate")
12100 (set_attr "length_immediate" "0")
12101 (set_attr "mode" "DI")])
12103 (define_insn "*rotldi3_1_rex64"
12104 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12105 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12106 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12107 (clobber (reg:CC FLAGS_REG))]
12108 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12110 rol{q}\t{%2, %0|%0, %2}
12111 rol{q}\t{%b2, %0|%0, %b2}"
12112 [(set_attr "type" "rotate")
12113 (set_attr "mode" "DI")])
12115 (define_expand "rotlsi3"
12116 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12117 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12118 (match_operand:QI 2 "nonmemory_operand" "")))]
12120 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12122 (define_insn "*rotlsi3_1_one_bit"
12123 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12124 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12125 (match_operand:QI 2 "const1_operand" "")))
12126 (clobber (reg:CC FLAGS_REG))]
12127 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12128 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12130 [(set_attr "type" "rotate")
12131 (set_attr "length_immediate" "0")
12132 (set_attr "mode" "SI")])
12134 (define_insn "*rotlsi3_1_one_bit_zext"
12135 [(set (match_operand:DI 0 "register_operand" "=r")
12137 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12138 (match_operand:QI 2 "const1_operand" ""))))
12139 (clobber (reg:CC FLAGS_REG))]
12141 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12142 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12144 [(set_attr "type" "rotate")
12145 (set_attr "length_immediate" "0")
12146 (set_attr "mode" "SI")])
12148 (define_insn "*rotlsi3_1"
12149 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12150 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12151 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12152 (clobber (reg:CC FLAGS_REG))]
12153 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12155 rol{l}\t{%2, %0|%0, %2}
12156 rol{l}\t{%b2, %0|%0, %b2}"
12157 [(set_attr "type" "rotate")
12158 (set_attr "mode" "SI")])
12160 (define_insn "*rotlsi3_1_zext"
12161 [(set (match_operand:DI 0 "register_operand" "=r,r")
12163 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12164 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12165 (clobber (reg:CC FLAGS_REG))]
12166 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12168 rol{l}\t{%2, %k0|%k0, %2}
12169 rol{l}\t{%b2, %k0|%k0, %b2}"
12170 [(set_attr "type" "rotate")
12171 (set_attr "mode" "SI")])
12173 (define_expand "rotlhi3"
12174 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12175 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12176 (match_operand:QI 2 "nonmemory_operand" "")))]
12177 "TARGET_HIMODE_MATH"
12178 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12180 (define_insn "*rotlhi3_1_one_bit"
12181 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12182 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12183 (match_operand:QI 2 "const1_operand" "")))
12184 (clobber (reg:CC FLAGS_REG))]
12185 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12186 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12188 [(set_attr "type" "rotate")
12189 (set_attr "length_immediate" "0")
12190 (set_attr "mode" "HI")])
12192 (define_insn "*rotlhi3_1"
12193 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12194 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12195 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12196 (clobber (reg:CC FLAGS_REG))]
12197 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12199 rol{w}\t{%2, %0|%0, %2}
12200 rol{w}\t{%b2, %0|%0, %b2}"
12201 [(set_attr "type" "rotate")
12202 (set_attr "mode" "HI")])
12205 [(set (match_operand:HI 0 "register_operand" "")
12206 (rotate:HI (match_dup 0) (const_int 8)))
12207 (clobber (reg:CC FLAGS_REG))]
12209 [(parallel [(set (strict_low_part (match_dup 0))
12210 (bswap:HI (match_dup 0)))
12211 (clobber (reg:CC FLAGS_REG))])]
12214 (define_expand "rotlqi3"
12215 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12216 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12217 (match_operand:QI 2 "nonmemory_operand" "")))]
12218 "TARGET_QIMODE_MATH"
12219 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12221 (define_insn "*rotlqi3_1_one_bit_slp"
12222 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12223 (rotate:QI (match_dup 0)
12224 (match_operand:QI 1 "const1_operand" "")))
12225 (clobber (reg:CC FLAGS_REG))]
12226 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12227 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12229 [(set_attr "type" "rotate1")
12230 (set_attr "length_immediate" "0")
12231 (set_attr "mode" "QI")])
12233 (define_insn "*rotlqi3_1_one_bit"
12234 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12235 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12236 (match_operand:QI 2 "const1_operand" "")))
12237 (clobber (reg:CC FLAGS_REG))]
12238 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12239 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12241 [(set_attr "type" "rotate")
12242 (set_attr "length_immediate" "0")
12243 (set_attr "mode" "QI")])
12245 (define_insn "*rotlqi3_1_slp"
12246 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12247 (rotate:QI (match_dup 0)
12248 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12249 (clobber (reg:CC FLAGS_REG))]
12250 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12251 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12253 rol{b}\t{%1, %0|%0, %1}
12254 rol{b}\t{%b1, %0|%0, %b1}"
12255 [(set_attr "type" "rotate1")
12256 (set_attr "mode" "QI")])
12258 (define_insn "*rotlqi3_1"
12259 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12260 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12261 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12262 (clobber (reg:CC FLAGS_REG))]
12263 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12265 rol{b}\t{%2, %0|%0, %2}
12266 rol{b}\t{%b2, %0|%0, %b2}"
12267 [(set_attr "type" "rotate")
12268 (set_attr "mode" "QI")])
12270 (define_expand "rotrdi3"
12271 [(set (match_operand:DI 0 "shiftdi_operand" "")
12272 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12273 (match_operand:QI 2 "nonmemory_operand" "")))]
12278 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12281 if (!const_1_to_31_operand (operands[2], VOIDmode))
12283 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12287 ;; Implement rotation using two double-precision shift instructions
12288 ;; and a scratch register.
12289 (define_insn_and_split "ix86_rotrdi3"
12290 [(set (match_operand:DI 0 "register_operand" "=r")
12291 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12292 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12293 (clobber (reg:CC FLAGS_REG))
12294 (clobber (match_scratch:SI 3 "=&r"))]
12297 "&& reload_completed"
12298 [(set (match_dup 3) (match_dup 4))
12300 [(set (match_dup 4)
12301 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12302 (ashift:SI (match_dup 5)
12303 (minus:QI (const_int 32) (match_dup 2)))))
12304 (clobber (reg:CC FLAGS_REG))])
12306 [(set (match_dup 5)
12307 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12308 (ashift:SI (match_dup 3)
12309 (minus:QI (const_int 32) (match_dup 2)))))
12310 (clobber (reg:CC FLAGS_REG))])]
12311 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12313 (define_insn "*rotrdi3_1_one_bit_rex64"
12314 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12315 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12316 (match_operand:QI 2 "const1_operand" "")))
12317 (clobber (reg:CC FLAGS_REG))]
12319 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12320 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12322 [(set_attr "type" "rotate")
12323 (set_attr "length_immediate" "0")
12324 (set_attr "mode" "DI")])
12326 (define_insn "*rotrdi3_1_rex64"
12327 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12328 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12329 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12330 (clobber (reg:CC FLAGS_REG))]
12331 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12333 ror{q}\t{%2, %0|%0, %2}
12334 ror{q}\t{%b2, %0|%0, %b2}"
12335 [(set_attr "type" "rotate")
12336 (set_attr "mode" "DI")])
12338 (define_expand "rotrsi3"
12339 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12340 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12341 (match_operand:QI 2 "nonmemory_operand" "")))]
12343 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12345 (define_insn "*rotrsi3_1_one_bit"
12346 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12347 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12348 (match_operand:QI 2 "const1_operand" "")))
12349 (clobber (reg:CC FLAGS_REG))]
12350 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12351 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12353 [(set_attr "type" "rotate")
12354 (set_attr "length_immediate" "0")
12355 (set_attr "mode" "SI")])
12357 (define_insn "*rotrsi3_1_one_bit_zext"
12358 [(set (match_operand:DI 0 "register_operand" "=r")
12360 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12361 (match_operand:QI 2 "const1_operand" ""))))
12362 (clobber (reg:CC FLAGS_REG))]
12364 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12365 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12367 [(set_attr "type" "rotate")
12368 (set_attr "length_immediate" "0")
12369 (set_attr "mode" "SI")])
12371 (define_insn "*rotrsi3_1"
12372 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12373 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12374 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12375 (clobber (reg:CC FLAGS_REG))]
12376 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12378 ror{l}\t{%2, %0|%0, %2}
12379 ror{l}\t{%b2, %0|%0, %b2}"
12380 [(set_attr "type" "rotate")
12381 (set_attr "mode" "SI")])
12383 (define_insn "*rotrsi3_1_zext"
12384 [(set (match_operand:DI 0 "register_operand" "=r,r")
12386 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12387 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12388 (clobber (reg:CC FLAGS_REG))]
12389 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12391 ror{l}\t{%2, %k0|%k0, %2}
12392 ror{l}\t{%b2, %k0|%k0, %b2}"
12393 [(set_attr "type" "rotate")
12394 (set_attr "mode" "SI")])
12396 (define_expand "rotrhi3"
12397 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12398 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12399 (match_operand:QI 2 "nonmemory_operand" "")))]
12400 "TARGET_HIMODE_MATH"
12401 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12403 (define_insn "*rotrhi3_one_bit"
12404 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12405 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12406 (match_operand:QI 2 "const1_operand" "")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12409 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12411 [(set_attr "type" "rotate")
12412 (set_attr "length_immediate" "0")
12413 (set_attr "mode" "HI")])
12415 (define_insn "*rotrhi3_1"
12416 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12417 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12418 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12422 ror{w}\t{%2, %0|%0, %2}
12423 ror{w}\t{%b2, %0|%0, %b2}"
12424 [(set_attr "type" "rotate")
12425 (set_attr "mode" "HI")])
12428 [(set (match_operand:HI 0 "register_operand" "")
12429 (rotatert:HI (match_dup 0) (const_int 8)))
12430 (clobber (reg:CC FLAGS_REG))]
12432 [(parallel [(set (strict_low_part (match_dup 0))
12433 (bswap:HI (match_dup 0)))
12434 (clobber (reg:CC FLAGS_REG))])]
12437 (define_expand "rotrqi3"
12438 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12439 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12440 (match_operand:QI 2 "nonmemory_operand" "")))]
12441 "TARGET_QIMODE_MATH"
12442 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12444 (define_insn "*rotrqi3_1_one_bit"
12445 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12446 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12447 (match_operand:QI 2 "const1_operand" "")))
12448 (clobber (reg:CC FLAGS_REG))]
12449 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12450 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12452 [(set_attr "type" "rotate")
12453 (set_attr "length_immediate" "0")
12454 (set_attr "mode" "QI")])
12456 (define_insn "*rotrqi3_1_one_bit_slp"
12457 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12458 (rotatert:QI (match_dup 0)
12459 (match_operand:QI 1 "const1_operand" "")))
12460 (clobber (reg:CC FLAGS_REG))]
12461 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12462 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12464 [(set_attr "type" "rotate1")
12465 (set_attr "length_immediate" "0")
12466 (set_attr "mode" "QI")])
12468 (define_insn "*rotrqi3_1"
12469 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12470 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12471 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12472 (clobber (reg:CC FLAGS_REG))]
12473 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12475 ror{b}\t{%2, %0|%0, %2}
12476 ror{b}\t{%b2, %0|%0, %b2}"
12477 [(set_attr "type" "rotate")
12478 (set_attr "mode" "QI")])
12480 (define_insn "*rotrqi3_1_slp"
12481 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12482 (rotatert:QI (match_dup 0)
12483 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12484 (clobber (reg:CC FLAGS_REG))]
12485 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12486 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12488 ror{b}\t{%1, %0|%0, %1}
12489 ror{b}\t{%b1, %0|%0, %b1}"
12490 [(set_attr "type" "rotate1")
12491 (set_attr "mode" "QI")])
12493 ;; Bit set / bit test instructions
12495 (define_expand "extv"
12496 [(set (match_operand:SI 0 "register_operand" "")
12497 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12498 (match_operand:SI 2 "const8_operand" "")
12499 (match_operand:SI 3 "const8_operand" "")))]
12502 /* Handle extractions from %ah et al. */
12503 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12506 /* From mips.md: extract_bit_field doesn't verify that our source
12507 matches the predicate, so check it again here. */
12508 if (! ext_register_operand (operands[1], VOIDmode))
12512 (define_expand "extzv"
12513 [(set (match_operand:SI 0 "register_operand" "")
12514 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12515 (match_operand:SI 2 "const8_operand" "")
12516 (match_operand:SI 3 "const8_operand" "")))]
12519 /* Handle extractions from %ah et al. */
12520 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12523 /* From mips.md: extract_bit_field doesn't verify that our source
12524 matches the predicate, so check it again here. */
12525 if (! ext_register_operand (operands[1], VOIDmode))
12529 (define_expand "insv"
12530 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12531 (match_operand 1 "const8_operand" "")
12532 (match_operand 2 "const8_operand" ""))
12533 (match_operand 3 "register_operand" ""))]
12536 /* Handle insertions to %ah et al. */
12537 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12540 /* From mips.md: insert_bit_field doesn't verify that our source
12541 matches the predicate, so check it again here. */
12542 if (! ext_register_operand (operands[0], VOIDmode))
12546 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12548 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12553 ;; %%% bts, btr, btc, bt.
12554 ;; In general these instructions are *slow* when applied to memory,
12555 ;; since they enforce atomic operation. When applied to registers,
12556 ;; it depends on the cpu implementation. They're never faster than
12557 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12558 ;; no point. But in 64-bit, we can't hold the relevant immediates
12559 ;; within the instruction itself, so operating on bits in the high
12560 ;; 32-bits of a register becomes easier.
12562 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12563 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12564 ;; negdf respectively, so they can never be disabled entirely.
12566 (define_insn "*btsq"
12567 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12569 (match_operand:DI 1 "const_0_to_63_operand" ""))
12571 (clobber (reg:CC FLAGS_REG))]
12572 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12573 "bts{q}\t{%1, %0|%0, %1}"
12574 [(set_attr "type" "alu1")
12575 (set_attr "prefix_0f" "1")
12576 (set_attr "mode" "DI")])
12578 (define_insn "*btrq"
12579 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12581 (match_operand:DI 1 "const_0_to_63_operand" ""))
12583 (clobber (reg:CC FLAGS_REG))]
12584 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12585 "btr{q}\t{%1, %0|%0, %1}"
12586 [(set_attr "type" "alu1")
12587 (set_attr "prefix_0f" "1")
12588 (set_attr "mode" "DI")])
12590 (define_insn "*btcq"
12591 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12593 (match_operand:DI 1 "const_0_to_63_operand" ""))
12594 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12595 (clobber (reg:CC FLAGS_REG))]
12596 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12597 "btc{q}\t{%1, %0|%0, %1}"
12598 [(set_attr "type" "alu1")
12599 (set_attr "prefix_0f" "1")
12600 (set_attr "mode" "DI")])
12602 ;; Allow Nocona to avoid these instructions if a register is available.
12605 [(match_scratch:DI 2 "r")
12606 (parallel [(set (zero_extract:DI
12607 (match_operand:DI 0 "register_operand" "")
12609 (match_operand:DI 1 "const_0_to_63_operand" ""))
12611 (clobber (reg:CC FLAGS_REG))])]
12612 "TARGET_64BIT && !TARGET_USE_BT"
12615 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12618 if (HOST_BITS_PER_WIDE_INT >= 64)
12619 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620 else if (i < HOST_BITS_PER_WIDE_INT)
12621 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12623 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12625 op1 = immed_double_const (lo, hi, DImode);
12628 emit_move_insn (operands[2], op1);
12632 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12637 [(match_scratch:DI 2 "r")
12638 (parallel [(set (zero_extract:DI
12639 (match_operand:DI 0 "register_operand" "")
12641 (match_operand:DI 1 "const_0_to_63_operand" ""))
12643 (clobber (reg:CC FLAGS_REG))])]
12644 "TARGET_64BIT && !TARGET_USE_BT"
12647 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12650 if (HOST_BITS_PER_WIDE_INT >= 64)
12651 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652 else if (i < HOST_BITS_PER_WIDE_INT)
12653 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12655 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12657 op1 = immed_double_const (~lo, ~hi, DImode);
12660 emit_move_insn (operands[2], op1);
12664 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12669 [(match_scratch:DI 2 "r")
12670 (parallel [(set (zero_extract:DI
12671 (match_operand:DI 0 "register_operand" "")
12673 (match_operand:DI 1 "const_0_to_63_operand" ""))
12674 (not:DI (zero_extract:DI
12675 (match_dup 0) (const_int 1) (match_dup 1))))
12676 (clobber (reg:CC FLAGS_REG))])]
12677 "TARGET_64BIT && !TARGET_USE_BT"
12680 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12683 if (HOST_BITS_PER_WIDE_INT >= 64)
12684 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685 else if (i < HOST_BITS_PER_WIDE_INT)
12686 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12688 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12690 op1 = immed_double_const (lo, hi, DImode);
12693 emit_move_insn (operands[2], op1);
12697 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12701 (define_insn "*btdi_rex64"
12702 [(set (reg:CCC FLAGS_REG)
12705 (match_operand:DI 0 "register_operand" "r")
12707 (match_operand:DI 1 "nonmemory_operand" "rN"))
12709 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12710 "bt{q}\t{%1, %0|%0, %1}"
12711 [(set_attr "type" "alu1")
12712 (set_attr "prefix_0f" "1")
12713 (set_attr "mode" "DI")])
12715 (define_insn "*btsi"
12716 [(set (reg:CCC FLAGS_REG)
12719 (match_operand:SI 0 "register_operand" "r")
12721 (match_operand:SI 1 "nonmemory_operand" "rN"))
12723 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12724 "bt{l}\t{%1, %0|%0, %1}"
12725 [(set_attr "type" "alu1")
12726 (set_attr "prefix_0f" "1")
12727 (set_attr "mode" "SI")])
12729 ;; Store-flag instructions.
12731 ;; For all sCOND expanders, also expand the compare or test insn that
12732 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12734 (define_insn_and_split "*setcc_di_1"
12735 [(set (match_operand:DI 0 "register_operand" "=q")
12736 (match_operator:DI 1 "ix86_comparison_operator"
12737 [(reg FLAGS_REG) (const_int 0)]))]
12738 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12740 "&& reload_completed"
12741 [(set (match_dup 2) (match_dup 1))
12742 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12744 PUT_MODE (operands[1], QImode);
12745 operands[2] = gen_lowpart (QImode, operands[0]);
12748 (define_insn_and_split "*setcc_si_1_and"
12749 [(set (match_operand:SI 0 "register_operand" "=q")
12750 (match_operator:SI 1 "ix86_comparison_operator"
12751 [(reg FLAGS_REG) (const_int 0)]))
12752 (clobber (reg:CC FLAGS_REG))]
12753 "!TARGET_PARTIAL_REG_STALL
12754 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12756 "&& reload_completed"
12757 [(set (match_dup 2) (match_dup 1))
12758 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12759 (clobber (reg:CC FLAGS_REG))])]
12761 PUT_MODE (operands[1], QImode);
12762 operands[2] = gen_lowpart (QImode, operands[0]);
12765 (define_insn_and_split "*setcc_si_1_movzbl"
12766 [(set (match_operand:SI 0 "register_operand" "=q")
12767 (match_operator:SI 1 "ix86_comparison_operator"
12768 [(reg FLAGS_REG) (const_int 0)]))]
12769 "!TARGET_PARTIAL_REG_STALL
12770 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12772 "&& reload_completed"
12773 [(set (match_dup 2) (match_dup 1))
12774 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12776 PUT_MODE (operands[1], QImode);
12777 operands[2] = gen_lowpart (QImode, operands[0]);
12780 (define_insn "*setcc_qi"
12781 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12782 (match_operator:QI 1 "ix86_comparison_operator"
12783 [(reg FLAGS_REG) (const_int 0)]))]
12786 [(set_attr "type" "setcc")
12787 (set_attr "mode" "QI")])
12789 (define_insn "*setcc_qi_slp"
12790 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12791 (match_operator:QI 1 "ix86_comparison_operator"
12792 [(reg FLAGS_REG) (const_int 0)]))]
12795 [(set_attr "type" "setcc")
12796 (set_attr "mode" "QI")])
12798 ;; In general it is not safe to assume too much about CCmode registers,
12799 ;; so simplify-rtx stops when it sees a second one. Under certain
12800 ;; conditions this is safe on x86, so help combine not create
12807 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12808 (ne:QI (match_operator 1 "ix86_comparison_operator"
12809 [(reg FLAGS_REG) (const_int 0)])
12812 [(set (match_dup 0) (match_dup 1))]
12814 PUT_MODE (operands[1], QImode);
12818 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12819 (ne:QI (match_operator 1 "ix86_comparison_operator"
12820 [(reg FLAGS_REG) (const_int 0)])
12823 [(set (match_dup 0) (match_dup 1))]
12825 PUT_MODE (operands[1], QImode);
12829 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12830 (eq:QI (match_operator 1 "ix86_comparison_operator"
12831 [(reg FLAGS_REG) (const_int 0)])
12834 [(set (match_dup 0) (match_dup 1))]
12836 rtx new_op1 = copy_rtx (operands[1]);
12837 operands[1] = new_op1;
12838 PUT_MODE (new_op1, QImode);
12839 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12840 GET_MODE (XEXP (new_op1, 0))));
12842 /* Make sure that (a) the CCmode we have for the flags is strong
12843 enough for the reversed compare or (b) we have a valid FP compare. */
12844 if (! ix86_comparison_operator (new_op1, VOIDmode))
12849 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12850 (eq:QI (match_operator 1 "ix86_comparison_operator"
12851 [(reg FLAGS_REG) (const_int 0)])
12854 [(set (match_dup 0) (match_dup 1))]
12856 rtx new_op1 = copy_rtx (operands[1]);
12857 operands[1] = new_op1;
12858 PUT_MODE (new_op1, QImode);
12859 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12860 GET_MODE (XEXP (new_op1, 0))));
12862 /* Make sure that (a) the CCmode we have for the flags is strong
12863 enough for the reversed compare or (b) we have a valid FP compare. */
12864 if (! ix86_comparison_operator (new_op1, VOIDmode))
12868 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12869 ;; subsequent logical operations are used to imitate conditional moves.
12870 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12873 (define_insn "*avx_setcc<mode>"
12874 [(set (match_operand:MODEF 0 "register_operand" "=x")
12875 (match_operator:MODEF 1 "avx_comparison_float_operator"
12876 [(match_operand:MODEF 2 "register_operand" "x")
12877 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12879 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12880 [(set_attr "type" "ssecmp")
12881 (set_attr "prefix" "vex")
12882 (set_attr "length_immediate" "1")
12883 (set_attr "mode" "<MODE>")])
12885 (define_insn "*sse_setcc<mode>"
12886 [(set (match_operand:MODEF 0 "register_operand" "=x")
12887 (match_operator:MODEF 1 "sse_comparison_operator"
12888 [(match_operand:MODEF 2 "register_operand" "0")
12889 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12890 "SSE_FLOAT_MODE_P (<MODE>mode)"
12891 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12892 [(set_attr "type" "ssecmp")
12893 (set_attr "length_immediate" "1")
12894 (set_attr "mode" "<MODE>")])
12896 ;; Basic conditional jump instructions.
12897 ;; We ignore the overflow flag for signed branch instructions.
12899 (define_insn "*jcc_1"
12901 (if_then_else (match_operator 1 "ix86_comparison_operator"
12902 [(reg FLAGS_REG) (const_int 0)])
12903 (label_ref (match_operand 0 "" ""))
12907 [(set_attr "type" "ibr")
12908 (set_attr "modrm" "0")
12909 (set (attr "length")
12910 (if_then_else (and (ge (minus (match_dup 0) (pc))
12912 (lt (minus (match_dup 0) (pc))
12917 (define_insn "*jcc_2"
12919 (if_then_else (match_operator 1 "ix86_comparison_operator"
12920 [(reg FLAGS_REG) (const_int 0)])
12922 (label_ref (match_operand 0 "" ""))))]
12925 [(set_attr "type" "ibr")
12926 (set_attr "modrm" "0")
12927 (set (attr "length")
12928 (if_then_else (and (ge (minus (match_dup 0) (pc))
12930 (lt (minus (match_dup 0) (pc))
12935 ;; In general it is not safe to assume too much about CCmode registers,
12936 ;; so simplify-rtx stops when it sees a second one. Under certain
12937 ;; conditions this is safe on x86, so help combine not create
12945 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12946 [(reg FLAGS_REG) (const_int 0)])
12948 (label_ref (match_operand 1 "" ""))
12952 (if_then_else (match_dup 0)
12953 (label_ref (match_dup 1))
12956 PUT_MODE (operands[0], VOIDmode);
12961 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12962 [(reg FLAGS_REG) (const_int 0)])
12964 (label_ref (match_operand 1 "" ""))
12968 (if_then_else (match_dup 0)
12969 (label_ref (match_dup 1))
12972 rtx new_op0 = copy_rtx (operands[0]);
12973 operands[0] = new_op0;
12974 PUT_MODE (new_op0, VOIDmode);
12975 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12976 GET_MODE (XEXP (new_op0, 0))));
12978 /* Make sure that (a) the CCmode we have for the flags is strong
12979 enough for the reversed compare or (b) we have a valid FP compare. */
12980 if (! ix86_comparison_operator (new_op0, VOIDmode))
12984 ;; zero_extend in SImode is correct, since this is what combine pass
12985 ;; generates from shift insn with QImode operand. Actually, the mode of
12986 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12987 ;; appropriate modulo of the bit offset value.
12989 (define_insn_and_split "*jcc_btdi_rex64"
12991 (if_then_else (match_operator 0 "bt_comparison_operator"
12993 (match_operand:DI 1 "register_operand" "r")
12996 (match_operand:QI 2 "register_operand" "r")))
12998 (label_ref (match_operand 3 "" ""))
13000 (clobber (reg:CC FLAGS_REG))]
13001 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13004 [(set (reg:CCC FLAGS_REG)
13012 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13013 (label_ref (match_dup 3))
13016 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13018 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13021 ;; avoid useless masking of bit offset operand
13022 (define_insn_and_split "*jcc_btdi_mask_rex64"
13024 (if_then_else (match_operator 0 "bt_comparison_operator"
13026 (match_operand:DI 1 "register_operand" "r")
13029 (match_operand:SI 2 "register_operand" "r")
13030 (match_operand:SI 3 "const_int_operand" "n")))])
13031 (label_ref (match_operand 4 "" ""))
13033 (clobber (reg:CC FLAGS_REG))]
13034 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13035 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13038 [(set (reg:CCC FLAGS_REG)
13046 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13047 (label_ref (match_dup 4))
13050 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13052 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13055 (define_insn_and_split "*jcc_btsi"
13057 (if_then_else (match_operator 0 "bt_comparison_operator"
13059 (match_operand:SI 1 "register_operand" "r")
13062 (match_operand:QI 2 "register_operand" "r")))
13064 (label_ref (match_operand 3 "" ""))
13066 (clobber (reg:CC FLAGS_REG))]
13067 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13070 [(set (reg:CCC FLAGS_REG)
13078 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13079 (label_ref (match_dup 3))
13082 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13084 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13087 ;; avoid useless masking of bit offset operand
13088 (define_insn_and_split "*jcc_btsi_mask"
13090 (if_then_else (match_operator 0 "bt_comparison_operator"
13092 (match_operand:SI 1 "register_operand" "r")
13095 (match_operand:SI 2 "register_operand" "r")
13096 (match_operand:SI 3 "const_int_operand" "n")))])
13097 (label_ref (match_operand 4 "" ""))
13099 (clobber (reg:CC FLAGS_REG))]
13100 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13101 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13104 [(set (reg:CCC FLAGS_REG)
13112 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13113 (label_ref (match_dup 4))
13115 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13117 (define_insn_and_split "*jcc_btsi_1"
13119 (if_then_else (match_operator 0 "bt_comparison_operator"
13122 (match_operand:SI 1 "register_operand" "r")
13123 (match_operand:QI 2 "register_operand" "r"))
13126 (label_ref (match_operand 3 "" ""))
13128 (clobber (reg:CC FLAGS_REG))]
13129 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13132 [(set (reg:CCC FLAGS_REG)
13140 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13141 (label_ref (match_dup 3))
13144 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13146 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13149 ;; avoid useless masking of bit offset operand
13150 (define_insn_and_split "*jcc_btsi_mask_1"
13153 (match_operator 0 "bt_comparison_operator"
13156 (match_operand:SI 1 "register_operand" "r")
13159 (match_operand:SI 2 "register_operand" "r")
13160 (match_operand:SI 3 "const_int_operand" "n")) 0))
13163 (label_ref (match_operand 4 "" ""))
13165 (clobber (reg:CC FLAGS_REG))]
13166 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13167 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13170 [(set (reg:CCC FLAGS_REG)
13178 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13179 (label_ref (match_dup 4))
13181 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13183 ;; Define combination compare-and-branch fp compare instructions to help
13186 (define_insn "*fp_jcc_3_387"
13188 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13189 [(match_operand 1 "register_operand" "f")
13190 (match_operand 2 "nonimmediate_operand" "fm")])
13191 (label_ref (match_operand 3 "" ""))
13193 (clobber (reg:CCFP FPSR_REG))
13194 (clobber (reg:CCFP FLAGS_REG))
13195 (clobber (match_scratch:HI 4 "=a"))]
13197 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13198 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13199 && SELECT_CC_MODE (GET_CODE (operands[0]),
13200 operands[1], operands[2]) == CCFPmode
13204 (define_insn "*fp_jcc_4_387"
13206 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13207 [(match_operand 1 "register_operand" "f")
13208 (match_operand 2 "nonimmediate_operand" "fm")])
13210 (label_ref (match_operand 3 "" ""))))
13211 (clobber (reg:CCFP FPSR_REG))
13212 (clobber (reg:CCFP FLAGS_REG))
13213 (clobber (match_scratch:HI 4 "=a"))]
13215 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13216 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13217 && SELECT_CC_MODE (GET_CODE (operands[0]),
13218 operands[1], operands[2]) == CCFPmode
13222 (define_insn "*fp_jcc_5_387"
13224 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13225 [(match_operand 1 "register_operand" "f")
13226 (match_operand 2 "register_operand" "f")])
13227 (label_ref (match_operand 3 "" ""))
13229 (clobber (reg:CCFP FPSR_REG))
13230 (clobber (reg:CCFP FLAGS_REG))
13231 (clobber (match_scratch:HI 4 "=a"))]
13232 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13233 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13237 (define_insn "*fp_jcc_6_387"
13239 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13240 [(match_operand 1 "register_operand" "f")
13241 (match_operand 2 "register_operand" "f")])
13243 (label_ref (match_operand 3 "" ""))))
13244 (clobber (reg:CCFP FPSR_REG))
13245 (clobber (reg:CCFP FLAGS_REG))
13246 (clobber (match_scratch:HI 4 "=a"))]
13247 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13248 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13252 (define_insn "*fp_jcc_7_387"
13254 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13255 [(match_operand 1 "register_operand" "f")
13256 (match_operand 2 "const0_operand" "")])
13257 (label_ref (match_operand 3 "" ""))
13259 (clobber (reg:CCFP FPSR_REG))
13260 (clobber (reg:CCFP FLAGS_REG))
13261 (clobber (match_scratch:HI 4 "=a"))]
13262 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13263 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13264 && SELECT_CC_MODE (GET_CODE (operands[0]),
13265 operands[1], operands[2]) == CCFPmode
13269 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13270 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13271 ;; with a precedence over other operators and is always put in the first
13272 ;; place. Swap condition and operands to match ficom instruction.
13274 (define_insn "*fp_jcc_8<mode>_387"
13276 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13277 [(match_operator 1 "float_operator"
13278 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13279 (match_operand 3 "register_operand" "f,f")])
13280 (label_ref (match_operand 4 "" ""))
13282 (clobber (reg:CCFP FPSR_REG))
13283 (clobber (reg:CCFP FLAGS_REG))
13284 (clobber (match_scratch:HI 5 "=a,a"))]
13285 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13286 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13287 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13288 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13294 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13295 [(match_operand 1 "register_operand" "")
13296 (match_operand 2 "nonimmediate_operand" "")])
13297 (match_operand 3 "" "")
13298 (match_operand 4 "" "")))
13299 (clobber (reg:CCFP FPSR_REG))
13300 (clobber (reg:CCFP FLAGS_REG))]
13304 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13305 operands[3], operands[4], NULL_RTX, NULL_RTX);
13311 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13312 [(match_operand 1 "register_operand" "")
13313 (match_operand 2 "general_operand" "")])
13314 (match_operand 3 "" "")
13315 (match_operand 4 "" "")))
13316 (clobber (reg:CCFP FPSR_REG))
13317 (clobber (reg:CCFP FLAGS_REG))
13318 (clobber (match_scratch:HI 5 "=a"))]
13322 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13323 operands[3], operands[4], operands[5], NULL_RTX);
13329 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13330 [(match_operator 1 "float_operator"
13331 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13332 (match_operand 3 "register_operand" "")])
13333 (match_operand 4 "" "")
13334 (match_operand 5 "" "")))
13335 (clobber (reg:CCFP FPSR_REG))
13336 (clobber (reg:CCFP FLAGS_REG))
13337 (clobber (match_scratch:HI 6 "=a"))]
13341 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13342 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13343 operands[3], operands[7],
13344 operands[4], operands[5], operands[6], NULL_RTX);
13348 ;; %%% Kill this when reload knows how to do it.
13351 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13352 [(match_operator 1 "float_operator"
13353 [(match_operand:X87MODEI12 2 "register_operand" "")])
13354 (match_operand 3 "register_operand" "")])
13355 (match_operand 4 "" "")
13356 (match_operand 5 "" "")))
13357 (clobber (reg:CCFP FPSR_REG))
13358 (clobber (reg:CCFP FLAGS_REG))
13359 (clobber (match_scratch:HI 6 "=a"))]
13363 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13364 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13365 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13366 operands[3], operands[7],
13367 operands[4], operands[5], operands[6], operands[2]);
13371 ;; Unconditional and other jump instructions
13373 (define_insn "jump"
13375 (label_ref (match_operand 0 "" "")))]
13378 [(set_attr "type" "ibr")
13379 (set (attr "length")
13380 (if_then_else (and (ge (minus (match_dup 0) (pc))
13382 (lt (minus (match_dup 0) (pc))
13386 (set_attr "modrm" "0")])
13388 (define_expand "indirect_jump"
13389 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13393 (define_insn "*indirect_jump"
13394 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13397 [(set_attr "type" "ibr")
13398 (set_attr "length_immediate" "0")])
13400 (define_expand "tablejump"
13401 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13402 (use (label_ref (match_operand 1 "" "")))])]
13405 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13406 relative. Convert the relative address to an absolute address. */
13410 enum rtx_code code;
13412 /* We can't use @GOTOFF for text labels on VxWorks;
13413 see gotoff_operand. */
13414 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13418 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13420 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13424 op1 = pic_offset_table_rtx;
13429 op0 = pic_offset_table_rtx;
13433 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13438 (define_insn "*tablejump_1"
13439 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13440 (use (label_ref (match_operand 1 "" "")))]
13443 [(set_attr "type" "ibr")
13444 (set_attr "length_immediate" "0")])
13446 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13449 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13450 (set (match_operand:QI 1 "register_operand" "")
13451 (match_operator:QI 2 "ix86_comparison_operator"
13452 [(reg FLAGS_REG) (const_int 0)]))
13453 (set (match_operand 3 "q_regs_operand" "")
13454 (zero_extend (match_dup 1)))]
13455 "(peep2_reg_dead_p (3, operands[1])
13456 || operands_match_p (operands[1], operands[3]))
13457 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13458 [(set (match_dup 4) (match_dup 0))
13459 (set (strict_low_part (match_dup 5))
13462 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13463 operands[5] = gen_lowpart (QImode, operands[3]);
13464 ix86_expand_clear (operands[3]);
13467 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13470 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13471 (set (match_operand:QI 1 "register_operand" "")
13472 (match_operator:QI 2 "ix86_comparison_operator"
13473 [(reg FLAGS_REG) (const_int 0)]))
13474 (parallel [(set (match_operand 3 "q_regs_operand" "")
13475 (zero_extend (match_dup 1)))
13476 (clobber (reg:CC FLAGS_REG))])]
13477 "(peep2_reg_dead_p (3, operands[1])
13478 || operands_match_p (operands[1], operands[3]))
13479 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13480 [(set (match_dup 4) (match_dup 0))
13481 (set (strict_low_part (match_dup 5))
13484 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13485 operands[5] = gen_lowpart (QImode, operands[3]);
13486 ix86_expand_clear (operands[3]);
13489 ;; Call instructions.
13491 ;; The predicates normally associated with named expanders are not properly
13492 ;; checked for calls. This is a bug in the generic code, but it isn't that
13493 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13495 ;; P6 processors will jump to the address after the decrement when %esp
13496 ;; is used as a call operand, so they will execute return address as a code.
13497 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13499 ;; Call subroutine returning no value.
13501 (define_expand "call_pop"
13502 [(parallel [(call (match_operand:QI 0 "" "")
13503 (match_operand:SI 1 "" ""))
13504 (set (reg:SI SP_REG)
13505 (plus:SI (reg:SI SP_REG)
13506 (match_operand:SI 3 "" "")))])]
13509 ix86_expand_call (NULL, operands[0], operands[1],
13510 operands[2], operands[3], 0);
13514 (define_insn "*call_pop_0"
13515 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13516 (match_operand:SI 1 "" ""))
13517 (set (reg:SI SP_REG)
13518 (plus:SI (reg:SI SP_REG)
13519 (match_operand:SI 2 "immediate_operand" "")))]
13522 if (SIBLING_CALL_P (insn))
13525 return "call\t%P0";
13527 [(set_attr "type" "call")])
13529 (define_insn "*call_pop_1"
13530 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13531 (match_operand:SI 1 "" ""))
13532 (set (reg:SI SP_REG)
13533 (plus:SI (reg:SI SP_REG)
13534 (match_operand:SI 2 "immediate_operand" "i")))]
13535 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13537 if (constant_call_address_operand (operands[0], Pmode))
13538 return "call\t%P0";
13539 return "call\t%A0";
13541 [(set_attr "type" "call")])
13543 (define_insn "*sibcall_pop_1"
13544 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13545 (match_operand:SI 1 "" ""))
13546 (set (reg:SI SP_REG)
13547 (plus:SI (reg:SI SP_REG)
13548 (match_operand:SI 2 "immediate_operand" "i,i")))]
13549 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13553 [(set_attr "type" "call")])
13555 (define_expand "call"
13556 [(call (match_operand:QI 0 "" "")
13557 (match_operand 1 "" ""))
13558 (use (match_operand 2 "" ""))]
13561 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13565 (define_expand "sibcall"
13566 [(call (match_operand:QI 0 "" "")
13567 (match_operand 1 "" ""))
13568 (use (match_operand 2 "" ""))]
13571 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13575 (define_insn "*call_0"
13576 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13577 (match_operand 1 "" ""))]
13580 if (SIBLING_CALL_P (insn))
13583 return "call\t%P0";
13585 [(set_attr "type" "call")])
13587 (define_insn "*call_1"
13588 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13589 (match_operand 1 "" ""))]
13590 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13592 if (constant_call_address_operand (operands[0], Pmode))
13593 return "call\t%P0";
13594 return "call\t%A0";
13596 [(set_attr "type" "call")])
13598 (define_insn "*sibcall_1"
13599 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13600 (match_operand 1 "" ""))]
13601 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13605 [(set_attr "type" "call")])
13607 (define_insn "*call_1_rex64"
13608 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13609 (match_operand 1 "" ""))]
13610 "TARGET_64BIT && !SIBLING_CALL_P (insn)
13611 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13613 if (constant_call_address_operand (operands[0], Pmode))
13614 return "call\t%P0";
13615 return "call\t%A0";
13617 [(set_attr "type" "call")])
13619 (define_insn "*call_1_rex64_ms_sysv"
13620 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13621 (match_operand 1 "" ""))
13622 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13623 (clobber (reg:TI XMM6_REG))
13624 (clobber (reg:TI XMM7_REG))
13625 (clobber (reg:TI XMM8_REG))
13626 (clobber (reg:TI XMM9_REG))
13627 (clobber (reg:TI XMM10_REG))
13628 (clobber (reg:TI XMM11_REG))
13629 (clobber (reg:TI XMM12_REG))
13630 (clobber (reg:TI XMM13_REG))
13631 (clobber (reg:TI XMM14_REG))
13632 (clobber (reg:TI XMM15_REG))
13633 (clobber (reg:DI SI_REG))
13634 (clobber (reg:DI DI_REG))]
13635 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13637 if (constant_call_address_operand (operands[0], Pmode))
13638 return "call\t%P0";
13639 return "call\t%A0";
13641 [(set_attr "type" "call")])
13643 (define_insn "*call_1_rex64_large"
13644 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13645 (match_operand 1 "" ""))]
13646 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13648 [(set_attr "type" "call")])
13650 (define_insn "*sibcall_1_rex64"
13651 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13652 (match_operand 1 "" ""))]
13653 "TARGET_64BIT && SIBLING_CALL_P (insn)"
13657 [(set_attr "type" "call")])
13659 ;; Call subroutine, returning value in operand 0
13660 (define_expand "call_value_pop"
13661 [(parallel [(set (match_operand 0 "" "")
13662 (call (match_operand:QI 1 "" "")
13663 (match_operand:SI 2 "" "")))
13664 (set (reg:SI SP_REG)
13665 (plus:SI (reg:SI SP_REG)
13666 (match_operand:SI 4 "" "")))])]
13669 ix86_expand_call (operands[0], operands[1], operands[2],
13670 operands[3], operands[4], 0);
13674 (define_expand "call_value"
13675 [(set (match_operand 0 "" "")
13676 (call (match_operand:QI 1 "" "")
13677 (match_operand:SI 2 "" "")))
13678 (use (match_operand:SI 3 "" ""))]
13679 ;; Operand 3 is not used on the i386.
13682 ix86_expand_call (operands[0], operands[1], operands[2],
13683 operands[3], NULL, 0);
13687 (define_expand "sibcall_value"
13688 [(set (match_operand 0 "" "")
13689 (call (match_operand:QI 1 "" "")
13690 (match_operand:SI 2 "" "")))
13691 (use (match_operand:SI 3 "" ""))]
13692 ;; Operand 3 is not used on the i386.
13695 ix86_expand_call (operands[0], operands[1], operands[2],
13696 operands[3], NULL, 1);
13700 ;; Call subroutine returning any type.
13702 (define_expand "untyped_call"
13703 [(parallel [(call (match_operand 0 "" "")
13705 (match_operand 1 "" "")
13706 (match_operand 2 "" "")])]
13711 /* In order to give reg-stack an easier job in validating two
13712 coprocessor registers as containing a possible return value,
13713 simply pretend the untyped call returns a complex long double
13716 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13717 and should have the default ABI. */
13719 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13720 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13721 operands[0], const0_rtx,
13722 GEN_INT ((TARGET_64BIT
13723 ? (ix86_abi == SYSV_ABI
13724 ? X86_64_SSE_REGPARM_MAX
13725 : X86_64_MS_SSE_REGPARM_MAX)
13726 : X86_32_SSE_REGPARM_MAX)
13730 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13732 rtx set = XVECEXP (operands[2], 0, i);
13733 emit_move_insn (SET_DEST (set), SET_SRC (set));
13736 /* The optimizer does not know that the call sets the function value
13737 registers we stored in the result block. We avoid problems by
13738 claiming that all hard registers are used and clobbered at this
13740 emit_insn (gen_blockage ());
13745 ;; Prologue and epilogue instructions
13747 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13748 ;; all of memory. This blocks insns from being moved across this point.
13750 (define_insn "blockage"
13751 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13754 [(set_attr "length" "0")])
13756 ;; Do not schedule instructions accessing memory across this point.
13758 (define_expand "memory_blockage"
13759 [(set (match_dup 0)
13760 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13763 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13764 MEM_VOLATILE_P (operands[0]) = 1;
13767 (define_insn "*memory_blockage"
13768 [(set (match_operand:BLK 0 "" "")
13769 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13772 [(set_attr "length" "0")])
13774 ;; As USE insns aren't meaningful after reload, this is used instead
13775 ;; to prevent deleting instructions setting registers for PIC code
13776 (define_insn "prologue_use"
13777 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13780 [(set_attr "length" "0")])
13782 ;; Insn emitted into the body of a function to return from a function.
13783 ;; This is only done if the function's epilogue is known to be simple.
13784 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13786 (define_expand "return"
13788 "ix86_can_use_return_insn_p ()"
13790 if (crtl->args.pops_args)
13792 rtx popc = GEN_INT (crtl->args.pops_args);
13793 emit_jump_insn (gen_return_pop_internal (popc));
13798 (define_insn "return_internal"
13802 [(set_attr "length" "1")
13803 (set_attr "atom_unit" "jeu")
13804 (set_attr "length_immediate" "0")
13805 (set_attr "modrm" "0")])
13807 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13808 ;; instruction Athlon and K8 have.
13810 (define_insn "return_internal_long"
13812 (unspec [(const_int 0)] UNSPEC_REP)]
13815 [(set_attr "length" "2")
13816 (set_attr "atom_unit" "jeu")
13817 (set_attr "length_immediate" "0")
13818 (set_attr "prefix_rep" "1")
13819 (set_attr "modrm" "0")])
13821 (define_insn "return_pop_internal"
13823 (use (match_operand:SI 0 "const_int_operand" ""))]
13826 [(set_attr "length" "3")
13827 (set_attr "atom_unit" "jeu")
13828 (set_attr "length_immediate" "2")
13829 (set_attr "modrm" "0")])
13831 (define_insn "return_indirect_internal"
13833 (use (match_operand:SI 0 "register_operand" "r"))]
13836 [(set_attr "type" "ibr")
13837 (set_attr "length_immediate" "0")])
13843 [(set_attr "length" "1")
13844 (set_attr "length_immediate" "0")
13845 (set_attr "modrm" "0")])
13847 (define_insn "vswapmov"
13848 [(set (match_operand:SI 0 "register_operand" "=r")
13849 (match_operand:SI 1 "register_operand" "r"))
13850 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13852 "movl.s\t{%1, %0|%0, %1}"
13853 [(set_attr "length" "2")
13854 (set_attr "length_immediate" "0")
13855 (set_attr "modrm" "0")])
13857 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13858 ;; branch prediction penalty for the third jump in a 16-byte
13862 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13865 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13866 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13868 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13869 The align insn is used to avoid 3 jump instructions in the row to improve
13870 branch prediction and the benefits hardly outweigh the cost of extra 8
13871 nops on the average inserted by full alignment pseudo operation. */
13875 [(set_attr "length" "16")])
13877 (define_expand "prologue"
13880 "ix86_expand_prologue (); DONE;")
13882 (define_insn "set_got"
13883 [(set (match_operand:SI 0 "register_operand" "=r")
13884 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13885 (clobber (reg:CC FLAGS_REG))]
13887 { return output_set_got (operands[0], NULL_RTX); }
13888 [(set_attr "type" "multi")
13889 (set_attr "length" "12")])
13891 (define_insn "set_got_labelled"
13892 [(set (match_operand:SI 0 "register_operand" "=r")
13893 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13895 (clobber (reg:CC FLAGS_REG))]
13897 { return output_set_got (operands[0], operands[1]); }
13898 [(set_attr "type" "multi")
13899 (set_attr "length" "12")])
13901 (define_insn "set_got_rex64"
13902 [(set (match_operand:DI 0 "register_operand" "=r")
13903 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13905 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13906 [(set_attr "type" "lea")
13907 (set_attr "length_address" "4")
13908 (set_attr "mode" "DI")])
13910 (define_insn "set_rip_rex64"
13911 [(set (match_operand:DI 0 "register_operand" "=r")
13912 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13914 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13915 [(set_attr "type" "lea")
13916 (set_attr "length_address" "4")
13917 (set_attr "mode" "DI")])
13919 (define_insn "set_got_offset_rex64"
13920 [(set (match_operand:DI 0 "register_operand" "=r")
13922 [(label_ref (match_operand 1 "" ""))]
13923 UNSPEC_SET_GOT_OFFSET))]
13925 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13926 [(set_attr "type" "imov")
13927 (set_attr "length_immediate" "0")
13928 (set_attr "length_address" "8")
13929 (set_attr "mode" "DI")])
13931 (define_expand "epilogue"
13934 "ix86_expand_epilogue (1); DONE;")
13936 (define_expand "sibcall_epilogue"
13939 "ix86_expand_epilogue (0); DONE;")
13941 (define_expand "eh_return"
13942 [(use (match_operand 0 "register_operand" ""))]
13945 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13947 /* Tricky bit: we write the address of the handler to which we will
13948 be returning into someone else's stack frame, one word below the
13949 stack address we wish to restore. */
13950 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13951 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13952 tmp = gen_rtx_MEM (Pmode, tmp);
13953 emit_move_insn (tmp, ra);
13955 emit_jump_insn (gen_eh_return_internal ());
13960 (define_insn_and_split "eh_return_internal"
13964 "epilogue_completed"
13966 "ix86_expand_epilogue (2); DONE;")
13968 (define_insn "leave"
13969 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13970 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13971 (clobber (mem:BLK (scratch)))]
13974 [(set_attr "type" "leave")])
13976 (define_insn "leave_rex64"
13977 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13978 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13979 (clobber (mem:BLK (scratch)))]
13982 [(set_attr "type" "leave")])
13984 (define_expand "ffssi2"
13986 [(set (match_operand:SI 0 "register_operand" "")
13987 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13988 (clobber (match_scratch:SI 2 ""))
13989 (clobber (reg:CC FLAGS_REG))])]
13994 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13999 (define_expand "ffs_cmove"
14000 [(set (match_dup 2) (const_int -1))
14001 (parallel [(set (reg:CCZ FLAGS_REG)
14002 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14004 (set (match_operand:SI 0 "register_operand" "")
14005 (ctz:SI (match_dup 1)))])
14006 (set (match_dup 0) (if_then_else:SI
14007 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14010 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14011 (clobber (reg:CC FLAGS_REG))])]
14013 "operands[2] = gen_reg_rtx (SImode);")
14015 (define_insn_and_split "*ffs_no_cmove"
14016 [(set (match_operand:SI 0 "register_operand" "=r")
14017 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018 (clobber (match_scratch:SI 2 "=&q"))
14019 (clobber (reg:CC FLAGS_REG))]
14022 "&& reload_completed"
14023 [(parallel [(set (reg:CCZ FLAGS_REG)
14024 (compare:CCZ (match_dup 1) (const_int 0)))
14025 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14026 (set (strict_low_part (match_dup 3))
14027 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14028 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14029 (clobber (reg:CC FLAGS_REG))])
14030 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14031 (clobber (reg:CC FLAGS_REG))])
14032 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14033 (clobber (reg:CC FLAGS_REG))])]
14035 operands[3] = gen_lowpart (QImode, operands[2]);
14036 ix86_expand_clear (operands[2]);
14039 (define_insn "*ffssi_1"
14040 [(set (reg:CCZ FLAGS_REG)
14041 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14043 (set (match_operand:SI 0 "register_operand" "=r")
14044 (ctz:SI (match_dup 1)))]
14046 "bsf{l}\t{%1, %0|%0, %1}"
14047 [(set_attr "type" "alu1")
14048 (set_attr "prefix_0f" "1")
14049 (set_attr "mode" "SI")])
14051 (define_expand "ffsdi2"
14052 [(set (match_dup 2) (const_int -1))
14053 (parallel [(set (reg:CCZ FLAGS_REG)
14054 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14056 (set (match_operand:DI 0 "register_operand" "")
14057 (ctz:DI (match_dup 1)))])
14058 (set (match_dup 0) (if_then_else:DI
14059 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14062 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14063 (clobber (reg:CC FLAGS_REG))])]
14065 "operands[2] = gen_reg_rtx (DImode);")
14067 (define_insn "*ffsdi_1"
14068 [(set (reg:CCZ FLAGS_REG)
14069 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14071 (set (match_operand:DI 0 "register_operand" "=r")
14072 (ctz:DI (match_dup 1)))]
14074 "bsf{q}\t{%1, %0|%0, %1}"
14075 [(set_attr "type" "alu1")
14076 (set_attr "prefix_0f" "1")
14077 (set_attr "mode" "DI")])
14079 (define_insn "ctzsi2"
14080 [(set (match_operand:SI 0 "register_operand" "=r")
14081 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14082 (clobber (reg:CC FLAGS_REG))]
14084 "bsf{l}\t{%1, %0|%0, %1}"
14085 [(set_attr "type" "alu1")
14086 (set_attr "prefix_0f" "1")
14087 (set_attr "mode" "SI")])
14089 (define_insn "ctzdi2"
14090 [(set (match_operand:DI 0 "register_operand" "=r")
14091 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14092 (clobber (reg:CC FLAGS_REG))]
14094 "bsf{q}\t{%1, %0|%0, %1}"
14095 [(set_attr "type" "alu1")
14096 (set_attr "prefix_0f" "1")
14097 (set_attr "mode" "DI")])
14099 (define_expand "clzsi2"
14101 [(set (match_operand:SI 0 "register_operand" "")
14102 (minus:SI (const_int 31)
14103 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14104 (clobber (reg:CC FLAGS_REG))])
14106 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14107 (clobber (reg:CC FLAGS_REG))])]
14112 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14117 (define_insn "clzsi2_abm"
14118 [(set (match_operand:SI 0 "register_operand" "=r")
14119 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14120 (clobber (reg:CC FLAGS_REG))]
14122 "lzcnt{l}\t{%1, %0|%0, %1}"
14123 [(set_attr "prefix_rep" "1")
14124 (set_attr "type" "bitmanip")
14125 (set_attr "mode" "SI")])
14128 [(set (match_operand:SI 0 "register_operand" "=r")
14129 (minus:SI (const_int 31)
14130 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14131 (clobber (reg:CC FLAGS_REG))]
14133 "bsr{l}\t{%1, %0|%0, %1}"
14134 [(set_attr "type" "alu1")
14135 (set_attr "prefix_0f" "1")
14136 (set_attr "mode" "SI")])
14138 (define_insn "popcount<mode>2"
14139 [(set (match_operand:SWI248 0 "register_operand" "=r")
14141 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14142 (clobber (reg:CC FLAGS_REG))]
14146 return "popcnt\t{%1, %0|%0, %1}";
14148 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14151 [(set_attr "prefix_rep" "1")
14152 (set_attr "type" "bitmanip")
14153 (set_attr "mode" "<MODE>")])
14155 (define_insn "*popcount<mode>2_cmp"
14156 [(set (reg FLAGS_REG)
14159 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14161 (set (match_operand:SWI248 0 "register_operand" "=r")
14162 (popcount:SWI248 (match_dup 1)))]
14163 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14166 return "popcnt\t{%1, %0|%0, %1}";
14168 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14171 [(set_attr "prefix_rep" "1")
14172 (set_attr "type" "bitmanip")
14173 (set_attr "mode" "<MODE>")])
14175 (define_insn "*popcountsi2_cmp_zext"
14176 [(set (reg FLAGS_REG)
14178 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14180 (set (match_operand:DI 0 "register_operand" "=r")
14181 (zero_extend:DI(popcount:SI (match_dup 1))))]
14182 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14185 return "popcnt\t{%1, %0|%0, %1}";
14187 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14190 [(set_attr "prefix_rep" "1")
14191 (set_attr "type" "bitmanip")
14192 (set_attr "mode" "SI")])
14194 (define_expand "bswapsi2"
14195 [(set (match_operand:SI 0 "register_operand" "")
14196 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14199 if (!(TARGET_BSWAP || TARGET_MOVBE))
14201 rtx x = operands[0];
14203 emit_move_insn (x, operands[1]);
14204 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14205 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14206 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14211 (define_insn "*bswapsi_movbe"
14212 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14213 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14214 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14217 movbe\t{%1, %0|%0, %1}
14218 movbe\t{%1, %0|%0, %1}"
14219 [(set_attr "type" "*,imov,imov")
14220 (set_attr "modrm" "*,1,1")
14221 (set_attr "prefix_0f" "1")
14222 (set_attr "prefix_extra" "*,1,1")
14223 (set_attr "length" "2,*,*")
14224 (set_attr "mode" "SI")])
14226 (define_insn "*bswapsi_1"
14227 [(set (match_operand:SI 0 "register_operand" "=r")
14228 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14231 [(set_attr "prefix_0f" "1")
14232 (set_attr "length" "2")])
14234 (define_insn "*bswaphi_lowpart_1"
14235 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14236 (bswap:HI (match_dup 0)))
14237 (clobber (reg:CC FLAGS_REG))]
14238 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14240 xchg{b}\t{%h0, %b0|%b0, %h0}
14241 rol{w}\t{$8, %0|%0, 8}"
14242 [(set_attr "length" "2,4")
14243 (set_attr "mode" "QI,HI")])
14245 (define_insn "bswaphi_lowpart"
14246 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14247 (bswap:HI (match_dup 0)))
14248 (clobber (reg:CC FLAGS_REG))]
14250 "rol{w}\t{$8, %0|%0, 8}"
14251 [(set_attr "length" "4")
14252 (set_attr "mode" "HI")])
14254 (define_expand "bswapdi2"
14255 [(set (match_operand:DI 0 "register_operand" "")
14256 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14260 (define_insn "*bswapdi_movbe"
14261 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14262 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14263 "TARGET_64BIT && TARGET_MOVBE
14264 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14267 movbe\t{%1, %0|%0, %1}
14268 movbe\t{%1, %0|%0, %1}"
14269 [(set_attr "type" "*,imov,imov")
14270 (set_attr "modrm" "*,1,1")
14271 (set_attr "prefix_0f" "1")
14272 (set_attr "prefix_extra" "*,1,1")
14273 (set_attr "length" "3,*,*")
14274 (set_attr "mode" "DI")])
14276 (define_insn "*bswapdi_1"
14277 [(set (match_operand:DI 0 "register_operand" "=r")
14278 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14281 [(set_attr "prefix_0f" "1")
14282 (set_attr "length" "3")])
14284 (define_expand "clzdi2"
14286 [(set (match_operand:DI 0 "register_operand" "")
14287 (minus:DI (const_int 63)
14288 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14289 (clobber (reg:CC FLAGS_REG))])
14291 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14292 (clobber (reg:CC FLAGS_REG))])]
14297 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14302 (define_insn "clzdi2_abm"
14303 [(set (match_operand:DI 0 "register_operand" "=r")
14304 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14305 (clobber (reg:CC FLAGS_REG))]
14306 "TARGET_64BIT && TARGET_ABM"
14307 "lzcnt{q}\t{%1, %0|%0, %1}"
14308 [(set_attr "prefix_rep" "1")
14309 (set_attr "type" "bitmanip")
14310 (set_attr "mode" "DI")])
14312 (define_insn "bsr_rex64"
14313 [(set (match_operand:DI 0 "register_operand" "=r")
14314 (minus:DI (const_int 63)
14315 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14316 (clobber (reg:CC FLAGS_REG))]
14318 "bsr{q}\t{%1, %0|%0, %1}"
14319 [(set_attr "type" "alu1")
14320 (set_attr "prefix_0f" "1")
14321 (set_attr "mode" "DI")])
14323 (define_expand "clzhi2"
14325 [(set (match_operand:HI 0 "register_operand" "")
14326 (minus:HI (const_int 15)
14327 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14328 (clobber (reg:CC FLAGS_REG))])
14330 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14331 (clobber (reg:CC FLAGS_REG))])]
14336 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14341 (define_insn "clzhi2_abm"
14342 [(set (match_operand:HI 0 "register_operand" "=r")
14343 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14344 (clobber (reg:CC FLAGS_REG))]
14346 "lzcnt{w}\t{%1, %0|%0, %1}"
14347 [(set_attr "prefix_rep" "1")
14348 (set_attr "type" "bitmanip")
14349 (set_attr "mode" "HI")])
14351 (define_insn "*bsrhi"
14352 [(set (match_operand:HI 0 "register_operand" "=r")
14353 (minus:HI (const_int 15)
14354 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14355 (clobber (reg:CC FLAGS_REG))]
14357 "bsr{w}\t{%1, %0|%0, %1}"
14358 [(set_attr "type" "alu1")
14359 (set_attr "prefix_0f" "1")
14360 (set_attr "mode" "HI")])
14362 (define_expand "paritydi2"
14363 [(set (match_operand:DI 0 "register_operand" "")
14364 (parity:DI (match_operand:DI 1 "register_operand" "")))]
14367 rtx scratch = gen_reg_rtx (QImode);
14370 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14371 NULL_RTX, operands[1]));
14373 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14374 gen_rtx_REG (CCmode, FLAGS_REG),
14376 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14379 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14382 rtx tmp = gen_reg_rtx (SImode);
14384 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14385 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14390 (define_insn_and_split "paritydi2_cmp"
14391 [(set (reg:CC FLAGS_REG)
14392 (parity:CC (match_operand:DI 3 "register_operand" "0")))
14393 (clobber (match_scratch:DI 0 "=r"))
14394 (clobber (match_scratch:SI 1 "=&r"))
14395 (clobber (match_scratch:HI 2 "=Q"))]
14398 "&& reload_completed"
14400 [(set (match_dup 1)
14401 (xor:SI (match_dup 1) (match_dup 4)))
14402 (clobber (reg:CC FLAGS_REG))])
14404 [(set (reg:CC FLAGS_REG)
14405 (parity:CC (match_dup 1)))
14406 (clobber (match_dup 1))
14407 (clobber (match_dup 2))])]
14409 operands[4] = gen_lowpart (SImode, operands[3]);
14413 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14414 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14417 operands[1] = gen_highpart (SImode, operands[3]);
14420 (define_expand "paritysi2"
14421 [(set (match_operand:SI 0 "register_operand" "")
14422 (parity:SI (match_operand:SI 1 "register_operand" "")))]
14425 rtx scratch = gen_reg_rtx (QImode);
14428 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14430 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14431 gen_rtx_REG (CCmode, FLAGS_REG),
14433 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14435 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14439 (define_insn_and_split "paritysi2_cmp"
14440 [(set (reg:CC FLAGS_REG)
14441 (parity:CC (match_operand:SI 2 "register_operand" "0")))
14442 (clobber (match_scratch:SI 0 "=r"))
14443 (clobber (match_scratch:HI 1 "=&Q"))]
14446 "&& reload_completed"
14448 [(set (match_dup 1)
14449 (xor:HI (match_dup 1) (match_dup 3)))
14450 (clobber (reg:CC FLAGS_REG))])
14452 [(set (reg:CC FLAGS_REG)
14453 (parity:CC (match_dup 1)))
14454 (clobber (match_dup 1))])]
14456 operands[3] = gen_lowpart (HImode, operands[2]);
14458 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14459 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14462 (define_insn "*parityhi2_cmp"
14463 [(set (reg:CC FLAGS_REG)
14464 (parity:CC (match_operand:HI 1 "register_operand" "0")))
14465 (clobber (match_scratch:HI 0 "=Q"))]
14467 "xor{b}\t{%h0, %b0|%b0, %h0}"
14468 [(set_attr "length" "2")
14469 (set_attr "mode" "HI")])
14471 (define_insn "*parityqi2_cmp"
14472 [(set (reg:CC FLAGS_REG)
14473 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14476 [(set_attr "length" "2")
14477 (set_attr "mode" "QI")])
14479 ;; Thread-local storage patterns for ELF.
14481 ;; Note that these code sequences must appear exactly as shown
14482 ;; in order to allow linker relaxation.
14484 (define_insn "*tls_global_dynamic_32_gnu"
14485 [(set (match_operand:SI 0 "register_operand" "=a")
14486 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14487 (match_operand:SI 2 "tls_symbolic_operand" "")
14488 (match_operand:SI 3 "call_insn_operand" "")]
14490 (clobber (match_scratch:SI 4 "=d"))
14491 (clobber (match_scratch:SI 5 "=c"))
14492 (clobber (reg:CC FLAGS_REG))]
14493 "!TARGET_64BIT && TARGET_GNU_TLS"
14494 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14495 [(set_attr "type" "multi")
14496 (set_attr "length" "12")])
14498 (define_insn "*tls_global_dynamic_32_sun"
14499 [(set (match_operand:SI 0 "register_operand" "=a")
14500 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14501 (match_operand:SI 2 "tls_symbolic_operand" "")
14502 (match_operand:SI 3 "call_insn_operand" "")]
14504 (clobber (match_scratch:SI 4 "=d"))
14505 (clobber (match_scratch:SI 5 "=c"))
14506 (clobber (reg:CC FLAGS_REG))]
14507 "!TARGET_64BIT && TARGET_SUN_TLS"
14508 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14509 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14510 [(set_attr "type" "multi")
14511 (set_attr "length" "14")])
14513 (define_expand "tls_global_dynamic_32"
14514 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14517 (match_operand:SI 1 "tls_symbolic_operand" "")
14520 (clobber (match_scratch:SI 4 ""))
14521 (clobber (match_scratch:SI 5 ""))
14522 (clobber (reg:CC FLAGS_REG))])]
14526 operands[2] = pic_offset_table_rtx;
14529 operands[2] = gen_reg_rtx (Pmode);
14530 emit_insn (gen_set_got (operands[2]));
14532 if (TARGET_GNU2_TLS)
14534 emit_insn (gen_tls_dynamic_gnu2_32
14535 (operands[0], operands[1], operands[2]));
14538 operands[3] = ix86_tls_get_addr ();
14541 (define_insn "*tls_global_dynamic_64"
14542 [(set (match_operand:DI 0 "register_operand" "=a")
14543 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14544 (match_operand:DI 3 "" "")))
14545 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14548 { 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"; }
14549 [(set_attr "type" "multi")
14550 (set_attr "length" "16")])
14552 (define_expand "tls_global_dynamic_64"
14553 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14554 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14555 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14559 if (TARGET_GNU2_TLS)
14561 emit_insn (gen_tls_dynamic_gnu2_64
14562 (operands[0], operands[1]));
14565 operands[2] = ix86_tls_get_addr ();
14568 (define_insn "*tls_local_dynamic_base_32_gnu"
14569 [(set (match_operand:SI 0 "register_operand" "=a")
14570 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14571 (match_operand:SI 2 "call_insn_operand" "")]
14572 UNSPEC_TLS_LD_BASE))
14573 (clobber (match_scratch:SI 3 "=d"))
14574 (clobber (match_scratch:SI 4 "=c"))
14575 (clobber (reg:CC FLAGS_REG))]
14576 "!TARGET_64BIT && TARGET_GNU_TLS"
14577 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14578 [(set_attr "type" "multi")
14579 (set_attr "length" "11")])
14581 (define_insn "*tls_local_dynamic_base_32_sun"
14582 [(set (match_operand:SI 0 "register_operand" "=a")
14583 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14584 (match_operand:SI 2 "call_insn_operand" "")]
14585 UNSPEC_TLS_LD_BASE))
14586 (clobber (match_scratch:SI 3 "=d"))
14587 (clobber (match_scratch:SI 4 "=c"))
14588 (clobber (reg:CC FLAGS_REG))]
14589 "!TARGET_64BIT && TARGET_SUN_TLS"
14590 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14591 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14592 [(set_attr "type" "multi")
14593 (set_attr "length" "13")])
14595 (define_expand "tls_local_dynamic_base_32"
14596 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14597 (unspec:SI [(match_dup 1) (match_dup 2)]
14598 UNSPEC_TLS_LD_BASE))
14599 (clobber (match_scratch:SI 3 ""))
14600 (clobber (match_scratch:SI 4 ""))
14601 (clobber (reg:CC FLAGS_REG))])]
14605 operands[1] = pic_offset_table_rtx;
14608 operands[1] = gen_reg_rtx (Pmode);
14609 emit_insn (gen_set_got (operands[1]));
14611 if (TARGET_GNU2_TLS)
14613 emit_insn (gen_tls_dynamic_gnu2_32
14614 (operands[0], ix86_tls_module_base (), operands[1]));
14617 operands[2] = ix86_tls_get_addr ();
14620 (define_insn "*tls_local_dynamic_base_64"
14621 [(set (match_operand:DI 0 "register_operand" "=a")
14622 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14623 (match_operand:DI 2 "" "")))
14624 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14626 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
14627 [(set_attr "type" "multi")
14628 (set_attr "length" "12")])
14630 (define_expand "tls_local_dynamic_base_64"
14631 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14632 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14633 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14636 if (TARGET_GNU2_TLS)
14638 emit_insn (gen_tls_dynamic_gnu2_64
14639 (operands[0], ix86_tls_module_base ()));
14642 operands[1] = ix86_tls_get_addr ();
14645 ;; Local dynamic of a single variable is a lose. Show combine how
14646 ;; to convert that back to global dynamic.
14648 (define_insn_and_split "*tls_local_dynamic_32_once"
14649 [(set (match_operand:SI 0 "register_operand" "=a")
14650 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14651 (match_operand:SI 2 "call_insn_operand" "")]
14652 UNSPEC_TLS_LD_BASE)
14653 (const:SI (unspec:SI
14654 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14656 (clobber (match_scratch:SI 4 "=d"))
14657 (clobber (match_scratch:SI 5 "=c"))
14658 (clobber (reg:CC FLAGS_REG))]
14662 [(parallel [(set (match_dup 0)
14663 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14665 (clobber (match_dup 4))
14666 (clobber (match_dup 5))
14667 (clobber (reg:CC FLAGS_REG))])]
14670 ;; Load and add the thread base pointer from %gs:0.
14672 (define_insn "*load_tp_si"
14673 [(set (match_operand:SI 0 "register_operand" "=r")
14674 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14676 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14677 [(set_attr "type" "imov")
14678 (set_attr "modrm" "0")
14679 (set_attr "length" "7")
14680 (set_attr "memory" "load")
14681 (set_attr "imm_disp" "false")])
14683 (define_insn "*add_tp_si"
14684 [(set (match_operand:SI 0 "register_operand" "=r")
14685 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14686 (match_operand:SI 1 "register_operand" "0")))
14687 (clobber (reg:CC FLAGS_REG))]
14689 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14690 [(set_attr "type" "alu")
14691 (set_attr "modrm" "0")
14692 (set_attr "length" "7")
14693 (set_attr "memory" "load")
14694 (set_attr "imm_disp" "false")])
14696 (define_insn "*load_tp_di"
14697 [(set (match_operand:DI 0 "register_operand" "=r")
14698 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14700 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14701 [(set_attr "type" "imov")
14702 (set_attr "modrm" "0")
14703 (set_attr "length" "7")
14704 (set_attr "memory" "load")
14705 (set_attr "imm_disp" "false")])
14707 (define_insn "*add_tp_di"
14708 [(set (match_operand:DI 0 "register_operand" "=r")
14709 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14710 (match_operand:DI 1 "register_operand" "0")))
14711 (clobber (reg:CC FLAGS_REG))]
14713 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14714 [(set_attr "type" "alu")
14715 (set_attr "modrm" "0")
14716 (set_attr "length" "7")
14717 (set_attr "memory" "load")
14718 (set_attr "imm_disp" "false")])
14720 ;; GNU2 TLS patterns can be split.
14722 (define_expand "tls_dynamic_gnu2_32"
14723 [(set (match_dup 3)
14724 (plus:SI (match_operand:SI 2 "register_operand" "")
14726 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14729 [(set (match_operand:SI 0 "register_operand" "")
14730 (unspec:SI [(match_dup 1) (match_dup 3)
14731 (match_dup 2) (reg:SI SP_REG)]
14733 (clobber (reg:CC FLAGS_REG))])]
14734 "!TARGET_64BIT && TARGET_GNU2_TLS"
14736 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14737 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14740 (define_insn "*tls_dynamic_lea_32"
14741 [(set (match_operand:SI 0 "register_operand" "=r")
14742 (plus:SI (match_operand:SI 1 "register_operand" "b")
14744 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14745 UNSPEC_TLSDESC))))]
14746 "!TARGET_64BIT && TARGET_GNU2_TLS"
14747 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14748 [(set_attr "type" "lea")
14749 (set_attr "mode" "SI")
14750 (set_attr "length" "6")
14751 (set_attr "length_address" "4")])
14753 (define_insn "*tls_dynamic_call_32"
14754 [(set (match_operand:SI 0 "register_operand" "=a")
14755 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14756 (match_operand:SI 2 "register_operand" "0")
14757 ;; we have to make sure %ebx still points to the GOT
14758 (match_operand:SI 3 "register_operand" "b")
14761 (clobber (reg:CC FLAGS_REG))]
14762 "!TARGET_64BIT && TARGET_GNU2_TLS"
14763 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14764 [(set_attr "type" "call")
14765 (set_attr "length" "2")
14766 (set_attr "length_address" "0")])
14768 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14769 [(set (match_operand:SI 0 "register_operand" "=&a")
14771 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14772 (match_operand:SI 4 "" "")
14773 (match_operand:SI 2 "register_operand" "b")
14776 (const:SI (unspec:SI
14777 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14779 (clobber (reg:CC FLAGS_REG))]
14780 "!TARGET_64BIT && TARGET_GNU2_TLS"
14783 [(set (match_dup 0) (match_dup 5))]
14785 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14786 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14789 (define_expand "tls_dynamic_gnu2_64"
14790 [(set (match_dup 2)
14791 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14794 [(set (match_operand:DI 0 "register_operand" "")
14795 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14797 (clobber (reg:CC FLAGS_REG))])]
14798 "TARGET_64BIT && TARGET_GNU2_TLS"
14800 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14801 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14804 (define_insn "*tls_dynamic_lea_64"
14805 [(set (match_operand:DI 0 "register_operand" "=r")
14806 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14808 "TARGET_64BIT && TARGET_GNU2_TLS"
14809 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14810 [(set_attr "type" "lea")
14811 (set_attr "mode" "DI")
14812 (set_attr "length" "7")
14813 (set_attr "length_address" "4")])
14815 (define_insn "*tls_dynamic_call_64"
14816 [(set (match_operand:DI 0 "register_operand" "=a")
14817 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14818 (match_operand:DI 2 "register_operand" "0")
14821 (clobber (reg:CC FLAGS_REG))]
14822 "TARGET_64BIT && TARGET_GNU2_TLS"
14823 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14824 [(set_attr "type" "call")
14825 (set_attr "length" "2")
14826 (set_attr "length_address" "0")])
14828 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14829 [(set (match_operand:DI 0 "register_operand" "=&a")
14831 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14832 (match_operand:DI 3 "" "")
14835 (const:DI (unspec:DI
14836 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14838 (clobber (reg:CC FLAGS_REG))]
14839 "TARGET_64BIT && TARGET_GNU2_TLS"
14842 [(set (match_dup 0) (match_dup 4))]
14844 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14845 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14850 ;; These patterns match the binary 387 instructions for addM3, subM3,
14851 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14852 ;; SFmode. The first is the normal insn, the second the same insn but
14853 ;; with one operand a conversion, and the third the same insn but with
14854 ;; the other operand a conversion. The conversion may be SFmode or
14855 ;; SImode if the target mode DFmode, but only SImode if the target mode
14858 ;; Gcc is slightly more smart about handling normal two address instructions
14859 ;; so use special patterns for add and mull.
14861 (define_insn "*fop_<mode>_comm_mixed_avx"
14862 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14863 (match_operator:MODEF 3 "binary_fp_operator"
14864 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14865 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14866 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14867 && COMMUTATIVE_ARITH_P (operands[3])
14868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14869 "* return output_387_binary_op (insn, operands);"
14870 [(set (attr "type")
14871 (if_then_else (eq_attr "alternative" "1")
14872 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14873 (const_string "ssemul")
14874 (const_string "sseadd"))
14875 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14876 (const_string "fmul")
14877 (const_string "fop"))))
14878 (set_attr "prefix" "orig,maybe_vex")
14879 (set_attr "mode" "<MODE>")])
14881 (define_insn "*fop_<mode>_comm_mixed"
14882 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14883 (match_operator:MODEF 3 "binary_fp_operator"
14884 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14885 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14886 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14887 && COMMUTATIVE_ARITH_P (operands[3])
14888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14889 "* return output_387_binary_op (insn, operands);"
14890 [(set (attr "type")
14891 (if_then_else (eq_attr "alternative" "1")
14892 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14893 (const_string "ssemul")
14894 (const_string "sseadd"))
14895 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14896 (const_string "fmul")
14897 (const_string "fop"))))
14898 (set_attr "mode" "<MODE>")])
14900 (define_insn "*fop_<mode>_comm_avx"
14901 [(set (match_operand:MODEF 0 "register_operand" "=x")
14902 (match_operator:MODEF 3 "binary_fp_operator"
14903 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14904 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14905 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14906 && COMMUTATIVE_ARITH_P (operands[3])
14907 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14908 "* return output_387_binary_op (insn, operands);"
14909 [(set (attr "type")
14910 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14911 (const_string "ssemul")
14912 (const_string "sseadd")))
14913 (set_attr "prefix" "vex")
14914 (set_attr "mode" "<MODE>")])
14916 (define_insn "*fop_<mode>_comm_sse"
14917 [(set (match_operand:MODEF 0 "register_operand" "=x")
14918 (match_operator:MODEF 3 "binary_fp_operator"
14919 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14920 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14921 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14922 && COMMUTATIVE_ARITH_P (operands[3])
14923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14924 "* return output_387_binary_op (insn, operands);"
14925 [(set (attr "type")
14926 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14927 (const_string "ssemul")
14928 (const_string "sseadd")))
14929 (set_attr "mode" "<MODE>")])
14931 (define_insn "*fop_<mode>_comm_i387"
14932 [(set (match_operand:MODEF 0 "register_operand" "=f")
14933 (match_operator:MODEF 3 "binary_fp_operator"
14934 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14935 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14936 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14937 && COMMUTATIVE_ARITH_P (operands[3])
14938 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14939 "* return output_387_binary_op (insn, operands);"
14940 [(set (attr "type")
14941 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14942 (const_string "fmul")
14943 (const_string "fop")))
14944 (set_attr "mode" "<MODE>")])
14946 (define_insn "*fop_<mode>_1_mixed_avx"
14947 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14948 (match_operator:MODEF 3 "binary_fp_operator"
14949 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14950 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14951 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14952 && !COMMUTATIVE_ARITH_P (operands[3])
14953 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14954 "* return output_387_binary_op (insn, operands);"
14955 [(set (attr "type")
14956 (cond [(and (eq_attr "alternative" "2")
14957 (match_operand:MODEF 3 "mult_operator" ""))
14958 (const_string "ssemul")
14959 (and (eq_attr "alternative" "2")
14960 (match_operand:MODEF 3 "div_operator" ""))
14961 (const_string "ssediv")
14962 (eq_attr "alternative" "2")
14963 (const_string "sseadd")
14964 (match_operand:MODEF 3 "mult_operator" "")
14965 (const_string "fmul")
14966 (match_operand:MODEF 3 "div_operator" "")
14967 (const_string "fdiv")
14969 (const_string "fop")))
14970 (set_attr "prefix" "orig,orig,maybe_vex")
14971 (set_attr "mode" "<MODE>")])
14973 (define_insn "*fop_<mode>_1_mixed"
14974 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14975 (match_operator:MODEF 3 "binary_fp_operator"
14976 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14977 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14978 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14979 && !COMMUTATIVE_ARITH_P (operands[3])
14980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14981 "* return output_387_binary_op (insn, operands);"
14982 [(set (attr "type")
14983 (cond [(and (eq_attr "alternative" "2")
14984 (match_operand:MODEF 3 "mult_operator" ""))
14985 (const_string "ssemul")
14986 (and (eq_attr "alternative" "2")
14987 (match_operand:MODEF 3 "div_operator" ""))
14988 (const_string "ssediv")
14989 (eq_attr "alternative" "2")
14990 (const_string "sseadd")
14991 (match_operand:MODEF 3 "mult_operator" "")
14992 (const_string "fmul")
14993 (match_operand:MODEF 3 "div_operator" "")
14994 (const_string "fdiv")
14996 (const_string "fop")))
14997 (set_attr "mode" "<MODE>")])
14999 (define_insn "*rcpsf2_sse"
15000 [(set (match_operand:SF 0 "register_operand" "=x")
15001 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15004 "%vrcpss\t{%1, %d0|%d0, %1}"
15005 [(set_attr "type" "sse")
15006 (set_attr "atom_sse_attr" "rcp")
15007 (set_attr "prefix" "maybe_vex")
15008 (set_attr "mode" "SF")])
15010 (define_insn "*fop_<mode>_1_avx"
15011 [(set (match_operand:MODEF 0 "register_operand" "=x")
15012 (match_operator:MODEF 3 "binary_fp_operator"
15013 [(match_operand:MODEF 1 "register_operand" "x")
15014 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15015 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15016 && !COMMUTATIVE_ARITH_P (operands[3])"
15017 "* return output_387_binary_op (insn, operands);"
15018 [(set (attr "type")
15019 (cond [(match_operand:MODEF 3 "mult_operator" "")
15020 (const_string "ssemul")
15021 (match_operand:MODEF 3 "div_operator" "")
15022 (const_string "ssediv")
15024 (const_string "sseadd")))
15025 (set_attr "prefix" "vex")
15026 (set_attr "mode" "<MODE>")])
15028 (define_insn "*fop_<mode>_1_sse"
15029 [(set (match_operand:MODEF 0 "register_operand" "=x")
15030 (match_operator:MODEF 3 "binary_fp_operator"
15031 [(match_operand:MODEF 1 "register_operand" "0")
15032 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15033 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15034 && !COMMUTATIVE_ARITH_P (operands[3])"
15035 "* return output_387_binary_op (insn, operands);"
15036 [(set (attr "type")
15037 (cond [(match_operand:MODEF 3 "mult_operator" "")
15038 (const_string "ssemul")
15039 (match_operand:MODEF 3 "div_operator" "")
15040 (const_string "ssediv")
15042 (const_string "sseadd")))
15043 (set_attr "mode" "<MODE>")])
15045 ;; This pattern is not fully shadowed by the pattern above.
15046 (define_insn "*fop_<mode>_1_i387"
15047 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15048 (match_operator:MODEF 3 "binary_fp_operator"
15049 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15050 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15051 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15052 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15053 && !COMMUTATIVE_ARITH_P (operands[3])
15054 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15055 "* return output_387_binary_op (insn, operands);"
15056 [(set (attr "type")
15057 (cond [(match_operand:MODEF 3 "mult_operator" "")
15058 (const_string "fmul")
15059 (match_operand:MODEF 3 "div_operator" "")
15060 (const_string "fdiv")
15062 (const_string "fop")))
15063 (set_attr "mode" "<MODE>")])
15065 ;; ??? Add SSE splitters for these!
15066 (define_insn "*fop_<MODEF:mode>_2_i387"
15067 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15068 (match_operator:MODEF 3 "binary_fp_operator"
15070 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15071 (match_operand:MODEF 2 "register_operand" "0,0")]))]
15072 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15073 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15074 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15075 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15076 [(set (attr "type")
15077 (cond [(match_operand:MODEF 3 "mult_operator" "")
15078 (const_string "fmul")
15079 (match_operand:MODEF 3 "div_operator" "")
15080 (const_string "fdiv")
15082 (const_string "fop")))
15083 (set_attr "fp_int_src" "true")
15084 (set_attr "mode" "<X87MODEI12:MODE>")])
15086 (define_insn "*fop_<MODEF:mode>_3_i387"
15087 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15088 (match_operator:MODEF 3 "binary_fp_operator"
15089 [(match_operand:MODEF 1 "register_operand" "0,0")
15091 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15092 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15093 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15094 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15095 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15096 [(set (attr "type")
15097 (cond [(match_operand:MODEF 3 "mult_operator" "")
15098 (const_string "fmul")
15099 (match_operand:MODEF 3 "div_operator" "")
15100 (const_string "fdiv")
15102 (const_string "fop")))
15103 (set_attr "fp_int_src" "true")
15104 (set_attr "mode" "<MODE>")])
15106 (define_insn "*fop_df_4_i387"
15107 [(set (match_operand:DF 0 "register_operand" "=f,f")
15108 (match_operator:DF 3 "binary_fp_operator"
15110 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15111 (match_operand:DF 2 "register_operand" "0,f")]))]
15112 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15113 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15114 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15115 "* return output_387_binary_op (insn, operands);"
15116 [(set (attr "type")
15117 (cond [(match_operand:DF 3 "mult_operator" "")
15118 (const_string "fmul")
15119 (match_operand:DF 3 "div_operator" "")
15120 (const_string "fdiv")
15122 (const_string "fop")))
15123 (set_attr "mode" "SF")])
15125 (define_insn "*fop_df_5_i387"
15126 [(set (match_operand:DF 0 "register_operand" "=f,f")
15127 (match_operator:DF 3 "binary_fp_operator"
15128 [(match_operand:DF 1 "register_operand" "0,f")
15130 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15131 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15132 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15133 "* return output_387_binary_op (insn, operands);"
15134 [(set (attr "type")
15135 (cond [(match_operand:DF 3 "mult_operator" "")
15136 (const_string "fmul")
15137 (match_operand:DF 3 "div_operator" "")
15138 (const_string "fdiv")
15140 (const_string "fop")))
15141 (set_attr "mode" "SF")])
15143 (define_insn "*fop_df_6_i387"
15144 [(set (match_operand:DF 0 "register_operand" "=f,f")
15145 (match_operator:DF 3 "binary_fp_operator"
15147 (match_operand:SF 1 "register_operand" "0,f"))
15149 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15150 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15151 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15152 "* return output_387_binary_op (insn, operands);"
15153 [(set (attr "type")
15154 (cond [(match_operand:DF 3 "mult_operator" "")
15155 (const_string "fmul")
15156 (match_operand:DF 3 "div_operator" "")
15157 (const_string "fdiv")
15159 (const_string "fop")))
15160 (set_attr "mode" "SF")])
15162 (define_insn "*fop_xf_comm_i387"
15163 [(set (match_operand:XF 0 "register_operand" "=f")
15164 (match_operator:XF 3 "binary_fp_operator"
15165 [(match_operand:XF 1 "register_operand" "%0")
15166 (match_operand:XF 2 "register_operand" "f")]))]
15168 && COMMUTATIVE_ARITH_P (operands[3])"
15169 "* return output_387_binary_op (insn, operands);"
15170 [(set (attr "type")
15171 (if_then_else (match_operand:XF 3 "mult_operator" "")
15172 (const_string "fmul")
15173 (const_string "fop")))
15174 (set_attr "mode" "XF")])
15176 (define_insn "*fop_xf_1_i387"
15177 [(set (match_operand:XF 0 "register_operand" "=f,f")
15178 (match_operator:XF 3 "binary_fp_operator"
15179 [(match_operand:XF 1 "register_operand" "0,f")
15180 (match_operand:XF 2 "register_operand" "f,0")]))]
15182 && !COMMUTATIVE_ARITH_P (operands[3])"
15183 "* return output_387_binary_op (insn, operands);"
15184 [(set (attr "type")
15185 (cond [(match_operand:XF 3 "mult_operator" "")
15186 (const_string "fmul")
15187 (match_operand:XF 3 "div_operator" "")
15188 (const_string "fdiv")
15190 (const_string "fop")))
15191 (set_attr "mode" "XF")])
15193 (define_insn "*fop_xf_2_i387"
15194 [(set (match_operand:XF 0 "register_operand" "=f,f")
15195 (match_operator:XF 3 "binary_fp_operator"
15197 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15198 (match_operand:XF 2 "register_operand" "0,0")]))]
15199 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15200 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15201 [(set (attr "type")
15202 (cond [(match_operand:XF 3 "mult_operator" "")
15203 (const_string "fmul")
15204 (match_operand:XF 3 "div_operator" "")
15205 (const_string "fdiv")
15207 (const_string "fop")))
15208 (set_attr "fp_int_src" "true")
15209 (set_attr "mode" "<MODE>")])
15211 (define_insn "*fop_xf_3_i387"
15212 [(set (match_operand:XF 0 "register_operand" "=f,f")
15213 (match_operator:XF 3 "binary_fp_operator"
15214 [(match_operand:XF 1 "register_operand" "0,0")
15216 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15217 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15218 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15219 [(set (attr "type")
15220 (cond [(match_operand:XF 3 "mult_operator" "")
15221 (const_string "fmul")
15222 (match_operand:XF 3 "div_operator" "")
15223 (const_string "fdiv")
15225 (const_string "fop")))
15226 (set_attr "fp_int_src" "true")
15227 (set_attr "mode" "<MODE>")])
15229 (define_insn "*fop_xf_4_i387"
15230 [(set (match_operand:XF 0 "register_operand" "=f,f")
15231 (match_operator:XF 3 "binary_fp_operator"
15233 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15234 (match_operand:XF 2 "register_operand" "0,f")]))]
15236 "* return output_387_binary_op (insn, operands);"
15237 [(set (attr "type")
15238 (cond [(match_operand:XF 3 "mult_operator" "")
15239 (const_string "fmul")
15240 (match_operand:XF 3 "div_operator" "")
15241 (const_string "fdiv")
15243 (const_string "fop")))
15244 (set_attr "mode" "<MODE>")])
15246 (define_insn "*fop_xf_5_i387"
15247 [(set (match_operand:XF 0 "register_operand" "=f,f")
15248 (match_operator:XF 3 "binary_fp_operator"
15249 [(match_operand:XF 1 "register_operand" "0,f")
15251 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15253 "* return output_387_binary_op (insn, operands);"
15254 [(set (attr "type")
15255 (cond [(match_operand:XF 3 "mult_operator" "")
15256 (const_string "fmul")
15257 (match_operand:XF 3 "div_operator" "")
15258 (const_string "fdiv")
15260 (const_string "fop")))
15261 (set_attr "mode" "<MODE>")])
15263 (define_insn "*fop_xf_6_i387"
15264 [(set (match_operand:XF 0 "register_operand" "=f,f")
15265 (match_operator:XF 3 "binary_fp_operator"
15267 (match_operand:MODEF 1 "register_operand" "0,f"))
15269 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15271 "* return output_387_binary_op (insn, operands);"
15272 [(set (attr "type")
15273 (cond [(match_operand:XF 3 "mult_operator" "")
15274 (const_string "fmul")
15275 (match_operand:XF 3 "div_operator" "")
15276 (const_string "fdiv")
15278 (const_string "fop")))
15279 (set_attr "mode" "<MODE>")])
15282 [(set (match_operand 0 "register_operand" "")
15283 (match_operator 3 "binary_fp_operator"
15284 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15285 (match_operand 2 "register_operand" "")]))]
15287 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15288 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15291 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15292 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15293 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15294 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15295 GET_MODE (operands[3]),
15298 ix86_free_from_memory (GET_MODE (operands[1]));
15303 [(set (match_operand 0 "register_operand" "")
15304 (match_operator 3 "binary_fp_operator"
15305 [(match_operand 1 "register_operand" "")
15306 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15308 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15309 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15312 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15313 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15314 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15315 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15316 GET_MODE (operands[3]),
15319 ix86_free_from_memory (GET_MODE (operands[2]));
15323 ;; FPU special functions.
15325 ;; This pattern implements a no-op XFmode truncation for
15326 ;; all fancy i386 XFmode math functions.
15328 (define_insn "truncxf<mode>2_i387_noop_unspec"
15329 [(set (match_operand:MODEF 0 "register_operand" "=f")
15330 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15331 UNSPEC_TRUNC_NOOP))]
15332 "TARGET_USE_FANCY_MATH_387"
15333 "* return output_387_reg_move (insn, operands);"
15334 [(set_attr "type" "fmov")
15335 (set_attr "mode" "<MODE>")])
15337 (define_insn "sqrtxf2"
15338 [(set (match_operand:XF 0 "register_operand" "=f")
15339 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15340 "TARGET_USE_FANCY_MATH_387"
15342 [(set_attr "type" "fpspc")
15343 (set_attr "mode" "XF")
15344 (set_attr "athlon_decode" "direct")
15345 (set_attr "amdfam10_decode" "direct")])
15347 (define_insn "sqrt_extend<mode>xf2_i387"
15348 [(set (match_operand:XF 0 "register_operand" "=f")
15351 (match_operand:MODEF 1 "register_operand" "0"))))]
15352 "TARGET_USE_FANCY_MATH_387"
15354 [(set_attr "type" "fpspc")
15355 (set_attr "mode" "XF")
15356 (set_attr "athlon_decode" "direct")
15357 (set_attr "amdfam10_decode" "direct")])
15359 (define_insn "*rsqrtsf2_sse"
15360 [(set (match_operand:SF 0 "register_operand" "=x")
15361 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15364 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15365 [(set_attr "type" "sse")
15366 (set_attr "atom_sse_attr" "rcp")
15367 (set_attr "prefix" "maybe_vex")
15368 (set_attr "mode" "SF")])
15370 (define_expand "rsqrtsf2"
15371 [(set (match_operand:SF 0 "register_operand" "")
15372 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15376 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15380 (define_insn "*sqrt<mode>2_sse"
15381 [(set (match_operand:MODEF 0 "register_operand" "=x")
15383 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15384 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15385 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15386 [(set_attr "type" "sse")
15387 (set_attr "atom_sse_attr" "sqrt")
15388 (set_attr "prefix" "maybe_vex")
15389 (set_attr "mode" "<MODE>")
15390 (set_attr "athlon_decode" "*")
15391 (set_attr "amdfam10_decode" "*")])
15393 (define_expand "sqrt<mode>2"
15394 [(set (match_operand:MODEF 0 "register_operand" "")
15396 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15397 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15398 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15400 if (<MODE>mode == SFmode
15401 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15402 && flag_finite_math_only && !flag_trapping_math
15403 && flag_unsafe_math_optimizations)
15405 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15409 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15411 rtx op0 = gen_reg_rtx (XFmode);
15412 rtx op1 = force_reg (<MODE>mode, operands[1]);
15414 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15415 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15420 (define_insn "fpremxf4_i387"
15421 [(set (match_operand:XF 0 "register_operand" "=f")
15422 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15423 (match_operand:XF 3 "register_operand" "1")]
15425 (set (match_operand:XF 1 "register_operand" "=u")
15426 (unspec:XF [(match_dup 2) (match_dup 3)]
15428 (set (reg:CCFP FPSR_REG)
15429 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15431 "TARGET_USE_FANCY_MATH_387"
15433 [(set_attr "type" "fpspc")
15434 (set_attr "mode" "XF")])
15436 (define_expand "fmodxf3"
15437 [(use (match_operand:XF 0 "register_operand" ""))
15438 (use (match_operand:XF 1 "general_operand" ""))
15439 (use (match_operand:XF 2 "general_operand" ""))]
15440 "TARGET_USE_FANCY_MATH_387"
15442 rtx label = gen_label_rtx ();
15444 rtx op1 = gen_reg_rtx (XFmode);
15445 rtx op2 = gen_reg_rtx (XFmode);
15447 emit_move_insn (op2, operands[2]);
15448 emit_move_insn (op1, operands[1]);
15450 emit_label (label);
15451 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15452 ix86_emit_fp_unordered_jump (label);
15453 LABEL_NUSES (label) = 1;
15455 emit_move_insn (operands[0], op1);
15459 (define_expand "fmod<mode>3"
15460 [(use (match_operand:MODEF 0 "register_operand" ""))
15461 (use (match_operand:MODEF 1 "general_operand" ""))
15462 (use (match_operand:MODEF 2 "general_operand" ""))]
15463 "TARGET_USE_FANCY_MATH_387"
15465 rtx label = gen_label_rtx ();
15467 rtx op1 = gen_reg_rtx (XFmode);
15468 rtx op2 = gen_reg_rtx (XFmode);
15470 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15471 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15473 emit_label (label);
15474 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15475 ix86_emit_fp_unordered_jump (label);
15476 LABEL_NUSES (label) = 1;
15478 /* Truncate the result properly for strict SSE math. */
15479 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15480 && !TARGET_MIX_SSE_I387)
15481 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15483 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15488 (define_insn "fprem1xf4_i387"
15489 [(set (match_operand:XF 0 "register_operand" "=f")
15490 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15491 (match_operand:XF 3 "register_operand" "1")]
15493 (set (match_operand:XF 1 "register_operand" "=u")
15494 (unspec:XF [(match_dup 2) (match_dup 3)]
15496 (set (reg:CCFP FPSR_REG)
15497 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15499 "TARGET_USE_FANCY_MATH_387"
15501 [(set_attr "type" "fpspc")
15502 (set_attr "mode" "XF")])
15504 (define_expand "remainderxf3"
15505 [(use (match_operand:XF 0 "register_operand" ""))
15506 (use (match_operand:XF 1 "general_operand" ""))
15507 (use (match_operand:XF 2 "general_operand" ""))]
15508 "TARGET_USE_FANCY_MATH_387"
15510 rtx label = gen_label_rtx ();
15512 rtx op1 = gen_reg_rtx (XFmode);
15513 rtx op2 = gen_reg_rtx (XFmode);
15515 emit_move_insn (op2, operands[2]);
15516 emit_move_insn (op1, operands[1]);
15518 emit_label (label);
15519 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15520 ix86_emit_fp_unordered_jump (label);
15521 LABEL_NUSES (label) = 1;
15523 emit_move_insn (operands[0], op1);
15527 (define_expand "remainder<mode>3"
15528 [(use (match_operand:MODEF 0 "register_operand" ""))
15529 (use (match_operand:MODEF 1 "general_operand" ""))
15530 (use (match_operand:MODEF 2 "general_operand" ""))]
15531 "TARGET_USE_FANCY_MATH_387"
15533 rtx label = gen_label_rtx ();
15535 rtx op1 = gen_reg_rtx (XFmode);
15536 rtx op2 = gen_reg_rtx (XFmode);
15538 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15539 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15541 emit_label (label);
15543 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15544 ix86_emit_fp_unordered_jump (label);
15545 LABEL_NUSES (label) = 1;
15547 /* Truncate the result properly for strict SSE math. */
15548 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15549 && !TARGET_MIX_SSE_I387)
15550 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15552 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15557 (define_insn "*sinxf2_i387"
15558 [(set (match_operand:XF 0 "register_operand" "=f")
15559 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15560 "TARGET_USE_FANCY_MATH_387
15561 && flag_unsafe_math_optimizations"
15563 [(set_attr "type" "fpspc")
15564 (set_attr "mode" "XF")])
15566 (define_insn "*sin_extend<mode>xf2_i387"
15567 [(set (match_operand:XF 0 "register_operand" "=f")
15568 (unspec:XF [(float_extend:XF
15569 (match_operand:MODEF 1 "register_operand" "0"))]
15571 "TARGET_USE_FANCY_MATH_387
15572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15573 || TARGET_MIX_SSE_I387)
15574 && flag_unsafe_math_optimizations"
15576 [(set_attr "type" "fpspc")
15577 (set_attr "mode" "XF")])
15579 (define_insn "*cosxf2_i387"
15580 [(set (match_operand:XF 0 "register_operand" "=f")
15581 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && flag_unsafe_math_optimizations"
15585 [(set_attr "type" "fpspc")
15586 (set_attr "mode" "XF")])
15588 (define_insn "*cos_extend<mode>xf2_i387"
15589 [(set (match_operand:XF 0 "register_operand" "=f")
15590 (unspec:XF [(float_extend:XF
15591 (match_operand:MODEF 1 "register_operand" "0"))]
15593 "TARGET_USE_FANCY_MATH_387
15594 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15595 || TARGET_MIX_SSE_I387)
15596 && flag_unsafe_math_optimizations"
15598 [(set_attr "type" "fpspc")
15599 (set_attr "mode" "XF")])
15601 ;; When sincos pattern is defined, sin and cos builtin functions will be
15602 ;; expanded to sincos pattern with one of its outputs left unused.
15603 ;; CSE pass will figure out if two sincos patterns can be combined,
15604 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15605 ;; depending on the unused output.
15607 (define_insn "sincosxf3"
15608 [(set (match_operand:XF 0 "register_operand" "=f")
15609 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15610 UNSPEC_SINCOS_COS))
15611 (set (match_operand:XF 1 "register_operand" "=u")
15612 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15613 "TARGET_USE_FANCY_MATH_387
15614 && flag_unsafe_math_optimizations"
15616 [(set_attr "type" "fpspc")
15617 (set_attr "mode" "XF")])
15620 [(set (match_operand:XF 0 "register_operand" "")
15621 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15622 UNSPEC_SINCOS_COS))
15623 (set (match_operand:XF 1 "register_operand" "")
15624 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15625 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15626 && !(reload_completed || reload_in_progress)"
15627 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15631 [(set (match_operand:XF 0 "register_operand" "")
15632 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15633 UNSPEC_SINCOS_COS))
15634 (set (match_operand:XF 1 "register_operand" "")
15635 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15636 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15637 && !(reload_completed || reload_in_progress)"
15638 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15641 (define_insn "sincos_extend<mode>xf3_i387"
15642 [(set (match_operand:XF 0 "register_operand" "=f")
15643 (unspec:XF [(float_extend:XF
15644 (match_operand:MODEF 2 "register_operand" "0"))]
15645 UNSPEC_SINCOS_COS))
15646 (set (match_operand:XF 1 "register_operand" "=u")
15647 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15648 "TARGET_USE_FANCY_MATH_387
15649 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15650 || TARGET_MIX_SSE_I387)
15651 && flag_unsafe_math_optimizations"
15653 [(set_attr "type" "fpspc")
15654 (set_attr "mode" "XF")])
15657 [(set (match_operand:XF 0 "register_operand" "")
15658 (unspec:XF [(float_extend:XF
15659 (match_operand:MODEF 2 "register_operand" ""))]
15660 UNSPEC_SINCOS_COS))
15661 (set (match_operand:XF 1 "register_operand" "")
15662 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15663 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15664 && !(reload_completed || reload_in_progress)"
15665 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15669 [(set (match_operand:XF 0 "register_operand" "")
15670 (unspec:XF [(float_extend:XF
15671 (match_operand:MODEF 2 "register_operand" ""))]
15672 UNSPEC_SINCOS_COS))
15673 (set (match_operand:XF 1 "register_operand" "")
15674 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15675 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15676 && !(reload_completed || reload_in_progress)"
15677 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15680 (define_expand "sincos<mode>3"
15681 [(use (match_operand:MODEF 0 "register_operand" ""))
15682 (use (match_operand:MODEF 1 "register_operand" ""))
15683 (use (match_operand:MODEF 2 "register_operand" ""))]
15684 "TARGET_USE_FANCY_MATH_387
15685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15686 || TARGET_MIX_SSE_I387)
15687 && flag_unsafe_math_optimizations"
15689 rtx op0 = gen_reg_rtx (XFmode);
15690 rtx op1 = gen_reg_rtx (XFmode);
15692 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15693 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15694 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15698 (define_insn "fptanxf4_i387"
15699 [(set (match_operand:XF 0 "register_operand" "=f")
15700 (match_operand:XF 3 "const_double_operand" "F"))
15701 (set (match_operand:XF 1 "register_operand" "=u")
15702 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15704 "TARGET_USE_FANCY_MATH_387
15705 && flag_unsafe_math_optimizations
15706 && standard_80387_constant_p (operands[3]) == 2"
15708 [(set_attr "type" "fpspc")
15709 (set_attr "mode" "XF")])
15711 (define_insn "fptan_extend<mode>xf4_i387"
15712 [(set (match_operand:MODEF 0 "register_operand" "=f")
15713 (match_operand:MODEF 3 "const_double_operand" "F"))
15714 (set (match_operand:XF 1 "register_operand" "=u")
15715 (unspec:XF [(float_extend:XF
15716 (match_operand:MODEF 2 "register_operand" "0"))]
15718 "TARGET_USE_FANCY_MATH_387
15719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15720 || TARGET_MIX_SSE_I387)
15721 && flag_unsafe_math_optimizations
15722 && standard_80387_constant_p (operands[3]) == 2"
15724 [(set_attr "type" "fpspc")
15725 (set_attr "mode" "XF")])
15727 (define_expand "tanxf2"
15728 [(use (match_operand:XF 0 "register_operand" ""))
15729 (use (match_operand:XF 1 "register_operand" ""))]
15730 "TARGET_USE_FANCY_MATH_387
15731 && flag_unsafe_math_optimizations"
15733 rtx one = gen_reg_rtx (XFmode);
15734 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15736 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15740 (define_expand "tan<mode>2"
15741 [(use (match_operand:MODEF 0 "register_operand" ""))
15742 (use (match_operand:MODEF 1 "register_operand" ""))]
15743 "TARGET_USE_FANCY_MATH_387
15744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15745 || TARGET_MIX_SSE_I387)
15746 && flag_unsafe_math_optimizations"
15748 rtx op0 = gen_reg_rtx (XFmode);
15750 rtx one = gen_reg_rtx (<MODE>mode);
15751 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15753 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15754 operands[1], op2));
15755 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15759 (define_insn "*fpatanxf3_i387"
15760 [(set (match_operand:XF 0 "register_operand" "=f")
15761 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15762 (match_operand:XF 2 "register_operand" "u")]
15764 (clobber (match_scratch:XF 3 "=2"))]
15765 "TARGET_USE_FANCY_MATH_387
15766 && flag_unsafe_math_optimizations"
15768 [(set_attr "type" "fpspc")
15769 (set_attr "mode" "XF")])
15771 (define_insn "fpatan_extend<mode>xf3_i387"
15772 [(set (match_operand:XF 0 "register_operand" "=f")
15773 (unspec:XF [(float_extend:XF
15774 (match_operand:MODEF 1 "register_operand" "0"))
15776 (match_operand:MODEF 2 "register_operand" "u"))]
15778 (clobber (match_scratch:XF 3 "=2"))]
15779 "TARGET_USE_FANCY_MATH_387
15780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15781 || TARGET_MIX_SSE_I387)
15782 && flag_unsafe_math_optimizations"
15784 [(set_attr "type" "fpspc")
15785 (set_attr "mode" "XF")])
15787 (define_expand "atan2xf3"
15788 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15789 (unspec:XF [(match_operand:XF 2 "register_operand" "")
15790 (match_operand:XF 1 "register_operand" "")]
15792 (clobber (match_scratch:XF 3 ""))])]
15793 "TARGET_USE_FANCY_MATH_387
15794 && flag_unsafe_math_optimizations"
15797 (define_expand "atan2<mode>3"
15798 [(use (match_operand:MODEF 0 "register_operand" ""))
15799 (use (match_operand:MODEF 1 "register_operand" ""))
15800 (use (match_operand:MODEF 2 "register_operand" ""))]
15801 "TARGET_USE_FANCY_MATH_387
15802 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15803 || TARGET_MIX_SSE_I387)
15804 && flag_unsafe_math_optimizations"
15806 rtx op0 = gen_reg_rtx (XFmode);
15808 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15809 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15813 (define_expand "atanxf2"
15814 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15815 (unspec:XF [(match_dup 2)
15816 (match_operand:XF 1 "register_operand" "")]
15818 (clobber (match_scratch:XF 3 ""))])]
15819 "TARGET_USE_FANCY_MATH_387
15820 && flag_unsafe_math_optimizations"
15822 operands[2] = gen_reg_rtx (XFmode);
15823 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15826 (define_expand "atan<mode>2"
15827 [(use (match_operand:MODEF 0 "register_operand" ""))
15828 (use (match_operand:MODEF 1 "register_operand" ""))]
15829 "TARGET_USE_FANCY_MATH_387
15830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15831 || TARGET_MIX_SSE_I387)
15832 && flag_unsafe_math_optimizations"
15834 rtx op0 = gen_reg_rtx (XFmode);
15836 rtx op2 = gen_reg_rtx (<MODE>mode);
15837 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15839 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15840 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15844 (define_expand "asinxf2"
15845 [(set (match_dup 2)
15846 (mult:XF (match_operand:XF 1 "register_operand" "")
15848 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15849 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15850 (parallel [(set (match_operand:XF 0 "register_operand" "")
15851 (unspec:XF [(match_dup 5) (match_dup 1)]
15853 (clobber (match_scratch:XF 6 ""))])]
15854 "TARGET_USE_FANCY_MATH_387
15855 && flag_unsafe_math_optimizations"
15859 if (optimize_insn_for_size_p ())
15862 for (i = 2; i < 6; i++)
15863 operands[i] = gen_reg_rtx (XFmode);
15865 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15868 (define_expand "asin<mode>2"
15869 [(use (match_operand:MODEF 0 "register_operand" ""))
15870 (use (match_operand:MODEF 1 "general_operand" ""))]
15871 "TARGET_USE_FANCY_MATH_387
15872 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15873 || TARGET_MIX_SSE_I387)
15874 && flag_unsafe_math_optimizations"
15876 rtx op0 = gen_reg_rtx (XFmode);
15877 rtx op1 = gen_reg_rtx (XFmode);
15879 if (optimize_insn_for_size_p ())
15882 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15883 emit_insn (gen_asinxf2 (op0, op1));
15884 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15888 (define_expand "acosxf2"
15889 [(set (match_dup 2)
15890 (mult:XF (match_operand:XF 1 "register_operand" "")
15892 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15893 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15894 (parallel [(set (match_operand:XF 0 "register_operand" "")
15895 (unspec:XF [(match_dup 1) (match_dup 5)]
15897 (clobber (match_scratch:XF 6 ""))])]
15898 "TARGET_USE_FANCY_MATH_387
15899 && flag_unsafe_math_optimizations"
15903 if (optimize_insn_for_size_p ())
15906 for (i = 2; i < 6; i++)
15907 operands[i] = gen_reg_rtx (XFmode);
15909 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15912 (define_expand "acos<mode>2"
15913 [(use (match_operand:MODEF 0 "register_operand" ""))
15914 (use (match_operand:MODEF 1 "general_operand" ""))]
15915 "TARGET_USE_FANCY_MATH_387
15916 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15917 || TARGET_MIX_SSE_I387)
15918 && flag_unsafe_math_optimizations"
15920 rtx op0 = gen_reg_rtx (XFmode);
15921 rtx op1 = gen_reg_rtx (XFmode);
15923 if (optimize_insn_for_size_p ())
15926 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15927 emit_insn (gen_acosxf2 (op0, op1));
15928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15932 (define_insn "fyl2xxf3_i387"
15933 [(set (match_operand:XF 0 "register_operand" "=f")
15934 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15935 (match_operand:XF 2 "register_operand" "u")]
15937 (clobber (match_scratch:XF 3 "=2"))]
15938 "TARGET_USE_FANCY_MATH_387
15939 && flag_unsafe_math_optimizations"
15941 [(set_attr "type" "fpspc")
15942 (set_attr "mode" "XF")])
15944 (define_insn "fyl2x_extend<mode>xf3_i387"
15945 [(set (match_operand:XF 0 "register_operand" "=f")
15946 (unspec:XF [(float_extend:XF
15947 (match_operand:MODEF 1 "register_operand" "0"))
15948 (match_operand:XF 2 "register_operand" "u")]
15950 (clobber (match_scratch:XF 3 "=2"))]
15951 "TARGET_USE_FANCY_MATH_387
15952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15953 || TARGET_MIX_SSE_I387)
15954 && flag_unsafe_math_optimizations"
15956 [(set_attr "type" "fpspc")
15957 (set_attr "mode" "XF")])
15959 (define_expand "logxf2"
15960 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15961 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15962 (match_dup 2)] UNSPEC_FYL2X))
15963 (clobber (match_scratch:XF 3 ""))])]
15964 "TARGET_USE_FANCY_MATH_387
15965 && flag_unsafe_math_optimizations"
15967 operands[2] = gen_reg_rtx (XFmode);
15968 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15971 (define_expand "log<mode>2"
15972 [(use (match_operand:MODEF 0 "register_operand" ""))
15973 (use (match_operand:MODEF 1 "register_operand" ""))]
15974 "TARGET_USE_FANCY_MATH_387
15975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15976 || TARGET_MIX_SSE_I387)
15977 && flag_unsafe_math_optimizations"
15979 rtx op0 = gen_reg_rtx (XFmode);
15981 rtx op2 = gen_reg_rtx (XFmode);
15982 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15984 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15985 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15989 (define_expand "log10xf2"
15990 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15991 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15992 (match_dup 2)] UNSPEC_FYL2X))
15993 (clobber (match_scratch:XF 3 ""))])]
15994 "TARGET_USE_FANCY_MATH_387
15995 && flag_unsafe_math_optimizations"
15997 operands[2] = gen_reg_rtx (XFmode);
15998 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16001 (define_expand "log10<mode>2"
16002 [(use (match_operand:MODEF 0 "register_operand" ""))
16003 (use (match_operand:MODEF 1 "register_operand" ""))]
16004 "TARGET_USE_FANCY_MATH_387
16005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16006 || TARGET_MIX_SSE_I387)
16007 && flag_unsafe_math_optimizations"
16009 rtx op0 = gen_reg_rtx (XFmode);
16011 rtx op2 = gen_reg_rtx (XFmode);
16012 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16014 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16015 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16019 (define_expand "log2xf2"
16020 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16021 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16022 (match_dup 2)] UNSPEC_FYL2X))
16023 (clobber (match_scratch:XF 3 ""))])]
16024 "TARGET_USE_FANCY_MATH_387
16025 && flag_unsafe_math_optimizations"
16027 operands[2] = gen_reg_rtx (XFmode);
16028 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16031 (define_expand "log2<mode>2"
16032 [(use (match_operand:MODEF 0 "register_operand" ""))
16033 (use (match_operand:MODEF 1 "register_operand" ""))]
16034 "TARGET_USE_FANCY_MATH_387
16035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16036 || TARGET_MIX_SSE_I387)
16037 && flag_unsafe_math_optimizations"
16039 rtx op0 = gen_reg_rtx (XFmode);
16041 rtx op2 = gen_reg_rtx (XFmode);
16042 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16044 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16045 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16049 (define_insn "fyl2xp1xf3_i387"
16050 [(set (match_operand:XF 0 "register_operand" "=f")
16051 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16052 (match_operand:XF 2 "register_operand" "u")]
16054 (clobber (match_scratch:XF 3 "=2"))]
16055 "TARGET_USE_FANCY_MATH_387
16056 && flag_unsafe_math_optimizations"
16058 [(set_attr "type" "fpspc")
16059 (set_attr "mode" "XF")])
16061 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16062 [(set (match_operand:XF 0 "register_operand" "=f")
16063 (unspec:XF [(float_extend:XF
16064 (match_operand:MODEF 1 "register_operand" "0"))
16065 (match_operand:XF 2 "register_operand" "u")]
16067 (clobber (match_scratch:XF 3 "=2"))]
16068 "TARGET_USE_FANCY_MATH_387
16069 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16070 || TARGET_MIX_SSE_I387)
16071 && flag_unsafe_math_optimizations"
16073 [(set_attr "type" "fpspc")
16074 (set_attr "mode" "XF")])
16076 (define_expand "log1pxf2"
16077 [(use (match_operand:XF 0 "register_operand" ""))
16078 (use (match_operand:XF 1 "register_operand" ""))]
16079 "TARGET_USE_FANCY_MATH_387
16080 && flag_unsafe_math_optimizations"
16082 if (optimize_insn_for_size_p ())
16085 ix86_emit_i387_log1p (operands[0], operands[1]);
16089 (define_expand "log1p<mode>2"
16090 [(use (match_operand:MODEF 0 "register_operand" ""))
16091 (use (match_operand:MODEF 1 "register_operand" ""))]
16092 "TARGET_USE_FANCY_MATH_387
16093 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16094 || TARGET_MIX_SSE_I387)
16095 && flag_unsafe_math_optimizations"
16099 if (optimize_insn_for_size_p ())
16102 op0 = gen_reg_rtx (XFmode);
16104 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16106 ix86_emit_i387_log1p (op0, operands[1]);
16107 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16111 (define_insn "fxtractxf3_i387"
16112 [(set (match_operand:XF 0 "register_operand" "=f")
16113 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16114 UNSPEC_XTRACT_FRACT))
16115 (set (match_operand:XF 1 "register_operand" "=u")
16116 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16117 "TARGET_USE_FANCY_MATH_387
16118 && flag_unsafe_math_optimizations"
16120 [(set_attr "type" "fpspc")
16121 (set_attr "mode" "XF")])
16123 (define_insn "fxtract_extend<mode>xf3_i387"
16124 [(set (match_operand:XF 0 "register_operand" "=f")
16125 (unspec:XF [(float_extend:XF
16126 (match_operand:MODEF 2 "register_operand" "0"))]
16127 UNSPEC_XTRACT_FRACT))
16128 (set (match_operand:XF 1 "register_operand" "=u")
16129 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16130 "TARGET_USE_FANCY_MATH_387
16131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16132 || TARGET_MIX_SSE_I387)
16133 && flag_unsafe_math_optimizations"
16135 [(set_attr "type" "fpspc")
16136 (set_attr "mode" "XF")])
16138 (define_expand "logbxf2"
16139 [(parallel [(set (match_dup 2)
16140 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16141 UNSPEC_XTRACT_FRACT))
16142 (set (match_operand:XF 0 "register_operand" "")
16143 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16144 "TARGET_USE_FANCY_MATH_387
16145 && flag_unsafe_math_optimizations"
16147 operands[2] = gen_reg_rtx (XFmode);
16150 (define_expand "logb<mode>2"
16151 [(use (match_operand:MODEF 0 "register_operand" ""))
16152 (use (match_operand:MODEF 1 "register_operand" ""))]
16153 "TARGET_USE_FANCY_MATH_387
16154 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16155 || TARGET_MIX_SSE_I387)
16156 && flag_unsafe_math_optimizations"
16158 rtx op0 = gen_reg_rtx (XFmode);
16159 rtx op1 = gen_reg_rtx (XFmode);
16161 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16162 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16166 (define_expand "ilogbxf2"
16167 [(use (match_operand:SI 0 "register_operand" ""))
16168 (use (match_operand:XF 1 "register_operand" ""))]
16169 "TARGET_USE_FANCY_MATH_387
16170 && flag_unsafe_math_optimizations"
16174 if (optimize_insn_for_size_p ())
16177 op0 = gen_reg_rtx (XFmode);
16178 op1 = gen_reg_rtx (XFmode);
16180 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16181 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16185 (define_expand "ilogb<mode>2"
16186 [(use (match_operand:SI 0 "register_operand" ""))
16187 (use (match_operand:MODEF 1 "register_operand" ""))]
16188 "TARGET_USE_FANCY_MATH_387
16189 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16190 || TARGET_MIX_SSE_I387)
16191 && flag_unsafe_math_optimizations"
16195 if (optimize_insn_for_size_p ())
16198 op0 = gen_reg_rtx (XFmode);
16199 op1 = gen_reg_rtx (XFmode);
16201 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16202 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16206 (define_insn "*f2xm1xf2_i387"
16207 [(set (match_operand:XF 0 "register_operand" "=f")
16208 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16210 "TARGET_USE_FANCY_MATH_387
16211 && flag_unsafe_math_optimizations"
16213 [(set_attr "type" "fpspc")
16214 (set_attr "mode" "XF")])
16216 (define_insn "*fscalexf4_i387"
16217 [(set (match_operand:XF 0 "register_operand" "=f")
16218 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16219 (match_operand:XF 3 "register_operand" "1")]
16220 UNSPEC_FSCALE_FRACT))
16221 (set (match_operand:XF 1 "register_operand" "=u")
16222 (unspec:XF [(match_dup 2) (match_dup 3)]
16223 UNSPEC_FSCALE_EXP))]
16224 "TARGET_USE_FANCY_MATH_387
16225 && flag_unsafe_math_optimizations"
16227 [(set_attr "type" "fpspc")
16228 (set_attr "mode" "XF")])
16230 (define_expand "expNcorexf3"
16231 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16232 (match_operand:XF 2 "register_operand" "")))
16233 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16234 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16235 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16236 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16237 (parallel [(set (match_operand:XF 0 "register_operand" "")
16238 (unspec:XF [(match_dup 8) (match_dup 4)]
16239 UNSPEC_FSCALE_FRACT))
16241 (unspec:XF [(match_dup 8) (match_dup 4)]
16242 UNSPEC_FSCALE_EXP))])]
16243 "TARGET_USE_FANCY_MATH_387
16244 && flag_unsafe_math_optimizations"
16248 if (optimize_insn_for_size_p ())
16251 for (i = 3; i < 10; i++)
16252 operands[i] = gen_reg_rtx (XFmode);
16254 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16257 (define_expand "expxf2"
16258 [(use (match_operand:XF 0 "register_operand" ""))
16259 (use (match_operand:XF 1 "register_operand" ""))]
16260 "TARGET_USE_FANCY_MATH_387
16261 && flag_unsafe_math_optimizations"
16265 if (optimize_insn_for_size_p ())
16268 op2 = gen_reg_rtx (XFmode);
16269 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16271 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16275 (define_expand "exp<mode>2"
16276 [(use (match_operand:MODEF 0 "register_operand" ""))
16277 (use (match_operand:MODEF 1 "general_operand" ""))]
16278 "TARGET_USE_FANCY_MATH_387
16279 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16280 || TARGET_MIX_SSE_I387)
16281 && flag_unsafe_math_optimizations"
16285 if (optimize_insn_for_size_p ())
16288 op0 = gen_reg_rtx (XFmode);
16289 op1 = gen_reg_rtx (XFmode);
16291 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16292 emit_insn (gen_expxf2 (op0, op1));
16293 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16297 (define_expand "exp10xf2"
16298 [(use (match_operand:XF 0 "register_operand" ""))
16299 (use (match_operand:XF 1 "register_operand" ""))]
16300 "TARGET_USE_FANCY_MATH_387
16301 && flag_unsafe_math_optimizations"
16305 if (optimize_insn_for_size_p ())
16308 op2 = gen_reg_rtx (XFmode);
16309 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16311 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16315 (define_expand "exp10<mode>2"
16316 [(use (match_operand:MODEF 0 "register_operand" ""))
16317 (use (match_operand:MODEF 1 "general_operand" ""))]
16318 "TARGET_USE_FANCY_MATH_387
16319 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16320 || TARGET_MIX_SSE_I387)
16321 && flag_unsafe_math_optimizations"
16325 if (optimize_insn_for_size_p ())
16328 op0 = gen_reg_rtx (XFmode);
16329 op1 = gen_reg_rtx (XFmode);
16331 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16332 emit_insn (gen_exp10xf2 (op0, op1));
16333 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16337 (define_expand "exp2xf2"
16338 [(use (match_operand:XF 0 "register_operand" ""))
16339 (use (match_operand:XF 1 "register_operand" ""))]
16340 "TARGET_USE_FANCY_MATH_387
16341 && flag_unsafe_math_optimizations"
16345 if (optimize_insn_for_size_p ())
16348 op2 = gen_reg_rtx (XFmode);
16349 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16351 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16355 (define_expand "exp2<mode>2"
16356 [(use (match_operand:MODEF 0 "register_operand" ""))
16357 (use (match_operand:MODEF 1 "general_operand" ""))]
16358 "TARGET_USE_FANCY_MATH_387
16359 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16360 || TARGET_MIX_SSE_I387)
16361 && flag_unsafe_math_optimizations"
16365 if (optimize_insn_for_size_p ())
16368 op0 = gen_reg_rtx (XFmode);
16369 op1 = gen_reg_rtx (XFmode);
16371 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16372 emit_insn (gen_exp2xf2 (op0, op1));
16373 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16377 (define_expand "expm1xf2"
16378 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16380 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16381 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16382 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16383 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16384 (parallel [(set (match_dup 7)
16385 (unspec:XF [(match_dup 6) (match_dup 4)]
16386 UNSPEC_FSCALE_FRACT))
16388 (unspec:XF [(match_dup 6) (match_dup 4)]
16389 UNSPEC_FSCALE_EXP))])
16390 (parallel [(set (match_dup 10)
16391 (unspec:XF [(match_dup 9) (match_dup 8)]
16392 UNSPEC_FSCALE_FRACT))
16393 (set (match_dup 11)
16394 (unspec:XF [(match_dup 9) (match_dup 8)]
16395 UNSPEC_FSCALE_EXP))])
16396 (set (match_dup 12) (minus:XF (match_dup 10)
16397 (float_extend:XF (match_dup 13))))
16398 (set (match_operand:XF 0 "register_operand" "")
16399 (plus:XF (match_dup 12) (match_dup 7)))]
16400 "TARGET_USE_FANCY_MATH_387
16401 && flag_unsafe_math_optimizations"
16405 if (optimize_insn_for_size_p ())
16408 for (i = 2; i < 13; i++)
16409 operands[i] = gen_reg_rtx (XFmode);
16412 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16414 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16417 (define_expand "expm1<mode>2"
16418 [(use (match_operand:MODEF 0 "register_operand" ""))
16419 (use (match_operand:MODEF 1 "general_operand" ""))]
16420 "TARGET_USE_FANCY_MATH_387
16421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16422 || TARGET_MIX_SSE_I387)
16423 && flag_unsafe_math_optimizations"
16427 if (optimize_insn_for_size_p ())
16430 op0 = gen_reg_rtx (XFmode);
16431 op1 = gen_reg_rtx (XFmode);
16433 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16434 emit_insn (gen_expm1xf2 (op0, op1));
16435 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16439 (define_expand "ldexpxf3"
16440 [(set (match_dup 3)
16441 (float:XF (match_operand:SI 2 "register_operand" "")))
16442 (parallel [(set (match_operand:XF 0 " register_operand" "")
16443 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16445 UNSPEC_FSCALE_FRACT))
16447 (unspec:XF [(match_dup 1) (match_dup 3)]
16448 UNSPEC_FSCALE_EXP))])]
16449 "TARGET_USE_FANCY_MATH_387
16450 && flag_unsafe_math_optimizations"
16452 if (optimize_insn_for_size_p ())
16455 operands[3] = gen_reg_rtx (XFmode);
16456 operands[4] = gen_reg_rtx (XFmode);
16459 (define_expand "ldexp<mode>3"
16460 [(use (match_operand:MODEF 0 "register_operand" ""))
16461 (use (match_operand:MODEF 1 "general_operand" ""))
16462 (use (match_operand:SI 2 "register_operand" ""))]
16463 "TARGET_USE_FANCY_MATH_387
16464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16465 || TARGET_MIX_SSE_I387)
16466 && flag_unsafe_math_optimizations"
16470 if (optimize_insn_for_size_p ())
16473 op0 = gen_reg_rtx (XFmode);
16474 op1 = gen_reg_rtx (XFmode);
16476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16477 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16478 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16482 (define_expand "scalbxf3"
16483 [(parallel [(set (match_operand:XF 0 " register_operand" "")
16484 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16485 (match_operand:XF 2 "register_operand" "")]
16486 UNSPEC_FSCALE_FRACT))
16488 (unspec:XF [(match_dup 1) (match_dup 2)]
16489 UNSPEC_FSCALE_EXP))])]
16490 "TARGET_USE_FANCY_MATH_387
16491 && flag_unsafe_math_optimizations"
16493 if (optimize_insn_for_size_p ())
16496 operands[3] = gen_reg_rtx (XFmode);
16499 (define_expand "scalb<mode>3"
16500 [(use (match_operand:MODEF 0 "register_operand" ""))
16501 (use (match_operand:MODEF 1 "general_operand" ""))
16502 (use (match_operand:MODEF 2 "general_operand" ""))]
16503 "TARGET_USE_FANCY_MATH_387
16504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16505 || TARGET_MIX_SSE_I387)
16506 && flag_unsafe_math_optimizations"
16510 if (optimize_insn_for_size_p ())
16513 op0 = gen_reg_rtx (XFmode);
16514 op1 = gen_reg_rtx (XFmode);
16515 op2 = gen_reg_rtx (XFmode);
16517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16518 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16519 emit_insn (gen_scalbxf3 (op0, op1, op2));
16520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16524 (define_expand "significandxf2"
16525 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16526 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16527 UNSPEC_XTRACT_FRACT))
16529 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16530 "TARGET_USE_FANCY_MATH_387
16531 && flag_unsafe_math_optimizations"
16533 operands[2] = gen_reg_rtx (XFmode);
16536 (define_expand "significand<mode>2"
16537 [(use (match_operand:MODEF 0 "register_operand" ""))
16538 (use (match_operand:MODEF 1 "register_operand" ""))]
16539 "TARGET_USE_FANCY_MATH_387
16540 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16541 || TARGET_MIX_SSE_I387)
16542 && flag_unsafe_math_optimizations"
16544 rtx op0 = gen_reg_rtx (XFmode);
16545 rtx op1 = gen_reg_rtx (XFmode);
16547 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16548 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16553 (define_insn "sse4_1_round<mode>2"
16554 [(set (match_operand:MODEF 0 "register_operand" "=x")
16555 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16556 (match_operand:SI 2 "const_0_to_15_operand" "n")]
16559 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16560 [(set_attr "type" "ssecvt")
16561 (set_attr "prefix_extra" "1")
16562 (set_attr "prefix" "maybe_vex")
16563 (set_attr "mode" "<MODE>")])
16565 (define_insn "rintxf2"
16566 [(set (match_operand:XF 0 "register_operand" "=f")
16567 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16569 "TARGET_USE_FANCY_MATH_387
16570 && flag_unsafe_math_optimizations"
16572 [(set_attr "type" "fpspc")
16573 (set_attr "mode" "XF")])
16575 (define_expand "rint<mode>2"
16576 [(use (match_operand:MODEF 0 "register_operand" ""))
16577 (use (match_operand:MODEF 1 "register_operand" ""))]
16578 "(TARGET_USE_FANCY_MATH_387
16579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16580 || TARGET_MIX_SSE_I387)
16581 && flag_unsafe_math_optimizations)
16582 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16583 && !flag_trapping_math)"
16585 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16586 && !flag_trapping_math)
16588 if (!TARGET_ROUND && optimize_insn_for_size_p ())
16591 emit_insn (gen_sse4_1_round<mode>2
16592 (operands[0], operands[1], GEN_INT (0x04)));
16594 ix86_expand_rint (operand0, operand1);
16598 rtx op0 = gen_reg_rtx (XFmode);
16599 rtx op1 = gen_reg_rtx (XFmode);
16601 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16602 emit_insn (gen_rintxf2 (op0, op1));
16604 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16609 (define_expand "round<mode>2"
16610 [(match_operand:MODEF 0 "register_operand" "")
16611 (match_operand:MODEF 1 "nonimmediate_operand" "")]
16612 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16613 && !flag_trapping_math && !flag_rounding_math"
16615 if (optimize_insn_for_size_p ())
16617 if (TARGET_64BIT || (<MODE>mode != DFmode))
16618 ix86_expand_round (operand0, operand1);
16620 ix86_expand_rounddf_32 (operand0, operand1);
16624 (define_insn_and_split "*fistdi2_1"
16625 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16626 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16628 "TARGET_USE_FANCY_MATH_387
16629 && can_create_pseudo_p ()"
16634 if (memory_operand (operands[0], VOIDmode))
16635 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16638 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16639 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16644 [(set_attr "type" "fpspc")
16645 (set_attr "mode" "DI")])
16647 (define_insn "fistdi2"
16648 [(set (match_operand:DI 0 "memory_operand" "=m")
16649 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16651 (clobber (match_scratch:XF 2 "=&1f"))]
16652 "TARGET_USE_FANCY_MATH_387"
16653 "* return output_fix_trunc (insn, operands, 0);"
16654 [(set_attr "type" "fpspc")
16655 (set_attr "mode" "DI")])
16657 (define_insn "fistdi2_with_temp"
16658 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16659 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16661 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16662 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16663 "TARGET_USE_FANCY_MATH_387"
16665 [(set_attr "type" "fpspc")
16666 (set_attr "mode" "DI")])
16669 [(set (match_operand:DI 0 "register_operand" "")
16670 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16672 (clobber (match_operand:DI 2 "memory_operand" ""))
16673 (clobber (match_scratch 3 ""))]
16675 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16676 (clobber (match_dup 3))])
16677 (set (match_dup 0) (match_dup 2))]
16681 [(set (match_operand:DI 0 "memory_operand" "")
16682 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16684 (clobber (match_operand:DI 2 "memory_operand" ""))
16685 (clobber (match_scratch 3 ""))]
16687 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16688 (clobber (match_dup 3))])]
16691 (define_insn_and_split "*fist<mode>2_1"
16692 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16693 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16695 "TARGET_USE_FANCY_MATH_387
16696 && can_create_pseudo_p ()"
16701 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16702 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16706 [(set_attr "type" "fpspc")
16707 (set_attr "mode" "<MODE>")])
16709 (define_insn "fist<mode>2"
16710 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16711 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16713 "TARGET_USE_FANCY_MATH_387"
16714 "* return output_fix_trunc (insn, operands, 0);"
16715 [(set_attr "type" "fpspc")
16716 (set_attr "mode" "<MODE>")])
16718 (define_insn "fist<mode>2_with_temp"
16719 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16720 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16722 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16723 "TARGET_USE_FANCY_MATH_387"
16725 [(set_attr "type" "fpspc")
16726 (set_attr "mode" "<MODE>")])
16729 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16730 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16732 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16734 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16735 (set (match_dup 0) (match_dup 2))]
16739 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16740 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16742 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16744 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16747 (define_expand "lrintxf<mode>2"
16748 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16749 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16751 "TARGET_USE_FANCY_MATH_387"
16754 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16755 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16756 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16757 UNSPEC_FIX_NOTRUNC))]
16758 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16759 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16762 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16763 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16764 (match_operand:MODEF 1 "register_operand" "")]
16765 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16766 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16767 && !flag_trapping_math && !flag_rounding_math"
16769 if (optimize_insn_for_size_p ())
16771 ix86_expand_lround (operand0, operand1);
16775 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16776 (define_insn_and_split "frndintxf2_floor"
16777 [(set (match_operand:XF 0 "register_operand" "")
16778 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16779 UNSPEC_FRNDINT_FLOOR))
16780 (clobber (reg:CC FLAGS_REG))]
16781 "TARGET_USE_FANCY_MATH_387
16782 && flag_unsafe_math_optimizations
16783 && can_create_pseudo_p ()"
16788 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16790 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16791 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16793 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16794 operands[2], operands[3]));
16797 [(set_attr "type" "frndint")
16798 (set_attr "i387_cw" "floor")
16799 (set_attr "mode" "XF")])
16801 (define_insn "frndintxf2_floor_i387"
16802 [(set (match_operand:XF 0 "register_operand" "=f")
16803 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16804 UNSPEC_FRNDINT_FLOOR))
16805 (use (match_operand:HI 2 "memory_operand" "m"))
16806 (use (match_operand:HI 3 "memory_operand" "m"))]
16807 "TARGET_USE_FANCY_MATH_387
16808 && flag_unsafe_math_optimizations"
16809 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16810 [(set_attr "type" "frndint")
16811 (set_attr "i387_cw" "floor")
16812 (set_attr "mode" "XF")])
16814 (define_expand "floorxf2"
16815 [(use (match_operand:XF 0 "register_operand" ""))
16816 (use (match_operand:XF 1 "register_operand" ""))]
16817 "TARGET_USE_FANCY_MATH_387
16818 && flag_unsafe_math_optimizations"
16820 if (optimize_insn_for_size_p ())
16822 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16826 (define_expand "floor<mode>2"
16827 [(use (match_operand:MODEF 0 "register_operand" ""))
16828 (use (match_operand:MODEF 1 "register_operand" ""))]
16829 "(TARGET_USE_FANCY_MATH_387
16830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831 || TARGET_MIX_SSE_I387)
16832 && flag_unsafe_math_optimizations)
16833 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16834 && !flag_trapping_math)"
16836 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16837 && !flag_trapping_math
16838 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16840 if (!TARGET_ROUND && optimize_insn_for_size_p ())
16843 emit_insn (gen_sse4_1_round<mode>2
16844 (operands[0], operands[1], GEN_INT (0x01)));
16845 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16846 ix86_expand_floorceil (operand0, operand1, true);
16848 ix86_expand_floorceildf_32 (operand0, operand1, true);
16854 if (optimize_insn_for_size_p ())
16857 op0 = gen_reg_rtx (XFmode);
16858 op1 = gen_reg_rtx (XFmode);
16859 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16860 emit_insn (gen_frndintxf2_floor (op0, op1));
16862 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16867 (define_insn_and_split "*fist<mode>2_floor_1"
16868 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16869 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16870 UNSPEC_FIST_FLOOR))
16871 (clobber (reg:CC FLAGS_REG))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && flag_unsafe_math_optimizations
16874 && can_create_pseudo_p ()"
16879 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16881 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16882 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16883 if (memory_operand (operands[0], VOIDmode))
16884 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16885 operands[2], operands[3]));
16888 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16889 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16890 operands[2], operands[3],
16895 [(set_attr "type" "fistp")
16896 (set_attr "i387_cw" "floor")
16897 (set_attr "mode" "<MODE>")])
16899 (define_insn "fistdi2_floor"
16900 [(set (match_operand:DI 0 "memory_operand" "=m")
16901 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16902 UNSPEC_FIST_FLOOR))
16903 (use (match_operand:HI 2 "memory_operand" "m"))
16904 (use (match_operand:HI 3 "memory_operand" "m"))
16905 (clobber (match_scratch:XF 4 "=&1f"))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && flag_unsafe_math_optimizations"
16908 "* return output_fix_trunc (insn, operands, 0);"
16909 [(set_attr "type" "fistp")
16910 (set_attr "i387_cw" "floor")
16911 (set_attr "mode" "DI")])
16913 (define_insn "fistdi2_floor_with_temp"
16914 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16915 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16916 UNSPEC_FIST_FLOOR))
16917 (use (match_operand:HI 2 "memory_operand" "m,m"))
16918 (use (match_operand:HI 3 "memory_operand" "m,m"))
16919 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16920 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16921 "TARGET_USE_FANCY_MATH_387
16922 && flag_unsafe_math_optimizations"
16924 [(set_attr "type" "fistp")
16925 (set_attr "i387_cw" "floor")
16926 (set_attr "mode" "DI")])
16929 [(set (match_operand:DI 0 "register_operand" "")
16930 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16931 UNSPEC_FIST_FLOOR))
16932 (use (match_operand:HI 2 "memory_operand" ""))
16933 (use (match_operand:HI 3 "memory_operand" ""))
16934 (clobber (match_operand:DI 4 "memory_operand" ""))
16935 (clobber (match_scratch 5 ""))]
16937 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16938 (use (match_dup 2))
16939 (use (match_dup 3))
16940 (clobber (match_dup 5))])
16941 (set (match_dup 0) (match_dup 4))]
16945 [(set (match_operand:DI 0 "memory_operand" "")
16946 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16947 UNSPEC_FIST_FLOOR))
16948 (use (match_operand:HI 2 "memory_operand" ""))
16949 (use (match_operand:HI 3 "memory_operand" ""))
16950 (clobber (match_operand:DI 4 "memory_operand" ""))
16951 (clobber (match_scratch 5 ""))]
16953 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16954 (use (match_dup 2))
16955 (use (match_dup 3))
16956 (clobber (match_dup 5))])]
16959 (define_insn "fist<mode>2_floor"
16960 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16961 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16962 UNSPEC_FIST_FLOOR))
16963 (use (match_operand:HI 2 "memory_operand" "m"))
16964 (use (match_operand:HI 3 "memory_operand" "m"))]
16965 "TARGET_USE_FANCY_MATH_387
16966 && flag_unsafe_math_optimizations"
16967 "* return output_fix_trunc (insn, operands, 0);"
16968 [(set_attr "type" "fistp")
16969 (set_attr "i387_cw" "floor")
16970 (set_attr "mode" "<MODE>")])
16972 (define_insn "fist<mode>2_floor_with_temp"
16973 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16974 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16975 UNSPEC_FIST_FLOOR))
16976 (use (match_operand:HI 2 "memory_operand" "m,m"))
16977 (use (match_operand:HI 3 "memory_operand" "m,m"))
16978 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16979 "TARGET_USE_FANCY_MATH_387
16980 && flag_unsafe_math_optimizations"
16982 [(set_attr "type" "fistp")
16983 (set_attr "i387_cw" "floor")
16984 (set_attr "mode" "<MODE>")])
16987 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16988 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16989 UNSPEC_FIST_FLOOR))
16990 (use (match_operand:HI 2 "memory_operand" ""))
16991 (use (match_operand:HI 3 "memory_operand" ""))
16992 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16994 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16995 UNSPEC_FIST_FLOOR))
16996 (use (match_dup 2))
16997 (use (match_dup 3))])
16998 (set (match_dup 0) (match_dup 4))]
17002 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17003 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17004 UNSPEC_FIST_FLOOR))
17005 (use (match_operand:HI 2 "memory_operand" ""))
17006 (use (match_operand:HI 3 "memory_operand" ""))
17007 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17009 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17010 UNSPEC_FIST_FLOOR))
17011 (use (match_dup 2))
17012 (use (match_dup 3))])]
17015 (define_expand "lfloorxf<mode>2"
17016 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17017 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17018 UNSPEC_FIST_FLOOR))
17019 (clobber (reg:CC FLAGS_REG))])]
17020 "TARGET_USE_FANCY_MATH_387
17021 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17022 && flag_unsafe_math_optimizations"
17025 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17026 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17027 (match_operand:MODEF 1 "register_operand" "")]
17028 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17029 && !flag_trapping_math"
17031 if (TARGET_64BIT && optimize_insn_for_size_p ())
17033 ix86_expand_lfloorceil (operand0, operand1, true);
17037 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17038 (define_insn_and_split "frndintxf2_ceil"
17039 [(set (match_operand:XF 0 "register_operand" "")
17040 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17041 UNSPEC_FRNDINT_CEIL))
17042 (clobber (reg:CC FLAGS_REG))]
17043 "TARGET_USE_FANCY_MATH_387
17044 && flag_unsafe_math_optimizations
17045 && can_create_pseudo_p ()"
17050 ix86_optimize_mode_switching[I387_CEIL] = 1;
17052 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17053 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17055 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17056 operands[2], operands[3]));
17059 [(set_attr "type" "frndint")
17060 (set_attr "i387_cw" "ceil")
17061 (set_attr "mode" "XF")])
17063 (define_insn "frndintxf2_ceil_i387"
17064 [(set (match_operand:XF 0 "register_operand" "=f")
17065 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17066 UNSPEC_FRNDINT_CEIL))
17067 (use (match_operand:HI 2 "memory_operand" "m"))
17068 (use (match_operand:HI 3 "memory_operand" "m"))]
17069 "TARGET_USE_FANCY_MATH_387
17070 && flag_unsafe_math_optimizations"
17071 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17072 [(set_attr "type" "frndint")
17073 (set_attr "i387_cw" "ceil")
17074 (set_attr "mode" "XF")])
17076 (define_expand "ceilxf2"
17077 [(use (match_operand:XF 0 "register_operand" ""))
17078 (use (match_operand:XF 1 "register_operand" ""))]
17079 "TARGET_USE_FANCY_MATH_387
17080 && flag_unsafe_math_optimizations"
17082 if (optimize_insn_for_size_p ())
17084 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17088 (define_expand "ceil<mode>2"
17089 [(use (match_operand:MODEF 0 "register_operand" ""))
17090 (use (match_operand:MODEF 1 "register_operand" ""))]
17091 "(TARGET_USE_FANCY_MATH_387
17092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17093 || TARGET_MIX_SSE_I387)
17094 && flag_unsafe_math_optimizations)
17095 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17096 && !flag_trapping_math)"
17098 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17099 && !flag_trapping_math
17100 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17103 emit_insn (gen_sse4_1_round<mode>2
17104 (operands[0], operands[1], GEN_INT (0x02)));
17105 else if (optimize_insn_for_size_p ())
17107 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17108 ix86_expand_floorceil (operand0, operand1, false);
17110 ix86_expand_floorceildf_32 (operand0, operand1, false);
17116 if (optimize_insn_for_size_p ())
17119 op0 = gen_reg_rtx (XFmode);
17120 op1 = gen_reg_rtx (XFmode);
17121 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17122 emit_insn (gen_frndintxf2_ceil (op0, op1));
17124 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17129 (define_insn_and_split "*fist<mode>2_ceil_1"
17130 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17131 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17133 (clobber (reg:CC FLAGS_REG))]
17134 "TARGET_USE_FANCY_MATH_387
17135 && flag_unsafe_math_optimizations
17136 && can_create_pseudo_p ()"
17141 ix86_optimize_mode_switching[I387_CEIL] = 1;
17143 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17144 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17145 if (memory_operand (operands[0], VOIDmode))
17146 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17147 operands[2], operands[3]));
17150 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17151 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17152 operands[2], operands[3],
17157 [(set_attr "type" "fistp")
17158 (set_attr "i387_cw" "ceil")
17159 (set_attr "mode" "<MODE>")])
17161 (define_insn "fistdi2_ceil"
17162 [(set (match_operand:DI 0 "memory_operand" "=m")
17163 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17165 (use (match_operand:HI 2 "memory_operand" "m"))
17166 (use (match_operand:HI 3 "memory_operand" "m"))
17167 (clobber (match_scratch:XF 4 "=&1f"))]
17168 "TARGET_USE_FANCY_MATH_387
17169 && flag_unsafe_math_optimizations"
17170 "* return output_fix_trunc (insn, operands, 0);"
17171 [(set_attr "type" "fistp")
17172 (set_attr "i387_cw" "ceil")
17173 (set_attr "mode" "DI")])
17175 (define_insn "fistdi2_ceil_with_temp"
17176 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17177 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17179 (use (match_operand:HI 2 "memory_operand" "m,m"))
17180 (use (match_operand:HI 3 "memory_operand" "m,m"))
17181 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17182 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17183 "TARGET_USE_FANCY_MATH_387
17184 && flag_unsafe_math_optimizations"
17186 [(set_attr "type" "fistp")
17187 (set_attr "i387_cw" "ceil")
17188 (set_attr "mode" "DI")])
17191 [(set (match_operand:DI 0 "register_operand" "")
17192 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17194 (use (match_operand:HI 2 "memory_operand" ""))
17195 (use (match_operand:HI 3 "memory_operand" ""))
17196 (clobber (match_operand:DI 4 "memory_operand" ""))
17197 (clobber (match_scratch 5 ""))]
17199 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17200 (use (match_dup 2))
17201 (use (match_dup 3))
17202 (clobber (match_dup 5))])
17203 (set (match_dup 0) (match_dup 4))]
17207 [(set (match_operand:DI 0 "memory_operand" "")
17208 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17210 (use (match_operand:HI 2 "memory_operand" ""))
17211 (use (match_operand:HI 3 "memory_operand" ""))
17212 (clobber (match_operand:DI 4 "memory_operand" ""))
17213 (clobber (match_scratch 5 ""))]
17215 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17216 (use (match_dup 2))
17217 (use (match_dup 3))
17218 (clobber (match_dup 5))])]
17221 (define_insn "fist<mode>2_ceil"
17222 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17223 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17225 (use (match_operand:HI 2 "memory_operand" "m"))
17226 (use (match_operand:HI 3 "memory_operand" "m"))]
17227 "TARGET_USE_FANCY_MATH_387
17228 && flag_unsafe_math_optimizations"
17229 "* return output_fix_trunc (insn, operands, 0);"
17230 [(set_attr "type" "fistp")
17231 (set_attr "i387_cw" "ceil")
17232 (set_attr "mode" "<MODE>")])
17234 (define_insn "fist<mode>2_ceil_with_temp"
17235 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17236 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17238 (use (match_operand:HI 2 "memory_operand" "m,m"))
17239 (use (match_operand:HI 3 "memory_operand" "m,m"))
17240 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17241 "TARGET_USE_FANCY_MATH_387
17242 && flag_unsafe_math_optimizations"
17244 [(set_attr "type" "fistp")
17245 (set_attr "i387_cw" "ceil")
17246 (set_attr "mode" "<MODE>")])
17249 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17250 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17252 (use (match_operand:HI 2 "memory_operand" ""))
17253 (use (match_operand:HI 3 "memory_operand" ""))
17254 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17256 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17258 (use (match_dup 2))
17259 (use (match_dup 3))])
17260 (set (match_dup 0) (match_dup 4))]
17264 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17265 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17267 (use (match_operand:HI 2 "memory_operand" ""))
17268 (use (match_operand:HI 3 "memory_operand" ""))
17269 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17271 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17273 (use (match_dup 2))
17274 (use (match_dup 3))])]
17277 (define_expand "lceilxf<mode>2"
17278 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17279 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17281 (clobber (reg:CC FLAGS_REG))])]
17282 "TARGET_USE_FANCY_MATH_387
17283 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17284 && flag_unsafe_math_optimizations"
17287 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17288 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17289 (match_operand:MODEF 1 "register_operand" "")]
17290 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17291 && !flag_trapping_math"
17293 ix86_expand_lfloorceil (operand0, operand1, false);
17297 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17298 (define_insn_and_split "frndintxf2_trunc"
17299 [(set (match_operand:XF 0 "register_operand" "")
17300 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17301 UNSPEC_FRNDINT_TRUNC))
17302 (clobber (reg:CC FLAGS_REG))]
17303 "TARGET_USE_FANCY_MATH_387
17304 && flag_unsafe_math_optimizations
17305 && can_create_pseudo_p ()"
17310 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17312 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17313 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17315 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17316 operands[2], operands[3]));
17319 [(set_attr "type" "frndint")
17320 (set_attr "i387_cw" "trunc")
17321 (set_attr "mode" "XF")])
17323 (define_insn "frndintxf2_trunc_i387"
17324 [(set (match_operand:XF 0 "register_operand" "=f")
17325 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17326 UNSPEC_FRNDINT_TRUNC))
17327 (use (match_operand:HI 2 "memory_operand" "m"))
17328 (use (match_operand:HI 3 "memory_operand" "m"))]
17329 "TARGET_USE_FANCY_MATH_387
17330 && flag_unsafe_math_optimizations"
17331 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17332 [(set_attr "type" "frndint")
17333 (set_attr "i387_cw" "trunc")
17334 (set_attr "mode" "XF")])
17336 (define_expand "btruncxf2"
17337 [(use (match_operand:XF 0 "register_operand" ""))
17338 (use (match_operand:XF 1 "register_operand" ""))]
17339 "TARGET_USE_FANCY_MATH_387
17340 && flag_unsafe_math_optimizations"
17342 if (optimize_insn_for_size_p ())
17344 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17348 (define_expand "btrunc<mode>2"
17349 [(use (match_operand:MODEF 0 "register_operand" ""))
17350 (use (match_operand:MODEF 1 "register_operand" ""))]
17351 "(TARGET_USE_FANCY_MATH_387
17352 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17353 || TARGET_MIX_SSE_I387)
17354 && flag_unsafe_math_optimizations)
17355 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17356 && !flag_trapping_math)"
17358 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17359 && !flag_trapping_math
17360 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17363 emit_insn (gen_sse4_1_round<mode>2
17364 (operands[0], operands[1], GEN_INT (0x03)));
17365 else if (optimize_insn_for_size_p ())
17367 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17368 ix86_expand_trunc (operand0, operand1);
17370 ix86_expand_truncdf_32 (operand0, operand1);
17376 if (optimize_insn_for_size_p ())
17379 op0 = gen_reg_rtx (XFmode);
17380 op1 = gen_reg_rtx (XFmode);
17381 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17382 emit_insn (gen_frndintxf2_trunc (op0, op1));
17384 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17389 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17390 (define_insn_and_split "frndintxf2_mask_pm"
17391 [(set (match_operand:XF 0 "register_operand" "")
17392 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17393 UNSPEC_FRNDINT_MASK_PM))
17394 (clobber (reg:CC FLAGS_REG))]
17395 "TARGET_USE_FANCY_MATH_387
17396 && flag_unsafe_math_optimizations
17397 && can_create_pseudo_p ()"
17402 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17404 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17405 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17407 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17408 operands[2], operands[3]));
17411 [(set_attr "type" "frndint")
17412 (set_attr "i387_cw" "mask_pm")
17413 (set_attr "mode" "XF")])
17415 (define_insn "frndintxf2_mask_pm_i387"
17416 [(set (match_operand:XF 0 "register_operand" "=f")
17417 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17418 UNSPEC_FRNDINT_MASK_PM))
17419 (use (match_operand:HI 2 "memory_operand" "m"))
17420 (use (match_operand:HI 3 "memory_operand" "m"))]
17421 "TARGET_USE_FANCY_MATH_387
17422 && flag_unsafe_math_optimizations"
17423 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17424 [(set_attr "type" "frndint")
17425 (set_attr "i387_cw" "mask_pm")
17426 (set_attr "mode" "XF")])
17428 (define_expand "nearbyintxf2"
17429 [(use (match_operand:XF 0 "register_operand" ""))
17430 (use (match_operand:XF 1 "register_operand" ""))]
17431 "TARGET_USE_FANCY_MATH_387
17432 && flag_unsafe_math_optimizations"
17434 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17439 (define_expand "nearbyint<mode>2"
17440 [(use (match_operand:MODEF 0 "register_operand" ""))
17441 (use (match_operand:MODEF 1 "register_operand" ""))]
17442 "TARGET_USE_FANCY_MATH_387
17443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17444 || TARGET_MIX_SSE_I387)
17445 && flag_unsafe_math_optimizations"
17447 rtx op0 = gen_reg_rtx (XFmode);
17448 rtx op1 = gen_reg_rtx (XFmode);
17450 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17451 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17453 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17457 (define_insn "fxam<mode>2_i387"
17458 [(set (match_operand:HI 0 "register_operand" "=a")
17460 [(match_operand:X87MODEF 1 "register_operand" "f")]
17462 "TARGET_USE_FANCY_MATH_387"
17463 "fxam\n\tfnstsw\t%0"
17464 [(set_attr "type" "multi")
17465 (set_attr "length" "4")
17466 (set_attr "unit" "i387")
17467 (set_attr "mode" "<MODE>")])
17469 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17470 [(set (match_operand:HI 0 "register_operand" "")
17472 [(match_operand:MODEF 1 "memory_operand" "")]
17474 "TARGET_USE_FANCY_MATH_387
17475 && can_create_pseudo_p ()"
17478 [(set (match_dup 2)(match_dup 1))
17480 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17482 operands[2] = gen_reg_rtx (<MODE>mode);
17484 MEM_VOLATILE_P (operands[1]) = 1;
17486 [(set_attr "type" "multi")
17487 (set_attr "unit" "i387")
17488 (set_attr "mode" "<MODE>")])
17490 (define_expand "isinfxf2"
17491 [(use (match_operand:SI 0 "register_operand" ""))
17492 (use (match_operand:XF 1 "register_operand" ""))]
17493 "TARGET_USE_FANCY_MATH_387
17494 && TARGET_C99_FUNCTIONS"
17496 rtx mask = GEN_INT (0x45);
17497 rtx val = GEN_INT (0x05);
17501 rtx scratch = gen_reg_rtx (HImode);
17502 rtx res = gen_reg_rtx (QImode);
17504 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17506 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17507 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17508 cond = gen_rtx_fmt_ee (EQ, QImode,
17509 gen_rtx_REG (CCmode, FLAGS_REG),
17511 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17512 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17516 (define_expand "isinf<mode>2"
17517 [(use (match_operand:SI 0 "register_operand" ""))
17518 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17519 "TARGET_USE_FANCY_MATH_387
17520 && TARGET_C99_FUNCTIONS
17521 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17523 rtx mask = GEN_INT (0x45);
17524 rtx val = GEN_INT (0x05);
17528 rtx scratch = gen_reg_rtx (HImode);
17529 rtx res = gen_reg_rtx (QImode);
17531 /* Remove excess precision by forcing value through memory. */
17532 if (memory_operand (operands[1], VOIDmode))
17533 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17536 enum ix86_stack_slot slot = (virtuals_instantiated
17539 rtx temp = assign_386_stack_local (<MODE>mode, slot);
17541 emit_move_insn (temp, operands[1]);
17542 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17545 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17546 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17547 cond = gen_rtx_fmt_ee (EQ, QImode,
17548 gen_rtx_REG (CCmode, FLAGS_REG),
17550 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17551 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17555 (define_expand "signbit<mode>2"
17556 [(use (match_operand:SI 0 "register_operand" ""))
17557 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17558 "TARGET_USE_FANCY_MATH_387
17559 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17561 rtx mask = GEN_INT (0x0200);
17563 rtx scratch = gen_reg_rtx (HImode);
17565 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17566 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17570 ;; Block operation instructions
17573 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17576 [(set_attr "length" "1")
17577 (set_attr "length_immediate" "0")
17578 (set_attr "modrm" "0")])
17580 (define_expand "movmemsi"
17581 [(use (match_operand:BLK 0 "memory_operand" ""))
17582 (use (match_operand:BLK 1 "memory_operand" ""))
17583 (use (match_operand:SI 2 "nonmemory_operand" ""))
17584 (use (match_operand:SI 3 "const_int_operand" ""))
17585 (use (match_operand:SI 4 "const_int_operand" ""))
17586 (use (match_operand:SI 5 "const_int_operand" ""))]
17589 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17590 operands[4], operands[5]))
17596 (define_expand "movmemdi"
17597 [(use (match_operand:BLK 0 "memory_operand" ""))
17598 (use (match_operand:BLK 1 "memory_operand" ""))
17599 (use (match_operand:DI 2 "nonmemory_operand" ""))
17600 (use (match_operand:DI 3 "const_int_operand" ""))
17601 (use (match_operand:SI 4 "const_int_operand" ""))
17602 (use (match_operand:SI 5 "const_int_operand" ""))]
17605 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17606 operands[4], operands[5]))
17612 ;; Most CPUs don't like single string operations
17613 ;; Handle this case here to simplify previous expander.
17615 (define_expand "strmov"
17616 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17617 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17618 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17619 (clobber (reg:CC FLAGS_REG))])
17620 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17621 (clobber (reg:CC FLAGS_REG))])]
17624 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17626 /* If .md ever supports :P for Pmode, these can be directly
17627 in the pattern above. */
17628 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17629 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17631 /* Can't use this if the user has appropriated esi or edi. */
17632 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17633 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17635 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17636 operands[2], operands[3],
17637 operands[5], operands[6]));
17641 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17644 (define_expand "strmov_singleop"
17645 [(parallel [(set (match_operand 1 "memory_operand" "")
17646 (match_operand 3 "memory_operand" ""))
17647 (set (match_operand 0 "register_operand" "")
17648 (match_operand 4 "" ""))
17649 (set (match_operand 2 "register_operand" "")
17650 (match_operand 5 "" ""))])]
17652 "ix86_current_function_needs_cld = 1;")
17654 (define_insn "*strmovdi_rex_1"
17655 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17656 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17657 (set (match_operand:DI 0 "register_operand" "=D")
17658 (plus:DI (match_dup 2)
17660 (set (match_operand:DI 1 "register_operand" "=S")
17661 (plus:DI (match_dup 3)
17665 [(set_attr "type" "str")
17666 (set_attr "mode" "DI")
17667 (set_attr "memory" "both")])
17669 (define_insn "*strmovsi_1"
17670 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17671 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17672 (set (match_operand:SI 0 "register_operand" "=D")
17673 (plus:SI (match_dup 2)
17675 (set (match_operand:SI 1 "register_operand" "=S")
17676 (plus:SI (match_dup 3)
17680 [(set_attr "type" "str")
17681 (set_attr "mode" "SI")
17682 (set_attr "memory" "both")])
17684 (define_insn "*strmovsi_rex_1"
17685 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17686 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17687 (set (match_operand:DI 0 "register_operand" "=D")
17688 (plus:DI (match_dup 2)
17690 (set (match_operand:DI 1 "register_operand" "=S")
17691 (plus:DI (match_dup 3)
17695 [(set_attr "type" "str")
17696 (set_attr "mode" "SI")
17697 (set_attr "memory" "both")])
17699 (define_insn "*strmovhi_1"
17700 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17701 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17702 (set (match_operand:SI 0 "register_operand" "=D")
17703 (plus:SI (match_dup 2)
17705 (set (match_operand:SI 1 "register_operand" "=S")
17706 (plus:SI (match_dup 3)
17710 [(set_attr "type" "str")
17711 (set_attr "memory" "both")
17712 (set_attr "mode" "HI")])
17714 (define_insn "*strmovhi_rex_1"
17715 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17716 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17717 (set (match_operand:DI 0 "register_operand" "=D")
17718 (plus:DI (match_dup 2)
17720 (set (match_operand:DI 1 "register_operand" "=S")
17721 (plus:DI (match_dup 3)
17725 [(set_attr "type" "str")
17726 (set_attr "memory" "both")
17727 (set_attr "mode" "HI")])
17729 (define_insn "*strmovqi_1"
17730 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17731 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17732 (set (match_operand:SI 0 "register_operand" "=D")
17733 (plus:SI (match_dup 2)
17735 (set (match_operand:SI 1 "register_operand" "=S")
17736 (plus:SI (match_dup 3)
17740 [(set_attr "type" "str")
17741 (set_attr "memory" "both")
17742 (set_attr "mode" "QI")])
17744 (define_insn "*strmovqi_rex_1"
17745 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17746 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17747 (set (match_operand:DI 0 "register_operand" "=D")
17748 (plus:DI (match_dup 2)
17750 (set (match_operand:DI 1 "register_operand" "=S")
17751 (plus:DI (match_dup 3)
17755 [(set_attr "type" "str")
17756 (set_attr "memory" "both")
17757 (set_attr "prefix_rex" "0")
17758 (set_attr "mode" "QI")])
17760 (define_expand "rep_mov"
17761 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17762 (set (match_operand 0 "register_operand" "")
17763 (match_operand 5 "" ""))
17764 (set (match_operand 2 "register_operand" "")
17765 (match_operand 6 "" ""))
17766 (set (match_operand 1 "memory_operand" "")
17767 (match_operand 3 "memory_operand" ""))
17768 (use (match_dup 4))])]
17770 "ix86_current_function_needs_cld = 1;")
17772 (define_insn "*rep_movdi_rex64"
17773 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17774 (set (match_operand:DI 0 "register_operand" "=D")
17775 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17777 (match_operand:DI 3 "register_operand" "0")))
17778 (set (match_operand:DI 1 "register_operand" "=S")
17779 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17780 (match_operand:DI 4 "register_operand" "1")))
17781 (set (mem:BLK (match_dup 3))
17782 (mem:BLK (match_dup 4)))
17783 (use (match_dup 5))]
17786 [(set_attr "type" "str")
17787 (set_attr "prefix_rep" "1")
17788 (set_attr "memory" "both")
17789 (set_attr "mode" "DI")])
17791 (define_insn "*rep_movsi"
17792 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17793 (set (match_operand:SI 0 "register_operand" "=D")
17794 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17796 (match_operand:SI 3 "register_operand" "0")))
17797 (set (match_operand:SI 1 "register_operand" "=S")
17798 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17799 (match_operand:SI 4 "register_operand" "1")))
17800 (set (mem:BLK (match_dup 3))
17801 (mem:BLK (match_dup 4)))
17802 (use (match_dup 5))]
17805 [(set_attr "type" "str")
17806 (set_attr "prefix_rep" "1")
17807 (set_attr "memory" "both")
17808 (set_attr "mode" "SI")])
17810 (define_insn "*rep_movsi_rex64"
17811 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17812 (set (match_operand:DI 0 "register_operand" "=D")
17813 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17815 (match_operand:DI 3 "register_operand" "0")))
17816 (set (match_operand:DI 1 "register_operand" "=S")
17817 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17818 (match_operand:DI 4 "register_operand" "1")))
17819 (set (mem:BLK (match_dup 3))
17820 (mem:BLK (match_dup 4)))
17821 (use (match_dup 5))]
17824 [(set_attr "type" "str")
17825 (set_attr "prefix_rep" "1")
17826 (set_attr "memory" "both")
17827 (set_attr "mode" "SI")])
17829 (define_insn "*rep_movqi"
17830 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17831 (set (match_operand:SI 0 "register_operand" "=D")
17832 (plus:SI (match_operand:SI 3 "register_operand" "0")
17833 (match_operand:SI 5 "register_operand" "2")))
17834 (set (match_operand:SI 1 "register_operand" "=S")
17835 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17836 (set (mem:BLK (match_dup 3))
17837 (mem:BLK (match_dup 4)))
17838 (use (match_dup 5))]
17841 [(set_attr "type" "str")
17842 (set_attr "prefix_rep" "1")
17843 (set_attr "memory" "both")
17844 (set_attr "mode" "SI")])
17846 (define_insn "*rep_movqi_rex64"
17847 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17848 (set (match_operand:DI 0 "register_operand" "=D")
17849 (plus:DI (match_operand:DI 3 "register_operand" "0")
17850 (match_operand:DI 5 "register_operand" "2")))
17851 (set (match_operand:DI 1 "register_operand" "=S")
17852 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17853 (set (mem:BLK (match_dup 3))
17854 (mem:BLK (match_dup 4)))
17855 (use (match_dup 5))]
17858 [(set_attr "type" "str")
17859 (set_attr "prefix_rep" "1")
17860 (set_attr "memory" "both")
17861 (set_attr "mode" "SI")])
17863 (define_expand "setmemsi"
17864 [(use (match_operand:BLK 0 "memory_operand" ""))
17865 (use (match_operand:SI 1 "nonmemory_operand" ""))
17866 (use (match_operand 2 "const_int_operand" ""))
17867 (use (match_operand 3 "const_int_operand" ""))
17868 (use (match_operand:SI 4 "const_int_operand" ""))
17869 (use (match_operand:SI 5 "const_int_operand" ""))]
17872 if (ix86_expand_setmem (operands[0], operands[1],
17873 operands[2], operands[3],
17874 operands[4], operands[5]))
17880 (define_expand "setmemdi"
17881 [(use (match_operand:BLK 0 "memory_operand" ""))
17882 (use (match_operand:DI 1 "nonmemory_operand" ""))
17883 (use (match_operand 2 "const_int_operand" ""))
17884 (use (match_operand 3 "const_int_operand" ""))
17885 (use (match_operand 4 "const_int_operand" ""))
17886 (use (match_operand 5 "const_int_operand" ""))]
17889 if (ix86_expand_setmem (operands[0], operands[1],
17890 operands[2], operands[3],
17891 operands[4], operands[5]))
17897 ;; Most CPUs don't like single string operations
17898 ;; Handle this case here to simplify previous expander.
17900 (define_expand "strset"
17901 [(set (match_operand 1 "memory_operand" "")
17902 (match_operand 2 "register_operand" ""))
17903 (parallel [(set (match_operand 0 "register_operand" "")
17905 (clobber (reg:CC FLAGS_REG))])]
17908 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17909 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17911 /* If .md ever supports :P for Pmode, this can be directly
17912 in the pattern above. */
17913 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17914 GEN_INT (GET_MODE_SIZE (GET_MODE
17916 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17918 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17924 (define_expand "strset_singleop"
17925 [(parallel [(set (match_operand 1 "memory_operand" "")
17926 (match_operand 2 "register_operand" ""))
17927 (set (match_operand 0 "register_operand" "")
17928 (match_operand 3 "" ""))])]
17930 "ix86_current_function_needs_cld = 1;")
17932 (define_insn "*strsetdi_rex_1"
17933 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17934 (match_operand:DI 2 "register_operand" "a"))
17935 (set (match_operand:DI 0 "register_operand" "=D")
17936 (plus:DI (match_dup 1)
17940 [(set_attr "type" "str")
17941 (set_attr "memory" "store")
17942 (set_attr "mode" "DI")])
17944 (define_insn "*strsetsi_1"
17945 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17946 (match_operand:SI 2 "register_operand" "a"))
17947 (set (match_operand:SI 0 "register_operand" "=D")
17948 (plus:SI (match_dup 1)
17952 [(set_attr "type" "str")
17953 (set_attr "memory" "store")
17954 (set_attr "mode" "SI")])
17956 (define_insn "*strsetsi_rex_1"
17957 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17958 (match_operand:SI 2 "register_operand" "a"))
17959 (set (match_operand:DI 0 "register_operand" "=D")
17960 (plus:DI (match_dup 1)
17964 [(set_attr "type" "str")
17965 (set_attr "memory" "store")
17966 (set_attr "mode" "SI")])
17968 (define_insn "*strsethi_1"
17969 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17970 (match_operand:HI 2 "register_operand" "a"))
17971 (set (match_operand:SI 0 "register_operand" "=D")
17972 (plus:SI (match_dup 1)
17976 [(set_attr "type" "str")
17977 (set_attr "memory" "store")
17978 (set_attr "mode" "HI")])
17980 (define_insn "*strsethi_rex_1"
17981 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17982 (match_operand:HI 2 "register_operand" "a"))
17983 (set (match_operand:DI 0 "register_operand" "=D")
17984 (plus:DI (match_dup 1)
17988 [(set_attr "type" "str")
17989 (set_attr "memory" "store")
17990 (set_attr "mode" "HI")])
17992 (define_insn "*strsetqi_1"
17993 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17994 (match_operand:QI 2 "register_operand" "a"))
17995 (set (match_operand:SI 0 "register_operand" "=D")
17996 (plus:SI (match_dup 1)
18000 [(set_attr "type" "str")
18001 (set_attr "memory" "store")
18002 (set_attr "mode" "QI")])
18004 (define_insn "*strsetqi_rex_1"
18005 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18006 (match_operand:QI 2 "register_operand" "a"))
18007 (set (match_operand:DI 0 "register_operand" "=D")
18008 (plus:DI (match_dup 1)
18012 [(set_attr "type" "str")
18013 (set_attr "memory" "store")
18014 (set_attr "prefix_rex" "0")
18015 (set_attr "mode" "QI")])
18017 (define_expand "rep_stos"
18018 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18019 (set (match_operand 0 "register_operand" "")
18020 (match_operand 4 "" ""))
18021 (set (match_operand 2 "memory_operand" "") (const_int 0))
18022 (use (match_operand 3 "register_operand" ""))
18023 (use (match_dup 1))])]
18025 "ix86_current_function_needs_cld = 1;")
18027 (define_insn "*rep_stosdi_rex64"
18028 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18029 (set (match_operand:DI 0 "register_operand" "=D")
18030 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18032 (match_operand:DI 3 "register_operand" "0")))
18033 (set (mem:BLK (match_dup 3))
18035 (use (match_operand:DI 2 "register_operand" "a"))
18036 (use (match_dup 4))]
18039 [(set_attr "type" "str")
18040 (set_attr "prefix_rep" "1")
18041 (set_attr "memory" "store")
18042 (set_attr "mode" "DI")])
18044 (define_insn "*rep_stossi"
18045 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18046 (set (match_operand:SI 0 "register_operand" "=D")
18047 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18049 (match_operand:SI 3 "register_operand" "0")))
18050 (set (mem:BLK (match_dup 3))
18052 (use (match_operand:SI 2 "register_operand" "a"))
18053 (use (match_dup 4))]
18056 [(set_attr "type" "str")
18057 (set_attr "prefix_rep" "1")
18058 (set_attr "memory" "store")
18059 (set_attr "mode" "SI")])
18061 (define_insn "*rep_stossi_rex64"
18062 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18063 (set (match_operand:DI 0 "register_operand" "=D")
18064 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18066 (match_operand:DI 3 "register_operand" "0")))
18067 (set (mem:BLK (match_dup 3))
18069 (use (match_operand:SI 2 "register_operand" "a"))
18070 (use (match_dup 4))]
18073 [(set_attr "type" "str")
18074 (set_attr "prefix_rep" "1")
18075 (set_attr "memory" "store")
18076 (set_attr "mode" "SI")])
18078 (define_insn "*rep_stosqi"
18079 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18080 (set (match_operand:SI 0 "register_operand" "=D")
18081 (plus:SI (match_operand:SI 3 "register_operand" "0")
18082 (match_operand:SI 4 "register_operand" "1")))
18083 (set (mem:BLK (match_dup 3))
18085 (use (match_operand:QI 2 "register_operand" "a"))
18086 (use (match_dup 4))]
18089 [(set_attr "type" "str")
18090 (set_attr "prefix_rep" "1")
18091 (set_attr "memory" "store")
18092 (set_attr "mode" "QI")])
18094 (define_insn "*rep_stosqi_rex64"
18095 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18096 (set (match_operand:DI 0 "register_operand" "=D")
18097 (plus:DI (match_operand:DI 3 "register_operand" "0")
18098 (match_operand:DI 4 "register_operand" "1")))
18099 (set (mem:BLK (match_dup 3))
18101 (use (match_operand:QI 2 "register_operand" "a"))
18102 (use (match_dup 4))]
18105 [(set_attr "type" "str")
18106 (set_attr "prefix_rep" "1")
18107 (set_attr "memory" "store")
18108 (set_attr "prefix_rex" "0")
18109 (set_attr "mode" "QI")])
18111 (define_expand "cmpstrnsi"
18112 [(set (match_operand:SI 0 "register_operand" "")
18113 (compare:SI (match_operand:BLK 1 "general_operand" "")
18114 (match_operand:BLK 2 "general_operand" "")))
18115 (use (match_operand 3 "general_operand" ""))
18116 (use (match_operand 4 "immediate_operand" ""))]
18119 rtx addr1, addr2, out, outlow, count, countreg, align;
18121 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18124 /* Can't use this if the user has appropriated esi or edi. */
18125 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18130 out = gen_reg_rtx (SImode);
18132 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18133 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18134 if (addr1 != XEXP (operands[1], 0))
18135 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18136 if (addr2 != XEXP (operands[2], 0))
18137 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18139 count = operands[3];
18140 countreg = ix86_zero_extend_to_Pmode (count);
18142 /* %%% Iff we are testing strict equality, we can use known alignment
18143 to good advantage. This may be possible with combine, particularly
18144 once cc0 is dead. */
18145 align = operands[4];
18147 if (CONST_INT_P (count))
18149 if (INTVAL (count) == 0)
18151 emit_move_insn (operands[0], const0_rtx);
18154 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18155 operands[1], operands[2]));
18159 rtx (*cmp_insn)(rtx, rtx);
18162 cmp_insn = gen_cmpdi_1;
18164 cmp_insn = gen_cmpsi_1;
18165 emit_insn (cmp_insn (countreg, countreg));
18166 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18167 operands[1], operands[2]));
18170 outlow = gen_lowpart (QImode, out);
18171 emit_insn (gen_cmpintqi (outlow));
18172 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18174 if (operands[0] != out)
18175 emit_move_insn (operands[0], out);
18180 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18182 (define_expand "cmpintqi"
18183 [(set (match_dup 1)
18184 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18186 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18187 (parallel [(set (match_operand:QI 0 "register_operand" "")
18188 (minus:QI (match_dup 1)
18190 (clobber (reg:CC FLAGS_REG))])]
18192 "operands[1] = gen_reg_rtx (QImode);
18193 operands[2] = gen_reg_rtx (QImode);")
18195 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18196 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18198 (define_expand "cmpstrnqi_nz_1"
18199 [(parallel [(set (reg:CC FLAGS_REG)
18200 (compare:CC (match_operand 4 "memory_operand" "")
18201 (match_operand 5 "memory_operand" "")))
18202 (use (match_operand 2 "register_operand" ""))
18203 (use (match_operand:SI 3 "immediate_operand" ""))
18204 (clobber (match_operand 0 "register_operand" ""))
18205 (clobber (match_operand 1 "register_operand" ""))
18206 (clobber (match_dup 2))])]
18208 "ix86_current_function_needs_cld = 1;")
18210 (define_insn "*cmpstrnqi_nz_1"
18211 [(set (reg:CC FLAGS_REG)
18212 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18213 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18214 (use (match_operand:SI 6 "register_operand" "2"))
18215 (use (match_operand:SI 3 "immediate_operand" "i"))
18216 (clobber (match_operand:SI 0 "register_operand" "=S"))
18217 (clobber (match_operand:SI 1 "register_operand" "=D"))
18218 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18221 [(set_attr "type" "str")
18222 (set_attr "mode" "QI")
18223 (set_attr "prefix_rep" "1")])
18225 (define_insn "*cmpstrnqi_nz_rex_1"
18226 [(set (reg:CC FLAGS_REG)
18227 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18228 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18229 (use (match_operand:DI 6 "register_operand" "2"))
18230 (use (match_operand:SI 3 "immediate_operand" "i"))
18231 (clobber (match_operand:DI 0 "register_operand" "=S"))
18232 (clobber (match_operand:DI 1 "register_operand" "=D"))
18233 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18236 [(set_attr "type" "str")
18237 (set_attr "mode" "QI")
18238 (set_attr "prefix_rex" "0")
18239 (set_attr "prefix_rep" "1")])
18241 ;; The same, but the count is not known to not be zero.
18243 (define_expand "cmpstrnqi_1"
18244 [(parallel [(set (reg:CC FLAGS_REG)
18245 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18247 (compare:CC (match_operand 4 "memory_operand" "")
18248 (match_operand 5 "memory_operand" ""))
18250 (use (match_operand:SI 3 "immediate_operand" ""))
18251 (use (reg:CC FLAGS_REG))
18252 (clobber (match_operand 0 "register_operand" ""))
18253 (clobber (match_operand 1 "register_operand" ""))
18254 (clobber (match_dup 2))])]
18256 "ix86_current_function_needs_cld = 1;")
18258 (define_insn "*cmpstrnqi_1"
18259 [(set (reg:CC FLAGS_REG)
18260 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18262 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18263 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18265 (use (match_operand:SI 3 "immediate_operand" "i"))
18266 (use (reg:CC FLAGS_REG))
18267 (clobber (match_operand:SI 0 "register_operand" "=S"))
18268 (clobber (match_operand:SI 1 "register_operand" "=D"))
18269 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18272 [(set_attr "type" "str")
18273 (set_attr "mode" "QI")
18274 (set_attr "prefix_rep" "1")])
18276 (define_insn "*cmpstrnqi_rex_1"
18277 [(set (reg:CC FLAGS_REG)
18278 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18280 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18281 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18283 (use (match_operand:SI 3 "immediate_operand" "i"))
18284 (use (reg:CC FLAGS_REG))
18285 (clobber (match_operand:DI 0 "register_operand" "=S"))
18286 (clobber (match_operand:DI 1 "register_operand" "=D"))
18287 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18290 [(set_attr "type" "str")
18291 (set_attr "mode" "QI")
18292 (set_attr "prefix_rex" "0")
18293 (set_attr "prefix_rep" "1")])
18295 (define_expand "strlensi"
18296 [(set (match_operand:SI 0 "register_operand" "")
18297 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18298 (match_operand:QI 2 "immediate_operand" "")
18299 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18302 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18308 (define_expand "strlendi"
18309 [(set (match_operand:DI 0 "register_operand" "")
18310 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18311 (match_operand:QI 2 "immediate_operand" "")
18312 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18315 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18321 (define_expand "strlenqi_1"
18322 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18323 (clobber (match_operand 1 "register_operand" ""))
18324 (clobber (reg:CC FLAGS_REG))])]
18326 "ix86_current_function_needs_cld = 1;")
18328 (define_insn "*strlenqi_1"
18329 [(set (match_operand:SI 0 "register_operand" "=&c")
18330 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18331 (match_operand:QI 2 "register_operand" "a")
18332 (match_operand:SI 3 "immediate_operand" "i")
18333 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18334 (clobber (match_operand:SI 1 "register_operand" "=D"))
18335 (clobber (reg:CC FLAGS_REG))]
18338 [(set_attr "type" "str")
18339 (set_attr "mode" "QI")
18340 (set_attr "prefix_rep" "1")])
18342 (define_insn "*strlenqi_rex_1"
18343 [(set (match_operand:DI 0 "register_operand" "=&c")
18344 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18345 (match_operand:QI 2 "register_operand" "a")
18346 (match_operand:DI 3 "immediate_operand" "i")
18347 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18348 (clobber (match_operand:DI 1 "register_operand" "=D"))
18349 (clobber (reg:CC FLAGS_REG))]
18352 [(set_attr "type" "str")
18353 (set_attr "mode" "QI")
18354 (set_attr "prefix_rex" "0")
18355 (set_attr "prefix_rep" "1")])
18357 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18358 ;; handled in combine, but it is not currently up to the task.
18359 ;; When used for their truth value, the cmpstrn* expanders generate
18368 ;; The intermediate three instructions are unnecessary.
18370 ;; This one handles cmpstrn*_nz_1...
18373 (set (reg:CC FLAGS_REG)
18374 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18375 (mem:BLK (match_operand 5 "register_operand" ""))))
18376 (use (match_operand 6 "register_operand" ""))
18377 (use (match_operand:SI 3 "immediate_operand" ""))
18378 (clobber (match_operand 0 "register_operand" ""))
18379 (clobber (match_operand 1 "register_operand" ""))
18380 (clobber (match_operand 2 "register_operand" ""))])
18381 (set (match_operand:QI 7 "register_operand" "")
18382 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18383 (set (match_operand:QI 8 "register_operand" "")
18384 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18385 (set (reg FLAGS_REG)
18386 (compare (match_dup 7) (match_dup 8)))
18388 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18390 (set (reg:CC FLAGS_REG)
18391 (compare:CC (mem:BLK (match_dup 4))
18392 (mem:BLK (match_dup 5))))
18393 (use (match_dup 6))
18394 (use (match_dup 3))
18395 (clobber (match_dup 0))
18396 (clobber (match_dup 1))
18397 (clobber (match_dup 2))])]
18400 ;; ...and this one handles cmpstrn*_1.
18403 (set (reg:CC FLAGS_REG)
18404 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18406 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18407 (mem:BLK (match_operand 5 "register_operand" "")))
18409 (use (match_operand:SI 3 "immediate_operand" ""))
18410 (use (reg:CC FLAGS_REG))
18411 (clobber (match_operand 0 "register_operand" ""))
18412 (clobber (match_operand 1 "register_operand" ""))
18413 (clobber (match_operand 2 "register_operand" ""))])
18414 (set (match_operand:QI 7 "register_operand" "")
18415 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18416 (set (match_operand:QI 8 "register_operand" "")
18417 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18418 (set (reg FLAGS_REG)
18419 (compare (match_dup 7) (match_dup 8)))
18421 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18423 (set (reg:CC FLAGS_REG)
18424 (if_then_else:CC (ne (match_dup 6)
18426 (compare:CC (mem:BLK (match_dup 4))
18427 (mem:BLK (match_dup 5)))
18429 (use (match_dup 3))
18430 (use (reg:CC FLAGS_REG))
18431 (clobber (match_dup 0))
18432 (clobber (match_dup 1))
18433 (clobber (match_dup 2))])]
18438 ;; Conditional move instructions.
18440 (define_expand "mov<mode>cc"
18441 [(set (match_operand:SWIM 0 "register_operand" "")
18442 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18443 (match_operand:SWIM 2 "general_operand" "")
18444 (match_operand:SWIM 3 "general_operand" "")))]
18446 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18448 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18449 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18450 ;; So just document what we're doing explicitly.
18452 (define_expand "x86_mov<mode>cc_0_m1"
18454 [(set (match_operand:SWI48 0 "register_operand" "")
18455 (if_then_else:SWI48
18456 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18457 [(match_operand 1 "flags_reg_operand" "")
18461 (clobber (reg:CC FLAGS_REG))])]
18465 (define_insn "*x86_mov<mode>cc_0_m1"
18466 [(set (match_operand:SWI48 0 "register_operand" "=r")
18467 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18468 [(reg FLAGS_REG) (const_int 0)])
18471 (clobber (reg:CC FLAGS_REG))]
18473 "sbb{<imodesuffix>}\t%0, %0"
18474 ; Since we don't have the proper number of operands for an alu insn,
18475 ; fill in all the blanks.
18476 [(set_attr "type" "alu")
18477 (set_attr "use_carry" "1")
18478 (set_attr "pent_pair" "pu")
18479 (set_attr "memory" "none")
18480 (set_attr "imm_disp" "false")
18481 (set_attr "mode" "<MODE>")
18482 (set_attr "length_immediate" "0")])
18484 (define_insn "*x86_mov<mode>cc_0_m1_se"
18485 [(set (match_operand:SWI48 0 "register_operand" "=r")
18486 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18487 [(reg FLAGS_REG) (const_int 0)])
18490 (clobber (reg:CC FLAGS_REG))]
18492 "sbb{<imodesuffix>}\t%0, %0"
18493 [(set_attr "type" "alu")
18494 (set_attr "use_carry" "1")
18495 (set_attr "pent_pair" "pu")
18496 (set_attr "memory" "none")
18497 (set_attr "imm_disp" "false")
18498 (set_attr "mode" "<MODE>")
18499 (set_attr "length_immediate" "0")])
18501 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18502 [(set (match_operand:SWI48 0 "register_operand" "=r")
18503 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18504 [(reg FLAGS_REG) (const_int 0)])))]
18506 "sbb{<imodesuffix>}\t%0, %0"
18507 [(set_attr "type" "alu")
18508 (set_attr "use_carry" "1")
18509 (set_attr "pent_pair" "pu")
18510 (set_attr "memory" "none")
18511 (set_attr "imm_disp" "false")
18512 (set_attr "mode" "<MODE>")
18513 (set_attr "length_immediate" "0")])
18515 (define_insn "*mov<mode>cc_noc"
18516 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18517 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18518 [(reg FLAGS_REG) (const_int 0)])
18519 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18520 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18521 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18523 cmov%O2%C1\t{%2, %0|%0, %2}
18524 cmov%O2%c1\t{%3, %0|%0, %3}"
18525 [(set_attr "type" "icmov")
18526 (set_attr "mode" "<MODE>")])
18528 (define_insn_and_split "*movqicc_noc"
18529 [(set (match_operand:QI 0 "register_operand" "=r,r")
18530 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18531 [(match_operand 4 "flags_reg_operand" "")
18533 (match_operand:QI 2 "register_operand" "r,0")
18534 (match_operand:QI 3 "register_operand" "0,r")))]
18535 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18537 "&& reload_completed"
18538 [(set (match_dup 0)
18539 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18542 "operands[0] = gen_lowpart (SImode, operands[0]);
18543 operands[2] = gen_lowpart (SImode, operands[2]);
18544 operands[3] = gen_lowpart (SImode, operands[3]);"
18545 [(set_attr "type" "icmov")
18546 (set_attr "mode" "SI")])
18548 (define_expand "mov<mode>cc"
18549 [(set (match_operand:X87MODEF 0 "register_operand" "")
18550 (if_then_else:X87MODEF
18551 (match_operand 1 "ix86_fp_comparison_operator" "")
18552 (match_operand:X87MODEF 2 "register_operand" "")
18553 (match_operand:X87MODEF 3 "register_operand" "")))]
18554 "(TARGET_80387 && TARGET_CMOVE)
18555 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18556 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18558 (define_insn "*movsfcc_1_387"
18559 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18560 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18561 [(reg FLAGS_REG) (const_int 0)])
18562 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18563 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18564 "TARGET_80387 && TARGET_CMOVE
18565 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18567 fcmov%F1\t{%2, %0|%0, %2}
18568 fcmov%f1\t{%3, %0|%0, %3}
18569 cmov%O2%C1\t{%2, %0|%0, %2}
18570 cmov%O2%c1\t{%3, %0|%0, %3}"
18571 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18572 (set_attr "mode" "SF,SF,SI,SI")])
18574 (define_insn "*movdfcc_1"
18575 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18576 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18577 [(reg FLAGS_REG) (const_int 0)])
18578 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18579 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18580 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18581 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18583 fcmov%F1\t{%2, %0|%0, %2}
18584 fcmov%f1\t{%3, %0|%0, %3}
18587 [(set_attr "type" "fcmov,fcmov,multi,multi")
18588 (set_attr "mode" "DF")])
18590 (define_insn "*movdfcc_1_rex64"
18591 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18592 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18593 [(reg FLAGS_REG) (const_int 0)])
18594 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18595 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18596 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18597 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18599 fcmov%F1\t{%2, %0|%0, %2}
18600 fcmov%f1\t{%3, %0|%0, %3}
18601 cmov%O2%C1\t{%2, %0|%0, %2}
18602 cmov%O2%c1\t{%3, %0|%0, %3}"
18603 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18604 (set_attr "mode" "DF")])
18607 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18608 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18609 [(match_operand 4 "flags_reg_operand" "")
18611 (match_operand:DF 2 "nonimmediate_operand" "")
18612 (match_operand:DF 3 "nonimmediate_operand" "")))]
18613 "!TARGET_64BIT && reload_completed"
18614 [(set (match_dup 2)
18615 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18619 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18622 "split_di (&operands[2], 2, &operands[5], &operands[7]);
18623 split_di (&operands[0], 1, &operands[2], &operands[3]);")
18625 (define_insn "*movxfcc_1"
18626 [(set (match_operand:XF 0 "register_operand" "=f,f")
18627 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18628 [(reg FLAGS_REG) (const_int 0)])
18629 (match_operand:XF 2 "register_operand" "f,0")
18630 (match_operand:XF 3 "register_operand" "0,f")))]
18631 "TARGET_80387 && TARGET_CMOVE"
18633 fcmov%F1\t{%2, %0|%0, %2}
18634 fcmov%f1\t{%3, %0|%0, %3}"
18635 [(set_attr "type" "fcmov")
18636 (set_attr "mode" "XF")])
18638 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18639 ;; the scalar versions to have only XMM registers as operands.
18641 ;; XOP conditional move
18642 (define_insn "*xop_pcmov_<mode>"
18643 [(set (match_operand:MODEF 0 "register_operand" "=x")
18644 (if_then_else:MODEF
18645 (match_operand:MODEF 1 "register_operand" "x")
18646 (match_operand:MODEF 2 "register_operand" "x")
18647 (match_operand:MODEF 3 "register_operand" "x")))]
18649 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18650 [(set_attr "type" "sse4arg")])
18652 ;; These versions of the min/max patterns are intentionally ignorant of
18653 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18654 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18655 ;; are undefined in this condition, we're certain this is correct.
18657 (define_insn "*avx_<code><mode>3"
18658 [(set (match_operand:MODEF 0 "register_operand" "=x")
18660 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18661 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18662 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18663 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18664 [(set_attr "type" "sseadd")
18665 (set_attr "prefix" "vex")
18666 (set_attr "mode" "<MODE>")])
18668 (define_insn "<code><mode>3"
18669 [(set (match_operand:MODEF 0 "register_operand" "=x")
18671 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18672 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18673 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18674 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18675 [(set_attr "type" "sseadd")
18676 (set_attr "mode" "<MODE>")])
18678 ;; These versions of the min/max patterns implement exactly the operations
18679 ;; min = (op1 < op2 ? op1 : op2)
18680 ;; max = (!(op1 < op2) ? op1 : op2)
18681 ;; Their operands are not commutative, and thus they may be used in the
18682 ;; presence of -0.0 and NaN.
18684 (define_insn "*avx_ieee_smin<mode>3"
18685 [(set (match_operand:MODEF 0 "register_operand" "=x")
18687 [(match_operand:MODEF 1 "register_operand" "x")
18688 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18690 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18691 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18692 [(set_attr "type" "sseadd")
18693 (set_attr "prefix" "vex")
18694 (set_attr "mode" "<MODE>")])
18696 (define_insn "*ieee_smin<mode>3"
18697 [(set (match_operand:MODEF 0 "register_operand" "=x")
18699 [(match_operand:MODEF 1 "register_operand" "0")
18700 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18702 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18703 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18704 [(set_attr "type" "sseadd")
18705 (set_attr "mode" "<MODE>")])
18707 (define_insn "*avx_ieee_smax<mode>3"
18708 [(set (match_operand:MODEF 0 "register_operand" "=x")
18710 [(match_operand:MODEF 1 "register_operand" "0")
18711 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18713 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18714 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18715 [(set_attr "type" "sseadd")
18716 (set_attr "prefix" "vex")
18717 (set_attr "mode" "<MODE>")])
18719 (define_insn "*ieee_smax<mode>3"
18720 [(set (match_operand:MODEF 0 "register_operand" "=x")
18722 [(match_operand:MODEF 1 "register_operand" "0")
18723 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18725 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18726 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18727 [(set_attr "type" "sseadd")
18728 (set_attr "mode" "<MODE>")])
18730 ;; Make two stack loads independent:
18732 ;; fld %st(0) -> fld bb
18733 ;; fmul bb fmul %st(1), %st
18735 ;; Actually we only match the last two instructions for simplicity.
18737 [(set (match_operand 0 "fp_register_operand" "")
18738 (match_operand 1 "fp_register_operand" ""))
18740 (match_operator 2 "binary_fp_operator"
18742 (match_operand 3 "memory_operand" "")]))]
18743 "REGNO (operands[0]) != REGNO (operands[1])"
18744 [(set (match_dup 0) (match_dup 3))
18745 (set (match_dup 0) (match_dup 4))]
18747 ;; The % modifier is not operational anymore in peephole2's, so we have to
18748 ;; swap the operands manually in the case of addition and multiplication.
18749 "if (COMMUTATIVE_ARITH_P (operands[2]))
18750 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18751 operands[0], operands[1]);
18753 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18754 operands[1], operands[0]);")
18756 ;; Conditional addition patterns
18757 (define_expand "add<mode>cc"
18758 [(match_operand:SWI 0 "register_operand" "")
18759 (match_operand 1 "comparison_operator" "")
18760 (match_operand:SWI 2 "register_operand" "")
18761 (match_operand:SWI 3 "const_int_operand" "")]
18763 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18766 ;; Misc patterns (?)
18768 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18769 ;; Otherwise there will be nothing to keep
18771 ;; [(set (reg ebp) (reg esp))]
18772 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18773 ;; (clobber (eflags)]
18774 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18776 ;; in proper program order.
18777 (define_insn "pro_epilogue_adjust_stack_1"
18778 [(set (match_operand:SI 0 "register_operand" "=r,r")
18779 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18780 (match_operand:SI 2 "immediate_operand" "i,i")))
18781 (clobber (reg:CC FLAGS_REG))
18782 (clobber (mem:BLK (scratch)))]
18785 switch (get_attr_type (insn))
18788 return "mov{l}\t{%1, %0|%0, %1}";
18791 if (CONST_INT_P (operands[2])
18792 && (INTVAL (operands[2]) == 128
18793 || (INTVAL (operands[2]) < 0
18794 && INTVAL (operands[2]) != -128)))
18796 operands[2] = GEN_INT (-INTVAL (operands[2]));
18797 return "sub{l}\t{%2, %0|%0, %2}";
18799 return "add{l}\t{%2, %0|%0, %2}";
18802 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18803 return "lea{l}\t{%a2, %0|%0, %a2}";
18806 gcc_unreachable ();
18809 [(set (attr "type")
18810 (cond [(and (eq_attr "alternative" "0")
18811 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18812 (const_string "alu")
18813 (match_operand:SI 2 "const0_operand" "")
18814 (const_string "imov")
18816 (const_string "lea")))
18817 (set (attr "length_immediate")
18818 (cond [(eq_attr "type" "imov")
18820 (and (eq_attr "type" "alu")
18821 (match_operand 2 "const128_operand" ""))
18824 (const_string "*")))
18825 (set_attr "mode" "SI")])
18827 (define_insn "pro_epilogue_adjust_stack_rex64"
18828 [(set (match_operand:DI 0 "register_operand" "=r,r")
18829 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18830 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18831 (clobber (reg:CC FLAGS_REG))
18832 (clobber (mem:BLK (scratch)))]
18835 switch (get_attr_type (insn))
18838 return "mov{q}\t{%1, %0|%0, %1}";
18841 if (CONST_INT_P (operands[2])
18842 /* Avoid overflows. */
18843 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18844 && (INTVAL (operands[2]) == 128
18845 || (INTVAL (operands[2]) < 0
18846 && INTVAL (operands[2]) != -128)))
18848 operands[2] = GEN_INT (-INTVAL (operands[2]));
18849 return "sub{q}\t{%2, %0|%0, %2}";
18851 return "add{q}\t{%2, %0|%0, %2}";
18854 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18855 return "lea{q}\t{%a2, %0|%0, %a2}";
18858 gcc_unreachable ();
18861 [(set (attr "type")
18862 (cond [(and (eq_attr "alternative" "0")
18863 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18864 (const_string "alu")
18865 (match_operand:DI 2 "const0_operand" "")
18866 (const_string "imov")
18868 (const_string "lea")))
18869 (set (attr "length_immediate")
18870 (cond [(eq_attr "type" "imov")
18872 (and (eq_attr "type" "alu")
18873 (match_operand 2 "const128_operand" ""))
18876 (const_string "*")))
18877 (set_attr "mode" "DI")])
18879 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18880 [(set (match_operand:DI 0 "register_operand" "=r,r")
18881 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18882 (match_operand:DI 3 "immediate_operand" "i,i")))
18883 (use (match_operand:DI 2 "register_operand" "r,r"))
18884 (clobber (reg:CC FLAGS_REG))
18885 (clobber (mem:BLK (scratch)))]
18888 switch (get_attr_type (insn))
18891 return "add{q}\t{%2, %0|%0, %2}";
18894 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18895 return "lea{q}\t{%a2, %0|%0, %a2}";
18898 gcc_unreachable ();
18901 [(set_attr "type" "alu,lea")
18902 (set_attr "mode" "DI")])
18904 (define_insn "allocate_stack_worker_32"
18905 [(set (match_operand:SI 0 "register_operand" "=a")
18906 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18907 UNSPECV_STACK_PROBE))
18908 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18909 (clobber (reg:CC FLAGS_REG))]
18910 "!TARGET_64BIT && TARGET_STACK_PROBE"
18912 [(set_attr "type" "multi")
18913 (set_attr "length" "5")])
18915 (define_insn "allocate_stack_worker_64"
18916 [(set (match_operand:DI 0 "register_operand" "=a")
18917 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18918 UNSPECV_STACK_PROBE))
18919 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18920 (clobber (reg:DI R10_REG))
18921 (clobber (reg:DI R11_REG))
18922 (clobber (reg:CC FLAGS_REG))]
18923 "TARGET_64BIT && TARGET_STACK_PROBE"
18925 [(set_attr "type" "multi")
18926 (set_attr "length" "5")])
18928 (define_expand "allocate_stack"
18929 [(match_operand 0 "register_operand" "")
18930 (match_operand 1 "general_operand" "")]
18931 "TARGET_STACK_PROBE"
18935 #ifndef CHECK_STACK_LIMIT
18936 #define CHECK_STACK_LIMIT 0
18939 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18940 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18942 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18943 stack_pointer_rtx, 0, OPTAB_DIRECT);
18944 if (x != stack_pointer_rtx)
18945 emit_move_insn (stack_pointer_rtx, x);
18949 x = copy_to_mode_reg (Pmode, operands[1]);
18951 x = gen_allocate_stack_worker_64 (x, x);
18953 x = gen_allocate_stack_worker_32 (x, x);
18957 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18961 ;; Use IOR for stack probes, this is shorter.
18962 (define_expand "probe_stack"
18963 [(match_operand 0 "memory_operand" "")]
18966 if (GET_MODE (operands[0]) == DImode)
18967 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18969 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18973 (define_expand "builtin_setjmp_receiver"
18974 [(label_ref (match_operand 0 "" ""))]
18975 "!TARGET_64BIT && flag_pic"
18981 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18982 rtx label_rtx = gen_label_rtx ();
18983 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18984 xops[0] = xops[1] = picreg;
18985 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18986 ix86_expand_binary_operator (MINUS, SImode, xops);
18990 emit_insn (gen_set_got (pic_offset_table_rtx));
18994 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18997 [(set (match_operand 0 "register_operand" "")
18998 (match_operator 3 "promotable_binary_operator"
18999 [(match_operand 1 "register_operand" "")
19000 (match_operand 2 "aligned_operand" "")]))
19001 (clobber (reg:CC FLAGS_REG))]
19002 "! TARGET_PARTIAL_REG_STALL && reload_completed
19003 && ((GET_MODE (operands[0]) == HImode
19004 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19005 /* ??? next two lines just !satisfies_constraint_K (...) */
19006 || !CONST_INT_P (operands[2])
19007 || satisfies_constraint_K (operands[2])))
19008 || (GET_MODE (operands[0]) == QImode
19009 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19010 [(parallel [(set (match_dup 0)
19011 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19012 (clobber (reg:CC FLAGS_REG))])]
19013 "operands[0] = gen_lowpart (SImode, operands[0]);
19014 operands[1] = gen_lowpart (SImode, operands[1]);
19015 if (GET_CODE (operands[3]) != ASHIFT)
19016 operands[2] = gen_lowpart (SImode, operands[2]);
19017 PUT_MODE (operands[3], SImode);")
19019 ; Promote the QImode tests, as i386 has encoding of the AND
19020 ; instruction with 32-bit sign-extended immediate and thus the
19021 ; instruction size is unchanged, except in the %eax case for
19022 ; which it is increased by one byte, hence the ! optimize_size.
19024 [(set (match_operand 0 "flags_reg_operand" "")
19025 (match_operator 2 "compare_operator"
19026 [(and (match_operand 3 "aligned_operand" "")
19027 (match_operand 4 "const_int_operand" ""))
19029 (set (match_operand 1 "register_operand" "")
19030 (and (match_dup 3) (match_dup 4)))]
19031 "! TARGET_PARTIAL_REG_STALL && reload_completed
19032 && optimize_insn_for_speed_p ()
19033 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19034 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19035 /* Ensure that the operand will remain sign-extended immediate. */
19036 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19037 [(parallel [(set (match_dup 0)
19038 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19041 (and:SI (match_dup 3) (match_dup 4)))])]
19044 = gen_int_mode (INTVAL (operands[4])
19045 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19046 operands[1] = gen_lowpart (SImode, operands[1]);
19047 operands[3] = gen_lowpart (SImode, operands[3]);
19050 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19051 ; the TEST instruction with 32-bit sign-extended immediate and thus
19052 ; the instruction size would at least double, which is not what we
19053 ; want even with ! optimize_size.
19055 [(set (match_operand 0 "flags_reg_operand" "")
19056 (match_operator 1 "compare_operator"
19057 [(and (match_operand:HI 2 "aligned_operand" "")
19058 (match_operand:HI 3 "const_int_operand" ""))
19060 "! TARGET_PARTIAL_REG_STALL && reload_completed
19061 && ! TARGET_FAST_PREFIX
19062 && optimize_insn_for_speed_p ()
19063 /* Ensure that the operand will remain sign-extended immediate. */
19064 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19065 [(set (match_dup 0)
19066 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19070 = gen_int_mode (INTVAL (operands[3])
19071 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19072 operands[2] = gen_lowpart (SImode, operands[2]);
19076 [(set (match_operand 0 "register_operand" "")
19077 (neg (match_operand 1 "register_operand" "")))
19078 (clobber (reg:CC FLAGS_REG))]
19079 "! TARGET_PARTIAL_REG_STALL && reload_completed
19080 && (GET_MODE (operands[0]) == HImode
19081 || (GET_MODE (operands[0]) == QImode
19082 && (TARGET_PROMOTE_QImode
19083 || optimize_insn_for_size_p ())))"
19084 [(parallel [(set (match_dup 0)
19085 (neg:SI (match_dup 1)))
19086 (clobber (reg:CC FLAGS_REG))])]
19087 "operands[0] = gen_lowpart (SImode, operands[0]);
19088 operands[1] = gen_lowpart (SImode, operands[1]);")
19091 [(set (match_operand 0 "register_operand" "")
19092 (not (match_operand 1 "register_operand" "")))]
19093 "! TARGET_PARTIAL_REG_STALL && reload_completed
19094 && (GET_MODE (operands[0]) == HImode
19095 || (GET_MODE (operands[0]) == QImode
19096 && (TARGET_PROMOTE_QImode
19097 || optimize_insn_for_size_p ())))"
19098 [(set (match_dup 0)
19099 (not:SI (match_dup 1)))]
19100 "operands[0] = gen_lowpart (SImode, operands[0]);
19101 operands[1] = gen_lowpart (SImode, operands[1]);")
19104 [(set (match_operand 0 "register_operand" "")
19105 (if_then_else (match_operator 1 "comparison_operator"
19106 [(reg FLAGS_REG) (const_int 0)])
19107 (match_operand 2 "register_operand" "")
19108 (match_operand 3 "register_operand" "")))]
19109 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19110 && (GET_MODE (operands[0]) == HImode
19111 || (GET_MODE (operands[0]) == QImode
19112 && (TARGET_PROMOTE_QImode
19113 || optimize_insn_for_size_p ())))"
19114 [(set (match_dup 0)
19115 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19116 "operands[0] = gen_lowpart (SImode, operands[0]);
19117 operands[2] = gen_lowpart (SImode, operands[2]);
19118 operands[3] = gen_lowpart (SImode, operands[3]);")
19121 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19122 ;; transform a complex memory operation into two memory to register operations.
19124 ;; Don't push memory operands
19126 [(set (match_operand:SI 0 "push_operand" "")
19127 (match_operand:SI 1 "memory_operand" ""))
19128 (match_scratch:SI 2 "r")]
19129 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19130 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19131 [(set (match_dup 2) (match_dup 1))
19132 (set (match_dup 0) (match_dup 2))]
19136 [(set (match_operand:DI 0 "push_operand" "")
19137 (match_operand:DI 1 "memory_operand" ""))
19138 (match_scratch:DI 2 "r")]
19139 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19140 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19141 [(set (match_dup 2) (match_dup 1))
19142 (set (match_dup 0) (match_dup 2))]
19145 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19148 [(set (match_operand:SF 0 "push_operand" "")
19149 (match_operand:SF 1 "memory_operand" ""))
19150 (match_scratch:SF 2 "r")]
19151 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19152 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19153 [(set (match_dup 2) (match_dup 1))
19154 (set (match_dup 0) (match_dup 2))]
19158 [(set (match_operand:HI 0 "push_operand" "")
19159 (match_operand:HI 1 "memory_operand" ""))
19160 (match_scratch:HI 2 "r")]
19161 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19162 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19163 [(set (match_dup 2) (match_dup 1))
19164 (set (match_dup 0) (match_dup 2))]
19168 [(set (match_operand:QI 0 "push_operand" "")
19169 (match_operand:QI 1 "memory_operand" ""))
19170 (match_scratch:QI 2 "q")]
19171 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19172 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19173 [(set (match_dup 2) (match_dup 1))
19174 (set (match_dup 0) (match_dup 2))]
19177 ;; Don't move an immediate directly to memory when the instruction
19180 [(match_scratch:SI 1 "r")
19181 (set (match_operand:SI 0 "memory_operand" "")
19183 "optimize_insn_for_speed_p ()
19184 && ! TARGET_USE_MOV0
19185 && TARGET_SPLIT_LONG_MOVES
19186 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19187 && peep2_regno_dead_p (0, FLAGS_REG)"
19188 [(parallel [(set (match_dup 1) (const_int 0))
19189 (clobber (reg:CC FLAGS_REG))])
19190 (set (match_dup 0) (match_dup 1))]
19194 [(match_scratch:HI 1 "r")
19195 (set (match_operand:HI 0 "memory_operand" "")
19197 "optimize_insn_for_speed_p ()
19198 && ! TARGET_USE_MOV0
19199 && TARGET_SPLIT_LONG_MOVES
19200 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19201 && peep2_regno_dead_p (0, FLAGS_REG)"
19202 [(parallel [(set (match_dup 2) (const_int 0))
19203 (clobber (reg:CC FLAGS_REG))])
19204 (set (match_dup 0) (match_dup 1))]
19205 "operands[2] = gen_lowpart (SImode, operands[1]);")
19208 [(match_scratch:QI 1 "q")
19209 (set (match_operand:QI 0 "memory_operand" "")
19211 "optimize_insn_for_speed_p ()
19212 && ! TARGET_USE_MOV0
19213 && TARGET_SPLIT_LONG_MOVES
19214 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19215 && peep2_regno_dead_p (0, FLAGS_REG)"
19216 [(parallel [(set (match_dup 2) (const_int 0))
19217 (clobber (reg:CC FLAGS_REG))])
19218 (set (match_dup 0) (match_dup 1))]
19219 "operands[2] = gen_lowpart (SImode, operands[1]);")
19222 [(match_scratch:SI 2 "r")
19223 (set (match_operand:SI 0 "memory_operand" "")
19224 (match_operand:SI 1 "immediate_operand" ""))]
19225 "optimize_insn_for_speed_p ()
19226 && TARGET_SPLIT_LONG_MOVES
19227 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19228 [(set (match_dup 2) (match_dup 1))
19229 (set (match_dup 0) (match_dup 2))]
19233 [(match_scratch:HI 2 "r")
19234 (set (match_operand:HI 0 "memory_operand" "")
19235 (match_operand:HI 1 "immediate_operand" ""))]
19236 "optimize_insn_for_speed_p ()
19237 && TARGET_SPLIT_LONG_MOVES
19238 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19239 [(set (match_dup 2) (match_dup 1))
19240 (set (match_dup 0) (match_dup 2))]
19244 [(match_scratch:QI 2 "q")
19245 (set (match_operand:QI 0 "memory_operand" "")
19246 (match_operand:QI 1 "immediate_operand" ""))]
19247 "optimize_insn_for_speed_p ()
19248 && TARGET_SPLIT_LONG_MOVES
19249 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19250 [(set (match_dup 2) (match_dup 1))
19251 (set (match_dup 0) (match_dup 2))]
19254 ;; Don't compare memory with zero, load and use a test instead.
19256 [(set (match_operand 0 "flags_reg_operand" "")
19257 (match_operator 1 "compare_operator"
19258 [(match_operand:SI 2 "memory_operand" "")
19260 (match_scratch:SI 3 "r")]
19261 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19262 [(set (match_dup 3) (match_dup 2))
19263 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19266 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19267 ;; Don't split NOTs with a displacement operand, because resulting XOR
19268 ;; will not be pairable anyway.
19270 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19271 ;; represented using a modRM byte. The XOR replacement is long decoded,
19272 ;; so this split helps here as well.
19274 ;; Note: Can't do this as a regular split because we can't get proper
19275 ;; lifetime information then.
19278 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19279 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19280 "optimize_insn_for_speed_p ()
19281 && ((TARGET_NOT_UNPAIRABLE
19282 && (!MEM_P (operands[0])
19283 || !memory_displacement_operand (operands[0], SImode)))
19284 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19285 && peep2_regno_dead_p (0, FLAGS_REG)"
19286 [(parallel [(set (match_dup 0)
19287 (xor:SI (match_dup 1) (const_int -1)))
19288 (clobber (reg:CC FLAGS_REG))])]
19292 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19293 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19294 "optimize_insn_for_speed_p ()
19295 && ((TARGET_NOT_UNPAIRABLE
19296 && (!MEM_P (operands[0])
19297 || !memory_displacement_operand (operands[0], HImode)))
19298 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19299 && peep2_regno_dead_p (0, FLAGS_REG)"
19300 [(parallel [(set (match_dup 0)
19301 (xor:HI (match_dup 1) (const_int -1)))
19302 (clobber (reg:CC FLAGS_REG))])]
19306 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19307 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19308 "optimize_insn_for_speed_p ()
19309 && ((TARGET_NOT_UNPAIRABLE
19310 && (!MEM_P (operands[0])
19311 || !memory_displacement_operand (operands[0], QImode)))
19312 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19313 && peep2_regno_dead_p (0, FLAGS_REG)"
19314 [(parallel [(set (match_dup 0)
19315 (xor:QI (match_dup 1) (const_int -1)))
19316 (clobber (reg:CC FLAGS_REG))])]
19319 ;; Non pairable "test imm, reg" instructions can be translated to
19320 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19321 ;; byte opcode instead of two, have a short form for byte operands),
19322 ;; so do it for other CPUs as well. Given that the value was dead,
19323 ;; this should not create any new dependencies. Pass on the sub-word
19324 ;; versions if we're concerned about partial register stalls.
19327 [(set (match_operand 0 "flags_reg_operand" "")
19328 (match_operator 1 "compare_operator"
19329 [(and:SI (match_operand:SI 2 "register_operand" "")
19330 (match_operand:SI 3 "immediate_operand" ""))
19332 "ix86_match_ccmode (insn, CCNOmode)
19333 && (true_regnum (operands[2]) != AX_REG
19334 || satisfies_constraint_K (operands[3]))
19335 && peep2_reg_dead_p (1, operands[2])"
19337 [(set (match_dup 0)
19338 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19341 (and:SI (match_dup 2) (match_dup 3)))])]
19344 ;; We don't need to handle HImode case, because it will be promoted to SImode
19345 ;; on ! TARGET_PARTIAL_REG_STALL
19348 [(set (match_operand 0 "flags_reg_operand" "")
19349 (match_operator 1 "compare_operator"
19350 [(and:QI (match_operand:QI 2 "register_operand" "")
19351 (match_operand:QI 3 "immediate_operand" ""))
19353 "! TARGET_PARTIAL_REG_STALL
19354 && ix86_match_ccmode (insn, CCNOmode)
19355 && true_regnum (operands[2]) != AX_REG
19356 && peep2_reg_dead_p (1, operands[2])"
19358 [(set (match_dup 0)
19359 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19362 (and:QI (match_dup 2) (match_dup 3)))])]
19366 [(set (match_operand 0 "flags_reg_operand" "")
19367 (match_operator 1 "compare_operator"
19370 (match_operand 2 "ext_register_operand" "")
19373 (match_operand 3 "const_int_operand" ""))
19375 "! TARGET_PARTIAL_REG_STALL
19376 && ix86_match_ccmode (insn, CCNOmode)
19377 && true_regnum (operands[2]) != AX_REG
19378 && peep2_reg_dead_p (1, operands[2])"
19379 [(parallel [(set (match_dup 0)
19388 (set (zero_extract:SI (match_dup 2)
19399 ;; Don't do logical operations with memory inputs.
19401 [(match_scratch:SI 2 "r")
19402 (parallel [(set (match_operand:SI 0 "register_operand" "")
19403 (match_operator:SI 3 "arith_or_logical_operator"
19405 (match_operand:SI 1 "memory_operand" "")]))
19406 (clobber (reg:CC FLAGS_REG))])]
19407 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19408 [(set (match_dup 2) (match_dup 1))
19409 (parallel [(set (match_dup 0)
19410 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19411 (clobber (reg:CC FLAGS_REG))])]
19415 [(match_scratch:SI 2 "r")
19416 (parallel [(set (match_operand:SI 0 "register_operand" "")
19417 (match_operator:SI 3 "arith_or_logical_operator"
19418 [(match_operand:SI 1 "memory_operand" "")
19420 (clobber (reg:CC FLAGS_REG))])]
19421 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19422 [(set (match_dup 2) (match_dup 1))
19423 (parallel [(set (match_dup 0)
19424 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19425 (clobber (reg:CC FLAGS_REG))])]
19428 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
19429 ;; refers to the destination of the load!
19432 [(set (match_operand:SI 0 "register_operand" "")
19433 (match_operand:SI 1 "register_operand" ""))
19434 (parallel [(set (match_dup 0)
19435 (match_operator:SI 3 "commutative_operator"
19437 (match_operand:SI 2 "memory_operand" "")]))
19438 (clobber (reg:CC FLAGS_REG))])]
19439 "REGNO (operands[0]) != REGNO (operands[1])
19440 && GENERAL_REGNO_P (REGNO (operands[0]))
19441 && GENERAL_REGNO_P (REGNO (operands[1]))"
19442 [(set (match_dup 0) (match_dup 4))
19443 (parallel [(set (match_dup 0)
19444 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19445 (clobber (reg:CC FLAGS_REG))])]
19446 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19449 [(set (match_operand 0 "register_operand" "")
19450 (match_operand 1 "register_operand" ""))
19452 (match_operator 3 "commutative_operator"
19454 (match_operand 2 "memory_operand" "")]))]
19455 "REGNO (operands[0]) != REGNO (operands[1])
19456 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
19457 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19458 [(set (match_dup 0) (match_dup 2))
19460 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19463 ; Don't do logical operations with memory outputs
19465 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19466 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19467 ; the same decoder scheduling characteristics as the original.
19470 [(match_scratch:SI 2 "r")
19471 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19472 (match_operator:SI 3 "arith_or_logical_operator"
19474 (match_operand:SI 1 "nonmemory_operand" "")]))
19475 (clobber (reg:CC FLAGS_REG))])]
19476 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19477 /* Do not split stack checking probes. */
19478 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19479 [(set (match_dup 2) (match_dup 0))
19480 (parallel [(set (match_dup 2)
19481 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19482 (clobber (reg:CC FLAGS_REG))])
19483 (set (match_dup 0) (match_dup 2))]
19487 [(match_scratch:SI 2 "r")
19488 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19489 (match_operator:SI 3 "arith_or_logical_operator"
19490 [(match_operand:SI 1 "nonmemory_operand" "")
19492 (clobber (reg:CC FLAGS_REG))])]
19493 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19494 /* Do not split stack checking probes. */
19495 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19496 [(set (match_dup 2) (match_dup 0))
19497 (parallel [(set (match_dup 2)
19498 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19499 (clobber (reg:CC FLAGS_REG))])
19500 (set (match_dup 0) (match_dup 2))]
19503 ;; Attempt to always use XOR for zeroing registers.
19505 [(set (match_operand 0 "register_operand" "")
19506 (match_operand 1 "const0_operand" ""))]
19507 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19508 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19509 && GENERAL_REG_P (operands[0])
19510 && peep2_regno_dead_p (0, FLAGS_REG)"
19511 [(parallel [(set (match_dup 0) (const_int 0))
19512 (clobber (reg:CC FLAGS_REG))])]
19514 operands[0] = gen_lowpart (word_mode, operands[0]);
19518 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19520 "(GET_MODE (operands[0]) == QImode
19521 || GET_MODE (operands[0]) == HImode)
19522 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19523 && peep2_regno_dead_p (0, FLAGS_REG)"
19524 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19525 (clobber (reg:CC FLAGS_REG))])])
19527 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19529 [(set (match_operand 0 "register_operand" "")
19531 "(GET_MODE (operands[0]) == HImode
19532 || GET_MODE (operands[0]) == SImode
19533 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19534 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19535 && peep2_regno_dead_p (0, FLAGS_REG)"
19536 [(parallel [(set (match_dup 0) (const_int -1))
19537 (clobber (reg:CC FLAGS_REG))])]
19538 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19541 ;; Attempt to convert simple leas to adds. These can be created by
19544 [(set (match_operand:SI 0 "register_operand" "")
19545 (plus:SI (match_dup 0)
19546 (match_operand:SI 1 "nonmemory_operand" "")))]
19547 "peep2_regno_dead_p (0, FLAGS_REG)"
19548 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19549 (clobber (reg:CC FLAGS_REG))])]
19553 [(set (match_operand:SI 0 "register_operand" "")
19554 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19555 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19556 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19557 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19558 (clobber (reg:CC FLAGS_REG))])]
19559 "operands[2] = gen_lowpart (SImode, operands[2]);")
19562 [(set (match_operand:DI 0 "register_operand" "")
19563 (plus:DI (match_dup 0)
19564 (match_operand:DI 1 "x86_64_general_operand" "")))]
19565 "peep2_regno_dead_p (0, FLAGS_REG)"
19566 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19567 (clobber (reg:CC FLAGS_REG))])]
19571 [(set (match_operand:SI 0 "register_operand" "")
19572 (mult:SI (match_dup 0)
19573 (match_operand:SI 1 "const_int_operand" "")))]
19574 "exact_log2 (INTVAL (operands[1])) >= 0
19575 && peep2_regno_dead_p (0, FLAGS_REG)"
19576 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19577 (clobber (reg:CC FLAGS_REG))])]
19578 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19581 [(set (match_operand:DI 0 "register_operand" "")
19582 (mult:DI (match_dup 0)
19583 (match_operand:DI 1 "const_int_operand" "")))]
19584 "exact_log2 (INTVAL (operands[1])) >= 0
19585 && peep2_regno_dead_p (0, FLAGS_REG)"
19586 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19587 (clobber (reg:CC FLAGS_REG))])]
19588 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19591 [(set (match_operand:SI 0 "register_operand" "")
19592 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19593 (match_operand:DI 2 "const_int_operand" "")) 0))]
19594 "exact_log2 (INTVAL (operands[2])) >= 0
19595 && REGNO (operands[0]) == REGNO (operands[1])
19596 && peep2_regno_dead_p (0, FLAGS_REG)"
19597 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19598 (clobber (reg:CC FLAGS_REG))])]
19599 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19601 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19602 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19603 ;; many CPUs it is also faster, since special hardware to avoid esp
19604 ;; dependencies is present.
19606 ;; While some of these conversions may be done using splitters, we use peepholes
19607 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19609 ;; Convert prologue esp subtractions to push.
19610 ;; We need register to push. In order to keep verify_flow_info happy we have
19612 ;; - use scratch and clobber it in order to avoid dependencies
19613 ;; - use already live register
19614 ;; We can't use the second way right now, since there is no reliable way how to
19615 ;; verify that given register is live. First choice will also most likely in
19616 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19617 ;; call clobbered registers are dead. We may want to use base pointer as an
19618 ;; alternative when no register is available later.
19621 [(match_scratch:SI 0 "r")
19622 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19623 (clobber (reg:CC FLAGS_REG))
19624 (clobber (mem:BLK (scratch)))])]
19625 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19626 [(clobber (match_dup 0))
19627 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19628 (clobber (mem:BLK (scratch)))])])
19631 [(match_scratch:SI 0 "r")
19632 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19633 (clobber (reg:CC FLAGS_REG))
19634 (clobber (mem:BLK (scratch)))])]
19635 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19636 [(clobber (match_dup 0))
19637 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19638 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19639 (clobber (mem:BLK (scratch)))])])
19641 ;; Convert esp subtractions to push.
19643 [(match_scratch:SI 0 "r")
19644 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19645 (clobber (reg:CC FLAGS_REG))])]
19646 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19647 [(clobber (match_dup 0))
19648 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19651 [(match_scratch:SI 0 "r")
19652 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19653 (clobber (reg:CC FLAGS_REG))])]
19654 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19655 [(clobber (match_dup 0))
19656 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19657 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19659 ;; Convert epilogue deallocator to pop.
19661 [(match_scratch:SI 0 "r")
19662 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19663 (clobber (reg:CC FLAGS_REG))
19664 (clobber (mem:BLK (scratch)))])]
19665 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19666 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19667 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19668 (clobber (mem:BLK (scratch)))])]
19671 ;; Two pops case is tricky, since pop causes dependency on destination register.
19672 ;; We use two registers if available.
19674 [(match_scratch:SI 0 "r")
19675 (match_scratch:SI 1 "r")
19676 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19677 (clobber (reg:CC FLAGS_REG))
19678 (clobber (mem:BLK (scratch)))])]
19679 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19680 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19681 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19682 (clobber (mem:BLK (scratch)))])
19683 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19684 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19688 [(match_scratch:SI 0 "r")
19689 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19690 (clobber (reg:CC FLAGS_REG))
19691 (clobber (mem:BLK (scratch)))])]
19692 "optimize_insn_for_size_p ()"
19693 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19694 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19695 (clobber (mem:BLK (scratch)))])
19696 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19697 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19700 ;; Convert esp additions to pop.
19702 [(match_scratch:SI 0 "r")
19703 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19704 (clobber (reg:CC FLAGS_REG))])]
19706 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19707 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19710 ;; Two pops case is tricky, since pop causes dependency on destination register.
19711 ;; We use two registers if available.
19713 [(match_scratch:SI 0 "r")
19714 (match_scratch:SI 1 "r")
19715 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19716 (clobber (reg:CC FLAGS_REG))])]
19718 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19719 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19720 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19721 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19725 [(match_scratch:SI 0 "r")
19726 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19727 (clobber (reg:CC FLAGS_REG))])]
19728 "optimize_insn_for_size_p ()"
19729 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19730 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19731 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19732 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19735 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19736 ;; required and register dies. Similarly for 128 to -128.
19738 [(set (match_operand 0 "flags_reg_operand" "")
19739 (match_operator 1 "compare_operator"
19740 [(match_operand 2 "register_operand" "")
19741 (match_operand 3 "const_int_operand" "")]))]
19742 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19743 && incdec_operand (operands[3], GET_MODE (operands[3])))
19744 || (!TARGET_FUSE_CMP_AND_BRANCH
19745 && INTVAL (operands[3]) == 128))
19746 && ix86_match_ccmode (insn, CCGCmode)
19747 && peep2_reg_dead_p (1, operands[2])"
19748 [(parallel [(set (match_dup 0)
19749 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19750 (clobber (match_dup 2))])]
19754 [(match_scratch:DI 0 "r")
19755 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19756 (clobber (reg:CC FLAGS_REG))
19757 (clobber (mem:BLK (scratch)))])]
19758 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19759 [(clobber (match_dup 0))
19760 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19761 (clobber (mem:BLK (scratch)))])])
19764 [(match_scratch:DI 0 "r")
19765 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19766 (clobber (reg:CC FLAGS_REG))
19767 (clobber (mem:BLK (scratch)))])]
19768 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19769 [(clobber (match_dup 0))
19770 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19771 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19772 (clobber (mem:BLK (scratch)))])])
19774 ;; Convert esp subtractions to push.
19776 [(match_scratch:DI 0 "r")
19777 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19778 (clobber (reg:CC FLAGS_REG))])]
19779 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19780 [(clobber (match_dup 0))
19781 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19784 [(match_scratch:DI 0 "r")
19785 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19786 (clobber (reg:CC FLAGS_REG))])]
19787 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19788 [(clobber (match_dup 0))
19789 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19790 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19792 ;; Convert epilogue deallocator to pop.
19794 [(match_scratch:DI 0 "r")
19795 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19796 (clobber (reg:CC FLAGS_REG))
19797 (clobber (mem:BLK (scratch)))])]
19798 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19799 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19800 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19801 (clobber (mem:BLK (scratch)))])]
19804 ;; Two pops case is tricky, since pop causes dependency on destination register.
19805 ;; We use two registers if available.
19807 [(match_scratch:DI 0 "r")
19808 (match_scratch:DI 1 "r")
19809 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19810 (clobber (reg:CC FLAGS_REG))
19811 (clobber (mem:BLK (scratch)))])]
19812 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19813 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19814 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19815 (clobber (mem:BLK (scratch)))])
19816 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19817 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19821 [(match_scratch:DI 0 "r")
19822 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19823 (clobber (reg:CC FLAGS_REG))
19824 (clobber (mem:BLK (scratch)))])]
19825 "optimize_insn_for_size_p ()"
19826 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19827 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19828 (clobber (mem:BLK (scratch)))])
19829 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19830 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19833 ;; Convert esp additions to pop.
19835 [(match_scratch:DI 0 "r")
19836 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19837 (clobber (reg:CC FLAGS_REG))])]
19839 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19840 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19843 ;; Two pops case is tricky, since pop causes dependency on destination register.
19844 ;; We use two registers if available.
19846 [(match_scratch:DI 0 "r")
19847 (match_scratch:DI 1 "r")
19848 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19849 (clobber (reg:CC FLAGS_REG))])]
19851 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19852 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19853 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19854 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19858 [(match_scratch:DI 0 "r")
19859 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19860 (clobber (reg:CC FLAGS_REG))])]
19861 "optimize_insn_for_size_p ()"
19862 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19863 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19864 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19865 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19868 ;; Convert imul by three, five and nine into lea
19871 [(set (match_operand:SI 0 "register_operand" "")
19872 (mult:SI (match_operand:SI 1 "register_operand" "")
19873 (match_operand:SI 2 "const_int_operand" "")))
19874 (clobber (reg:CC FLAGS_REG))])]
19875 "INTVAL (operands[2]) == 3
19876 || INTVAL (operands[2]) == 5
19877 || INTVAL (operands[2]) == 9"
19878 [(set (match_dup 0)
19879 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19881 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19885 [(set (match_operand:SI 0 "register_operand" "")
19886 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19887 (match_operand:SI 2 "const_int_operand" "")))
19888 (clobber (reg:CC FLAGS_REG))])]
19889 "optimize_insn_for_speed_p ()
19890 && (INTVAL (operands[2]) == 3
19891 || INTVAL (operands[2]) == 5
19892 || INTVAL (operands[2]) == 9)"
19893 [(set (match_dup 0) (match_dup 1))
19895 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19897 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19901 [(set (match_operand:DI 0 "register_operand" "")
19902 (mult:DI (match_operand:DI 1 "register_operand" "")
19903 (match_operand:DI 2 "const_int_operand" "")))
19904 (clobber (reg:CC FLAGS_REG))])]
19906 && (INTVAL (operands[2]) == 3
19907 || INTVAL (operands[2]) == 5
19908 || INTVAL (operands[2]) == 9)"
19909 [(set (match_dup 0)
19910 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19912 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19916 [(set (match_operand:DI 0 "register_operand" "")
19917 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19918 (match_operand:DI 2 "const_int_operand" "")))
19919 (clobber (reg:CC FLAGS_REG))])]
19921 && optimize_insn_for_speed_p ()
19922 && (INTVAL (operands[2]) == 3
19923 || INTVAL (operands[2]) == 5
19924 || INTVAL (operands[2]) == 9)"
19925 [(set (match_dup 0) (match_dup 1))
19927 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19929 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19931 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19932 ;; imul $32bit_imm, reg, reg is direct decoded.
19934 [(match_scratch:DI 3 "r")
19935 (parallel [(set (match_operand:DI 0 "register_operand" "")
19936 (mult:DI (match_operand:DI 1 "memory_operand" "")
19937 (match_operand:DI 2 "immediate_operand" "")))
19938 (clobber (reg:CC FLAGS_REG))])]
19939 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19940 && !satisfies_constraint_K (operands[2])"
19941 [(set (match_dup 3) (match_dup 1))
19942 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19943 (clobber (reg:CC FLAGS_REG))])]
19947 [(match_scratch:SI 3 "r")
19948 (parallel [(set (match_operand:SI 0 "register_operand" "")
19949 (mult:SI (match_operand:SI 1 "memory_operand" "")
19950 (match_operand:SI 2 "immediate_operand" "")))
19951 (clobber (reg:CC FLAGS_REG))])]
19952 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19953 && !satisfies_constraint_K (operands[2])"
19954 [(set (match_dup 3) (match_dup 1))
19955 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19956 (clobber (reg:CC FLAGS_REG))])]
19960 [(match_scratch:SI 3 "r")
19961 (parallel [(set (match_operand:DI 0 "register_operand" "")
19963 (mult:SI (match_operand:SI 1 "memory_operand" "")
19964 (match_operand:SI 2 "immediate_operand" ""))))
19965 (clobber (reg:CC FLAGS_REG))])]
19966 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19967 && !satisfies_constraint_K (operands[2])"
19968 [(set (match_dup 3) (match_dup 1))
19969 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19970 (clobber (reg:CC FLAGS_REG))])]
19973 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19974 ;; Convert it into imul reg, reg
19975 ;; It would be better to force assembler to encode instruction using long
19976 ;; immediate, but there is apparently no way to do so.
19978 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19979 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19980 (match_operand:DI 2 "const_int_operand" "")))
19981 (clobber (reg:CC FLAGS_REG))])
19982 (match_scratch:DI 3 "r")]
19983 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19984 && satisfies_constraint_K (operands[2])"
19985 [(set (match_dup 3) (match_dup 2))
19986 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19987 (clobber (reg:CC FLAGS_REG))])]
19989 if (!rtx_equal_p (operands[0], operands[1]))
19990 emit_move_insn (operands[0], operands[1]);
19994 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19995 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19996 (match_operand:SI 2 "const_int_operand" "")))
19997 (clobber (reg:CC FLAGS_REG))])
19998 (match_scratch:SI 3 "r")]
19999 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20000 && satisfies_constraint_K (operands[2])"
20001 [(set (match_dup 3) (match_dup 2))
20002 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20003 (clobber (reg:CC FLAGS_REG))])]
20005 if (!rtx_equal_p (operands[0], operands[1]))
20006 emit_move_insn (operands[0], operands[1]);
20010 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20011 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20012 (match_operand:HI 2 "immediate_operand" "")))
20013 (clobber (reg:CC FLAGS_REG))])
20014 (match_scratch:HI 3 "r")]
20015 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20016 [(set (match_dup 3) (match_dup 2))
20017 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20018 (clobber (reg:CC FLAGS_REG))])]
20020 if (!rtx_equal_p (operands[0], operands[1]))
20021 emit_move_insn (operands[0], operands[1]);
20024 ;; After splitting up read-modify operations, array accesses with memory
20025 ;; operands might end up in form:
20027 ;; movl 4(%esp), %edx
20029 ;; instead of pre-splitting:
20031 ;; addl 4(%esp), %eax
20033 ;; movl 4(%esp), %edx
20034 ;; leal (%edx,%eax,4), %eax
20037 [(parallel [(set (match_operand 0 "register_operand" "")
20038 (ashift (match_operand 1 "register_operand" "")
20039 (match_operand 2 "const_int_operand" "")))
20040 (clobber (reg:CC FLAGS_REG))])
20041 (set (match_operand 3 "register_operand")
20042 (match_operand 4 "x86_64_general_operand" ""))
20043 (parallel [(set (match_operand 5 "register_operand" "")
20044 (plus (match_operand 6 "register_operand" "")
20045 (match_operand 7 "register_operand" "")))
20046 (clobber (reg:CC FLAGS_REG))])]
20047 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20048 /* Validate MODE for lea. */
20049 && ((!TARGET_PARTIAL_REG_STALL
20050 && (GET_MODE (operands[0]) == QImode
20051 || GET_MODE (operands[0]) == HImode))
20052 || GET_MODE (operands[0]) == SImode
20053 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20054 /* We reorder load and the shift. */
20055 && !rtx_equal_p (operands[1], operands[3])
20056 && !reg_overlap_mentioned_p (operands[0], operands[4])
20057 /* Last PLUS must consist of operand 0 and 3. */
20058 && !rtx_equal_p (operands[0], operands[3])
20059 && (rtx_equal_p (operands[3], operands[6])
20060 || rtx_equal_p (operands[3], operands[7]))
20061 && (rtx_equal_p (operands[0], operands[6])
20062 || rtx_equal_p (operands[0], operands[7]))
20063 /* The intermediate operand 0 must die or be same as output. */
20064 && (rtx_equal_p (operands[0], operands[5])
20065 || peep2_reg_dead_p (3, operands[0]))"
20066 [(set (match_dup 3) (match_dup 4))
20067 (set (match_dup 0) (match_dup 1))]
20069 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20070 int scale = 1 << INTVAL (operands[2]);
20071 rtx index = gen_lowpart (Pmode, operands[1]);
20072 rtx base = gen_lowpart (Pmode, operands[3]);
20073 rtx dest = gen_lowpart (mode, operands[5]);
20075 operands[1] = gen_rtx_PLUS (Pmode, base,
20076 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20078 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20079 operands[0] = dest;
20082 ;; Call-value patterns last so that the wildcard operand does not
20083 ;; disrupt insn-recog's switch tables.
20085 (define_insn "*call_value_pop_0"
20086 [(set (match_operand 0 "" "")
20087 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20088 (match_operand:SI 2 "" "")))
20089 (set (reg:SI SP_REG)
20090 (plus:SI (reg:SI SP_REG)
20091 (match_operand:SI 3 "immediate_operand" "")))]
20094 if (SIBLING_CALL_P (insn))
20097 return "call\t%P1";
20099 [(set_attr "type" "callv")])
20101 (define_insn "*call_value_pop_1"
20102 [(set (match_operand 0 "" "")
20103 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20104 (match_operand:SI 2 "" "")))
20105 (set (reg:SI SP_REG)
20106 (plus:SI (reg:SI SP_REG)
20107 (match_operand:SI 3 "immediate_operand" "i")))]
20108 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20110 if (constant_call_address_operand (operands[1], Pmode))
20111 return "call\t%P1";
20112 return "call\t%A1";
20114 [(set_attr "type" "callv")])
20116 (define_insn "*sibcall_value_pop_1"
20117 [(set (match_operand 0 "" "")
20118 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20119 (match_operand:SI 2 "" "")))
20120 (set (reg:SI SP_REG)
20121 (plus:SI (reg:SI SP_REG)
20122 (match_operand:SI 3 "immediate_operand" "i,i")))]
20123 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20127 [(set_attr "type" "callv")])
20129 (define_insn "*call_value_0"
20130 [(set (match_operand 0 "" "")
20131 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20132 (match_operand:SI 2 "" "")))]
20135 if (SIBLING_CALL_P (insn))
20138 return "call\t%P1";
20140 [(set_attr "type" "callv")])
20142 (define_insn "*call_value_0_rex64"
20143 [(set (match_operand 0 "" "")
20144 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20145 (match_operand:DI 2 "const_int_operand" "")))]
20148 if (SIBLING_CALL_P (insn))
20151 return "call\t%P1";
20153 [(set_attr "type" "callv")])
20155 (define_insn "*call_value_0_rex64_ms_sysv"
20156 [(set (match_operand 0 "" "")
20157 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20158 (match_operand:DI 2 "const_int_operand" "")))
20159 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20160 (clobber (reg:TI XMM6_REG))
20161 (clobber (reg:TI XMM7_REG))
20162 (clobber (reg:TI XMM8_REG))
20163 (clobber (reg:TI XMM9_REG))
20164 (clobber (reg:TI XMM10_REG))
20165 (clobber (reg:TI XMM11_REG))
20166 (clobber (reg:TI XMM12_REG))
20167 (clobber (reg:TI XMM13_REG))
20168 (clobber (reg:TI XMM14_REG))
20169 (clobber (reg:TI XMM15_REG))
20170 (clobber (reg:DI SI_REG))
20171 (clobber (reg:DI DI_REG))]
20172 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20174 if (SIBLING_CALL_P (insn))
20177 return "call\t%P1";
20179 [(set_attr "type" "callv")])
20181 (define_insn "*call_value_1"
20182 [(set (match_operand 0 "" "")
20183 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20184 (match_operand:SI 2 "" "")))]
20185 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20187 if (constant_call_address_operand (operands[1], Pmode))
20188 return "call\t%P1";
20189 return "call\t%A1";
20191 [(set_attr "type" "callv")])
20193 (define_insn "*sibcall_value_1"
20194 [(set (match_operand 0 "" "")
20195 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20196 (match_operand:SI 2 "" "")))]
20197 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20201 [(set_attr "type" "callv")])
20203 (define_insn "*call_value_1_rex64"
20204 [(set (match_operand 0 "" "")
20205 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20206 (match_operand:DI 2 "" "")))]
20207 "TARGET_64BIT && !SIBLING_CALL_P (insn)
20208 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20210 if (constant_call_address_operand (operands[1], Pmode))
20211 return "call\t%P1";
20212 return "call\t%A1";
20214 [(set_attr "type" "callv")])
20216 (define_insn "*call_value_1_rex64_ms_sysv"
20217 [(set (match_operand 0 "" "")
20218 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20219 (match_operand:DI 2 "" "")))
20220 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20221 (clobber (reg:TI XMM6_REG))
20222 (clobber (reg:TI XMM7_REG))
20223 (clobber (reg:TI XMM8_REG))
20224 (clobber (reg:TI XMM9_REG))
20225 (clobber (reg:TI XMM10_REG))
20226 (clobber (reg:TI XMM11_REG))
20227 (clobber (reg:TI XMM12_REG))
20228 (clobber (reg:TI XMM13_REG))
20229 (clobber (reg:TI XMM14_REG))
20230 (clobber (reg:TI XMM15_REG))
20231 (clobber (reg:DI SI_REG))
20232 (clobber (reg:DI DI_REG))]
20233 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20235 if (constant_call_address_operand (operands[1], Pmode))
20236 return "call\t%P1";
20237 return "call\t%A1";
20239 [(set_attr "type" "callv")])
20241 (define_insn "*call_value_1_rex64_large"
20242 [(set (match_operand 0 "" "")
20243 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20244 (match_operand:DI 2 "" "")))]
20245 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20247 [(set_attr "type" "callv")])
20249 (define_insn "*sibcall_value_1_rex64"
20250 [(set (match_operand 0 "" "")
20251 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20252 (match_operand:DI 2 "" "")))]
20253 "TARGET_64BIT && SIBLING_CALL_P (insn)"
20257 [(set_attr "type" "callv")])
20259 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20260 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20261 ;; caught for use by garbage collectors and the like. Using an insn that
20262 ;; maps to SIGILL makes it more likely the program will rightfully die.
20263 ;; Keeping with tradition, "6" is in honor of #UD.
20264 (define_insn "trap"
20265 [(trap_if (const_int 1) (const_int 6))]
20267 { return ASM_SHORT "0x0b0f"; }
20268 [(set_attr "length" "2")])
20270 (define_expand "sse_prologue_save"
20271 [(parallel [(set (match_operand:BLK 0 "" "")
20272 (unspec:BLK [(reg:DI XMM0_REG)
20279 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20280 (use (match_operand:DI 1 "register_operand" ""))
20281 (use (match_operand:DI 2 "immediate_operand" ""))
20282 (use (label_ref:DI (match_operand 3 "" "")))])]
20286 (define_insn "*sse_prologue_save_insn"
20287 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20288 (match_operand:DI 4 "const_int_operand" "n")))
20289 (unspec:BLK [(reg:DI XMM0_REG)
20296 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20297 (use (match_operand:DI 1 "register_operand" "r"))
20298 (use (match_operand:DI 2 "const_int_operand" "i"))
20299 (use (label_ref:DI (match_operand 3 "" "X")))]
20301 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20302 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20305 operands[0] = gen_rtx_MEM (Pmode,
20306 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20307 /* VEX instruction with a REX prefix will #UD. */
20308 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20309 gcc_unreachable ();
20311 output_asm_insn ("jmp\t%A1", operands);
20312 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20314 operands[4] = adjust_address (operands[0], DImode, i*16);
20315 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20316 PUT_MODE (operands[4], TImode);
20317 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20318 output_asm_insn ("rex", operands);
20319 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20321 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20322 CODE_LABEL_NUMBER (operands[3]));
20325 [(set_attr "type" "other")
20326 (set_attr "length_immediate" "0")
20327 (set_attr "length_address" "0")
20328 (set (attr "length")
20330 (eq (symbol_ref "TARGET_AVX") (const_int 0))
20331 (const_string "34")
20332 (const_string "42")))
20333 (set_attr "memory" "store")
20334 (set_attr "modrm" "0")
20335 (set_attr "prefix" "maybe_vex")
20336 (set_attr "mode" "DI")])
20338 (define_expand "prefetch"
20339 [(prefetch (match_operand 0 "address_operand" "")
20340 (match_operand:SI 1 "const_int_operand" "")
20341 (match_operand:SI 2 "const_int_operand" ""))]
20342 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20344 int rw = INTVAL (operands[1]);
20345 int locality = INTVAL (operands[2]);
20347 gcc_assert (rw == 0 || rw == 1);
20348 gcc_assert (locality >= 0 && locality <= 3);
20349 gcc_assert (GET_MODE (operands[0]) == Pmode
20350 || GET_MODE (operands[0]) == VOIDmode);
20352 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20353 supported by SSE counterpart or the SSE prefetch is not available
20354 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20356 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20357 operands[2] = GEN_INT (3);
20359 operands[1] = const0_rtx;
20362 (define_insn "*prefetch_sse"
20363 [(prefetch (match_operand:SI 0 "address_operand" "p")
20365 (match_operand:SI 1 "const_int_operand" ""))]
20366 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20368 static const char * const patterns[4] = {
20369 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20372 int locality = INTVAL (operands[1]);
20373 gcc_assert (locality >= 0 && locality <= 3);
20375 return patterns[locality];
20377 [(set_attr "type" "sse")
20378 (set_attr "atom_sse_attr" "prefetch")
20379 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20380 (set_attr "memory" "none")])
20382 (define_insn "*prefetch_sse_rex"
20383 [(prefetch (match_operand:DI 0 "address_operand" "p")
20385 (match_operand:SI 1 "const_int_operand" ""))]
20386 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20388 static const char * const patterns[4] = {
20389 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20392 int locality = INTVAL (operands[1]);
20393 gcc_assert (locality >= 0 && locality <= 3);
20395 return patterns[locality];
20397 [(set_attr "type" "sse")
20398 (set_attr "atom_sse_attr" "prefetch")
20399 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20400 (set_attr "memory" "none")])
20402 (define_insn "*prefetch_3dnow"
20403 [(prefetch (match_operand:SI 0 "address_operand" "p")
20404 (match_operand:SI 1 "const_int_operand" "n")
20406 "TARGET_3DNOW && !TARGET_64BIT"
20408 if (INTVAL (operands[1]) == 0)
20409 return "prefetch\t%a0";
20411 return "prefetchw\t%a0";
20413 [(set_attr "type" "mmx")
20414 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20415 (set_attr "memory" "none")])
20417 (define_insn "*prefetch_3dnow_rex"
20418 [(prefetch (match_operand:DI 0 "address_operand" "p")
20419 (match_operand:SI 1 "const_int_operand" "n")
20421 "TARGET_3DNOW && TARGET_64BIT"
20423 if (INTVAL (operands[1]) == 0)
20424 return "prefetch\t%a0";
20426 return "prefetchw\t%a0";
20428 [(set_attr "type" "mmx")
20429 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20430 (set_attr "memory" "none")])
20432 (define_expand "stack_protect_set"
20433 [(match_operand 0 "memory_operand" "")
20434 (match_operand 1 "memory_operand" "")]
20437 #ifdef TARGET_THREAD_SSP_OFFSET
20439 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20440 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20442 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20443 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20446 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20448 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20453 (define_insn "stack_protect_set_si"
20454 [(set (match_operand:SI 0 "memory_operand" "=m")
20455 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20456 (set (match_scratch:SI 2 "=&r") (const_int 0))
20457 (clobber (reg:CC FLAGS_REG))]
20459 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20460 [(set_attr "type" "multi")])
20462 (define_insn "stack_protect_set_di"
20463 [(set (match_operand:DI 0 "memory_operand" "=m")
20464 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20465 (set (match_scratch:DI 2 "=&r") (const_int 0))
20466 (clobber (reg:CC FLAGS_REG))]
20468 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20469 [(set_attr "type" "multi")])
20471 (define_insn "stack_tls_protect_set_si"
20472 [(set (match_operand:SI 0 "memory_operand" "=m")
20473 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20474 (set (match_scratch:SI 2 "=&r") (const_int 0))
20475 (clobber (reg:CC FLAGS_REG))]
20477 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20478 [(set_attr "type" "multi")])
20480 (define_insn "stack_tls_protect_set_di"
20481 [(set (match_operand:DI 0 "memory_operand" "=m")
20482 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20483 (set (match_scratch:DI 2 "=&r") (const_int 0))
20484 (clobber (reg:CC FLAGS_REG))]
20487 /* The kernel uses a different segment register for performance reasons; a
20488 system call would not have to trash the userspace segment register,
20489 which would be expensive */
20490 if (ix86_cmodel != CM_KERNEL)
20491 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20493 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20495 [(set_attr "type" "multi")])
20497 (define_expand "stack_protect_test"
20498 [(match_operand 0 "memory_operand" "")
20499 (match_operand 1 "memory_operand" "")
20500 (match_operand 2 "" "")]
20503 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20505 #ifdef TARGET_THREAD_SSP_OFFSET
20507 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20508 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20510 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20511 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20514 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20516 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20519 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20520 flags, const0_rtx, operands[2]));
20524 (define_insn "stack_protect_test_si"
20525 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20526 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20527 (match_operand:SI 2 "memory_operand" "m")]
20529 (clobber (match_scratch:SI 3 "=&r"))]
20531 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20532 [(set_attr "type" "multi")])
20534 (define_insn "stack_protect_test_di"
20535 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20536 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20537 (match_operand:DI 2 "memory_operand" "m")]
20539 (clobber (match_scratch:DI 3 "=&r"))]
20541 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20542 [(set_attr "type" "multi")])
20544 (define_insn "stack_tls_protect_test_si"
20545 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20546 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20547 (match_operand:SI 2 "const_int_operand" "i")]
20548 UNSPEC_SP_TLS_TEST))
20549 (clobber (match_scratch:SI 3 "=r"))]
20551 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20552 [(set_attr "type" "multi")])
20554 (define_insn "stack_tls_protect_test_di"
20555 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20556 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20557 (match_operand:DI 2 "const_int_operand" "i")]
20558 UNSPEC_SP_TLS_TEST))
20559 (clobber (match_scratch:DI 3 "=r"))]
20562 /* The kernel uses a different segment register for performance reasons; a
20563 system call would not have to trash the userspace segment register,
20564 which would be expensive */
20565 if (ix86_cmodel != CM_KERNEL)
20566 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20568 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20570 [(set_attr "type" "multi")])
20572 (define_insn "sse4_2_crc32<mode>"
20573 [(set (match_operand:SI 0 "register_operand" "=r")
20575 [(match_operand:SI 1 "register_operand" "0")
20576 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20578 "TARGET_SSE4_2 || TARGET_CRC32"
20579 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20580 [(set_attr "type" "sselog1")
20581 (set_attr "prefix_rep" "1")
20582 (set_attr "prefix_extra" "1")
20583 (set (attr "prefix_data16")
20584 (if_then_else (match_operand:HI 2 "" "")
20586 (const_string "*")))
20587 (set (attr "prefix_rex")
20588 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20590 (const_string "*")))
20591 (set_attr "mode" "SI")])
20593 (define_insn "sse4_2_crc32di"
20594 [(set (match_operand:DI 0 "register_operand" "=r")
20596 [(match_operand:DI 1 "register_operand" "0")
20597 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20599 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20600 "crc32{q}\t{%2, %0|%0, %2}"
20601 [(set_attr "type" "sselog1")
20602 (set_attr "prefix_rep" "1")
20603 (set_attr "prefix_extra" "1")
20604 (set_attr "mode" "DI")])
20606 (define_expand "rdpmc"
20607 [(match_operand:DI 0 "register_operand" "")
20608 (match_operand:SI 1 "register_operand" "")]
20611 rtx reg = gen_reg_rtx (DImode);
20614 /* Force operand 1 into ECX. */
20615 rtx ecx = gen_rtx_REG (SImode, CX_REG);
20616 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20617 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20622 rtvec vec = rtvec_alloc (2);
20623 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20624 rtx upper = gen_reg_rtx (DImode);
20625 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20626 gen_rtvec (1, const0_rtx),
20628 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20629 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20631 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20632 NULL, 1, OPTAB_DIRECT);
20633 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20637 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20638 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20642 (define_insn "*rdpmc"
20643 [(set (match_operand:DI 0 "register_operand" "=A")
20644 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20648 [(set_attr "type" "other")
20649 (set_attr "length" "2")])
20651 (define_insn "*rdpmc_rex64"
20652 [(set (match_operand:DI 0 "register_operand" "=a")
20653 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20655 (set (match_operand:DI 1 "register_operand" "=d")
20656 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20659 [(set_attr "type" "other")
20660 (set_attr "length" "2")])
20662 (define_expand "rdtsc"
20663 [(set (match_operand:DI 0 "register_operand" "")
20664 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20669 rtvec vec = rtvec_alloc (2);
20670 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20671 rtx upper = gen_reg_rtx (DImode);
20672 rtx lower = gen_reg_rtx (DImode);
20673 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20674 gen_rtvec (1, const0_rtx),
20676 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20677 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20679 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20680 NULL, 1, OPTAB_DIRECT);
20681 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20683 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20688 (define_insn "*rdtsc"
20689 [(set (match_operand:DI 0 "register_operand" "=A")
20690 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20693 [(set_attr "type" "other")
20694 (set_attr "length" "2")])
20696 (define_insn "*rdtsc_rex64"
20697 [(set (match_operand:DI 0 "register_operand" "=a")
20698 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20699 (set (match_operand:DI 1 "register_operand" "=d")
20700 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20703 [(set_attr "type" "other")
20704 (set_attr "length" "2")])
20706 (define_expand "rdtscp"
20707 [(match_operand:DI 0 "register_operand" "")
20708 (match_operand:SI 1 "memory_operand" "")]
20711 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20712 gen_rtvec (1, const0_rtx),
20714 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20715 gen_rtvec (1, const0_rtx),
20717 rtx reg = gen_reg_rtx (DImode);
20718 rtx tmp = gen_reg_rtx (SImode);
20722 rtvec vec = rtvec_alloc (3);
20723 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20724 rtx upper = gen_reg_rtx (DImode);
20725 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20726 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20727 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20729 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20730 NULL, 1, OPTAB_DIRECT);
20731 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20736 rtvec vec = rtvec_alloc (2);
20737 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20738 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20739 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20742 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20743 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20747 (define_insn "*rdtscp"
20748 [(set (match_operand:DI 0 "register_operand" "=A")
20749 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20750 (set (match_operand:SI 1 "register_operand" "=c")
20751 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20754 [(set_attr "type" "other")
20755 (set_attr "length" "3")])
20757 (define_insn "*rdtscp_rex64"
20758 [(set (match_operand:DI 0 "register_operand" "=a")
20759 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20760 (set (match_operand:DI 1 "register_operand" "=d")
20761 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20762 (set (match_operand:SI 2 "register_operand" "=c")
20763 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20766 [(set_attr "type" "other")
20767 (set_attr "length" "3")])
20769 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20771 ;; LWP instructions
20773 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20775 (define_expand "lwp_llwpcb"
20776 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20777 UNSPECV_LLWP_INTRINSIC)]
20781 (define_insn "*lwp_llwpcb<mode>1"
20782 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20783 UNSPECV_LLWP_INTRINSIC)]
20786 [(set_attr "type" "lwp")
20787 (set_attr "mode" "<MODE>")
20788 (set_attr "length" "5")])
20790 (define_expand "lwp_slwpcb"
20791 [(set (match_operand 0 "register_operand" "=r")
20792 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20796 emit_insn (gen_lwp_slwpcbdi (operands[0]));
20798 emit_insn (gen_lwp_slwpcbsi (operands[0]));
20802 (define_insn "lwp_slwpcb<mode>"
20803 [(set (match_operand:P 0 "register_operand" "=r")
20804 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20807 [(set_attr "type" "lwp")
20808 (set_attr "mode" "<MODE>")
20809 (set_attr "length" "5")])
20811 (define_expand "lwp_lwpval<mode>3"
20812 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20813 (match_operand:SI 2 "nonimmediate_operand" "rm")
20814 (match_operand:SI 3 "const_int_operand" "i")]
20815 UNSPECV_LWPVAL_INTRINSIC)]
20817 "/* Avoid unused variable warning. */
20820 (define_insn "*lwp_lwpval<mode>3_1"
20821 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20822 (match_operand:SI 1 "nonimmediate_operand" "rm")
20823 (match_operand:SI 2 "const_int_operand" "i")]
20824 UNSPECV_LWPVAL_INTRINSIC)]
20826 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20827 [(set_attr "type" "lwp")
20828 (set_attr "mode" "<MODE>")
20829 (set (attr "length")
20830 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20832 (define_expand "lwp_lwpins<mode>3"
20833 [(set (reg:CCC FLAGS_REG)
20834 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20835 (match_operand:SI 2 "nonimmediate_operand" "rm")
20836 (match_operand:SI 3 "const_int_operand" "i")]
20837 UNSPECV_LWPINS_INTRINSIC))
20838 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20839 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20843 (define_insn "*lwp_lwpins<mode>3_1"
20844 [(set (reg:CCC FLAGS_REG)
20845 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20846 (match_operand:SI 1 "nonimmediate_operand" "rm")
20847 (match_operand:SI 2 "const_int_operand" "i")]
20848 UNSPECV_LWPINS_INTRINSIC))]
20850 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20851 [(set_attr "type" "lwp")
20852 (set_attr "mode" "<MODE>")
20853 (set (attr "length")
20854 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20858 (include "sync.md")