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 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
61 (UNSPEC_MACHOPIC_OFFSET 10)
64 (UNSPEC_STACK_ALLOC 11)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70 (UNSPEC_SET_GOT_OFFSET 17)
71 (UNSPEC_MEMORY_BLOCKAGE 18)
76 (UNSPEC_TLS_LD_BASE 22)
79 ; Other random patterns
88 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
89 (UNSPEC_TRUNC_NOOP 39)
91 ; For SSE/MMX support:
92 (UNSPEC_FIX_NOTRUNC 40)
109 (UNSPEC_MS_TO_SYSV_CALL 48)
111 ; Generic math support
113 (UNSPEC_IEEE_MIN 51) ; not commutative
114 (UNSPEC_IEEE_MAX 52) ; not commutative
129 (UNSPEC_FRNDINT_FLOOR 70)
130 (UNSPEC_FRNDINT_CEIL 71)
131 (UNSPEC_FRNDINT_TRUNC 72)
132 (UNSPEC_FRNDINT_MASK_PM 73)
133 (UNSPEC_FIST_FLOOR 74)
134 (UNSPEC_FIST_CEIL 75)
136 ; x87 Double output FP
137 (UNSPEC_SINCOS_COS 80)
138 (UNSPEC_SINCOS_SIN 81)
139 (UNSPEC_XTRACT_FRACT 84)
140 (UNSPEC_XTRACT_EXP 85)
141 (UNSPEC_FSCALE_FRACT 86)
142 (UNSPEC_FSCALE_EXP 87)
154 (UNSPEC_SP_TLS_SET 102)
155 (UNSPEC_SP_TLS_TEST 103)
165 (UNSPEC_INSERTQI 132)
170 (UNSPEC_INSERTPS 135)
172 (UNSPEC_MOVNTDQA 137)
174 (UNSPEC_PHMINPOSUW 139)
180 (UNSPEC_PCMPESTR 144)
181 (UNSPEC_PCMPISTR 145)
184 (UNSPEC_SSE5_INTRINSIC 150)
185 (UNSPEC_SSE5_UNSIGNED_CMP 151)
186 (UNSPEC_SSE5_TRUEFALSE 152)
187 (UNSPEC_SSE5_PERMUTE 153)
189 (UNSPEC_CVTPH2PS 155)
190 (UNSPEC_CVTPS2PH 156)
194 (UNSPEC_AESENCLAST 160)
196 (UNSPEC_AESDECLAST 162)
198 (UNSPEC_AESKEYGENASSIST 164)
206 (UNSPEC_VPERMIL2F128 168)
207 (UNSPEC_MASKLOAD 169)
208 (UNSPEC_MASKSTORE 170)
214 [(UNSPECV_BLOCKAGE 0)
215 (UNSPECV_STACK_PROBE 1)
227 (UNSPECV_PROLOGUE_USE 14)
229 (UNSPECV_VZEROALL 16)
230 (UNSPECV_VZEROUPPER 17)
233 ;; Constants to represent pcomtrue/pcomfalse variants
243 ;; Constants used in the SSE5 pperm instruction
245 [(PPERM_SRC 0x00) /* copy source */
246 (PPERM_INVERT 0x20) /* invert source */
247 (PPERM_REVERSE 0x40) /* bit reverse source */
248 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
249 (PPERM_ZERO 0x80) /* all 0's */
250 (PPERM_ONES 0xa0) /* all 1's */
251 (PPERM_SIGN 0xc0) /* propagate sign bit */
252 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
253 (PPERM_SRC1 0x00) /* use first source byte */
254 (PPERM_SRC2 0x10) /* use second source byte */
257 ;; Registers by name.
309 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
312 ;; In C guard expressions, put expressions which may be compile-time
313 ;; constants first. This allows for better optimization. For
314 ;; example, write "TARGET_64BIT && reload_completed", not
315 ;; "reload_completed && TARGET_64BIT".
319 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
321 (const (symbol_ref "ix86_schedule")))
323 ;; A basic instruction type. Refinements due to arguments to be
324 ;; provided in other attributes.
327 alu,alu1,negnot,imov,imovx,lea,
328 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
329 icmp,test,ibr,setcc,icmov,
330 push,pop,call,callv,leave,
332 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
333 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
334 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
336 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
337 (const_string "other"))
339 ;; Main data type used by the insn
341 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
342 (const_string "unknown"))
344 ;; The CPU unit operations uses.
345 (define_attr "unit" "integer,i387,sse,mmx,unknown"
346 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
347 (const_string "i387")
348 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
349 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
350 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
352 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
354 (eq_attr "type" "other")
355 (const_string "unknown")]
356 (const_string "integer")))
358 ;; The (bounding maximum) length of an instruction immediate.
359 (define_attr "length_immediate" ""
360 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
363 (eq_attr "unit" "i387,sse,mmx")
365 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
367 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
368 (eq_attr "type" "imov,test")
369 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
370 (eq_attr "type" "call")
371 (if_then_else (match_operand 0 "constant_call_address_operand" "")
374 (eq_attr "type" "callv")
375 (if_then_else (match_operand 1 "constant_call_address_operand" "")
378 ;; We don't know the size before shorten_branches. Expect
379 ;; the instruction to fit for better scheduling.
380 (eq_attr "type" "ibr")
383 (symbol_ref "/* Update immediate_length and other attributes! */
384 gcc_unreachable (),1")))
386 ;; The (bounding maximum) length of an instruction address.
387 (define_attr "length_address" ""
388 (cond [(eq_attr "type" "str,other,multi,fxch")
390 (and (eq_attr "type" "call")
391 (match_operand 0 "constant_call_address_operand" ""))
393 (and (eq_attr "type" "callv")
394 (match_operand 1 "constant_call_address_operand" ""))
397 (symbol_ref "ix86_attr_length_address_default (insn)")))
399 ;; Set when length prefix is used.
400 (define_attr "prefix_data16" ""
401 (if_then_else (ior (eq_attr "mode" "HI")
402 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
406 ;; Set when string REP prefix is used.
407 (define_attr "prefix_rep" ""
408 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
415 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416 (eq_attr "unit" "sse,mmx"))
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422 (cond [(and (eq_attr "mode" "DI")
423 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
425 (and (eq_attr "mode" "QI")
426 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
429 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
435 ;; There are also additional prefixes in SSSE3.
436 (define_attr "prefix_extra" "" (const_int 0))
438 ;; Prefix used: original, VEX or maybe VEX.
439 (define_attr "prefix" "orig,vex,maybe_vex"
440 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
442 (const_string "orig")))
444 ;; There is a 8bit immediate for VEX.
445 (define_attr "prefix_vex_imm8" "" (const_int 0))
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
450 ;; The length of VEX prefix
451 (define_attr "length_vex" ""
452 (if_then_else (eq_attr "prefix_0f" "1")
453 (if_then_else (eq_attr "prefix_vex_w" "1")
454 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
455 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
456 (if_then_else (eq_attr "prefix_vex_w" "1")
457 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
458 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
460 ;; Set when modrm byte is used.
461 (define_attr "modrm" ""
462 (cond [(eq_attr "type" "str,leave")
464 (eq_attr "unit" "i387")
466 (and (eq_attr "type" "incdec")
467 (ior (match_operand:SI 1 "register_operand" "")
468 (match_operand:HI 1 "register_operand" "")))
470 (and (eq_attr "type" "push")
471 (not (match_operand 1 "memory_operand" "")))
473 (and (eq_attr "type" "pop")
474 (not (match_operand 0 "memory_operand" "")))
476 (and (eq_attr "type" "imov")
477 (ior (and (match_operand 0 "register_operand" "")
478 (match_operand 1 "immediate_operand" ""))
479 (ior (and (match_operand 0 "ax_reg_operand" "")
480 (match_operand 1 "memory_displacement_only_operand" ""))
481 (and (match_operand 0 "memory_displacement_only_operand" "")
482 (match_operand 1 "ax_reg_operand" "")))))
484 (and (eq_attr "type" "call")
485 (match_operand 0 "constant_call_address_operand" ""))
487 (and (eq_attr "type" "callv")
488 (match_operand 1 "constant_call_address_operand" ""))
493 ;; The (bounding maximum) length of an instruction in bytes.
494 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
495 ;; Later we may want to split them and compute proper length as for
497 (define_attr "length" ""
498 (cond [(eq_attr "type" "other,multi,fistp,frndint")
500 (eq_attr "type" "fcmp")
502 (eq_attr "unit" "i387")
504 (plus (attr "prefix_data16")
505 (attr "length_address")))
506 (ior (eq_attr "prefix" "vex")
507 (and (eq_attr "prefix" "maybe_vex")
508 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
509 (plus (attr "length_vex")
510 (plus (attr "prefix_vex_imm8")
512 (attr "length_address"))))]
513 (plus (plus (attr "modrm")
514 (plus (attr "prefix_0f")
515 (plus (attr "prefix_rex")
516 (plus (attr "prefix_extra")
518 (plus (attr "prefix_rep")
519 (plus (attr "prefix_data16")
520 (plus (attr "length_immediate")
521 (attr "length_address")))))))
523 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
524 ;; `store' if there is a simple memory reference therein, or `unknown'
525 ;; if the instruction is complex.
527 (define_attr "memory" "none,load,store,both,unknown"
528 (cond [(eq_attr "type" "other,multi,str")
529 (const_string "unknown")
530 (eq_attr "type" "lea,fcmov,fpspc")
531 (const_string "none")
532 (eq_attr "type" "fistp,leave")
533 (const_string "both")
534 (eq_attr "type" "frndint")
535 (const_string "load")
536 (eq_attr "type" "push")
537 (if_then_else (match_operand 1 "memory_operand" "")
538 (const_string "both")
539 (const_string "store"))
540 (eq_attr "type" "pop")
541 (if_then_else (match_operand 0 "memory_operand" "")
542 (const_string "both")
543 (const_string "load"))
544 (eq_attr "type" "setcc")
545 (if_then_else (match_operand 0 "memory_operand" "")
546 (const_string "store")
547 (const_string "none"))
548 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
549 (if_then_else (ior (match_operand 0 "memory_operand" "")
550 (match_operand 1 "memory_operand" ""))
551 (const_string "load")
552 (const_string "none"))
553 (eq_attr "type" "ibr")
554 (if_then_else (match_operand 0 "memory_operand" "")
555 (const_string "load")
556 (const_string "none"))
557 (eq_attr "type" "call")
558 (if_then_else (match_operand 0 "constant_call_address_operand" "")
559 (const_string "none")
560 (const_string "load"))
561 (eq_attr "type" "callv")
562 (if_then_else (match_operand 1 "constant_call_address_operand" "")
563 (const_string "none")
564 (const_string "load"))
565 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
566 (match_operand 1 "memory_operand" ""))
567 (const_string "both")
568 (and (match_operand 0 "memory_operand" "")
569 (match_operand 1 "memory_operand" ""))
570 (const_string "both")
571 (match_operand 0 "memory_operand" "")
572 (const_string "store")
573 (match_operand 1 "memory_operand" "")
574 (const_string "load")
576 "!alu1,negnot,ishift1,
577 imov,imovx,icmp,test,bitmanip,
579 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
580 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
581 (match_operand 2 "memory_operand" ""))
582 (const_string "load")
583 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
584 (match_operand 3 "memory_operand" ""))
585 (const_string "load")
587 (const_string "none")))
589 ;; Indicates if an instruction has both an immediate and a displacement.
591 (define_attr "imm_disp" "false,true,unknown"
592 (cond [(eq_attr "type" "other,multi")
593 (const_string "unknown")
594 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
595 (and (match_operand 0 "memory_displacement_operand" "")
596 (match_operand 1 "immediate_operand" "")))
597 (const_string "true")
598 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
599 (and (match_operand 0 "memory_displacement_operand" "")
600 (match_operand 2 "immediate_operand" "")))
601 (const_string "true")
603 (const_string "false")))
605 ;; Indicates if an FP operation has an integer source.
607 (define_attr "fp_int_src" "false,true"
608 (const_string "false"))
610 ;; Defines rounding mode of an FP operation.
612 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
613 (const_string "any"))
615 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
616 (define_attr "use_carry" "0,1" (const_string "0"))
618 ;; Define attribute to indicate unaligned ssemov insns
619 (define_attr "movu" "0,1" (const_string "0"))
621 ;; Describe a user's asm statement.
622 (define_asm_attributes
623 [(set_attr "length" "128")
624 (set_attr "type" "multi")])
626 ;; All integer comparison codes.
627 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
629 ;; All floating-point comparison codes.
630 (define_code_iterator fp_cond [unordered ordered
631 uneq unge ungt unle unlt ltgt ])
633 (define_code_iterator plusminus [plus minus])
635 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
637 ;; Base name for define_insn
638 (define_code_attr plusminus_insn
639 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
640 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
642 ;; Base name for insn mnemonic.
643 (define_code_attr plusminus_mnemonic
644 [(plus "add") (ss_plus "adds") (us_plus "addus")
645 (minus "sub") (ss_minus "subs") (us_minus "subus")])
647 ;; Mark commutative operators as such in constraints.
648 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
649 (minus "") (ss_minus "") (us_minus "")])
651 ;; Mapping of signed max and min
652 (define_code_iterator smaxmin [smax smin])
654 ;; Mapping of unsigned max and min
655 (define_code_iterator umaxmin [umax umin])
657 ;; Mapping of signed/unsigned max and min
658 (define_code_iterator maxmin [smax smin umax umin])
660 ;; Base name for integer and FP insn mnemonic
661 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
662 (umax "maxu") (umin "minu")])
663 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
665 ;; Mapping of parallel logic operators
666 (define_code_iterator plogic [and ior xor])
668 ;; Base name for insn mnemonic.
669 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
671 ;; Mapping of abs neg operators
672 (define_code_iterator absneg [abs neg])
674 ;; Base name for x87 insn mnemonic.
675 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
677 ;; All single word integer modes.
678 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
680 ;; Single word integer modes without QImode.
681 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
683 ;; Instruction suffix for integer modes.
684 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
686 ;; Register class for integer modes.
687 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
689 ;; Immediate operand constraint for integer modes.
690 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
692 ;; General operand predicate for integer modes.
693 (define_mode_attr general_operand
694 [(QI "general_operand")
695 (HI "general_operand")
696 (SI "general_operand")
697 (DI "x86_64_general_operand")])
699 ;; SSE and x87 SFmode and DFmode floating point modes
700 (define_mode_iterator MODEF [SF DF])
702 ;; All x87 floating point modes
703 (define_mode_iterator X87MODEF [SF DF XF])
705 ;; All integer modes handled by x87 fisttp operator.
706 (define_mode_iterator X87MODEI [HI SI DI])
708 ;; All integer modes handled by integer x87 operators.
709 (define_mode_iterator X87MODEI12 [HI SI])
711 ;; All integer modes handled by SSE cvtts?2si* operators.
712 (define_mode_iterator SSEMODEI24 [SI DI])
714 ;; SSE asm suffix for floating point modes
715 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
717 ;; SSE vector mode corresponding to a scalar mode
718 (define_mode_attr ssevecmode
719 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
721 ;; Instruction suffix for REX 64bit operators.
722 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
724 ;; This mode iterator allows :P to be used for patterns that operate on
725 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
726 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
729 ;; Scheduling descriptions
731 (include "pentium.md")
734 (include "athlon.md")
739 ;; Operand and operator predicates and constraints
741 (include "predicates.md")
742 (include "constraints.md")
745 ;; Compare instructions.
747 ;; All compare insns have expanders that save the operands away without
748 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
749 ;; after the cmp) will actually emit the cmpM.
751 (define_expand "cmpti"
752 [(set (reg:CC FLAGS_REG)
753 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
754 (match_operand:TI 1 "x86_64_general_operand" "")))]
757 if (MEM_P (operands[0]) && MEM_P (operands[1]))
758 operands[0] = force_reg (TImode, operands[0]);
759 ix86_compare_op0 = operands[0];
760 ix86_compare_op1 = operands[1];
764 (define_expand "cmpdi"
765 [(set (reg:CC FLAGS_REG)
766 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
767 (match_operand:DI 1 "x86_64_general_operand" "")))]
770 if (MEM_P (operands[0]) && MEM_P (operands[1]))
771 operands[0] = force_reg (DImode, operands[0]);
772 ix86_compare_op0 = operands[0];
773 ix86_compare_op1 = operands[1];
777 (define_expand "cmpsi"
778 [(set (reg:CC FLAGS_REG)
779 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
780 (match_operand:SI 1 "general_operand" "")))]
783 if (MEM_P (operands[0]) && MEM_P (operands[1]))
784 operands[0] = force_reg (SImode, operands[0]);
785 ix86_compare_op0 = operands[0];
786 ix86_compare_op1 = operands[1];
790 (define_expand "cmphi"
791 [(set (reg:CC FLAGS_REG)
792 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
793 (match_operand:HI 1 "general_operand" "")))]
796 if (MEM_P (operands[0]) && MEM_P (operands[1]))
797 operands[0] = force_reg (HImode, operands[0]);
798 ix86_compare_op0 = operands[0];
799 ix86_compare_op1 = operands[1];
803 (define_expand "cmpqi"
804 [(set (reg:CC FLAGS_REG)
805 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
806 (match_operand:QI 1 "general_operand" "")))]
809 if (MEM_P (operands[0]) && MEM_P (operands[1]))
810 operands[0] = force_reg (QImode, operands[0]);
811 ix86_compare_op0 = operands[0];
812 ix86_compare_op1 = operands[1];
816 (define_insn "cmpdi_ccno_1_rex64"
817 [(set (reg FLAGS_REG)
818 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
819 (match_operand:DI 1 "const0_operand" "")))]
820 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
823 cmp{q}\t{%1, %0|%0, %1}"
824 [(set_attr "type" "test,icmp")
825 (set_attr "length_immediate" "0,1")
826 (set_attr "mode" "DI")])
828 (define_insn "*cmpdi_minus_1_rex64"
829 [(set (reg FLAGS_REG)
830 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
831 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
833 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
834 "cmp{q}\t{%1, %0|%0, %1}"
835 [(set_attr "type" "icmp")
836 (set_attr "mode" "DI")])
838 (define_expand "cmpdi_1_rex64"
839 [(set (reg:CC FLAGS_REG)
840 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
841 (match_operand:DI 1 "general_operand" "")))]
845 (define_insn "cmpdi_1_insn_rex64"
846 [(set (reg FLAGS_REG)
847 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
848 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
849 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
850 "cmp{q}\t{%1, %0|%0, %1}"
851 [(set_attr "type" "icmp")
852 (set_attr "mode" "DI")])
855 (define_insn "*cmpsi_ccno_1"
856 [(set (reg FLAGS_REG)
857 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
858 (match_operand:SI 1 "const0_operand" "")))]
859 "ix86_match_ccmode (insn, CCNOmode)"
862 cmp{l}\t{%1, %0|%0, %1}"
863 [(set_attr "type" "test,icmp")
864 (set_attr "length_immediate" "0,1")
865 (set_attr "mode" "SI")])
867 (define_insn "*cmpsi_minus_1"
868 [(set (reg FLAGS_REG)
869 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
870 (match_operand:SI 1 "general_operand" "ri,mr"))
872 "ix86_match_ccmode (insn, CCGOCmode)"
873 "cmp{l}\t{%1, %0|%0, %1}"
874 [(set_attr "type" "icmp")
875 (set_attr "mode" "SI")])
877 (define_expand "cmpsi_1"
878 [(set (reg:CC FLAGS_REG)
879 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
880 (match_operand:SI 1 "general_operand" "")))]
884 (define_insn "*cmpsi_1_insn"
885 [(set (reg FLAGS_REG)
886 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
887 (match_operand:SI 1 "general_operand" "ri,mr")))]
888 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
889 && ix86_match_ccmode (insn, CCmode)"
890 "cmp{l}\t{%1, %0|%0, %1}"
891 [(set_attr "type" "icmp")
892 (set_attr "mode" "SI")])
894 (define_insn "*cmphi_ccno_1"
895 [(set (reg FLAGS_REG)
896 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
897 (match_operand:HI 1 "const0_operand" "")))]
898 "ix86_match_ccmode (insn, CCNOmode)"
901 cmp{w}\t{%1, %0|%0, %1}"
902 [(set_attr "type" "test,icmp")
903 (set_attr "length_immediate" "0,1")
904 (set_attr "mode" "HI")])
906 (define_insn "*cmphi_minus_1"
907 [(set (reg FLAGS_REG)
908 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
909 (match_operand:HI 1 "general_operand" "rn,mr"))
911 "ix86_match_ccmode (insn, CCGOCmode)"
912 "cmp{w}\t{%1, %0|%0, %1}"
913 [(set_attr "type" "icmp")
914 (set_attr "mode" "HI")])
916 (define_insn "*cmphi_1"
917 [(set (reg FLAGS_REG)
918 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
919 (match_operand:HI 1 "general_operand" "rn,mr")))]
920 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
921 && ix86_match_ccmode (insn, CCmode)"
922 "cmp{w}\t{%1, %0|%0, %1}"
923 [(set_attr "type" "icmp")
924 (set_attr "mode" "HI")])
926 (define_insn "*cmpqi_ccno_1"
927 [(set (reg FLAGS_REG)
928 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
929 (match_operand:QI 1 "const0_operand" "")))]
930 "ix86_match_ccmode (insn, CCNOmode)"
933 cmp{b}\t{$0, %0|%0, 0}"
934 [(set_attr "type" "test,icmp")
935 (set_attr "length_immediate" "0,1")
936 (set_attr "mode" "QI")])
938 (define_insn "*cmpqi_1"
939 [(set (reg FLAGS_REG)
940 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
941 (match_operand:QI 1 "general_operand" "qn,mq")))]
942 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
943 && ix86_match_ccmode (insn, CCmode)"
944 "cmp{b}\t{%1, %0|%0, %1}"
945 [(set_attr "type" "icmp")
946 (set_attr "mode" "QI")])
948 (define_insn "*cmpqi_minus_1"
949 [(set (reg FLAGS_REG)
950 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
951 (match_operand:QI 1 "general_operand" "qn,mq"))
953 "ix86_match_ccmode (insn, CCGOCmode)"
954 "cmp{b}\t{%1, %0|%0, %1}"
955 [(set_attr "type" "icmp")
956 (set_attr "mode" "QI")])
958 (define_insn "*cmpqi_ext_1"
959 [(set (reg FLAGS_REG)
961 (match_operand:QI 0 "general_operand" "Qm")
964 (match_operand 1 "ext_register_operand" "Q")
967 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
968 "cmp{b}\t{%h1, %0|%0, %h1}"
969 [(set_attr "type" "icmp")
970 (set_attr "mode" "QI")])
972 (define_insn "*cmpqi_ext_1_rex64"
973 [(set (reg FLAGS_REG)
975 (match_operand:QI 0 "register_operand" "Q")
978 (match_operand 1 "ext_register_operand" "Q")
981 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
982 "cmp{b}\t{%h1, %0|%0, %h1}"
983 [(set_attr "type" "icmp")
984 (set_attr "mode" "QI")])
986 (define_insn "*cmpqi_ext_2"
987 [(set (reg FLAGS_REG)
991 (match_operand 0 "ext_register_operand" "Q")
994 (match_operand:QI 1 "const0_operand" "")))]
995 "ix86_match_ccmode (insn, CCNOmode)"
997 [(set_attr "type" "test")
998 (set_attr "length_immediate" "0")
999 (set_attr "mode" "QI")])
1001 (define_expand "cmpqi_ext_3"
1002 [(set (reg:CC FLAGS_REG)
1006 (match_operand 0 "ext_register_operand" "")
1009 (match_operand:QI 1 "general_operand" "")))]
1013 (define_insn "cmpqi_ext_3_insn"
1014 [(set (reg FLAGS_REG)
1018 (match_operand 0 "ext_register_operand" "Q")
1021 (match_operand:QI 1 "general_operand" "Qmn")))]
1022 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1023 "cmp{b}\t{%1, %h0|%h0, %1}"
1024 [(set_attr "type" "icmp")
1025 (set_attr "mode" "QI")])
1027 (define_insn "cmpqi_ext_3_insn_rex64"
1028 [(set (reg FLAGS_REG)
1032 (match_operand 0 "ext_register_operand" "Q")
1035 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1036 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1037 "cmp{b}\t{%1, %h0|%h0, %1}"
1038 [(set_attr "type" "icmp")
1039 (set_attr "mode" "QI")])
1041 (define_insn "*cmpqi_ext_4"
1042 [(set (reg FLAGS_REG)
1046 (match_operand 0 "ext_register_operand" "Q")
1051 (match_operand 1 "ext_register_operand" "Q")
1053 (const_int 8)) 0)))]
1054 "ix86_match_ccmode (insn, CCmode)"
1055 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1056 [(set_attr "type" "icmp")
1057 (set_attr "mode" "QI")])
1059 ;; These implement float point compares.
1060 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1061 ;; which would allow mix and match FP modes on the compares. Which is what
1062 ;; the old patterns did, but with many more of them.
1064 (define_expand "cmpxf"
1065 [(set (reg:CC FLAGS_REG)
1066 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1067 (match_operand:XF 1 "nonmemory_operand" "")))]
1070 ix86_compare_op0 = operands[0];
1071 ix86_compare_op1 = operands[1];
1075 (define_expand "cmp<mode>"
1076 [(set (reg:CC FLAGS_REG)
1077 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1078 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1079 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1081 ix86_compare_op0 = operands[0];
1082 ix86_compare_op1 = operands[1];
1086 ;; FP compares, step 1:
1087 ;; Set the FP condition codes.
1089 ;; CCFPmode compare with exceptions
1090 ;; CCFPUmode compare with no exceptions
1092 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1093 ;; used to manage the reg stack popping would not be preserved.
1095 (define_insn "*cmpfp_0"
1096 [(set (match_operand:HI 0 "register_operand" "=a")
1099 (match_operand 1 "register_operand" "f")
1100 (match_operand 2 "const0_operand" ""))]
1102 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1103 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1104 "* return output_fp_compare (insn, operands, 0, 0);"
1105 [(set_attr "type" "multi")
1106 (set_attr "unit" "i387")
1108 (cond [(match_operand:SF 1 "" "")
1110 (match_operand:DF 1 "" "")
1113 (const_string "XF")))])
1115 (define_insn_and_split "*cmpfp_0_cc"
1116 [(set (reg:CCFP FLAGS_REG)
1118 (match_operand 1 "register_operand" "f")
1119 (match_operand 2 "const0_operand" "")))
1120 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1121 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122 && TARGET_SAHF && !TARGET_CMOVE
1123 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1125 "&& reload_completed"
1128 [(compare:CCFP (match_dup 1)(match_dup 2))]
1130 (set (reg:CC FLAGS_REG)
1131 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1133 [(set_attr "type" "multi")
1134 (set_attr "unit" "i387")
1136 (cond [(match_operand:SF 1 "" "")
1138 (match_operand:DF 1 "" "")
1141 (const_string "XF")))])
1143 (define_insn "*cmpfp_xf"
1144 [(set (match_operand:HI 0 "register_operand" "=a")
1147 (match_operand:XF 1 "register_operand" "f")
1148 (match_operand:XF 2 "register_operand" "f"))]
1151 "* return output_fp_compare (insn, operands, 0, 0);"
1152 [(set_attr "type" "multi")
1153 (set_attr "unit" "i387")
1154 (set_attr "mode" "XF")])
1156 (define_insn_and_split "*cmpfp_xf_cc"
1157 [(set (reg:CCFP FLAGS_REG)
1159 (match_operand:XF 1 "register_operand" "f")
1160 (match_operand:XF 2 "register_operand" "f")))
1161 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1163 && TARGET_SAHF && !TARGET_CMOVE"
1165 "&& reload_completed"
1168 [(compare:CCFP (match_dup 1)(match_dup 2))]
1170 (set (reg:CC FLAGS_REG)
1171 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1173 [(set_attr "type" "multi")
1174 (set_attr "unit" "i387")
1175 (set_attr "mode" "XF")])
1177 (define_insn "*cmpfp_<mode>"
1178 [(set (match_operand:HI 0 "register_operand" "=a")
1181 (match_operand:MODEF 1 "register_operand" "f")
1182 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1185 "* return output_fp_compare (insn, operands, 0, 0);"
1186 [(set_attr "type" "multi")
1187 (set_attr "unit" "i387")
1188 (set_attr "mode" "<MODE>")])
1190 (define_insn_and_split "*cmpfp_<mode>_cc"
1191 [(set (reg:CCFP FLAGS_REG)
1193 (match_operand:MODEF 1 "register_operand" "f")
1194 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1195 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1197 && TARGET_SAHF && !TARGET_CMOVE"
1199 "&& reload_completed"
1202 [(compare:CCFP (match_dup 1)(match_dup 2))]
1204 (set (reg:CC FLAGS_REG)
1205 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1207 [(set_attr "type" "multi")
1208 (set_attr "unit" "i387")
1209 (set_attr "mode" "<MODE>")])
1211 (define_insn "*cmpfp_u"
1212 [(set (match_operand:HI 0 "register_operand" "=a")
1215 (match_operand 1 "register_operand" "f")
1216 (match_operand 2 "register_operand" "f"))]
1218 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1219 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1220 "* return output_fp_compare (insn, operands, 0, 1);"
1221 [(set_attr "type" "multi")
1222 (set_attr "unit" "i387")
1224 (cond [(match_operand:SF 1 "" "")
1226 (match_operand:DF 1 "" "")
1229 (const_string "XF")))])
1231 (define_insn_and_split "*cmpfp_u_cc"
1232 [(set (reg:CCFPU FLAGS_REG)
1234 (match_operand 1 "register_operand" "f")
1235 (match_operand 2 "register_operand" "f")))
1236 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1237 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1238 && TARGET_SAHF && !TARGET_CMOVE
1239 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1241 "&& reload_completed"
1244 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1246 (set (reg:CC FLAGS_REG)
1247 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1249 [(set_attr "type" "multi")
1250 (set_attr "unit" "i387")
1252 (cond [(match_operand:SF 1 "" "")
1254 (match_operand:DF 1 "" "")
1257 (const_string "XF")))])
1259 (define_insn "*cmpfp_<mode>"
1260 [(set (match_operand:HI 0 "register_operand" "=a")
1263 (match_operand 1 "register_operand" "f")
1264 (match_operator 3 "float_operator"
1265 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1267 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1268 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1269 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1270 "* return output_fp_compare (insn, operands, 0, 0);"
1271 [(set_attr "type" "multi")
1272 (set_attr "unit" "i387")
1273 (set_attr "fp_int_src" "true")
1274 (set_attr "mode" "<MODE>")])
1276 (define_insn_and_split "*cmpfp_<mode>_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1279 (match_operand 1 "register_operand" "f")
1280 (match_operator 3 "float_operator"
1281 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1282 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1283 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1284 && TARGET_SAHF && !TARGET_CMOVE
1285 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1286 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1288 "&& reload_completed"
1293 (match_op_dup 3 [(match_dup 2)]))]
1295 (set (reg:CC FLAGS_REG)
1296 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1298 [(set_attr "type" "multi")
1299 (set_attr "unit" "i387")
1300 (set_attr "fp_int_src" "true")
1301 (set_attr "mode" "<MODE>")])
1303 ;; FP compares, step 2
1304 ;; Move the fpsw to ax.
1306 (define_insn "x86_fnstsw_1"
1307 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1311 [(set_attr "length" "2")
1312 (set_attr "mode" "SI")
1313 (set_attr "unit" "i387")])
1315 ;; FP compares, step 3
1316 ;; Get ax into flags, general case.
1318 (define_insn "x86_sahf_1"
1319 [(set (reg:CC FLAGS_REG)
1320 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1324 #ifdef HAVE_AS_IX86_SAHF
1327 return ".byte\t0x9e";
1330 [(set_attr "length" "1")
1331 (set_attr "athlon_decode" "vector")
1332 (set_attr "amdfam10_decode" "direct")
1333 (set_attr "mode" "SI")])
1335 ;; Pentium Pro can do steps 1 through 3 in one go.
1336 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1337 (define_insn "*cmpfp_i_mixed"
1338 [(set (reg:CCFP FLAGS_REG)
1339 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1340 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1341 "TARGET_MIX_SSE_I387
1342 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1343 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1344 "* return output_fp_compare (insn, operands, 1, 0);"
1345 [(set_attr "type" "fcmp,ssecomi")
1346 (set_attr "prefix" "orig,maybe_vex")
1348 (if_then_else (match_operand:SF 1 "" "")
1350 (const_string "DF")))
1351 (set_attr "athlon_decode" "vector")
1352 (set_attr "amdfam10_decode" "direct")])
1354 (define_insn "*cmpfp_i_sse"
1355 [(set (reg:CCFP FLAGS_REG)
1356 (compare:CCFP (match_operand 0 "register_operand" "x")
1357 (match_operand 1 "nonimmediate_operand" "xm")))]
1359 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1360 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1361 "* return output_fp_compare (insn, operands, 1, 0);"
1362 [(set_attr "type" "ssecomi")
1363 (set_attr "prefix" "maybe_vex")
1365 (if_then_else (match_operand:SF 1 "" "")
1367 (const_string "DF")))
1368 (set_attr "athlon_decode" "vector")
1369 (set_attr "amdfam10_decode" "direct")])
1371 (define_insn "*cmpfp_i_i387"
1372 [(set (reg:CCFP FLAGS_REG)
1373 (compare:CCFP (match_operand 0 "register_operand" "f")
1374 (match_operand 1 "register_operand" "f")))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1377 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1378 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1379 "* return output_fp_compare (insn, operands, 1, 0);"
1380 [(set_attr "type" "fcmp")
1382 (cond [(match_operand:SF 1 "" "")
1384 (match_operand:DF 1 "" "")
1387 (const_string "XF")))
1388 (set_attr "athlon_decode" "vector")
1389 (set_attr "amdfam10_decode" "direct")])
1391 (define_insn "*cmpfp_iu_mixed"
1392 [(set (reg:CCFPU FLAGS_REG)
1393 (compare:CCFPU (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, 1);"
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 "athlon_decode" "vector")
1406 (set_attr "amdfam10_decode" "direct")])
1408 (define_insn "*cmpfp_iu_sse"
1409 [(set (reg:CCFPU FLAGS_REG)
1410 (compare:CCFPU (match_operand 0 "register_operand" "x")
1411 (match_operand 1 "nonimmediate_operand" "xm")))]
1413 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1414 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1415 "* return output_fp_compare (insn, operands, 1, 1);"
1416 [(set_attr "type" "ssecomi")
1417 (set_attr "prefix" "maybe_vex")
1419 (if_then_else (match_operand:SF 1 "" "")
1421 (const_string "DF")))
1422 (set_attr "athlon_decode" "vector")
1423 (set_attr "amdfam10_decode" "direct")])
1425 (define_insn "*cmpfp_iu_387"
1426 [(set (reg:CCFPU FLAGS_REG)
1427 (compare:CCFPU (match_operand 0 "register_operand" "f")
1428 (match_operand 1 "register_operand" "f")))]
1429 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1431 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1432 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1433 "* return output_fp_compare (insn, operands, 1, 1);"
1434 [(set_attr "type" "fcmp")
1436 (cond [(match_operand:SF 1 "" "")
1438 (match_operand:DF 1 "" "")
1441 (const_string "XF")))
1442 (set_attr "athlon_decode" "vector")
1443 (set_attr "amdfam10_decode" "direct")])
1445 ;; Move instructions.
1447 ;; General case of fullword move.
1449 (define_expand "movsi"
1450 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1451 (match_operand:SI 1 "general_operand" ""))]
1453 "ix86_expand_move (SImode, operands); DONE;")
1455 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1458 ;; %%% We don't use a post-inc memory reference because x86 is not a
1459 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1460 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1461 ;; targets without our curiosities, and it is just as easy to represent
1462 ;; this differently.
1464 (define_insn "*pushsi2"
1465 [(set (match_operand:SI 0 "push_operand" "=<")
1466 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1469 [(set_attr "type" "push")
1470 (set_attr "mode" "SI")])
1472 ;; For 64BIT abi we always round up to 8 bytes.
1473 (define_insn "*pushsi2_rex64"
1474 [(set (match_operand:SI 0 "push_operand" "=X")
1475 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1478 [(set_attr "type" "push")
1479 (set_attr "mode" "SI")])
1481 (define_insn "*pushsi2_prologue"
1482 [(set (match_operand:SI 0 "push_operand" "=<")
1483 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1484 (clobber (mem:BLK (scratch)))]
1487 [(set_attr "type" "push")
1488 (set_attr "mode" "SI")])
1490 (define_insn "*popsi1_epilogue"
1491 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1492 (mem:SI (reg:SI SP_REG)))
1493 (set (reg:SI SP_REG)
1494 (plus:SI (reg:SI SP_REG) (const_int 4)))
1495 (clobber (mem:BLK (scratch)))]
1498 [(set_attr "type" "pop")
1499 (set_attr "mode" "SI")])
1501 (define_insn "popsi1"
1502 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1503 (mem:SI (reg:SI SP_REG)))
1504 (set (reg:SI SP_REG)
1505 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1508 [(set_attr "type" "pop")
1509 (set_attr "mode" "SI")])
1511 (define_insn "*movsi_xor"
1512 [(set (match_operand:SI 0 "register_operand" "=r")
1513 (match_operand:SI 1 "const0_operand" ""))
1514 (clobber (reg:CC FLAGS_REG))]
1517 [(set_attr "type" "alu1")
1518 (set_attr "mode" "SI")
1519 (set_attr "length_immediate" "0")])
1521 (define_insn "*movsi_or"
1522 [(set (match_operand:SI 0 "register_operand" "=r")
1523 (match_operand:SI 1 "immediate_operand" "i"))
1524 (clobber (reg:CC FLAGS_REG))]
1526 && operands[1] == constm1_rtx"
1528 operands[1] = constm1_rtx;
1529 return "or{l}\t{%1, %0|%0, %1}";
1531 [(set_attr "type" "alu1")
1532 (set_attr "mode" "SI")
1533 (set_attr "length_immediate" "1")])
1535 (define_insn "*movsi_1"
1536 [(set (match_operand:SI 0 "nonimmediate_operand"
1537 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1538 (match_operand:SI 1 "general_operand"
1539 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1540 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1542 switch (get_attr_type (insn))
1545 if (get_attr_mode (insn) == MODE_TI)
1546 return "%vpxor\t%0, %d0";
1547 return "%vxorps\t%0, %d0";
1550 switch (get_attr_mode (insn))
1553 return "%vmovdqa\t{%1, %0|%0, %1}";
1555 return "%vmovaps\t{%1, %0|%0, %1}";
1557 return "%vmovd\t{%1, %0|%0, %1}";
1559 return "%vmovss\t{%1, %0|%0, %1}";
1565 return "pxor\t%0, %0";
1568 if (get_attr_mode (insn) == MODE_DI)
1569 return "movq\t{%1, %0|%0, %1}";
1570 return "movd\t{%1, %0|%0, %1}";
1573 return "lea{l}\t{%1, %0|%0, %1}";
1576 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1577 return "mov{l}\t{%1, %0|%0, %1}";
1581 (cond [(eq_attr "alternative" "2")
1582 (const_string "mmx")
1583 (eq_attr "alternative" "3,4,5")
1584 (const_string "mmxmov")
1585 (eq_attr "alternative" "6")
1586 (const_string "sselog1")
1587 (eq_attr "alternative" "7,8,9,10,11")
1588 (const_string "ssemov")
1589 (match_operand:DI 1 "pic_32bit_operand" "")
1590 (const_string "lea")
1592 (const_string "imov")))
1593 (set (attr "prefix")
1594 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1595 (const_string "orig")
1596 (const_string "maybe_vex")))
1598 (cond [(eq_attr "alternative" "2,3")
1600 (eq_attr "alternative" "6,7")
1602 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1603 (const_string "V4SF")
1604 (const_string "TI"))
1605 (and (eq_attr "alternative" "8,9,10,11")
1606 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1609 (const_string "SI")))])
1611 ;; Stores and loads of ax to arbitrary constant address.
1612 ;; We fake an second form of instruction to force reload to load address
1613 ;; into register when rax is not available
1614 (define_insn "*movabssi_1_rex64"
1615 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1616 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1617 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1619 movabs{l}\t{%1, %P0|%P0, %1}
1620 mov{l}\t{%1, %a0|%a0, %1}"
1621 [(set_attr "type" "imov")
1622 (set_attr "modrm" "0,*")
1623 (set_attr "length_address" "8,0")
1624 (set_attr "length_immediate" "0,*")
1625 (set_attr "memory" "store")
1626 (set_attr "mode" "SI")])
1628 (define_insn "*movabssi_2_rex64"
1629 [(set (match_operand:SI 0 "register_operand" "=a,r")
1630 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1631 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1633 movabs{l}\t{%P1, %0|%0, %P1}
1634 mov{l}\t{%a1, %0|%0, %a1}"
1635 [(set_attr "type" "imov")
1636 (set_attr "modrm" "0,*")
1637 (set_attr "length_address" "8,0")
1638 (set_attr "length_immediate" "0")
1639 (set_attr "memory" "load")
1640 (set_attr "mode" "SI")])
1642 (define_insn "*swapsi"
1643 [(set (match_operand:SI 0 "register_operand" "+r")
1644 (match_operand:SI 1 "register_operand" "+r"))
1649 [(set_attr "type" "imov")
1650 (set_attr "mode" "SI")
1651 (set_attr "pent_pair" "np")
1652 (set_attr "athlon_decode" "vector")
1653 (set_attr "amdfam10_decode" "double")])
1655 (define_expand "movhi"
1656 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1657 (match_operand:HI 1 "general_operand" ""))]
1659 "ix86_expand_move (HImode, operands); DONE;")
1661 (define_insn "*pushhi2"
1662 [(set (match_operand:HI 0 "push_operand" "=X")
1663 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1666 [(set_attr "type" "push")
1667 (set_attr "mode" "SI")])
1669 ;; For 64BIT abi we always round up to 8 bytes.
1670 (define_insn "*pushhi2_rex64"
1671 [(set (match_operand:HI 0 "push_operand" "=X")
1672 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1675 [(set_attr "type" "push")
1676 (set_attr "mode" "DI")])
1678 (define_insn "*movhi_1"
1679 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1680 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1681 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1683 switch (get_attr_type (insn))
1686 /* movzwl is faster than movw on p2 due to partial word stalls,
1687 though not as fast as an aligned movl. */
1688 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1690 if (get_attr_mode (insn) == MODE_SI)
1691 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1693 return "mov{w}\t{%1, %0|%0, %1}";
1697 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1698 (const_string "imov")
1699 (and (eq_attr "alternative" "0")
1700 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1702 (eq (symbol_ref "TARGET_HIMODE_MATH")
1704 (const_string "imov")
1705 (and (eq_attr "alternative" "1,2")
1706 (match_operand:HI 1 "aligned_operand" ""))
1707 (const_string "imov")
1708 (and (ne (symbol_ref "TARGET_MOVX")
1710 (eq_attr "alternative" "0,2"))
1711 (const_string "imovx")
1713 (const_string "imov")))
1715 (cond [(eq_attr "type" "imovx")
1717 (and (eq_attr "alternative" "1,2")
1718 (match_operand:HI 1 "aligned_operand" ""))
1720 (and (eq_attr "alternative" "0")
1721 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1723 (eq (symbol_ref "TARGET_HIMODE_MATH")
1727 (const_string "HI")))])
1729 ;; Stores and loads of ax to arbitrary constant address.
1730 ;; We fake an second form of instruction to force reload to load address
1731 ;; into register when rax is not available
1732 (define_insn "*movabshi_1_rex64"
1733 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1734 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1735 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1737 movabs{w}\t{%1, %P0|%P0, %1}
1738 mov{w}\t{%1, %a0|%a0, %1}"
1739 [(set_attr "type" "imov")
1740 (set_attr "modrm" "0,*")
1741 (set_attr "length_address" "8,0")
1742 (set_attr "length_immediate" "0,*")
1743 (set_attr "memory" "store")
1744 (set_attr "mode" "HI")])
1746 (define_insn "*movabshi_2_rex64"
1747 [(set (match_operand:HI 0 "register_operand" "=a,r")
1748 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1749 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1751 movabs{w}\t{%P1, %0|%0, %P1}
1752 mov{w}\t{%a1, %0|%0, %a1}"
1753 [(set_attr "type" "imov")
1754 (set_attr "modrm" "0,*")
1755 (set_attr "length_address" "8,0")
1756 (set_attr "length_immediate" "0")
1757 (set_attr "memory" "load")
1758 (set_attr "mode" "HI")])
1760 (define_insn "*swaphi_1"
1761 [(set (match_operand:HI 0 "register_operand" "+r")
1762 (match_operand:HI 1 "register_operand" "+r"))
1765 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1767 [(set_attr "type" "imov")
1768 (set_attr "mode" "SI")
1769 (set_attr "pent_pair" "np")
1770 (set_attr "athlon_decode" "vector")
1771 (set_attr "amdfam10_decode" "double")])
1773 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1774 (define_insn "*swaphi_2"
1775 [(set (match_operand:HI 0 "register_operand" "+r")
1776 (match_operand:HI 1 "register_operand" "+r"))
1779 "TARGET_PARTIAL_REG_STALL"
1781 [(set_attr "type" "imov")
1782 (set_attr "mode" "HI")
1783 (set_attr "pent_pair" "np")
1784 (set_attr "athlon_decode" "vector")])
1786 (define_expand "movstricthi"
1787 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1788 (match_operand:HI 1 "general_operand" ""))]
1791 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1793 /* Don't generate memory->memory moves, go through a register */
1794 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1795 operands[1] = force_reg (HImode, operands[1]);
1798 (define_insn "*movstricthi_1"
1799 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1800 (match_operand:HI 1 "general_operand" "rn,m"))]
1801 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1802 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1803 "mov{w}\t{%1, %0|%0, %1}"
1804 [(set_attr "type" "imov")
1805 (set_attr "mode" "HI")])
1807 (define_insn "*movstricthi_xor"
1808 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1809 (match_operand:HI 1 "const0_operand" ""))
1810 (clobber (reg:CC FLAGS_REG))]
1813 [(set_attr "type" "alu1")
1814 (set_attr "mode" "HI")
1815 (set_attr "length_immediate" "0")])
1817 (define_expand "movqi"
1818 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1819 (match_operand:QI 1 "general_operand" ""))]
1821 "ix86_expand_move (QImode, operands); DONE;")
1823 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1824 ;; "push a byte". But actually we use pushl, which has the effect
1825 ;; of rounding the amount pushed up to a word.
1827 (define_insn "*pushqi2"
1828 [(set (match_operand:QI 0 "push_operand" "=X")
1829 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1832 [(set_attr "type" "push")
1833 (set_attr "mode" "SI")])
1835 ;; For 64BIT abi we always round up to 8 bytes.
1836 (define_insn "*pushqi2_rex64"
1837 [(set (match_operand:QI 0 "push_operand" "=X")
1838 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1841 [(set_attr "type" "push")
1842 (set_attr "mode" "DI")])
1844 ;; Situation is quite tricky about when to choose full sized (SImode) move
1845 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1846 ;; partial register dependency machines (such as AMD Athlon), where QImode
1847 ;; moves issue extra dependency and for partial register stalls machines
1848 ;; that don't use QImode patterns (and QImode move cause stall on the next
1851 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1852 ;; register stall machines with, where we use QImode instructions, since
1853 ;; partial register stall can be caused there. Then we use movzx.
1854 (define_insn "*movqi_1"
1855 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1856 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1857 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1859 switch (get_attr_type (insn))
1862 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1863 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1865 if (get_attr_mode (insn) == MODE_SI)
1866 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1868 return "mov{b}\t{%1, %0|%0, %1}";
1872 (cond [(and (eq_attr "alternative" "5")
1873 (not (match_operand:QI 1 "aligned_operand" "")))
1874 (const_string "imovx")
1875 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1876 (const_string "imov")
1877 (and (eq_attr "alternative" "3")
1878 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1880 (eq (symbol_ref "TARGET_QIMODE_MATH")
1882 (const_string "imov")
1883 (eq_attr "alternative" "3,5")
1884 (const_string "imovx")
1885 (and (ne (symbol_ref "TARGET_MOVX")
1887 (eq_attr "alternative" "2"))
1888 (const_string "imovx")
1890 (const_string "imov")))
1892 (cond [(eq_attr "alternative" "3,4,5")
1894 (eq_attr "alternative" "6")
1896 (eq_attr "type" "imovx")
1898 (and (eq_attr "type" "imov")
1899 (and (eq_attr "alternative" "0,1")
1900 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1902 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1904 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1907 ;; Avoid partial register stalls when not using QImode arithmetic
1908 (and (eq_attr "type" "imov")
1909 (and (eq_attr "alternative" "0,1")
1910 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1912 (eq (symbol_ref "TARGET_QIMODE_MATH")
1916 (const_string "QI")))])
1918 (define_insn "*swapqi_1"
1919 [(set (match_operand:QI 0 "register_operand" "+r")
1920 (match_operand:QI 1 "register_operand" "+r"))
1923 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1925 [(set_attr "type" "imov")
1926 (set_attr "mode" "SI")
1927 (set_attr "pent_pair" "np")
1928 (set_attr "athlon_decode" "vector")
1929 (set_attr "amdfam10_decode" "vector")])
1931 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1932 (define_insn "*swapqi_2"
1933 [(set (match_operand:QI 0 "register_operand" "+q")
1934 (match_operand:QI 1 "register_operand" "+q"))
1937 "TARGET_PARTIAL_REG_STALL"
1939 [(set_attr "type" "imov")
1940 (set_attr "mode" "QI")
1941 (set_attr "pent_pair" "np")
1942 (set_attr "athlon_decode" "vector")])
1944 (define_expand "movstrictqi"
1945 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1946 (match_operand:QI 1 "general_operand" ""))]
1949 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1951 /* Don't generate memory->memory moves, go through a register. */
1952 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1953 operands[1] = force_reg (QImode, operands[1]);
1956 (define_insn "*movstrictqi_1"
1957 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1958 (match_operand:QI 1 "general_operand" "*qn,m"))]
1959 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1960 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1961 "mov{b}\t{%1, %0|%0, %1}"
1962 [(set_attr "type" "imov")
1963 (set_attr "mode" "QI")])
1965 (define_insn "*movstrictqi_xor"
1966 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1967 (match_operand:QI 1 "const0_operand" ""))
1968 (clobber (reg:CC FLAGS_REG))]
1971 [(set_attr "type" "alu1")
1972 (set_attr "mode" "QI")
1973 (set_attr "length_immediate" "0")])
1975 (define_insn "*movsi_extv_1"
1976 [(set (match_operand:SI 0 "register_operand" "=R")
1977 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1981 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1982 [(set_attr "type" "imovx")
1983 (set_attr "mode" "SI")])
1985 (define_insn "*movhi_extv_1"
1986 [(set (match_operand:HI 0 "register_operand" "=R")
1987 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1991 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1992 [(set_attr "type" "imovx")
1993 (set_attr "mode" "SI")])
1995 (define_insn "*movqi_extv_1"
1996 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1997 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2002 switch (get_attr_type (insn))
2005 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2007 return "mov{b}\t{%h1, %0|%0, %h1}";
2011 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2012 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2013 (ne (symbol_ref "TARGET_MOVX")
2015 (const_string "imovx")
2016 (const_string "imov")))
2018 (if_then_else (eq_attr "type" "imovx")
2020 (const_string "QI")))])
2022 (define_insn "*movqi_extv_1_rex64"
2023 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2024 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2029 switch (get_attr_type (insn))
2032 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2034 return "mov{b}\t{%h1, %0|%0, %h1}";
2038 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2039 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2040 (ne (symbol_ref "TARGET_MOVX")
2042 (const_string "imovx")
2043 (const_string "imov")))
2045 (if_then_else (eq_attr "type" "imovx")
2047 (const_string "QI")))])
2049 ;; Stores and loads of ax to arbitrary constant address.
2050 ;; We fake an second form of instruction to force reload to load address
2051 ;; into register when rax is not available
2052 (define_insn "*movabsqi_1_rex64"
2053 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2054 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2055 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2057 movabs{b}\t{%1, %P0|%P0, %1}
2058 mov{b}\t{%1, %a0|%a0, %1}"
2059 [(set_attr "type" "imov")
2060 (set_attr "modrm" "0,*")
2061 (set_attr "length_address" "8,0")
2062 (set_attr "length_immediate" "0,*")
2063 (set_attr "memory" "store")
2064 (set_attr "mode" "QI")])
2066 (define_insn "*movabsqi_2_rex64"
2067 [(set (match_operand:QI 0 "register_operand" "=a,r")
2068 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2069 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2071 movabs{b}\t{%P1, %0|%0, %P1}
2072 mov{b}\t{%a1, %0|%0, %a1}"
2073 [(set_attr "type" "imov")
2074 (set_attr "modrm" "0,*")
2075 (set_attr "length_address" "8,0")
2076 (set_attr "length_immediate" "0")
2077 (set_attr "memory" "load")
2078 (set_attr "mode" "QI")])
2080 (define_insn "*movdi_extzv_1"
2081 [(set (match_operand:DI 0 "register_operand" "=R")
2082 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2086 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2087 [(set_attr "type" "imovx")
2088 (set_attr "mode" "DI")])
2090 (define_insn "*movsi_extzv_1"
2091 [(set (match_operand:SI 0 "register_operand" "=R")
2092 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2096 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2097 [(set_attr "type" "imovx")
2098 (set_attr "mode" "SI")])
2100 (define_insn "*movqi_extzv_2"
2101 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2102 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2107 switch (get_attr_type (insn))
2110 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2112 return "mov{b}\t{%h1, %0|%0, %h1}";
2116 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2117 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2118 (ne (symbol_ref "TARGET_MOVX")
2120 (const_string "imovx")
2121 (const_string "imov")))
2123 (if_then_else (eq_attr "type" "imovx")
2125 (const_string "QI")))])
2127 (define_insn "*movqi_extzv_2_rex64"
2128 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2129 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2134 switch (get_attr_type (insn))
2137 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2139 return "mov{b}\t{%h1, %0|%0, %h1}";
2143 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2144 (ne (symbol_ref "TARGET_MOVX")
2146 (const_string "imovx")
2147 (const_string "imov")))
2149 (if_then_else (eq_attr "type" "imovx")
2151 (const_string "QI")))])
2153 (define_insn "movsi_insv_1"
2154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2157 (match_operand:SI 1 "general_operand" "Qmn"))]
2159 "mov{b}\t{%b1, %h0|%h0, %b1}"
2160 [(set_attr "type" "imov")
2161 (set_attr "mode" "QI")])
2163 (define_insn "*movsi_insv_1_rex64"
2164 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2167 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2169 "mov{b}\t{%b1, %h0|%h0, %b1}"
2170 [(set_attr "type" "imov")
2171 (set_attr "mode" "QI")])
2173 (define_insn "movdi_insv_1_rex64"
2174 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2177 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2179 "mov{b}\t{%b1, %h0|%h0, %b1}"
2180 [(set_attr "type" "imov")
2181 (set_attr "mode" "QI")])
2183 (define_insn "*movqi_insv_2"
2184 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2187 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2190 "mov{b}\t{%h1, %h0|%h0, %h1}"
2191 [(set_attr "type" "imov")
2192 (set_attr "mode" "QI")])
2194 (define_expand "movdi"
2195 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2196 (match_operand:DI 1 "general_operand" ""))]
2198 "ix86_expand_move (DImode, operands); DONE;")
2200 (define_insn "*pushdi"
2201 [(set (match_operand:DI 0 "push_operand" "=<")
2202 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2206 (define_insn "*pushdi2_rex64"
2207 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2208 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2213 [(set_attr "type" "push,multi")
2214 (set_attr "mode" "DI")])
2216 ;; Convert impossible pushes of immediate to existing instructions.
2217 ;; First try to get scratch register and go through it. In case this
2218 ;; fails, push sign extended lower part first and then overwrite
2219 ;; upper part by 32bit move.
2221 [(match_scratch:DI 2 "r")
2222 (set (match_operand:DI 0 "push_operand" "")
2223 (match_operand:DI 1 "immediate_operand" ""))]
2224 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2225 && !x86_64_immediate_operand (operands[1], DImode)"
2226 [(set (match_dup 2) (match_dup 1))
2227 (set (match_dup 0) (match_dup 2))]
2230 ;; We need to define this as both peepholer and splitter for case
2231 ;; peephole2 pass is not run.
2232 ;; "&& 1" is needed to keep it from matching the previous pattern.
2234 [(set (match_operand:DI 0 "push_operand" "")
2235 (match_operand:DI 1 "immediate_operand" ""))]
2236 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2237 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2238 [(set (match_dup 0) (match_dup 1))
2239 (set (match_dup 2) (match_dup 3))]
2240 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2241 operands[1] = gen_lowpart (DImode, operands[2]);
2242 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2247 [(set (match_operand:DI 0 "push_operand" "")
2248 (match_operand:DI 1 "immediate_operand" ""))]
2249 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2250 ? epilogue_completed : reload_completed)
2251 && !symbolic_operand (operands[1], DImode)
2252 && !x86_64_immediate_operand (operands[1], DImode)"
2253 [(set (match_dup 0) (match_dup 1))
2254 (set (match_dup 2) (match_dup 3))]
2255 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2256 operands[1] = gen_lowpart (DImode, operands[2]);
2257 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2261 (define_insn "*pushdi2_prologue_rex64"
2262 [(set (match_operand:DI 0 "push_operand" "=<")
2263 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2264 (clobber (mem:BLK (scratch)))]
2267 [(set_attr "type" "push")
2268 (set_attr "mode" "DI")])
2270 (define_insn "*popdi1_epilogue_rex64"
2271 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2272 (mem:DI (reg:DI SP_REG)))
2273 (set (reg:DI SP_REG)
2274 (plus:DI (reg:DI SP_REG) (const_int 8)))
2275 (clobber (mem:BLK (scratch)))]
2278 [(set_attr "type" "pop")
2279 (set_attr "mode" "DI")])
2281 (define_insn "popdi1"
2282 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2283 (mem:DI (reg:DI SP_REG)))
2284 (set (reg:DI SP_REG)
2285 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2288 [(set_attr "type" "pop")
2289 (set_attr "mode" "DI")])
2291 (define_insn "*movdi_xor_rex64"
2292 [(set (match_operand:DI 0 "register_operand" "=r")
2293 (match_operand:DI 1 "const0_operand" ""))
2294 (clobber (reg:CC FLAGS_REG))]
2296 && reload_completed"
2298 [(set_attr "type" "alu1")
2299 (set_attr "mode" "SI")
2300 (set_attr "length_immediate" "0")])
2302 (define_insn "*movdi_or_rex64"
2303 [(set (match_operand:DI 0 "register_operand" "=r")
2304 (match_operand:DI 1 "const_int_operand" "i"))
2305 (clobber (reg:CC FLAGS_REG))]
2308 && operands[1] == constm1_rtx"
2310 operands[1] = constm1_rtx;
2311 return "or{q}\t{%1, %0|%0, %1}";
2313 [(set_attr "type" "alu1")
2314 (set_attr "mode" "DI")
2315 (set_attr "length_immediate" "1")])
2317 (define_insn "*movdi_2"
2318 [(set (match_operand:DI 0 "nonimmediate_operand"
2319 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2320 (match_operand:DI 1 "general_operand"
2321 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2322 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2327 movq\t{%1, %0|%0, %1}
2328 movq\t{%1, %0|%0, %1}
2330 %vmovq\t{%1, %0|%0, %1}
2331 %vmovdqa\t{%1, %0|%0, %1}
2332 %vmovq\t{%1, %0|%0, %1}
2334 movlps\t{%1, %0|%0, %1}
2335 movaps\t{%1, %0|%0, %1}
2336 movlps\t{%1, %0|%0, %1}"
2337 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2338 (set (attr "prefix")
2339 (if_then_else (eq_attr "alternative" "5,6,7,8")
2340 (const_string "vex")
2341 (const_string "orig")))
2342 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2345 [(set (match_operand:DI 0 "push_operand" "")
2346 (match_operand:DI 1 "general_operand" ""))]
2347 "!TARGET_64BIT && reload_completed
2348 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2350 "ix86_split_long_move (operands); DONE;")
2352 ;; %%% This multiword shite has got to go.
2354 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2355 (match_operand:DI 1 "general_operand" ""))]
2356 "!TARGET_64BIT && reload_completed
2357 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2358 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2360 "ix86_split_long_move (operands); DONE;")
2362 (define_insn "*movdi_1_rex64"
2363 [(set (match_operand:DI 0 "nonimmediate_operand"
2364 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2365 (match_operand:DI 1 "general_operand"
2366 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2367 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2369 switch (get_attr_type (insn))
2372 if (SSE_REG_P (operands[0]))
2373 return "movq2dq\t{%1, %0|%0, %1}";
2375 return "movdq2q\t{%1, %0|%0, %1}";
2380 if (get_attr_mode (insn) == MODE_TI)
2381 return "vmovdqa\t{%1, %0|%0, %1}";
2383 return "vmovq\t{%1, %0|%0, %1}";
2386 if (get_attr_mode (insn) == MODE_TI)
2387 return "movdqa\t{%1, %0|%0, %1}";
2391 /* Moves from and into integer register is done using movd
2392 opcode with REX prefix. */
2393 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2394 return "movd\t{%1, %0|%0, %1}";
2395 return "movq\t{%1, %0|%0, %1}";
2398 return "%vpxor\t%0, %d0";
2401 return "pxor\t%0, %0";
2407 return "lea{q}\t{%a1, %0|%0, %a1}";
2410 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2411 if (get_attr_mode (insn) == MODE_SI)
2412 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2413 else if (which_alternative == 2)
2414 return "movabs{q}\t{%1, %0|%0, %1}";
2416 return "mov{q}\t{%1, %0|%0, %1}";
2420 (cond [(eq_attr "alternative" "5")
2421 (const_string "mmx")
2422 (eq_attr "alternative" "6,7,8,9,10")
2423 (const_string "mmxmov")
2424 (eq_attr "alternative" "11")
2425 (const_string "sselog1")
2426 (eq_attr "alternative" "12,13,14,15,16")
2427 (const_string "ssemov")
2428 (eq_attr "alternative" "17,18")
2429 (const_string "ssecvt")
2430 (eq_attr "alternative" "4")
2431 (const_string "multi")
2432 (match_operand:DI 1 "pic_32bit_operand" "")
2433 (const_string "lea")
2435 (const_string "imov")))
2436 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2437 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2438 (set (attr "prefix")
2439 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2440 (const_string "maybe_vex")
2441 (const_string "orig")))
2442 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2444 ;; Stores and loads of ax to arbitrary constant address.
2445 ;; We fake an second form of instruction to force reload to load address
2446 ;; into register when rax is not available
2447 (define_insn "*movabsdi_1_rex64"
2448 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2449 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2450 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2452 movabs{q}\t{%1, %P0|%P0, %1}
2453 mov{q}\t{%1, %a0|%a0, %1}"
2454 [(set_attr "type" "imov")
2455 (set_attr "modrm" "0,*")
2456 (set_attr "length_address" "8,0")
2457 (set_attr "length_immediate" "0,*")
2458 (set_attr "memory" "store")
2459 (set_attr "mode" "DI")])
2461 (define_insn "*movabsdi_2_rex64"
2462 [(set (match_operand:DI 0 "register_operand" "=a,r")
2463 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2464 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2466 movabs{q}\t{%P1, %0|%0, %P1}
2467 mov{q}\t{%a1, %0|%0, %a1}"
2468 [(set_attr "type" "imov")
2469 (set_attr "modrm" "0,*")
2470 (set_attr "length_address" "8,0")
2471 (set_attr "length_immediate" "0")
2472 (set_attr "memory" "load")
2473 (set_attr "mode" "DI")])
2475 ;; Convert impossible stores of immediate to existing instructions.
2476 ;; First try to get scratch register and go through it. In case this
2477 ;; fails, move by 32bit parts.
2479 [(match_scratch:DI 2 "r")
2480 (set (match_operand:DI 0 "memory_operand" "")
2481 (match_operand:DI 1 "immediate_operand" ""))]
2482 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2483 && !x86_64_immediate_operand (operands[1], DImode)"
2484 [(set (match_dup 2) (match_dup 1))
2485 (set (match_dup 0) (match_dup 2))]
2488 ;; We need to define this as both peepholer and splitter for case
2489 ;; peephole2 pass is not run.
2490 ;; "&& 1" is needed to keep it from matching the previous pattern.
2492 [(set (match_operand:DI 0 "memory_operand" "")
2493 (match_operand:DI 1 "immediate_operand" ""))]
2494 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2495 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2496 [(set (match_dup 2) (match_dup 3))
2497 (set (match_dup 4) (match_dup 5))]
2498 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2501 [(set (match_operand:DI 0 "memory_operand" "")
2502 (match_operand:DI 1 "immediate_operand" ""))]
2503 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2504 ? epilogue_completed : reload_completed)
2505 && !symbolic_operand (operands[1], DImode)
2506 && !x86_64_immediate_operand (operands[1], DImode)"
2507 [(set (match_dup 2) (match_dup 3))
2508 (set (match_dup 4) (match_dup 5))]
2509 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2511 (define_insn "*swapdi_rex64"
2512 [(set (match_operand:DI 0 "register_operand" "+r")
2513 (match_operand:DI 1 "register_operand" "+r"))
2518 [(set_attr "type" "imov")
2519 (set_attr "mode" "DI")
2520 (set_attr "pent_pair" "np")
2521 (set_attr "athlon_decode" "vector")
2522 (set_attr "amdfam10_decode" "double")])
2524 (define_expand "movoi"
2525 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2526 (match_operand:OI 1 "general_operand" ""))]
2528 "ix86_expand_move (OImode, operands); DONE;")
2530 (define_insn "*movoi_internal"
2531 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2532 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2534 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2536 switch (which_alternative)
2539 return "vxorps\t%0, %0, %0";
2542 if (misaligned_operand (operands[0], OImode)
2543 || misaligned_operand (operands[1], OImode))
2544 return "vmovdqu\t{%1, %0|%0, %1}";
2546 return "vmovdqa\t{%1, %0|%0, %1}";
2551 [(set_attr "type" "sselog1,ssemov,ssemov")
2552 (set_attr "prefix" "vex")
2553 (set_attr "mode" "OI")])
2555 (define_expand "movti"
2556 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2557 (match_operand:TI 1 "nonimmediate_operand" ""))]
2558 "TARGET_SSE || TARGET_64BIT"
2561 ix86_expand_move (TImode, operands);
2562 else if (push_operand (operands[0], TImode))
2563 ix86_expand_push (TImode, operands[1]);
2565 ix86_expand_vector_move (TImode, operands);
2569 (define_insn "*movti_internal"
2570 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2571 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2572 "TARGET_SSE && !TARGET_64BIT
2573 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2575 switch (which_alternative)
2578 if (get_attr_mode (insn) == MODE_V4SF)
2579 return "%vxorps\t%0, %d0";
2581 return "%vpxor\t%0, %d0";
2584 /* TDmode values are passed as TImode on the stack. Moving them
2585 to stack may result in unaligned memory access. */
2586 if (misaligned_operand (operands[0], TImode)
2587 || misaligned_operand (operands[1], TImode))
2589 if (get_attr_mode (insn) == MODE_V4SF)
2590 return "%vmovups\t{%1, %0|%0, %1}";
2592 return "%vmovdqu\t{%1, %0|%0, %1}";
2596 if (get_attr_mode (insn) == MODE_V4SF)
2597 return "%vmovaps\t{%1, %0|%0, %1}";
2599 return "%vmovdqa\t{%1, %0|%0, %1}";
2605 [(set_attr "type" "sselog1,ssemov,ssemov")
2606 (set_attr "prefix" "maybe_vex")
2608 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2609 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2610 (const_string "V4SF")
2611 (and (eq_attr "alternative" "2")
2612 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2614 (const_string "V4SF")]
2615 (const_string "TI")))])
2617 (define_insn "*movti_rex64"
2618 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2619 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2621 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2623 switch (which_alternative)
2629 if (get_attr_mode (insn) == MODE_V4SF)
2630 return "%vxorps\t%0, %d0";
2632 return "%vpxor\t%0, %d0";
2635 /* TDmode values are passed as TImode on the stack. Moving them
2636 to stack may result in unaligned memory access. */
2637 if (misaligned_operand (operands[0], TImode)
2638 || misaligned_operand (operands[1], TImode))
2640 if (get_attr_mode (insn) == MODE_V4SF)
2641 return "%vmovups\t{%1, %0|%0, %1}";
2643 return "%vmovdqu\t{%1, %0|%0, %1}";
2647 if (get_attr_mode (insn) == MODE_V4SF)
2648 return "%vmovaps\t{%1, %0|%0, %1}";
2650 return "%vmovdqa\t{%1, %0|%0, %1}";
2656 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2657 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2659 (cond [(eq_attr "alternative" "2,3")
2661 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2663 (const_string "V4SF")
2664 (const_string "TI"))
2665 (eq_attr "alternative" "4")
2667 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2669 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2671 (const_string "V4SF")
2672 (const_string "TI"))]
2673 (const_string "DI")))])
2676 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2677 (match_operand:TI 1 "general_operand" ""))]
2678 "reload_completed && !SSE_REG_P (operands[0])
2679 && !SSE_REG_P (operands[1])"
2681 "ix86_split_long_move (operands); DONE;")
2683 ;; This expands to what emit_move_complex would generate if we didn't
2684 ;; have a movti pattern. Having this avoids problems with reload on
2685 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2686 ;; to have around all the time.
2687 (define_expand "movcdi"
2688 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2689 (match_operand:CDI 1 "general_operand" ""))]
2692 if (push_operand (operands[0], CDImode))
2693 emit_move_complex_push (CDImode, operands[0], operands[1]);
2695 emit_move_complex_parts (operands[0], operands[1]);
2699 (define_expand "movsf"
2700 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2701 (match_operand:SF 1 "general_operand" ""))]
2703 "ix86_expand_move (SFmode, operands); DONE;")
2705 (define_insn "*pushsf"
2706 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2707 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2710 /* Anything else should be already split before reg-stack. */
2711 gcc_assert (which_alternative == 1);
2712 return "push{l}\t%1";
2714 [(set_attr "type" "multi,push,multi")
2715 (set_attr "unit" "i387,*,*")
2716 (set_attr "mode" "SF,SI,SF")])
2718 (define_insn "*pushsf_rex64"
2719 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2720 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2723 /* Anything else should be already split before reg-stack. */
2724 gcc_assert (which_alternative == 1);
2725 return "push{q}\t%q1";
2727 [(set_attr "type" "multi,push,multi")
2728 (set_attr "unit" "i387,*,*")
2729 (set_attr "mode" "SF,DI,SF")])
2732 [(set (match_operand:SF 0 "push_operand" "")
2733 (match_operand:SF 1 "memory_operand" ""))]
2735 && MEM_P (operands[1])
2736 && (operands[2] = find_constant_src (insn))"
2741 ;; %%% Kill this when call knows how to work this out.
2743 [(set (match_operand:SF 0 "push_operand" "")
2744 (match_operand:SF 1 "any_fp_register_operand" ""))]
2746 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2747 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2750 [(set (match_operand:SF 0 "push_operand" "")
2751 (match_operand:SF 1 "any_fp_register_operand" ""))]
2753 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2754 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2756 (define_insn "*movsf_1"
2757 [(set (match_operand:SF 0 "nonimmediate_operand"
2758 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2759 (match_operand:SF 1 "general_operand"
2760 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2761 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2762 && (reload_in_progress || reload_completed
2763 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2764 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2765 && standard_80387_constant_p (operands[1]))
2766 || GET_CODE (operands[1]) != CONST_DOUBLE
2767 || memory_operand (operands[0], SFmode))"
2769 switch (which_alternative)
2773 return output_387_reg_move (insn, operands);
2776 return standard_80387_constant_opcode (operands[1]);
2780 return "mov{l}\t{%1, %0|%0, %1}";
2782 if (get_attr_mode (insn) == MODE_TI)
2783 return "%vpxor\t%0, %d0";
2785 return "%vxorps\t%0, %d0";
2787 if (get_attr_mode (insn) == MODE_V4SF)
2788 return "%vmovaps\t{%1, %0|%0, %1}";
2790 return "%vmovss\t{%1, %d0|%d0, %1}";
2793 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2794 : "vmovss\t{%1, %0|%0, %1}";
2796 return "movss\t{%1, %0|%0, %1}";
2798 return "%vmovss\t{%1, %0|%0, %1}";
2800 case 9: case 10: case 14: case 15:
2801 return "movd\t{%1, %0|%0, %1}";
2803 return "%vmovd\t{%1, %0|%0, %1}";
2806 return "movq\t{%1, %0|%0, %1}";
2812 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2813 (set (attr "prefix")
2814 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2815 (const_string "maybe_vex")
2816 (const_string "orig")))
2818 (cond [(eq_attr "alternative" "3,4,9,10")
2820 (eq_attr "alternative" "5")
2822 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2824 (ne (symbol_ref "TARGET_SSE2")
2826 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2829 (const_string "V4SF"))
2830 /* For architectures resolving dependencies on
2831 whole SSE registers use APS move to break dependency
2832 chains, otherwise use short move to avoid extra work.
2834 Do the same for architectures resolving dependencies on
2835 the parts. While in DF mode it is better to always handle
2836 just register parts, the SF mode is different due to lack
2837 of instructions to load just part of the register. It is
2838 better to maintain the whole registers in single format
2839 to avoid problems on using packed logical operations. */
2840 (eq_attr "alternative" "6")
2842 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2844 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2846 (const_string "V4SF")
2847 (const_string "SF"))
2848 (eq_attr "alternative" "11")
2849 (const_string "DI")]
2850 (const_string "SF")))])
2852 (define_insn "*swapsf"
2853 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2854 (match_operand:SF 1 "fp_register_operand" "+f"))
2857 "reload_completed || TARGET_80387"
2859 if (STACK_TOP_P (operands[0]))
2864 [(set_attr "type" "fxch")
2865 (set_attr "mode" "SF")])
2867 (define_expand "movdf"
2868 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2869 (match_operand:DF 1 "general_operand" ""))]
2871 "ix86_expand_move (DFmode, operands); DONE;")
2873 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2874 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2875 ;; On the average, pushdf using integers can be still shorter. Allow this
2876 ;; pattern for optimize_size too.
2878 (define_insn "*pushdf_nointeger"
2879 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2880 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2881 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2883 /* This insn should be already split before reg-stack. */
2886 [(set_attr "type" "multi")
2887 (set_attr "unit" "i387,*,*,*")
2888 (set_attr "mode" "DF,SI,SI,DF")])
2890 (define_insn "*pushdf_integer"
2891 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2892 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2893 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2895 /* This insn should be already split before reg-stack. */
2898 [(set_attr "type" "multi")
2899 (set_attr "unit" "i387,*,*")
2900 (set_attr "mode" "DF,SI,DF")])
2902 ;; %%% Kill this when call knows how to work this out.
2904 [(set (match_operand:DF 0 "push_operand" "")
2905 (match_operand:DF 1 "any_fp_register_operand" ""))]
2907 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2908 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2912 [(set (match_operand:DF 0 "push_operand" "")
2913 (match_operand:DF 1 "general_operand" ""))]
2916 "ix86_split_long_move (operands); DONE;")
2918 ;; Moving is usually shorter when only FP registers are used. This separate
2919 ;; movdf pattern avoids the use of integer registers for FP operations
2920 ;; when optimizing for size.
2922 (define_insn "*movdf_nointeger"
2923 [(set (match_operand:DF 0 "nonimmediate_operand"
2924 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2925 (match_operand:DF 1 "general_operand"
2926 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2927 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2928 && ((optimize_function_for_size_p (cfun)
2929 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2930 && (reload_in_progress || reload_completed
2931 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2932 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2933 && optimize_function_for_size_p (cfun)
2934 && !memory_operand (operands[0], DFmode)
2935 && standard_80387_constant_p (operands[1]))
2936 || GET_CODE (operands[1]) != CONST_DOUBLE
2937 || ((optimize_function_for_size_p (cfun)
2938 || !TARGET_MEMORY_MISMATCH_STALL
2939 || reload_in_progress || reload_completed)
2940 && memory_operand (operands[0], DFmode)))"
2942 switch (which_alternative)
2946 return output_387_reg_move (insn, operands);
2949 return standard_80387_constant_opcode (operands[1]);
2955 switch (get_attr_mode (insn))
2958 return "%vxorps\t%0, %d0";
2960 return "%vxorpd\t%0, %d0";
2962 return "%vpxor\t%0, %d0";
2969 switch (get_attr_mode (insn))
2972 return "%vmovaps\t{%1, %0|%0, %1}";
2974 return "%vmovapd\t{%1, %0|%0, %1}";
2976 return "%vmovdqa\t{%1, %0|%0, %1}";
2978 return "%vmovq\t{%1, %0|%0, %1}";
2982 if (REG_P (operands[0]) && REG_P (operands[1]))
2983 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2985 return "vmovsd\t{%1, %0|%0, %1}";
2988 return "movsd\t{%1, %0|%0, %1}";
2992 if (REG_P (operands[0]))
2993 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2995 return "vmovlpd\t{%1, %0|%0, %1}";
2998 return "movlpd\t{%1, %0|%0, %1}";
3002 if (REG_P (operands[0]))
3003 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3005 return "vmovlps\t{%1, %0|%0, %1}";
3008 return "movlps\t{%1, %0|%0, %1}";
3017 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3018 (set (attr "prefix")
3019 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3020 (const_string "orig")
3021 (const_string "maybe_vex")))
3023 (cond [(eq_attr "alternative" "0,1,2")
3025 (eq_attr "alternative" "3,4")
3028 /* For SSE1, we have many fewer alternatives. */
3029 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3030 (cond [(eq_attr "alternative" "5,6")
3031 (const_string "V4SF")
3033 (const_string "V2SF"))
3035 /* xorps is one byte shorter. */
3036 (eq_attr "alternative" "5")
3037 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3039 (const_string "V4SF")
3040 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3044 (const_string "V2DF"))
3046 /* For architectures resolving dependencies on
3047 whole SSE registers use APD move to break dependency
3048 chains, otherwise use short move to avoid extra work.
3050 movaps encodes one byte shorter. */
3051 (eq_attr "alternative" "6")
3053 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3055 (const_string "V4SF")
3056 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3058 (const_string "V2DF")
3060 (const_string "DF"))
3061 /* For architectures resolving dependencies on register
3062 parts we may avoid extra work to zero out upper part
3064 (eq_attr "alternative" "7")
3066 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3068 (const_string "V1DF")
3069 (const_string "DF"))
3071 (const_string "DF")))])
3073 (define_insn "*movdf_integer_rex64"
3074 [(set (match_operand:DF 0 "nonimmediate_operand"
3075 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3076 (match_operand:DF 1 "general_operand"
3077 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3078 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3079 && (reload_in_progress || reload_completed
3080 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3081 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3082 && optimize_function_for_size_p (cfun)
3083 && standard_80387_constant_p (operands[1]))
3084 || GET_CODE (operands[1]) != CONST_DOUBLE
3085 || memory_operand (operands[0], DFmode))"
3087 switch (which_alternative)
3091 return output_387_reg_move (insn, operands);
3094 return standard_80387_constant_opcode (operands[1]);
3101 switch (get_attr_mode (insn))
3104 return "%vxorps\t%0, %d0";
3106 return "%vxorpd\t%0, %d0";
3108 return "%vpxor\t%0, %d0";
3115 switch (get_attr_mode (insn))
3118 return "%vmovaps\t{%1, %0|%0, %1}";
3120 return "%vmovapd\t{%1, %0|%0, %1}";
3122 return "%vmovdqa\t{%1, %0|%0, %1}";
3124 return "%vmovq\t{%1, %0|%0, %1}";
3128 if (REG_P (operands[0]) && REG_P (operands[1]))
3129 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3131 return "vmovsd\t{%1, %0|%0, %1}";
3134 return "movsd\t{%1, %0|%0, %1}";
3136 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3138 return "%vmovlps\t{%1, %d0|%d0, %1}";
3145 return "%vmovd\t{%1, %0|%0, %1}";
3151 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3152 (set (attr "prefix")
3153 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3154 (const_string "orig")
3155 (const_string "maybe_vex")))
3157 (cond [(eq_attr "alternative" "0,1,2")
3159 (eq_attr "alternative" "3,4,9,10")
3162 /* For SSE1, we have many fewer alternatives. */
3163 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3164 (cond [(eq_attr "alternative" "5,6")
3165 (const_string "V4SF")
3167 (const_string "V2SF"))
3169 /* xorps is one byte shorter. */
3170 (eq_attr "alternative" "5")
3171 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3173 (const_string "V4SF")
3174 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3178 (const_string "V2DF"))
3180 /* For architectures resolving dependencies on
3181 whole SSE registers use APD move to break dependency
3182 chains, otherwise use short move to avoid extra work.
3184 movaps encodes one byte shorter. */
3185 (eq_attr "alternative" "6")
3187 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3189 (const_string "V4SF")
3190 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3192 (const_string "V2DF")
3194 (const_string "DF"))
3195 /* For architectures resolving dependencies on register
3196 parts we may avoid extra work to zero out upper part
3198 (eq_attr "alternative" "7")
3200 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3202 (const_string "V1DF")
3203 (const_string "DF"))
3205 (const_string "DF")))])
3207 (define_insn "*movdf_integer"
3208 [(set (match_operand:DF 0 "nonimmediate_operand"
3209 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3210 (match_operand:DF 1 "general_operand"
3211 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3212 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3213 && optimize_function_for_speed_p (cfun)
3214 && TARGET_INTEGER_DFMODE_MOVES
3215 && (reload_in_progress || reload_completed
3216 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3217 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3218 && optimize_function_for_size_p (cfun)
3219 && standard_80387_constant_p (operands[1]))
3220 || GET_CODE (operands[1]) != CONST_DOUBLE
3221 || memory_operand (operands[0], DFmode))"
3223 switch (which_alternative)
3227 return output_387_reg_move (insn, operands);
3230 return standard_80387_constant_opcode (operands[1]);
3237 switch (get_attr_mode (insn))
3240 return "xorps\t%0, %0";
3242 return "xorpd\t%0, %0";
3244 return "pxor\t%0, %0";
3251 switch (get_attr_mode (insn))
3254 return "movaps\t{%1, %0|%0, %1}";
3256 return "movapd\t{%1, %0|%0, %1}";
3258 return "movdqa\t{%1, %0|%0, %1}";
3260 return "movq\t{%1, %0|%0, %1}";
3262 return "movsd\t{%1, %0|%0, %1}";
3264 return "movlpd\t{%1, %0|%0, %1}";
3266 return "movlps\t{%1, %0|%0, %1}";
3275 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3277 (cond [(eq_attr "alternative" "0,1,2")
3279 (eq_attr "alternative" "3,4")
3282 /* For SSE1, we have many fewer alternatives. */
3283 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3284 (cond [(eq_attr "alternative" "5,6")
3285 (const_string "V4SF")
3287 (const_string "V2SF"))
3289 /* xorps is one byte shorter. */
3290 (eq_attr "alternative" "5")
3291 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3293 (const_string "V4SF")
3294 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3298 (const_string "V2DF"))
3300 /* For architectures resolving dependencies on
3301 whole SSE registers use APD move to break dependency
3302 chains, otherwise use short move to avoid extra work.
3304 movaps encodes one byte shorter. */
3305 (eq_attr "alternative" "6")
3307 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3309 (const_string "V4SF")
3310 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3312 (const_string "V2DF")
3314 (const_string "DF"))
3315 /* For architectures resolving dependencies on register
3316 parts we may avoid extra work to zero out upper part
3318 (eq_attr "alternative" "7")
3320 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3322 (const_string "V1DF")
3323 (const_string "DF"))
3325 (const_string "DF")))])
3328 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3329 (match_operand:DF 1 "general_operand" ""))]
3331 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3332 && ! (ANY_FP_REG_P (operands[0]) ||
3333 (GET_CODE (operands[0]) == SUBREG
3334 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3335 && ! (ANY_FP_REG_P (operands[1]) ||
3336 (GET_CODE (operands[1]) == SUBREG
3337 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3339 "ix86_split_long_move (operands); DONE;")
3341 (define_insn "*swapdf"
3342 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3343 (match_operand:DF 1 "fp_register_operand" "+f"))
3346 "reload_completed || TARGET_80387"
3348 if (STACK_TOP_P (operands[0]))
3353 [(set_attr "type" "fxch")
3354 (set_attr "mode" "DF")])
3356 (define_expand "movxf"
3357 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3358 (match_operand:XF 1 "general_operand" ""))]
3360 "ix86_expand_move (XFmode, operands); DONE;")
3362 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3363 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3364 ;; Pushing using integer instructions is longer except for constants
3365 ;; and direct memory references.
3366 ;; (assuming that any given constant is pushed only once, but this ought to be
3367 ;; handled elsewhere).
3369 (define_insn "*pushxf_nointeger"
3370 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3371 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3372 "optimize_function_for_size_p (cfun)"
3374 /* This insn should be already split before reg-stack. */
3377 [(set_attr "type" "multi")
3378 (set_attr "unit" "i387,*,*")
3379 (set_attr "mode" "XF,SI,SI")])
3381 (define_insn "*pushxf_integer"
3382 [(set (match_operand:XF 0 "push_operand" "=<,<")
3383 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3384 "optimize_function_for_speed_p (cfun)"
3386 /* This insn should be already split before reg-stack. */
3389 [(set_attr "type" "multi")
3390 (set_attr "unit" "i387,*")
3391 (set_attr "mode" "XF,SI")])
3394 [(set (match_operand 0 "push_operand" "")
3395 (match_operand 1 "general_operand" ""))]
3397 && (GET_MODE (operands[0]) == XFmode
3398 || GET_MODE (operands[0]) == DFmode)
3399 && !ANY_FP_REG_P (operands[1])"
3401 "ix86_split_long_move (operands); DONE;")
3404 [(set (match_operand:XF 0 "push_operand" "")
3405 (match_operand:XF 1 "any_fp_register_operand" ""))]
3407 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3408 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3409 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3411 ;; Do not use integer registers when optimizing for size
3412 (define_insn "*movxf_nointeger"
3413 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3414 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3415 "optimize_function_for_size_p (cfun)
3416 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3417 && (reload_in_progress || reload_completed
3418 || standard_80387_constant_p (operands[1])
3419 || GET_CODE (operands[1]) != CONST_DOUBLE
3420 || memory_operand (operands[0], XFmode))"
3422 switch (which_alternative)
3426 return output_387_reg_move (insn, operands);
3429 return standard_80387_constant_opcode (operands[1]);
3437 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3438 (set_attr "mode" "XF,XF,XF,SI,SI")])
3440 (define_insn "*movxf_integer"
3441 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3442 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3443 "optimize_function_for_speed_p (cfun)
3444 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3445 && (reload_in_progress || reload_completed
3446 || GET_CODE (operands[1]) != CONST_DOUBLE
3447 || memory_operand (operands[0], XFmode))"
3449 switch (which_alternative)
3453 return output_387_reg_move (insn, operands);
3456 return standard_80387_constant_opcode (operands[1]);
3465 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3466 (set_attr "mode" "XF,XF,XF,SI,SI")])
3468 (define_expand "movtf"
3469 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3470 (match_operand:TF 1 "nonimmediate_operand" ""))]
3473 ix86_expand_move (TFmode, operands);
3477 (define_insn "*movtf_internal"
3478 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3479 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3483 switch (which_alternative)
3487 if (get_attr_mode (insn) == MODE_V4SF)
3488 return "%vmovaps\t{%1, %0|%0, %1}";
3490 return "%vmovdqa\t{%1, %0|%0, %1}";
3492 if (get_attr_mode (insn) == MODE_V4SF)
3493 return "%vxorps\t%0, %d0";
3495 return "%vpxor\t%0, %d0";
3503 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3504 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3506 (cond [(eq_attr "alternative" "0,2")
3508 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3510 (const_string "V4SF")
3511 (const_string "TI"))
3512 (eq_attr "alternative" "1")
3514 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3516 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3518 (const_string "V4SF")
3519 (const_string "TI"))]
3520 (const_string "DI")))])
3522 (define_insn "*pushtf_sse"
3523 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3524 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3527 /* This insn should be already split before reg-stack. */
3530 [(set_attr "type" "multi")
3531 (set_attr "unit" "sse,*,*")
3532 (set_attr "mode" "TF,SI,SI")])
3535 [(set (match_operand:TF 0 "push_operand" "")
3536 (match_operand:TF 1 "general_operand" ""))]
3537 "TARGET_SSE2 && reload_completed
3538 && !SSE_REG_P (operands[1])"
3540 "ix86_split_long_move (operands); DONE;")
3543 [(set (match_operand:TF 0 "push_operand" "")
3544 (match_operand:TF 1 "any_fp_register_operand" ""))]
3546 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3547 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3551 [(set (match_operand 0 "nonimmediate_operand" "")
3552 (match_operand 1 "general_operand" ""))]
3554 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3555 && GET_MODE (operands[0]) == XFmode
3556 && ! (ANY_FP_REG_P (operands[0]) ||
3557 (GET_CODE (operands[0]) == SUBREG
3558 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3559 && ! (ANY_FP_REG_P (operands[1]) ||
3560 (GET_CODE (operands[1]) == SUBREG
3561 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3563 "ix86_split_long_move (operands); DONE;")
3566 [(set (match_operand 0 "register_operand" "")
3567 (match_operand 1 "memory_operand" ""))]
3569 && MEM_P (operands[1])
3570 && (GET_MODE (operands[0]) == TFmode
3571 || GET_MODE (operands[0]) == XFmode
3572 || GET_MODE (operands[0]) == SFmode
3573 || GET_MODE (operands[0]) == DFmode)
3574 && (operands[2] = find_constant_src (insn))"
3575 [(set (match_dup 0) (match_dup 2))]
3577 rtx c = operands[2];
3578 rtx r = operands[0];
3580 if (GET_CODE (r) == SUBREG)
3585 if (!standard_sse_constant_p (c))
3588 else if (FP_REG_P (r))
3590 if (!standard_80387_constant_p (c))
3593 else if (MMX_REG_P (r))
3598 [(set (match_operand 0 "register_operand" "")
3599 (float_extend (match_operand 1 "memory_operand" "")))]
3601 && MEM_P (operands[1])
3602 && (GET_MODE (operands[0]) == TFmode
3603 || GET_MODE (operands[0]) == XFmode
3604 || GET_MODE (operands[0]) == SFmode
3605 || GET_MODE (operands[0]) == DFmode)
3606 && (operands[2] = find_constant_src (insn))"
3607 [(set (match_dup 0) (match_dup 2))]
3609 rtx c = operands[2];
3610 rtx r = operands[0];
3612 if (GET_CODE (r) == SUBREG)
3617 if (!standard_sse_constant_p (c))
3620 else if (FP_REG_P (r))
3622 if (!standard_80387_constant_p (c))
3625 else if (MMX_REG_P (r))
3629 (define_insn "swapxf"
3630 [(set (match_operand:XF 0 "register_operand" "+f")
3631 (match_operand:XF 1 "register_operand" "+f"))
3636 if (STACK_TOP_P (operands[0]))
3641 [(set_attr "type" "fxch")
3642 (set_attr "mode" "XF")])
3644 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3646 [(set (match_operand:X87MODEF 0 "register_operand" "")
3647 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3648 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3649 && (standard_80387_constant_p (operands[1]) == 8
3650 || standard_80387_constant_p (operands[1]) == 9)"
3651 [(set (match_dup 0)(match_dup 1))
3653 (neg:X87MODEF (match_dup 0)))]
3657 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3658 if (real_isnegzero (&r))
3659 operands[1] = CONST0_RTX (<MODE>mode);
3661 operands[1] = CONST1_RTX (<MODE>mode);
3665 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3666 (match_operand:TF 1 "general_operand" ""))]
3668 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3670 "ix86_split_long_move (operands); DONE;")
3672 ;; Zero extension instructions
3674 (define_expand "zero_extendhisi2"
3675 [(set (match_operand:SI 0 "register_operand" "")
3676 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3679 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3681 operands[1] = force_reg (HImode, operands[1]);
3682 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3687 (define_insn "zero_extendhisi2_and"
3688 [(set (match_operand:SI 0 "register_operand" "=r")
3689 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3690 (clobber (reg:CC FLAGS_REG))]
3691 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3693 [(set_attr "type" "alu1")
3694 (set_attr "mode" "SI")])
3697 [(set (match_operand:SI 0 "register_operand" "")
3698 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3699 (clobber (reg:CC FLAGS_REG))]
3700 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3701 && optimize_function_for_speed_p (cfun)"
3702 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3703 (clobber (reg:CC FLAGS_REG))])]
3706 (define_insn "*zero_extendhisi2_movzwl"
3707 [(set (match_operand:SI 0 "register_operand" "=r")
3708 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3709 "!TARGET_ZERO_EXTEND_WITH_AND
3710 || optimize_function_for_size_p (cfun)"
3711 "movz{wl|x}\t{%1, %0|%0, %1}"
3712 [(set_attr "type" "imovx")
3713 (set_attr "mode" "SI")])
3715 (define_expand "zero_extendqihi2"
3717 [(set (match_operand:HI 0 "register_operand" "")
3718 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3719 (clobber (reg:CC FLAGS_REG))])]
3723 (define_insn "*zero_extendqihi2_and"
3724 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3725 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3726 (clobber (reg:CC FLAGS_REG))]
3727 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3729 [(set_attr "type" "alu1")
3730 (set_attr "mode" "HI")])
3732 (define_insn "*zero_extendqihi2_movzbw_and"
3733 [(set (match_operand:HI 0 "register_operand" "=r,r")
3734 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3735 (clobber (reg:CC FLAGS_REG))]
3736 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3738 [(set_attr "type" "imovx,alu1")
3739 (set_attr "mode" "HI")])
3741 ; zero extend to SImode here to avoid partial register stalls
3742 (define_insn "*zero_extendqihi2_movzbl"
3743 [(set (match_operand:HI 0 "register_operand" "=r")
3744 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3745 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3746 && reload_completed"
3747 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3748 [(set_attr "type" "imovx")
3749 (set_attr "mode" "SI")])
3751 ;; For the movzbw case strip only the clobber
3753 [(set (match_operand:HI 0 "register_operand" "")
3754 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3755 (clobber (reg:CC FLAGS_REG))]
3757 && (!TARGET_ZERO_EXTEND_WITH_AND
3758 || optimize_function_for_size_p (cfun))
3759 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3760 [(set (match_operand:HI 0 "register_operand" "")
3761 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3763 ;; When source and destination does not overlap, clear destination
3764 ;; first and then do the movb
3766 [(set (match_operand:HI 0 "register_operand" "")
3767 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3768 (clobber (reg:CC FLAGS_REG))]
3770 && ANY_QI_REG_P (operands[0])
3771 && (TARGET_ZERO_EXTEND_WITH_AND
3772 && optimize_function_for_speed_p (cfun))
3773 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3774 [(set (match_dup 0) (const_int 0))
3775 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3776 "operands[2] = gen_lowpart (QImode, operands[0]);")
3778 ;; Rest is handled by single and.
3780 [(set (match_operand:HI 0 "register_operand" "")
3781 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3782 (clobber (reg:CC FLAGS_REG))]
3784 && true_regnum (operands[0]) == true_regnum (operands[1])"
3785 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3786 (clobber (reg:CC FLAGS_REG))])]
3789 (define_expand "zero_extendqisi2"
3791 [(set (match_operand:SI 0 "register_operand" "")
3792 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3793 (clobber (reg:CC FLAGS_REG))])]
3797 (define_insn "*zero_extendqisi2_and"
3798 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3799 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3800 (clobber (reg:CC FLAGS_REG))]
3801 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3803 [(set_attr "type" "alu1")
3804 (set_attr "mode" "SI")])
3806 (define_insn "*zero_extendqisi2_movzbw_and"
3807 [(set (match_operand:SI 0 "register_operand" "=r,r")
3808 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3809 (clobber (reg:CC FLAGS_REG))]
3810 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3812 [(set_attr "type" "imovx,alu1")
3813 (set_attr "mode" "SI")])
3815 (define_insn "*zero_extendqisi2_movzbw"
3816 [(set (match_operand:SI 0 "register_operand" "=r")
3817 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3818 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3819 && reload_completed"
3820 "movz{bl|x}\t{%1, %0|%0, %1}"
3821 [(set_attr "type" "imovx")
3822 (set_attr "mode" "SI")])
3824 ;; For the movzbl case strip only the clobber
3826 [(set (match_operand:SI 0 "register_operand" "")
3827 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3828 (clobber (reg:CC FLAGS_REG))]
3830 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3831 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3833 (zero_extend:SI (match_dup 1)))])
3835 ;; When source and destination does not overlap, clear destination
3836 ;; first and then do the movb
3838 [(set (match_operand:SI 0 "register_operand" "")
3839 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3840 (clobber (reg:CC FLAGS_REG))]
3842 && ANY_QI_REG_P (operands[0])
3843 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3844 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3845 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3846 [(set (match_dup 0) (const_int 0))
3847 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3848 "operands[2] = gen_lowpart (QImode, operands[0]);")
3850 ;; Rest is handled by single and.
3852 [(set (match_operand:SI 0 "register_operand" "")
3853 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3854 (clobber (reg:CC FLAGS_REG))]
3856 && true_regnum (operands[0]) == true_regnum (operands[1])"
3857 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3858 (clobber (reg:CC FLAGS_REG))])]
3861 ;; %%% Kill me once multi-word ops are sane.
3862 (define_expand "zero_extendsidi2"
3863 [(set (match_operand:DI 0 "register_operand" "")
3864 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3869 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3874 (define_insn "zero_extendsidi2_32"
3875 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3877 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3878 (clobber (reg:CC FLAGS_REG))]
3884 movd\t{%1, %0|%0, %1}
3885 movd\t{%1, %0|%0, %1}
3886 %vmovd\t{%1, %0|%0, %1}
3887 %vmovd\t{%1, %0|%0, %1}"
3888 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3889 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3890 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3892 (define_insn "zero_extendsidi2_rex64"
3893 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3895 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3898 mov\t{%k1, %k0|%k0, %k1}
3900 movd\t{%1, %0|%0, %1}
3901 movd\t{%1, %0|%0, %1}
3902 %vmovd\t{%1, %0|%0, %1}
3903 %vmovd\t{%1, %0|%0, %1}"
3904 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3905 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3906 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3909 [(set (match_operand:DI 0 "memory_operand" "")
3910 (zero_extend:DI (match_dup 0)))]
3912 [(set (match_dup 4) (const_int 0))]
3913 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3916 [(set (match_operand:DI 0 "register_operand" "")
3917 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3918 (clobber (reg:CC FLAGS_REG))]
3919 "!TARGET_64BIT && reload_completed
3920 && true_regnum (operands[0]) == true_regnum (operands[1])"
3921 [(set (match_dup 4) (const_int 0))]
3922 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3925 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3926 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3927 (clobber (reg:CC FLAGS_REG))]
3928 "!TARGET_64BIT && reload_completed
3929 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3930 [(set (match_dup 3) (match_dup 1))
3931 (set (match_dup 4) (const_int 0))]
3932 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3934 (define_insn "zero_extendhidi2"
3935 [(set (match_operand:DI 0 "register_operand" "=r")
3936 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3938 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3939 [(set_attr "type" "imovx")
3940 (set_attr "mode" "DI")])
3942 (define_insn "zero_extendqidi2"
3943 [(set (match_operand:DI 0 "register_operand" "=r")
3944 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3946 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3947 [(set_attr "type" "imovx")
3948 (set_attr "mode" "DI")])
3950 ;; Sign extension instructions
3952 (define_expand "extendsidi2"
3953 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3954 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3955 (clobber (reg:CC FLAGS_REG))
3956 (clobber (match_scratch:SI 2 ""))])]
3961 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3966 (define_insn "*extendsidi2_1"
3967 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3968 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3969 (clobber (reg:CC FLAGS_REG))
3970 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3974 (define_insn "extendsidi2_rex64"
3975 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3976 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3980 movs{lq|x}\t{%1,%0|%0, %1}"
3981 [(set_attr "type" "imovx")
3982 (set_attr "mode" "DI")
3983 (set_attr "prefix_0f" "0")
3984 (set_attr "modrm" "0,1")])
3986 (define_insn "extendhidi2"
3987 [(set (match_operand:DI 0 "register_operand" "=r")
3988 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3990 "movs{wq|x}\t{%1,%0|%0, %1}"
3991 [(set_attr "type" "imovx")
3992 (set_attr "mode" "DI")])
3994 (define_insn "extendqidi2"
3995 [(set (match_operand:DI 0 "register_operand" "=r")
3996 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3998 "movs{bq|x}\t{%1,%0|%0, %1}"
3999 [(set_attr "type" "imovx")
4000 (set_attr "mode" "DI")])
4002 ;; Extend to memory case when source register does die.
4004 [(set (match_operand:DI 0 "memory_operand" "")
4005 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4006 (clobber (reg:CC FLAGS_REG))
4007 (clobber (match_operand:SI 2 "register_operand" ""))]
4009 && dead_or_set_p (insn, operands[1])
4010 && !reg_mentioned_p (operands[1], operands[0]))"
4011 [(set (match_dup 3) (match_dup 1))
4012 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4013 (clobber (reg:CC FLAGS_REG))])
4014 (set (match_dup 4) (match_dup 1))]
4015 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4017 ;; Extend to memory case when source register does not die.
4019 [(set (match_operand:DI 0 "memory_operand" "")
4020 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4021 (clobber (reg:CC FLAGS_REG))
4022 (clobber (match_operand:SI 2 "register_operand" ""))]
4026 split_di (&operands[0], 1, &operands[3], &operands[4]);
4028 emit_move_insn (operands[3], operands[1]);
4030 /* Generate a cltd if possible and doing so it profitable. */
4031 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4032 && true_regnum (operands[1]) == AX_REG
4033 && true_regnum (operands[2]) == DX_REG)
4035 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4039 emit_move_insn (operands[2], operands[1]);
4040 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4042 emit_move_insn (operands[4], operands[2]);
4046 ;; Extend to register case. Optimize case where source and destination
4047 ;; registers match and cases where we can use cltd.
4049 [(set (match_operand:DI 0 "register_operand" "")
4050 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4051 (clobber (reg:CC FLAGS_REG))
4052 (clobber (match_scratch:SI 2 ""))]
4056 split_di (&operands[0], 1, &operands[3], &operands[4]);
4058 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4059 emit_move_insn (operands[3], operands[1]);
4061 /* Generate a cltd if possible and doing so it profitable. */
4062 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4063 && true_regnum (operands[3]) == AX_REG)
4065 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4069 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4070 emit_move_insn (operands[4], operands[1]);
4072 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4076 (define_insn "extendhisi2"
4077 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4078 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4081 switch (get_attr_prefix_0f (insn))
4084 return "{cwtl|cwde}";
4086 return "movs{wl|x}\t{%1,%0|%0, %1}";
4089 [(set_attr "type" "imovx")
4090 (set_attr "mode" "SI")
4091 (set (attr "prefix_0f")
4092 ;; movsx is short decodable while cwtl is vector decoded.
4093 (if_then_else (and (eq_attr "cpu" "!k6")
4094 (eq_attr "alternative" "0"))
4096 (const_string "1")))
4098 (if_then_else (eq_attr "prefix_0f" "0")
4100 (const_string "1")))])
4102 (define_insn "*extendhisi2_zext"
4103 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4105 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4108 switch (get_attr_prefix_0f (insn))
4111 return "{cwtl|cwde}";
4113 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4116 [(set_attr "type" "imovx")
4117 (set_attr "mode" "SI")
4118 (set (attr "prefix_0f")
4119 ;; movsx is short decodable while cwtl is vector decoded.
4120 (if_then_else (and (eq_attr "cpu" "!k6")
4121 (eq_attr "alternative" "0"))
4123 (const_string "1")))
4125 (if_then_else (eq_attr "prefix_0f" "0")
4127 (const_string "1")))])
4129 (define_insn "extendqihi2"
4130 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4131 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4134 switch (get_attr_prefix_0f (insn))
4137 return "{cbtw|cbw}";
4139 return "movs{bw|x}\t{%1,%0|%0, %1}";
4142 [(set_attr "type" "imovx")
4143 (set_attr "mode" "HI")
4144 (set (attr "prefix_0f")
4145 ;; movsx is short decodable while cwtl is vector decoded.
4146 (if_then_else (and (eq_attr "cpu" "!k6")
4147 (eq_attr "alternative" "0"))
4149 (const_string "1")))
4151 (if_then_else (eq_attr "prefix_0f" "0")
4153 (const_string "1")))])
4155 (define_insn "extendqisi2"
4156 [(set (match_operand:SI 0 "register_operand" "=r")
4157 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4159 "movs{bl|x}\t{%1,%0|%0, %1}"
4160 [(set_attr "type" "imovx")
4161 (set_attr "mode" "SI")])
4163 (define_insn "*extendqisi2_zext"
4164 [(set (match_operand:DI 0 "register_operand" "=r")
4166 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4168 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4169 [(set_attr "type" "imovx")
4170 (set_attr "mode" "SI")])
4172 ;; Conversions between float and double.
4174 ;; These are all no-ops in the model used for the 80387. So just
4177 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4178 (define_insn "*dummy_extendsfdf2"
4179 [(set (match_operand:DF 0 "push_operand" "=<")
4180 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4185 [(set (match_operand:DF 0 "push_operand" "")
4186 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4188 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4189 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4191 (define_insn "*dummy_extendsfxf2"
4192 [(set (match_operand:XF 0 "push_operand" "=<")
4193 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4198 [(set (match_operand:XF 0 "push_operand" "")
4199 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4201 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4202 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4203 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4206 [(set (match_operand:XF 0 "push_operand" "")
4207 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4209 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4210 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4211 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4213 (define_expand "extendsfdf2"
4214 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4215 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4216 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4218 /* ??? Needed for compress_float_constant since all fp constants
4219 are LEGITIMATE_CONSTANT_P. */
4220 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4222 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4223 && standard_80387_constant_p (operands[1]) > 0)
4225 operands[1] = simplify_const_unary_operation
4226 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4227 emit_move_insn_1 (operands[0], operands[1]);
4230 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4234 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4236 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4238 We do the conversion post reload to avoid producing of 128bit spills
4239 that might lead to ICE on 32bit target. The sequence unlikely combine
4242 [(set (match_operand:DF 0 "register_operand" "")
4244 (match_operand:SF 1 "nonimmediate_operand" "")))]
4245 "TARGET_USE_VECTOR_FP_CONVERTS
4246 && optimize_insn_for_speed_p ()
4247 && reload_completed && SSE_REG_P (operands[0])"
4252 (parallel [(const_int 0) (const_int 1)]))))]
4254 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4255 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4256 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4257 Try to avoid move when unpacking can be done in source. */
4258 if (REG_P (operands[1]))
4260 /* If it is unsafe to overwrite upper half of source, we need
4261 to move to destination and unpack there. */
4262 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4263 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4264 && true_regnum (operands[0]) != true_regnum (operands[1]))
4266 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4267 emit_move_insn (tmp, operands[1]);
4270 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4271 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4274 emit_insn (gen_vec_setv4sf_0 (operands[3],
4275 CONST0_RTX (V4SFmode), operands[1]));
4278 (define_insn "*extendsfdf2_mixed"
4279 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4281 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4282 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4284 switch (which_alternative)
4288 return output_387_reg_move (insn, operands);
4291 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4297 [(set_attr "type" "fmov,fmov,ssecvt")
4298 (set_attr "prefix" "orig,orig,maybe_vex")
4299 (set_attr "mode" "SF,XF,DF")])
4301 (define_insn "*extendsfdf2_sse"
4302 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4303 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4304 "TARGET_SSE2 && TARGET_SSE_MATH"
4305 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4306 [(set_attr "type" "ssecvt")
4307 (set_attr "prefix" "maybe_vex")
4308 (set_attr "mode" "DF")])
4310 (define_insn "*extendsfdf2_i387"
4311 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4312 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4314 "* return output_387_reg_move (insn, operands);"
4315 [(set_attr "type" "fmov")
4316 (set_attr "mode" "SF,XF")])
4318 (define_expand "extend<mode>xf2"
4319 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4320 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4323 /* ??? Needed for compress_float_constant since all fp constants
4324 are LEGITIMATE_CONSTANT_P. */
4325 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4327 if (standard_80387_constant_p (operands[1]) > 0)
4329 operands[1] = simplify_const_unary_operation
4330 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4331 emit_move_insn_1 (operands[0], operands[1]);
4334 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4338 (define_insn "*extend<mode>xf2_i387"
4339 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4341 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4343 "* return output_387_reg_move (insn, operands);"
4344 [(set_attr "type" "fmov")
4345 (set_attr "mode" "<MODE>,XF")])
4347 ;; %%% This seems bad bad news.
4348 ;; This cannot output into an f-reg because there is no way to be sure
4349 ;; of truncating in that case. Otherwise this is just like a simple move
4350 ;; insn. So we pretend we can output to a reg in order to get better
4351 ;; register preferencing, but we really use a stack slot.
4353 ;; Conversion from DFmode to SFmode.
4355 (define_expand "truncdfsf2"
4356 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4358 (match_operand:DF 1 "nonimmediate_operand" "")))]
4359 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4361 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4363 else if (flag_unsafe_math_optimizations)
4367 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4368 rtx temp = assign_386_stack_local (SFmode, slot);
4369 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4374 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4376 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4378 We do the conversion post reload to avoid producing of 128bit spills
4379 that might lead to ICE on 32bit target. The sequence unlikely combine
4382 [(set (match_operand:SF 0 "register_operand" "")
4384 (match_operand:DF 1 "nonimmediate_operand" "")))]
4385 "TARGET_USE_VECTOR_FP_CONVERTS
4386 && optimize_insn_for_speed_p ()
4387 && reload_completed && SSE_REG_P (operands[0])"
4390 (float_truncate:V2SF
4394 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4395 operands[3] = CONST0_RTX (V2SFmode);
4396 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4397 /* Use movsd for loading from memory, unpcklpd for registers.
4398 Try to avoid move when unpacking can be done in source, or SSE3
4399 movddup is available. */
4400 if (REG_P (operands[1]))
4403 && true_regnum (operands[0]) != true_regnum (operands[1])
4404 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4405 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4407 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4408 emit_move_insn (tmp, operands[1]);
4411 else if (!TARGET_SSE3)
4412 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4413 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4416 emit_insn (gen_sse2_loadlpd (operands[4],
4417 CONST0_RTX (V2DFmode), operands[1]));
4420 (define_expand "truncdfsf2_with_temp"
4421 [(parallel [(set (match_operand:SF 0 "" "")
4422 (float_truncate:SF (match_operand:DF 1 "" "")))
4423 (clobber (match_operand:SF 2 "" ""))])]
4426 (define_insn "*truncdfsf_fast_mixed"
4427 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4429 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4430 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4432 switch (which_alternative)
4435 return output_387_reg_move (insn, operands);
4437 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4442 [(set_attr "type" "fmov,ssecvt")
4443 (set_attr "prefix" "orig,maybe_vex")
4444 (set_attr "mode" "SF")])
4446 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4447 ;; because nothing we do here is unsafe.
4448 (define_insn "*truncdfsf_fast_sse"
4449 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4451 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4452 "TARGET_SSE2 && TARGET_SSE_MATH"
4453 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4454 [(set_attr "type" "ssecvt")
4455 (set_attr "prefix" "maybe_vex")
4456 (set_attr "mode" "SF")])
4458 (define_insn "*truncdfsf_fast_i387"
4459 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4461 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4462 "TARGET_80387 && flag_unsafe_math_optimizations"
4463 "* return output_387_reg_move (insn, operands);"
4464 [(set_attr "type" "fmov")
4465 (set_attr "mode" "SF")])
4467 (define_insn "*truncdfsf_mixed"
4468 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4470 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4471 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4472 "TARGET_MIX_SSE_I387"
4474 switch (which_alternative)
4477 return output_387_reg_move (insn, operands);
4479 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4485 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4486 (set_attr "unit" "*,*,i387,i387,i387")
4487 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4488 (set_attr "mode" "SF")])
4490 (define_insn "*truncdfsf_i387"
4491 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4493 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4494 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4497 switch (which_alternative)
4500 return output_387_reg_move (insn, operands);
4506 [(set_attr "type" "fmov,multi,multi,multi")
4507 (set_attr "unit" "*,i387,i387,i387")
4508 (set_attr "mode" "SF")])
4510 (define_insn "*truncdfsf2_i387_1"
4511 [(set (match_operand:SF 0 "memory_operand" "=m")
4513 (match_operand:DF 1 "register_operand" "f")))]
4515 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4516 && !TARGET_MIX_SSE_I387"
4517 "* return output_387_reg_move (insn, operands);"
4518 [(set_attr "type" "fmov")
4519 (set_attr "mode" "SF")])
4522 [(set (match_operand:SF 0 "register_operand" "")
4524 (match_operand:DF 1 "fp_register_operand" "")))
4525 (clobber (match_operand 2 "" ""))]
4527 [(set (match_dup 2) (match_dup 1))
4528 (set (match_dup 0) (match_dup 2))]
4530 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4533 ;; Conversion from XFmode to {SF,DF}mode
4535 (define_expand "truncxf<mode>2"
4536 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4537 (float_truncate:MODEF
4538 (match_operand:XF 1 "register_operand" "")))
4539 (clobber (match_dup 2))])]
4542 if (flag_unsafe_math_optimizations)
4544 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4545 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4546 if (reg != operands[0])
4547 emit_move_insn (operands[0], reg);
4552 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4553 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4557 (define_insn "*truncxfsf2_mixed"
4558 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4560 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4561 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4564 gcc_assert (!which_alternative);
4565 return output_387_reg_move (insn, operands);
4567 [(set_attr "type" "fmov,multi,multi,multi")
4568 (set_attr "unit" "*,i387,i387,i387")
4569 (set_attr "mode" "SF")])
4571 (define_insn "*truncxfdf2_mixed"
4572 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4574 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4575 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4578 gcc_assert (!which_alternative);
4579 return output_387_reg_move (insn, operands);
4581 [(set_attr "type" "fmov,multi,multi,multi")
4582 (set_attr "unit" "*,i387,i387,i387")
4583 (set_attr "mode" "DF")])
4585 (define_insn "truncxf<mode>2_i387_noop"
4586 [(set (match_operand:MODEF 0 "register_operand" "=f")
4587 (float_truncate:MODEF
4588 (match_operand:XF 1 "register_operand" "f")))]
4589 "TARGET_80387 && flag_unsafe_math_optimizations"
4590 "* return output_387_reg_move (insn, operands);"
4591 [(set_attr "type" "fmov")
4592 (set_attr "mode" "<MODE>")])
4594 (define_insn "*truncxf<mode>2_i387"
4595 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4596 (float_truncate:MODEF
4597 (match_operand:XF 1 "register_operand" "f")))]
4599 "* return output_387_reg_move (insn, operands);"
4600 [(set_attr "type" "fmov")
4601 (set_attr "mode" "<MODE>")])
4604 [(set (match_operand:MODEF 0 "register_operand" "")
4605 (float_truncate:MODEF
4606 (match_operand:XF 1 "register_operand" "")))
4607 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4608 "TARGET_80387 && reload_completed"
4609 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4610 (set (match_dup 0) (match_dup 2))]
4614 [(set (match_operand:MODEF 0 "memory_operand" "")
4615 (float_truncate:MODEF
4616 (match_operand:XF 1 "register_operand" "")))
4617 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4619 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4622 ;; Signed conversion to DImode.
4624 (define_expand "fix_truncxfdi2"
4625 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4626 (fix:DI (match_operand:XF 1 "register_operand" "")))
4627 (clobber (reg:CC FLAGS_REG))])]
4632 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4637 (define_expand "fix_trunc<mode>di2"
4638 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4639 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4640 (clobber (reg:CC FLAGS_REG))])]
4641 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4644 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4646 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4649 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4651 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4652 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4653 if (out != operands[0])
4654 emit_move_insn (operands[0], out);
4659 ;; Signed conversion to SImode.
4661 (define_expand "fix_truncxfsi2"
4662 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4663 (fix:SI (match_operand:XF 1 "register_operand" "")))
4664 (clobber (reg:CC FLAGS_REG))])]
4669 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4674 (define_expand "fix_trunc<mode>si2"
4675 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4676 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4677 (clobber (reg:CC FLAGS_REG))])]
4678 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4681 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4683 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4686 if (SSE_FLOAT_MODE_P (<MODE>mode))
4688 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4689 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4690 if (out != operands[0])
4691 emit_move_insn (operands[0], out);
4696 ;; Signed conversion to HImode.
4698 (define_expand "fix_trunc<mode>hi2"
4699 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4700 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4701 (clobber (reg:CC FLAGS_REG))])]
4703 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4707 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4712 ;; Unsigned conversion to SImode.
4714 (define_expand "fixuns_trunc<mode>si2"
4716 [(set (match_operand:SI 0 "register_operand" "")
4718 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4720 (clobber (match_scratch:<ssevecmode> 3 ""))
4721 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4722 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4724 enum machine_mode mode = <MODE>mode;
4725 enum machine_mode vecmode = <ssevecmode>mode;
4726 REAL_VALUE_TYPE TWO31r;
4729 if (optimize_insn_for_size_p ())
4732 real_ldexp (&TWO31r, &dconst1, 31);
4733 two31 = const_double_from_real_value (TWO31r, mode);
4734 two31 = ix86_build_const_vector (mode, true, two31);
4735 operands[2] = force_reg (vecmode, two31);
4738 (define_insn_and_split "*fixuns_trunc<mode>_1"
4739 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4741 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4742 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4743 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4744 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4745 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4746 && optimize_function_for_speed_p (cfun)"
4748 "&& reload_completed"
4751 ix86_split_convert_uns_si_sse (operands);
4755 ;; Unsigned conversion to HImode.
4756 ;; Without these patterns, we'll try the unsigned SI conversion which
4757 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4759 (define_expand "fixuns_trunc<mode>hi2"
4761 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4762 (set (match_operand:HI 0 "nonimmediate_operand" "")
4763 (subreg:HI (match_dup 2) 0))]
4764 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4765 "operands[2] = gen_reg_rtx (SImode);")
4767 ;; When SSE is available, it is always faster to use it!
4768 (define_insn "fix_trunc<mode>di_sse"
4769 [(set (match_operand:DI 0 "register_operand" "=r,r")
4770 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4771 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4772 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4773 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4774 [(set_attr "type" "sseicvt")
4775 (set_attr "prefix" "maybe_vex")
4776 (set_attr "mode" "<MODE>")
4777 (set_attr "athlon_decode" "double,vector")
4778 (set_attr "amdfam10_decode" "double,double")])
4780 (define_insn "fix_trunc<mode>si_sse"
4781 [(set (match_operand:SI 0 "register_operand" "=r,r")
4782 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4783 "SSE_FLOAT_MODE_P (<MODE>mode)
4784 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4785 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4786 [(set_attr "type" "sseicvt")
4787 (set_attr "prefix" "maybe_vex")
4788 (set_attr "mode" "<MODE>")
4789 (set_attr "athlon_decode" "double,vector")
4790 (set_attr "amdfam10_decode" "double,double")])
4792 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4794 [(set (match_operand:MODEF 0 "register_operand" "")
4795 (match_operand:MODEF 1 "memory_operand" ""))
4796 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4797 (fix:SSEMODEI24 (match_dup 0)))]
4798 "TARGET_SHORTEN_X87_SSE
4799 && peep2_reg_dead_p (2, operands[0])"
4800 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4803 ;; Avoid vector decoded forms of the instruction.
4805 [(match_scratch:DF 2 "Y2")
4806 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4807 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4808 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4809 [(set (match_dup 2) (match_dup 1))
4810 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4814 [(match_scratch:SF 2 "x")
4815 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4816 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4817 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4818 [(set (match_dup 2) (match_dup 1))
4819 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4822 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4823 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4824 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4825 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4827 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4828 && (TARGET_64BIT || <MODE>mode != DImode))
4830 && !(reload_completed || reload_in_progress)"
4835 if (memory_operand (operands[0], VOIDmode))
4836 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4839 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4840 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4846 [(set_attr "type" "fisttp")
4847 (set_attr "mode" "<MODE>")])
4849 (define_insn "fix_trunc<mode>_i387_fisttp"
4850 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4851 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4852 (clobber (match_scratch:XF 2 "=&1f"))]
4853 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4855 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4856 && (TARGET_64BIT || <MODE>mode != DImode))
4857 && TARGET_SSE_MATH)"
4858 "* return output_fix_trunc (insn, operands, 1);"
4859 [(set_attr "type" "fisttp")
4860 (set_attr "mode" "<MODE>")])
4862 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4863 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4864 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4865 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4866 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4867 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4869 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4870 && (TARGET_64BIT || <MODE>mode != DImode))
4871 && TARGET_SSE_MATH)"
4873 [(set_attr "type" "fisttp")
4874 (set_attr "mode" "<MODE>")])
4877 [(set (match_operand:X87MODEI 0 "register_operand" "")
4878 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4879 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4880 (clobber (match_scratch 3 ""))]
4882 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4883 (clobber (match_dup 3))])
4884 (set (match_dup 0) (match_dup 2))]
4888 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4889 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4890 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4891 (clobber (match_scratch 3 ""))]
4893 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4894 (clobber (match_dup 3))])]
4897 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4898 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4899 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4900 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4901 ;; function in i386.c.
4902 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4903 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4904 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4905 (clobber (reg:CC FLAGS_REG))]
4906 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4908 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4909 && (TARGET_64BIT || <MODE>mode != DImode))
4910 && !(reload_completed || reload_in_progress)"
4915 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4917 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4918 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4919 if (memory_operand (operands[0], VOIDmode))
4920 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4921 operands[2], operands[3]));
4924 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4925 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4926 operands[2], operands[3],
4931 [(set_attr "type" "fistp")
4932 (set_attr "i387_cw" "trunc")
4933 (set_attr "mode" "<MODE>")])
4935 (define_insn "fix_truncdi_i387"
4936 [(set (match_operand:DI 0 "memory_operand" "=m")
4937 (fix:DI (match_operand 1 "register_operand" "f")))
4938 (use (match_operand:HI 2 "memory_operand" "m"))
4939 (use (match_operand:HI 3 "memory_operand" "m"))
4940 (clobber (match_scratch:XF 4 "=&1f"))]
4941 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4943 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4944 "* return output_fix_trunc (insn, operands, 0);"
4945 [(set_attr "type" "fistp")
4946 (set_attr "i387_cw" "trunc")
4947 (set_attr "mode" "DI")])
4949 (define_insn "fix_truncdi_i387_with_temp"
4950 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4951 (fix:DI (match_operand 1 "register_operand" "f,f")))
4952 (use (match_operand:HI 2 "memory_operand" "m,m"))
4953 (use (match_operand:HI 3 "memory_operand" "m,m"))
4954 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4955 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4956 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4958 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4960 [(set_attr "type" "fistp")
4961 (set_attr "i387_cw" "trunc")
4962 (set_attr "mode" "DI")])
4965 [(set (match_operand:DI 0 "register_operand" "")
4966 (fix:DI (match_operand 1 "register_operand" "")))
4967 (use (match_operand:HI 2 "memory_operand" ""))
4968 (use (match_operand:HI 3 "memory_operand" ""))
4969 (clobber (match_operand:DI 4 "memory_operand" ""))
4970 (clobber (match_scratch 5 ""))]
4972 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4975 (clobber (match_dup 5))])
4976 (set (match_dup 0) (match_dup 4))]
4980 [(set (match_operand:DI 0 "memory_operand" "")
4981 (fix:DI (match_operand 1 "register_operand" "")))
4982 (use (match_operand:HI 2 "memory_operand" ""))
4983 (use (match_operand:HI 3 "memory_operand" ""))
4984 (clobber (match_operand:DI 4 "memory_operand" ""))
4985 (clobber (match_scratch 5 ""))]
4987 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4990 (clobber (match_dup 5))])]
4993 (define_insn "fix_trunc<mode>_i387"
4994 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4995 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4996 (use (match_operand:HI 2 "memory_operand" "m"))
4997 (use (match_operand:HI 3 "memory_operand" "m"))]
4998 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5000 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5001 "* return output_fix_trunc (insn, operands, 0);"
5002 [(set_attr "type" "fistp")
5003 (set_attr "i387_cw" "trunc")
5004 (set_attr "mode" "<MODE>")])
5006 (define_insn "fix_trunc<mode>_i387_with_temp"
5007 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5008 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5009 (use (match_operand:HI 2 "memory_operand" "m,m"))
5010 (use (match_operand:HI 3 "memory_operand" "m,m"))
5011 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5012 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5014 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5016 [(set_attr "type" "fistp")
5017 (set_attr "i387_cw" "trunc")
5018 (set_attr "mode" "<MODE>")])
5021 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5022 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5023 (use (match_operand:HI 2 "memory_operand" ""))
5024 (use (match_operand:HI 3 "memory_operand" ""))
5025 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5027 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5029 (use (match_dup 3))])
5030 (set (match_dup 0) (match_dup 4))]
5034 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5035 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5036 (use (match_operand:HI 2 "memory_operand" ""))
5037 (use (match_operand:HI 3 "memory_operand" ""))
5038 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5040 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5042 (use (match_dup 3))])]
5045 (define_insn "x86_fnstcw_1"
5046 [(set (match_operand:HI 0 "memory_operand" "=m")
5047 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5050 [(set_attr "length" "2")
5051 (set_attr "mode" "HI")
5052 (set_attr "unit" "i387")])
5054 (define_insn "x86_fldcw_1"
5055 [(set (reg:HI FPCR_REG)
5056 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5059 [(set_attr "length" "2")
5060 (set_attr "mode" "HI")
5061 (set_attr "unit" "i387")
5062 (set_attr "athlon_decode" "vector")
5063 (set_attr "amdfam10_decode" "vector")])
5065 ;; Conversion between fixed point and floating point.
5067 ;; Even though we only accept memory inputs, the backend _really_
5068 ;; wants to be able to do this between registers.
5070 (define_expand "floathi<mode>2"
5071 [(set (match_operand:X87MODEF 0 "register_operand" "")
5072 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5074 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5075 || TARGET_MIX_SSE_I387)"
5078 ;; Pre-reload splitter to add memory clobber to the pattern.
5079 (define_insn_and_split "*floathi<mode>2_1"
5080 [(set (match_operand:X87MODEF 0 "register_operand" "")
5081 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5083 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5084 || TARGET_MIX_SSE_I387)
5085 && !(reload_completed || reload_in_progress)"
5088 [(parallel [(set (match_dup 0)
5089 (float:X87MODEF (match_dup 1)))
5090 (clobber (match_dup 2))])]
5091 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5093 (define_insn "*floathi<mode>2_i387_with_temp"
5094 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5095 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5096 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5099 || TARGET_MIX_SSE_I387)"
5101 [(set_attr "type" "fmov,multi")
5102 (set_attr "mode" "<MODE>")
5103 (set_attr "unit" "*,i387")
5104 (set_attr "fp_int_src" "true")])
5106 (define_insn "*floathi<mode>2_i387"
5107 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5108 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5111 || TARGET_MIX_SSE_I387)"
5113 [(set_attr "type" "fmov")
5114 (set_attr "mode" "<MODE>")
5115 (set_attr "fp_int_src" "true")])
5118 [(set (match_operand:X87MODEF 0 "register_operand" "")
5119 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5120 (clobber (match_operand:HI 2 "memory_operand" ""))]
5122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5123 || TARGET_MIX_SSE_I387)
5124 && reload_completed"
5125 [(set (match_dup 2) (match_dup 1))
5126 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5130 [(set (match_operand:X87MODEF 0 "register_operand" "")
5131 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5132 (clobber (match_operand:HI 2 "memory_operand" ""))]
5134 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5135 || TARGET_MIX_SSE_I387)
5136 && reload_completed"
5137 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5140 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5141 [(set (match_operand:X87MODEF 0 "register_operand" "")
5143 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5145 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5146 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5149 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5151 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5153 rtx reg = gen_reg_rtx (XFmode);
5154 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5155 /* Avoid references to nonexistent function in dead code in XFmode case. */
5156 #define gen_truncxfxf2 gen_truncxfdf2
5157 emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5158 #undef gen_truncxfxf2
5163 ;; Pre-reload splitter to add memory clobber to the pattern.
5164 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5165 [(set (match_operand:X87MODEF 0 "register_operand" "")
5166 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5168 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5169 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5170 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5171 || TARGET_MIX_SSE_I387))
5172 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5173 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5174 && ((<SSEMODEI24:MODE>mode == SImode
5175 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5176 && optimize_function_for_speed_p (cfun)
5177 && flag_trapping_math)
5178 || !(TARGET_INTER_UNIT_CONVERSIONS
5179 || optimize_function_for_size_p (cfun)))))
5180 && !(reload_completed || reload_in_progress)"
5183 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5184 (clobber (match_dup 2))])]
5186 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5188 /* Avoid store forwarding (partial memory) stall penalty
5189 by passing DImode value through XMM registers. */
5190 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5191 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5192 && optimize_function_for_speed_p (cfun))
5194 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5201 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5202 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5204 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5205 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5206 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5207 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5209 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5210 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5211 (set_attr "unit" "*,i387,*,*,*")
5212 (set_attr "athlon_decode" "*,*,double,direct,double")
5213 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5214 (set_attr "fp_int_src" "true")])
5216 (define_insn "*floatsi<mode>2_vector_mixed"
5217 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5218 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5219 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5220 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5224 [(set_attr "type" "fmov,sseicvt")
5225 (set_attr "mode" "<MODE>,<ssevecmode>")
5226 (set_attr "unit" "i387,*")
5227 (set_attr "athlon_decode" "*,direct")
5228 (set_attr "amdfam10_decode" "*,double")
5229 (set_attr "fp_int_src" "true")])
5231 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5232 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5234 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5235 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5236 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5237 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5239 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5240 (set_attr "mode" "<MODEF:MODE>")
5241 (set_attr "unit" "*,i387,*,*")
5242 (set_attr "athlon_decode" "*,*,double,direct")
5243 (set_attr "amdfam10_decode" "*,*,vector,double")
5244 (set_attr "fp_int_src" "true")])
5247 [(set (match_operand:MODEF 0 "register_operand" "")
5248 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5249 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5250 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5251 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5252 && TARGET_INTER_UNIT_CONVERSIONS
5254 && (SSE_REG_P (operands[0])
5255 || (GET_CODE (operands[0]) == SUBREG
5256 && SSE_REG_P (operands[0])))"
5257 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5261 [(set (match_operand:MODEF 0 "register_operand" "")
5262 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5263 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5264 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5265 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5266 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5268 && (SSE_REG_P (operands[0])
5269 || (GET_CODE (operands[0]) == SUBREG
5270 && SSE_REG_P (operands[0])))"
5271 [(set (match_dup 2) (match_dup 1))
5272 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5275 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5276 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5278 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5279 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5280 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5281 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5284 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5285 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5286 [(set_attr "type" "fmov,sseicvt,sseicvt")
5287 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5288 (set_attr "mode" "<MODEF:MODE>")
5289 (set_attr "unit" "i387,*,*")
5290 (set_attr "athlon_decode" "*,double,direct")
5291 (set_attr "amdfam10_decode" "*,vector,double")
5292 (set_attr "fp_int_src" "true")])
5294 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5295 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5297 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5298 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5299 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5300 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5303 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5304 [(set_attr "type" "fmov,sseicvt")
5305 (set_attr "prefix" "orig,maybe_vex")
5306 (set_attr "mode" "<MODEF:MODE>")
5307 (set_attr "athlon_decode" "*,direct")
5308 (set_attr "amdfam10_decode" "*,double")
5309 (set_attr "fp_int_src" "true")])
5311 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5312 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5314 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5315 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5316 "TARGET_SSE2 && TARGET_SSE_MATH
5317 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5319 [(set_attr "type" "sseicvt")
5320 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5321 (set_attr "athlon_decode" "double,direct,double")
5322 (set_attr "amdfam10_decode" "vector,double,double")
5323 (set_attr "fp_int_src" "true")])
5325 (define_insn "*floatsi<mode>2_vector_sse"
5326 [(set (match_operand:MODEF 0 "register_operand" "=x")
5327 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5328 "TARGET_SSE2 && TARGET_SSE_MATH
5329 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5331 [(set_attr "type" "sseicvt")
5332 (set_attr "mode" "<MODE>")
5333 (set_attr "athlon_decode" "direct")
5334 (set_attr "amdfam10_decode" "double")
5335 (set_attr "fp_int_src" "true")])
5338 [(set (match_operand:MODEF 0 "register_operand" "")
5339 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5340 (clobber (match_operand:SI 2 "memory_operand" ""))]
5341 "TARGET_SSE2 && TARGET_SSE_MATH
5342 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5344 && (SSE_REG_P (operands[0])
5345 || (GET_CODE (operands[0]) == SUBREG
5346 && SSE_REG_P (operands[0])))"
5349 rtx op1 = operands[1];
5351 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5353 if (GET_CODE (op1) == SUBREG)
5354 op1 = SUBREG_REG (op1);
5356 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5358 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5359 emit_insn (gen_sse2_loadld (operands[4],
5360 CONST0_RTX (V4SImode), operands[1]));
5362 /* We can ignore possible trapping value in the
5363 high part of SSE register for non-trapping math. */
5364 else if (SSE_REG_P (op1) && !flag_trapping_math)
5365 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5368 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5369 emit_move_insn (operands[2], operands[1]);
5370 emit_insn (gen_sse2_loadld (operands[4],
5371 CONST0_RTX (V4SImode), operands[2]));
5374 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5379 [(set (match_operand:MODEF 0 "register_operand" "")
5380 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5381 (clobber (match_operand:SI 2 "memory_operand" ""))]
5382 "TARGET_SSE2 && TARGET_SSE_MATH
5383 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5385 && (SSE_REG_P (operands[0])
5386 || (GET_CODE (operands[0]) == SUBREG
5387 && SSE_REG_P (operands[0])))"
5390 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5392 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5394 emit_insn (gen_sse2_loadld (operands[4],
5395 CONST0_RTX (V4SImode), operands[1]));
5397 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5402 [(set (match_operand:MODEF 0 "register_operand" "")
5403 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5404 "TARGET_SSE2 && TARGET_SSE_MATH
5405 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5407 && (SSE_REG_P (operands[0])
5408 || (GET_CODE (operands[0]) == SUBREG
5409 && SSE_REG_P (operands[0])))"
5412 rtx op1 = operands[1];
5414 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5416 if (GET_CODE (op1) == SUBREG)
5417 op1 = SUBREG_REG (op1);
5419 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5421 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5422 emit_insn (gen_sse2_loadld (operands[4],
5423 CONST0_RTX (V4SImode), operands[1]));
5425 /* We can ignore possible trapping value in the
5426 high part of SSE register for non-trapping math. */
5427 else if (SSE_REG_P (op1) && !flag_trapping_math)
5428 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5432 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5437 [(set (match_operand:MODEF 0 "register_operand" "")
5438 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5439 "TARGET_SSE2 && TARGET_SSE_MATH
5440 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5442 && (SSE_REG_P (operands[0])
5443 || (GET_CODE (operands[0]) == SUBREG
5444 && SSE_REG_P (operands[0])))"
5447 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5449 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5451 emit_insn (gen_sse2_loadld (operands[4],
5452 CONST0_RTX (V4SImode), operands[1]));
5454 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5458 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5459 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5461 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5462 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5463 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5464 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5466 [(set_attr "type" "sseicvt")
5467 (set_attr "mode" "<MODEF:MODE>")
5468 (set_attr "athlon_decode" "double,direct")
5469 (set_attr "amdfam10_decode" "vector,double")
5470 (set_attr "fp_int_src" "true")])
5472 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5473 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5475 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5476 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5477 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5478 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5479 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5480 [(set_attr "type" "sseicvt")
5481 (set_attr "prefix" "maybe_vex")
5482 (set_attr "mode" "<MODEF:MODE>")
5483 (set_attr "athlon_decode" "double,direct")
5484 (set_attr "amdfam10_decode" "vector,double")
5485 (set_attr "fp_int_src" "true")])
5488 [(set (match_operand:MODEF 0 "register_operand" "")
5489 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5490 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5491 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5492 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5493 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5495 && (SSE_REG_P (operands[0])
5496 || (GET_CODE (operands[0]) == SUBREG
5497 && SSE_REG_P (operands[0])))"
5498 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5501 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5502 [(set (match_operand:MODEF 0 "register_operand" "=x")
5504 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5505 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5506 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5507 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5508 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5509 [(set_attr "type" "sseicvt")
5510 (set_attr "prefix" "maybe_vex")
5511 (set_attr "mode" "<MODEF:MODE>")
5512 (set_attr "athlon_decode" "direct")
5513 (set_attr "amdfam10_decode" "double")
5514 (set_attr "fp_int_src" "true")])
5517 [(set (match_operand:MODEF 0 "register_operand" "")
5518 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5519 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5520 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5521 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5522 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5524 && (SSE_REG_P (operands[0])
5525 || (GET_CODE (operands[0]) == SUBREG
5526 && SSE_REG_P (operands[0])))"
5527 [(set (match_dup 2) (match_dup 1))
5528 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5532 [(set (match_operand:MODEF 0 "register_operand" "")
5533 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5534 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5535 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5536 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5538 && (SSE_REG_P (operands[0])
5539 || (GET_CODE (operands[0]) == SUBREG
5540 && SSE_REG_P (operands[0])))"
5541 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5544 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5545 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5547 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5548 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5550 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5554 [(set_attr "type" "fmov,multi")
5555 (set_attr "mode" "<X87MODEF:MODE>")
5556 (set_attr "unit" "*,i387")
5557 (set_attr "fp_int_src" "true")])
5559 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5560 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5562 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5564 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5566 [(set_attr "type" "fmov")
5567 (set_attr "mode" "<X87MODEF:MODE>")
5568 (set_attr "fp_int_src" "true")])
5571 [(set (match_operand:X87MODEF 0 "register_operand" "")
5572 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5573 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5575 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5577 && FP_REG_P (operands[0])"
5578 [(set (match_dup 2) (match_dup 1))
5579 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5583 [(set (match_operand:X87MODEF 0 "register_operand" "")
5584 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5585 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5587 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5589 && FP_REG_P (operands[0])"
5590 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5593 ;; Avoid store forwarding (partial memory) stall penalty
5594 ;; by passing DImode value through XMM registers. */
5596 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5597 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5599 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5600 (clobber (match_scratch:V4SI 3 "=X,x"))
5601 (clobber (match_scratch:V4SI 4 "=X,x"))
5602 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5603 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5604 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5605 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5607 [(set_attr "type" "multi")
5608 (set_attr "mode" "<X87MODEF:MODE>")
5609 (set_attr "unit" "i387")
5610 (set_attr "fp_int_src" "true")])
5613 [(set (match_operand:X87MODEF 0 "register_operand" "")
5614 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5615 (clobber (match_scratch:V4SI 3 ""))
5616 (clobber (match_scratch:V4SI 4 ""))
5617 (clobber (match_operand:DI 2 "memory_operand" ""))]
5618 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5619 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5620 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5622 && FP_REG_P (operands[0])"
5623 [(set (match_dup 2) (match_dup 3))
5624 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5626 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5627 Assemble the 64-bit DImode value in an xmm register. */
5628 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5629 gen_rtx_SUBREG (SImode, operands[1], 0)));
5630 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5631 gen_rtx_SUBREG (SImode, operands[1], 4)));
5632 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5634 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5638 [(set (match_operand:X87MODEF 0 "register_operand" "")
5639 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5640 (clobber (match_scratch:V4SI 3 ""))
5641 (clobber (match_scratch:V4SI 4 ""))
5642 (clobber (match_operand:DI 2 "memory_operand" ""))]
5643 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5644 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5645 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5647 && FP_REG_P (operands[0])"
5648 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5651 ;; Avoid store forwarding (partial memory) stall penalty by extending
5652 ;; SImode value to DImode through XMM register instead of pushing two
5653 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5654 ;; targets benefit from this optimization. Also note that fild
5655 ;; loads from memory only.
5657 (define_insn "*floatunssi<mode>2_1"
5658 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5659 (unsigned_float:X87MODEF
5660 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5661 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5662 (clobber (match_scratch:SI 3 "=X,x"))]
5664 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5667 [(set_attr "type" "multi")
5668 (set_attr "mode" "<MODE>")])
5671 [(set (match_operand:X87MODEF 0 "register_operand" "")
5672 (unsigned_float:X87MODEF
5673 (match_operand:SI 1 "register_operand" "")))
5674 (clobber (match_operand:DI 2 "memory_operand" ""))
5675 (clobber (match_scratch:SI 3 ""))]
5677 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5679 && reload_completed"
5680 [(set (match_dup 2) (match_dup 1))
5682 (float:X87MODEF (match_dup 2)))]
5683 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5686 [(set (match_operand:X87MODEF 0 "register_operand" "")
5687 (unsigned_float:X87MODEF
5688 (match_operand:SI 1 "memory_operand" "")))
5689 (clobber (match_operand:DI 2 "memory_operand" ""))
5690 (clobber (match_scratch:SI 3 ""))]
5692 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5694 && reload_completed"
5695 [(set (match_dup 2) (match_dup 3))
5697 (float:X87MODEF (match_dup 2)))]
5699 emit_move_insn (operands[3], operands[1]);
5700 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5703 (define_expand "floatunssi<mode>2"
5705 [(set (match_operand:X87MODEF 0 "register_operand" "")
5706 (unsigned_float:X87MODEF
5707 (match_operand:SI 1 "nonimmediate_operand" "")))
5708 (clobber (match_dup 2))
5709 (clobber (match_scratch:SI 3 ""))])]
5711 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5713 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5715 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5717 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5722 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5723 operands[2] = assign_386_stack_local (DImode, slot);
5727 (define_expand "floatunsdisf2"
5728 [(use (match_operand:SF 0 "register_operand" ""))
5729 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5730 "TARGET_64BIT && TARGET_SSE_MATH"
5731 "x86_emit_floatuns (operands); DONE;")
5733 (define_expand "floatunsdidf2"
5734 [(use (match_operand:DF 0 "register_operand" ""))
5735 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5736 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5737 && TARGET_SSE2 && TARGET_SSE_MATH"
5740 x86_emit_floatuns (operands);
5742 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5748 ;; %%% splits for addditi3
5750 (define_expand "addti3"
5751 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5752 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5753 (match_operand:TI 2 "x86_64_general_operand" "")))]
5755 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5757 (define_insn "*addti3_1"
5758 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5759 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5760 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5761 (clobber (reg:CC FLAGS_REG))]
5762 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5766 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5767 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5768 (match_operand:TI 2 "x86_64_general_operand" "")))
5769 (clobber (reg:CC FLAGS_REG))]
5770 "TARGET_64BIT && reload_completed"
5771 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5773 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5774 (parallel [(set (match_dup 3)
5775 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5778 (clobber (reg:CC FLAGS_REG))])]
5779 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5781 ;; %%% splits for addsidi3
5782 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5783 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5784 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5786 (define_expand "adddi3"
5787 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5788 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5789 (match_operand:DI 2 "x86_64_general_operand" "")))]
5791 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5793 (define_insn "*adddi3_1"
5794 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5795 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5796 (match_operand:DI 2 "general_operand" "roiF,riF")))
5797 (clobber (reg:CC FLAGS_REG))]
5798 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5802 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5803 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5804 (match_operand:DI 2 "general_operand" "")))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "!TARGET_64BIT && reload_completed"
5807 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5809 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5810 (parallel [(set (match_dup 3)
5811 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5814 (clobber (reg:CC FLAGS_REG))])]
5815 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5817 (define_insn "adddi3_carry_rex64"
5818 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5819 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5820 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5821 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5822 (clobber (reg:CC FLAGS_REG))]
5823 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5824 "adc{q}\t{%2, %0|%0, %2}"
5825 [(set_attr "type" "alu")
5826 (set_attr "use_carry" "1")
5827 (set_attr "pent_pair" "pu")
5828 (set_attr "mode" "DI")])
5830 (define_insn "*adddi3_cc_rex64"
5831 [(set (reg:CC FLAGS_REG)
5832 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5833 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5835 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5836 (plus:DI (match_dup 1) (match_dup 2)))]
5837 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5838 "add{q}\t{%2, %0|%0, %2}"
5839 [(set_attr "type" "alu")
5840 (set_attr "mode" "DI")])
5842 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5843 [(set (reg:CCC FLAGS_REG)
5846 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5847 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5849 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5850 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5851 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5852 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5853 [(set_attr "type" "alu")
5854 (set_attr "mode" "<MODE>")])
5856 (define_insn "*add<mode>3_cconly_overflow"
5857 [(set (reg:CCC FLAGS_REG)
5859 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5860 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5862 (clobber (match_scratch:SWI 0 "=<r>"))]
5863 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5864 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5865 [(set_attr "type" "alu")
5866 (set_attr "mode" "<MODE>")])
5868 (define_insn "*sub<mode>3_cconly_overflow"
5869 [(set (reg:CCC FLAGS_REG)
5871 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5872 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5875 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5876 [(set_attr "type" "icmp")
5877 (set_attr "mode" "<MODE>")])
5879 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5880 [(set (reg:CCC FLAGS_REG)
5882 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5883 (match_operand:SI 2 "general_operand" "g"))
5885 (set (match_operand:DI 0 "register_operand" "=r")
5886 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5887 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5888 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5889 [(set_attr "type" "alu")
5890 (set_attr "mode" "SI")])
5892 (define_insn "addqi3_carry"
5893 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5894 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5895 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5896 (match_operand:QI 2 "general_operand" "qn,qm")))
5897 (clobber (reg:CC FLAGS_REG))]
5898 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5899 "adc{b}\t{%2, %0|%0, %2}"
5900 [(set_attr "type" "alu")
5901 (set_attr "use_carry" "1")
5902 (set_attr "pent_pair" "pu")
5903 (set_attr "mode" "QI")])
5905 (define_insn "addhi3_carry"
5906 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5907 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5908 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5909 (match_operand:HI 2 "general_operand" "rn,rm")))
5910 (clobber (reg:CC FLAGS_REG))]
5911 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5912 "adc{w}\t{%2, %0|%0, %2}"
5913 [(set_attr "type" "alu")
5914 (set_attr "use_carry" "1")
5915 (set_attr "pent_pair" "pu")
5916 (set_attr "mode" "HI")])
5918 (define_insn "addsi3_carry"
5919 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5920 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5921 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5922 (match_operand:SI 2 "general_operand" "ri,rm")))
5923 (clobber (reg:CC FLAGS_REG))]
5924 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5925 "adc{l}\t{%2, %0|%0, %2}"
5926 [(set_attr "type" "alu")
5927 (set_attr "use_carry" "1")
5928 (set_attr "pent_pair" "pu")
5929 (set_attr "mode" "SI")])
5931 (define_insn "*addsi3_carry_zext"
5932 [(set (match_operand:DI 0 "register_operand" "=r")
5934 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5935 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5936 (match_operand:SI 2 "general_operand" "g"))))
5937 (clobber (reg:CC FLAGS_REG))]
5938 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5939 "adc{l}\t{%2, %k0|%k0, %2}"
5940 [(set_attr "type" "alu")
5941 (set_attr "use_carry" "1")
5942 (set_attr "pent_pair" "pu")
5943 (set_attr "mode" "SI")])
5945 (define_insn "*addsi3_cc"
5946 [(set (reg:CC FLAGS_REG)
5947 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5948 (match_operand:SI 2 "general_operand" "ri,rm")]
5950 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5951 (plus:SI (match_dup 1) (match_dup 2)))]
5952 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5953 "add{l}\t{%2, %0|%0, %2}"
5954 [(set_attr "type" "alu")
5955 (set_attr "mode" "SI")])
5957 (define_insn "addqi3_cc"
5958 [(set (reg:CC FLAGS_REG)
5959 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5960 (match_operand:QI 2 "general_operand" "qn,qm")]
5962 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5963 (plus:QI (match_dup 1) (match_dup 2)))]
5964 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5965 "add{b}\t{%2, %0|%0, %2}"
5966 [(set_attr "type" "alu")
5967 (set_attr "mode" "QI")])
5969 (define_expand "addsi3"
5970 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5971 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5972 (match_operand:SI 2 "general_operand" "")))]
5974 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5976 (define_insn "*lea_1"
5977 [(set (match_operand:SI 0 "register_operand" "=r")
5978 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5980 "lea{l}\t{%a1, %0|%0, %a1}"
5981 [(set_attr "type" "lea")
5982 (set_attr "mode" "SI")])
5984 (define_insn "*lea_1_rex64"
5985 [(set (match_operand:SI 0 "register_operand" "=r")
5986 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5988 "lea{l}\t{%a1, %0|%0, %a1}"
5989 [(set_attr "type" "lea")
5990 (set_attr "mode" "SI")])
5992 (define_insn "*lea_1_zext"
5993 [(set (match_operand:DI 0 "register_operand" "=r")
5995 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5997 "lea{l}\t{%a1, %k0|%k0, %a1}"
5998 [(set_attr "type" "lea")
5999 (set_attr "mode" "SI")])
6001 (define_insn "*lea_2_rex64"
6002 [(set (match_operand:DI 0 "register_operand" "=r")
6003 (match_operand:DI 1 "no_seg_address_operand" "p"))]
6005 "lea{q}\t{%a1, %0|%0, %a1}"
6006 [(set_attr "type" "lea")
6007 (set_attr "mode" "DI")])
6009 ;; The lea patterns for non-Pmodes needs to be matched by several
6010 ;; insns converted to real lea by splitters.
6012 (define_insn_and_split "*lea_general_1"
6013 [(set (match_operand 0 "register_operand" "=r")
6014 (plus (plus (match_operand 1 "index_register_operand" "l")
6015 (match_operand 2 "register_operand" "r"))
6016 (match_operand 3 "immediate_operand" "i")))]
6017 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6018 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6019 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6020 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6021 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6022 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6023 || GET_MODE (operands[3]) == VOIDmode)"
6025 "&& reload_completed"
6029 operands[0] = gen_lowpart (SImode, operands[0]);
6030 operands[1] = gen_lowpart (Pmode, operands[1]);
6031 operands[2] = gen_lowpart (Pmode, operands[2]);
6032 operands[3] = gen_lowpart (Pmode, operands[3]);
6033 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6035 if (Pmode != SImode)
6036 pat = gen_rtx_SUBREG (SImode, pat, 0);
6037 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6040 [(set_attr "type" "lea")
6041 (set_attr "mode" "SI")])
6043 (define_insn_and_split "*lea_general_1_zext"
6044 [(set (match_operand:DI 0 "register_operand" "=r")
6046 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6047 (match_operand:SI 2 "register_operand" "r"))
6048 (match_operand:SI 3 "immediate_operand" "i"))))]
6051 "&& reload_completed"
6053 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6055 (match_dup 3)) 0)))]
6057 operands[1] = gen_lowpart (Pmode, operands[1]);
6058 operands[2] = gen_lowpart (Pmode, operands[2]);
6059 operands[3] = gen_lowpart (Pmode, operands[3]);
6061 [(set_attr "type" "lea")
6062 (set_attr "mode" "SI")])
6064 (define_insn_and_split "*lea_general_2"
6065 [(set (match_operand 0 "register_operand" "=r")
6066 (plus (mult (match_operand 1 "index_register_operand" "l")
6067 (match_operand 2 "const248_operand" "i"))
6068 (match_operand 3 "nonmemory_operand" "ri")))]
6069 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6070 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6071 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6072 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6073 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6074 || GET_MODE (operands[3]) == VOIDmode)"
6076 "&& reload_completed"
6080 operands[0] = gen_lowpart (SImode, operands[0]);
6081 operands[1] = gen_lowpart (Pmode, operands[1]);
6082 operands[3] = gen_lowpart (Pmode, operands[3]);
6083 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6085 if (Pmode != SImode)
6086 pat = gen_rtx_SUBREG (SImode, pat, 0);
6087 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6090 [(set_attr "type" "lea")
6091 (set_attr "mode" "SI")])
6093 (define_insn_and_split "*lea_general_2_zext"
6094 [(set (match_operand:DI 0 "register_operand" "=r")
6096 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6097 (match_operand:SI 2 "const248_operand" "n"))
6098 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6101 "&& reload_completed"
6103 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6105 (match_dup 3)) 0)))]
6107 operands[1] = gen_lowpart (Pmode, operands[1]);
6108 operands[3] = gen_lowpart (Pmode, operands[3]);
6110 [(set_attr "type" "lea")
6111 (set_attr "mode" "SI")])
6113 (define_insn_and_split "*lea_general_3"
6114 [(set (match_operand 0 "register_operand" "=r")
6115 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6116 (match_operand 2 "const248_operand" "i"))
6117 (match_operand 3 "register_operand" "r"))
6118 (match_operand 4 "immediate_operand" "i")))]
6119 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6120 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6121 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6122 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6123 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6125 "&& reload_completed"
6129 operands[0] = gen_lowpart (SImode, operands[0]);
6130 operands[1] = gen_lowpart (Pmode, operands[1]);
6131 operands[3] = gen_lowpart (Pmode, operands[3]);
6132 operands[4] = gen_lowpart (Pmode, operands[4]);
6133 pat = gen_rtx_PLUS (Pmode,
6134 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6138 if (Pmode != SImode)
6139 pat = gen_rtx_SUBREG (SImode, pat, 0);
6140 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6143 [(set_attr "type" "lea")
6144 (set_attr "mode" "SI")])
6146 (define_insn_and_split "*lea_general_3_zext"
6147 [(set (match_operand:DI 0 "register_operand" "=r")
6149 (plus:SI (plus:SI (mult:SI
6150 (match_operand:SI 1 "index_register_operand" "l")
6151 (match_operand:SI 2 "const248_operand" "n"))
6152 (match_operand:SI 3 "register_operand" "r"))
6153 (match_operand:SI 4 "immediate_operand" "i"))))]
6156 "&& reload_completed"
6158 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6161 (match_dup 4)) 0)))]
6163 operands[1] = gen_lowpart (Pmode, operands[1]);
6164 operands[3] = gen_lowpart (Pmode, operands[3]);
6165 operands[4] = gen_lowpart (Pmode, operands[4]);
6167 [(set_attr "type" "lea")
6168 (set_attr "mode" "SI")])
6170 (define_insn "*adddi_1_rex64"
6171 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6172 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6173 (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6174 (clobber (reg:CC FLAGS_REG))]
6175 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6177 switch (get_attr_type (insn))
6180 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6181 return "lea{q}\t{%a2, %0|%0, %a2}";
6184 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6185 if (operands[2] == const1_rtx)
6186 return "inc{q}\t%0";
6189 gcc_assert (operands[2] == constm1_rtx);
6190 return "dec{q}\t%0";
6194 /* Use add as much as possible to replace lea for AGU optimization. */
6195 if (which_alternative == 2 && TARGET_OPT_AGU)
6196 return "add{q}\t{%1, %0|%0, %1}";
6198 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6200 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6201 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6202 if (CONST_INT_P (operands[2])
6203 /* Avoid overflows. */
6204 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6205 && (INTVAL (operands[2]) == 128
6206 || (INTVAL (operands[2]) < 0
6207 && INTVAL (operands[2]) != -128)))
6209 operands[2] = GEN_INT (-INTVAL (operands[2]));
6210 return "sub{q}\t{%2, %0|%0, %2}";
6212 return "add{q}\t{%2, %0|%0, %2}";
6216 (cond [(and (eq_attr "alternative" "2")
6217 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6218 (const_string "lea")
6219 (eq_attr "alternative" "3")
6220 (const_string "lea")
6221 ; Current assemblers are broken and do not allow @GOTOFF in
6222 ; ought but a memory context.
6223 (match_operand:DI 2 "pic_symbolic_operand" "")
6224 (const_string "lea")
6225 (match_operand:DI 2 "incdec_operand" "")
6226 (const_string "incdec")
6228 (const_string "alu")))
6229 (set_attr "mode" "DI")])
6231 ;; Convert lea to the lea pattern to avoid flags dependency.
6233 [(set (match_operand:DI 0 "register_operand" "")
6234 (plus:DI (match_operand:DI 1 "register_operand" "")
6235 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6236 (clobber (reg:CC FLAGS_REG))]
6237 "TARGET_64BIT && reload_completed
6238 && true_regnum (operands[0]) != true_regnum (operands[1])"
6240 (plus:DI (match_dup 1)
6244 (define_insn "*adddi_2_rex64"
6245 [(set (reg FLAGS_REG)
6247 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6248 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6250 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6251 (plus:DI (match_dup 1) (match_dup 2)))]
6252 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6253 && ix86_binary_operator_ok (PLUS, DImode, operands)
6254 /* Current assemblers are broken and do not allow @GOTOFF in
6255 ought but a memory context. */
6256 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6258 switch (get_attr_type (insn))
6261 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6262 if (operands[2] == const1_rtx)
6263 return "inc{q}\t%0";
6266 gcc_assert (operands[2] == constm1_rtx);
6267 return "dec{q}\t%0";
6271 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6272 /* ???? We ought to handle there the 32bit case too
6273 - do we need new constraint? */
6274 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6275 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6276 if (CONST_INT_P (operands[2])
6277 /* Avoid overflows. */
6278 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6279 && (INTVAL (operands[2]) == 128
6280 || (INTVAL (operands[2]) < 0
6281 && INTVAL (operands[2]) != -128)))
6283 operands[2] = GEN_INT (-INTVAL (operands[2]));
6284 return "sub{q}\t{%2, %0|%0, %2}";
6286 return "add{q}\t{%2, %0|%0, %2}";
6290 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6291 (const_string "incdec")
6292 (const_string "alu")))
6293 (set_attr "mode" "DI")])
6295 (define_insn "*adddi_3_rex64"
6296 [(set (reg FLAGS_REG)
6297 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6298 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6299 (clobber (match_scratch:DI 0 "=r"))]
6301 && ix86_match_ccmode (insn, CCZmode)
6302 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6303 /* Current assemblers are broken and do not allow @GOTOFF in
6304 ought but a memory context. */
6305 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6307 switch (get_attr_type (insn))
6310 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6311 if (operands[2] == const1_rtx)
6312 return "inc{q}\t%0";
6315 gcc_assert (operands[2] == constm1_rtx);
6316 return "dec{q}\t%0";
6320 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6321 /* ???? We ought to handle there the 32bit case too
6322 - do we need new constraint? */
6323 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6324 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6325 if (CONST_INT_P (operands[2])
6326 /* Avoid overflows. */
6327 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6328 && (INTVAL (operands[2]) == 128
6329 || (INTVAL (operands[2]) < 0
6330 && INTVAL (operands[2]) != -128)))
6332 operands[2] = GEN_INT (-INTVAL (operands[2]));
6333 return "sub{q}\t{%2, %0|%0, %2}";
6335 return "add{q}\t{%2, %0|%0, %2}";
6339 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6340 (const_string "incdec")
6341 (const_string "alu")))
6342 (set_attr "mode" "DI")])
6344 ; For comparisons against 1, -1 and 128, we may generate better code
6345 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6346 ; is matched then. We can't accept general immediate, because for
6347 ; case of overflows, the result is messed up.
6348 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6350 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6351 ; only for comparisons not depending on it.
6352 (define_insn "*adddi_4_rex64"
6353 [(set (reg FLAGS_REG)
6354 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6355 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6356 (clobber (match_scratch:DI 0 "=rm"))]
6358 && ix86_match_ccmode (insn, CCGCmode)"
6360 switch (get_attr_type (insn))
6363 if (operands[2] == constm1_rtx)
6364 return "inc{q}\t%0";
6367 gcc_assert (operands[2] == const1_rtx);
6368 return "dec{q}\t%0";
6372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6373 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6374 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6375 if ((INTVAL (operands[2]) == -128
6376 || (INTVAL (operands[2]) > 0
6377 && INTVAL (operands[2]) != 128))
6378 /* Avoid overflows. */
6379 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6380 return "sub{q}\t{%2, %0|%0, %2}";
6381 operands[2] = GEN_INT (-INTVAL (operands[2]));
6382 return "add{q}\t{%2, %0|%0, %2}";
6386 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6387 (const_string "incdec")
6388 (const_string "alu")))
6389 (set_attr "mode" "DI")])
6391 (define_insn "*adddi_5_rex64"
6392 [(set (reg FLAGS_REG)
6394 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6395 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6397 (clobber (match_scratch:DI 0 "=r"))]
6399 && ix86_match_ccmode (insn, CCGOCmode)
6400 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6401 /* Current assemblers are broken and do not allow @GOTOFF in
6402 ought but a memory context. */
6403 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6405 switch (get_attr_type (insn))
6408 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6409 if (operands[2] == const1_rtx)
6410 return "inc{q}\t%0";
6413 gcc_assert (operands[2] == constm1_rtx);
6414 return "dec{q}\t%0";
6418 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6419 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6420 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6421 if (CONST_INT_P (operands[2])
6422 /* Avoid overflows. */
6423 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6424 && (INTVAL (operands[2]) == 128
6425 || (INTVAL (operands[2]) < 0
6426 && INTVAL (operands[2]) != -128)))
6428 operands[2] = GEN_INT (-INTVAL (operands[2]));
6429 return "sub{q}\t{%2, %0|%0, %2}";
6431 return "add{q}\t{%2, %0|%0, %2}";
6435 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6436 (const_string "incdec")
6437 (const_string "alu")))
6438 (set_attr "mode" "DI")])
6441 (define_insn "*addsi_1"
6442 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6443 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6444 (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6445 (clobber (reg:CC FLAGS_REG))]
6446 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6448 switch (get_attr_type (insn))
6451 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6452 return "lea{l}\t{%a2, %0|%0, %a2}";
6455 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6456 if (operands[2] == const1_rtx)
6457 return "inc{l}\t%0";
6460 gcc_assert (operands[2] == constm1_rtx);
6461 return "dec{l}\t%0";
6465 /* Use add as much as possible to replace lea for AGU optimization. */
6466 if (which_alternative == 2 && TARGET_OPT_AGU)
6467 return "add{l}\t{%1, %0|%0, %1}";
6469 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6471 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6472 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6473 if (CONST_INT_P (operands[2])
6474 && (INTVAL (operands[2]) == 128
6475 || (INTVAL (operands[2]) < 0
6476 && INTVAL (operands[2]) != -128)))
6478 operands[2] = GEN_INT (-INTVAL (operands[2]));
6479 return "sub{l}\t{%2, %0|%0, %2}";
6481 return "add{l}\t{%2, %0|%0, %2}";
6485 (cond [(and (eq_attr "alternative" "2")
6486 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6487 (const_string "lea")
6488 (eq_attr "alternative" "3")
6489 (const_string "lea")
6490 ; Current assemblers are broken and do not allow @GOTOFF in
6491 ; ought but a memory context.
6492 (match_operand:SI 2 "pic_symbolic_operand" "")
6493 (const_string "lea")
6494 (match_operand:SI 2 "incdec_operand" "")
6495 (const_string "incdec")
6497 (const_string "alu")))
6498 (set_attr "mode" "SI")])
6500 ;; Convert lea to the lea pattern to avoid flags dependency.
6502 [(set (match_operand 0 "register_operand" "")
6503 (plus (match_operand 1 "register_operand" "")
6504 (match_operand 2 "nonmemory_operand" "")))
6505 (clobber (reg:CC FLAGS_REG))]
6507 && true_regnum (operands[0]) != true_regnum (operands[1])"
6511 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6512 may confuse gen_lowpart. */
6513 if (GET_MODE (operands[0]) != Pmode)
6515 operands[1] = gen_lowpart (Pmode, operands[1]);
6516 operands[2] = gen_lowpart (Pmode, operands[2]);
6518 operands[0] = gen_lowpart (SImode, operands[0]);
6519 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6520 if (Pmode != SImode)
6521 pat = gen_rtx_SUBREG (SImode, pat, 0);
6522 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6526 ;; It may seem that nonimmediate operand is proper one for operand 1.
6527 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6528 ;; we take care in ix86_binary_operator_ok to not allow two memory
6529 ;; operands so proper swapping will be done in reload. This allow
6530 ;; patterns constructed from addsi_1 to match.
6531 (define_insn "addsi_1_zext"
6532 [(set (match_operand:DI 0 "register_operand" "=r,r")
6534 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6535 (match_operand:SI 2 "general_operand" "g,li"))))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6539 switch (get_attr_type (insn))
6542 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6543 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6546 if (operands[2] == const1_rtx)
6547 return "inc{l}\t%k0";
6550 gcc_assert (operands[2] == constm1_rtx);
6551 return "dec{l}\t%k0";
6555 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6556 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6557 if (CONST_INT_P (operands[2])
6558 && (INTVAL (operands[2]) == 128
6559 || (INTVAL (operands[2]) < 0
6560 && INTVAL (operands[2]) != -128)))
6562 operands[2] = GEN_INT (-INTVAL (operands[2]));
6563 return "sub{l}\t{%2, %k0|%k0, %2}";
6565 return "add{l}\t{%2, %k0|%k0, %2}";
6569 (cond [(eq_attr "alternative" "1")
6570 (const_string "lea")
6571 ; Current assemblers are broken and do not allow @GOTOFF in
6572 ; ought but a memory context.
6573 (match_operand:SI 2 "pic_symbolic_operand" "")
6574 (const_string "lea")
6575 (match_operand:SI 2 "incdec_operand" "")
6576 (const_string "incdec")
6578 (const_string "alu")))
6579 (set_attr "mode" "SI")])
6581 ;; Convert lea to the lea pattern to avoid flags dependency.
6583 [(set (match_operand:DI 0 "register_operand" "")
6585 (plus:SI (match_operand:SI 1 "register_operand" "")
6586 (match_operand:SI 2 "nonmemory_operand" ""))))
6587 (clobber (reg:CC FLAGS_REG))]
6588 "TARGET_64BIT && reload_completed
6589 && true_regnum (operands[0]) != true_regnum (operands[1])"
6591 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6593 operands[1] = gen_lowpart (Pmode, operands[1]);
6594 operands[2] = gen_lowpart (Pmode, operands[2]);
6597 (define_insn "*addsi_2"
6598 [(set (reg FLAGS_REG)
6600 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6601 (match_operand:SI 2 "general_operand" "g,ri"))
6603 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6604 (plus:SI (match_dup 1) (match_dup 2)))]
6605 "ix86_match_ccmode (insn, CCGOCmode)
6606 && ix86_binary_operator_ok (PLUS, SImode, operands)
6607 /* Current assemblers are broken and do not allow @GOTOFF in
6608 ought but a memory context. */
6609 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6611 switch (get_attr_type (insn))
6614 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6615 if (operands[2] == const1_rtx)
6616 return "inc{l}\t%0";
6619 gcc_assert (operands[2] == constm1_rtx);
6620 return "dec{l}\t%0";
6624 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6625 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6626 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6627 if (CONST_INT_P (operands[2])
6628 && (INTVAL (operands[2]) == 128
6629 || (INTVAL (operands[2]) < 0
6630 && INTVAL (operands[2]) != -128)))
6632 operands[2] = GEN_INT (-INTVAL (operands[2]));
6633 return "sub{l}\t{%2, %0|%0, %2}";
6635 return "add{l}\t{%2, %0|%0, %2}";
6639 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6640 (const_string "incdec")
6641 (const_string "alu")))
6642 (set_attr "mode" "SI")])
6644 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6645 (define_insn "*addsi_2_zext"
6646 [(set (reg FLAGS_REG)
6648 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6649 (match_operand:SI 2 "general_operand" "g"))
6651 (set (match_operand:DI 0 "register_operand" "=r")
6652 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6653 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6654 && ix86_binary_operator_ok (PLUS, SImode, operands)
6655 /* Current assemblers are broken and do not allow @GOTOFF in
6656 ought but a memory context. */
6657 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6659 switch (get_attr_type (insn))
6662 if (operands[2] == const1_rtx)
6663 return "inc{l}\t%k0";
6666 gcc_assert (operands[2] == constm1_rtx);
6667 return "dec{l}\t%k0";
6671 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6672 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6673 if (CONST_INT_P (operands[2])
6674 && (INTVAL (operands[2]) == 128
6675 || (INTVAL (operands[2]) < 0
6676 && INTVAL (operands[2]) != -128)))
6678 operands[2] = GEN_INT (-INTVAL (operands[2]));
6679 return "sub{l}\t{%2, %k0|%k0, %2}";
6681 return "add{l}\t{%2, %k0|%k0, %2}";
6685 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6686 (const_string "incdec")
6687 (const_string "alu")))
6688 (set_attr "mode" "SI")])
6690 (define_insn "*addsi_3"
6691 [(set (reg FLAGS_REG)
6692 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6693 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6694 (clobber (match_scratch:SI 0 "=r"))]
6695 "ix86_match_ccmode (insn, CCZmode)
6696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6697 /* Current assemblers are broken and do not allow @GOTOFF in
6698 ought but a memory context. */
6699 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6701 switch (get_attr_type (insn))
6704 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6705 if (operands[2] == const1_rtx)
6706 return "inc{l}\t%0";
6709 gcc_assert (operands[2] == constm1_rtx);
6710 return "dec{l}\t%0";
6714 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6715 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6716 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6717 if (CONST_INT_P (operands[2])
6718 && (INTVAL (operands[2]) == 128
6719 || (INTVAL (operands[2]) < 0
6720 && INTVAL (operands[2]) != -128)))
6722 operands[2] = GEN_INT (-INTVAL (operands[2]));
6723 return "sub{l}\t{%2, %0|%0, %2}";
6725 return "add{l}\t{%2, %0|%0, %2}";
6729 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6730 (const_string "incdec")
6731 (const_string "alu")))
6732 (set_attr "mode" "SI")])
6734 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6735 (define_insn "*addsi_3_zext"
6736 [(set (reg FLAGS_REG)
6737 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6738 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6739 (set (match_operand:DI 0 "register_operand" "=r")
6740 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6741 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6742 && ix86_binary_operator_ok (PLUS, SImode, operands)
6743 /* Current assemblers are broken and do not allow @GOTOFF in
6744 ought but a memory context. */
6745 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6747 switch (get_attr_type (insn))
6750 if (operands[2] == const1_rtx)
6751 return "inc{l}\t%k0";
6754 gcc_assert (operands[2] == constm1_rtx);
6755 return "dec{l}\t%k0";
6759 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6760 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6761 if (CONST_INT_P (operands[2])
6762 && (INTVAL (operands[2]) == 128
6763 || (INTVAL (operands[2]) < 0
6764 && INTVAL (operands[2]) != -128)))
6766 operands[2] = GEN_INT (-INTVAL (operands[2]));
6767 return "sub{l}\t{%2, %k0|%k0, %2}";
6769 return "add{l}\t{%2, %k0|%k0, %2}";
6773 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6774 (const_string "incdec")
6775 (const_string "alu")))
6776 (set_attr "mode" "SI")])
6778 ; For comparisons against 1, -1 and 128, we may generate better code
6779 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6780 ; is matched then. We can't accept general immediate, because for
6781 ; case of overflows, the result is messed up.
6782 ; This pattern also don't hold of 0x80000000, since the value overflows
6784 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6785 ; only for comparisons not depending on it.
6786 (define_insn "*addsi_4"
6787 [(set (reg FLAGS_REG)
6788 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6789 (match_operand:SI 2 "const_int_operand" "n")))
6790 (clobber (match_scratch:SI 0 "=rm"))]
6791 "ix86_match_ccmode (insn, CCGCmode)
6792 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6794 switch (get_attr_type (insn))
6797 if (operands[2] == constm1_rtx)
6798 return "inc{l}\t%0";
6801 gcc_assert (operands[2] == const1_rtx);
6802 return "dec{l}\t%0";
6806 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6807 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6808 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6809 if ((INTVAL (operands[2]) == -128
6810 || (INTVAL (operands[2]) > 0
6811 && INTVAL (operands[2]) != 128)))
6812 return "sub{l}\t{%2, %0|%0, %2}";
6813 operands[2] = GEN_INT (-INTVAL (operands[2]));
6814 return "add{l}\t{%2, %0|%0, %2}";
6818 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6819 (const_string "incdec")
6820 (const_string "alu")))
6821 (set_attr "mode" "SI")])
6823 (define_insn "*addsi_5"
6824 [(set (reg FLAGS_REG)
6826 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6827 (match_operand:SI 2 "general_operand" "g"))
6829 (clobber (match_scratch:SI 0 "=r"))]
6830 "ix86_match_ccmode (insn, CCGOCmode)
6831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6832 /* Current assemblers are broken and do not allow @GOTOFF in
6833 ought but a memory context. */
6834 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6836 switch (get_attr_type (insn))
6839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6840 if (operands[2] == const1_rtx)
6841 return "inc{l}\t%0";
6844 gcc_assert (operands[2] == constm1_rtx);
6845 return "dec{l}\t%0";
6849 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6850 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6851 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6852 if (CONST_INT_P (operands[2])
6853 && (INTVAL (operands[2]) == 128
6854 || (INTVAL (operands[2]) < 0
6855 && INTVAL (operands[2]) != -128)))
6857 operands[2] = GEN_INT (-INTVAL (operands[2]));
6858 return "sub{l}\t{%2, %0|%0, %2}";
6860 return "add{l}\t{%2, %0|%0, %2}";
6864 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6865 (const_string "incdec")
6866 (const_string "alu")))
6867 (set_attr "mode" "SI")])
6869 (define_expand "addhi3"
6870 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6871 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6872 (match_operand:HI 2 "general_operand" "")))]
6873 "TARGET_HIMODE_MATH"
6874 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6876 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6877 ;; type optimizations enabled by define-splits. This is not important
6878 ;; for PII, and in fact harmful because of partial register stalls.
6880 (define_insn "*addhi_1_lea"
6881 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6882 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6883 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6884 (clobber (reg:CC FLAGS_REG))]
6885 "!TARGET_PARTIAL_REG_STALL
6886 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6888 switch (get_attr_type (insn))
6893 if (operands[2] == const1_rtx)
6894 return "inc{w}\t%0";
6897 gcc_assert (operands[2] == constm1_rtx);
6898 return "dec{w}\t%0";
6902 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6903 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6904 if (CONST_INT_P (operands[2])
6905 && (INTVAL (operands[2]) == 128
6906 || (INTVAL (operands[2]) < 0
6907 && INTVAL (operands[2]) != -128)))
6909 operands[2] = GEN_INT (-INTVAL (operands[2]));
6910 return "sub{w}\t{%2, %0|%0, %2}";
6912 return "add{w}\t{%2, %0|%0, %2}";
6916 (if_then_else (eq_attr "alternative" "2")
6917 (const_string "lea")
6918 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6919 (const_string "incdec")
6920 (const_string "alu"))))
6921 (set_attr "mode" "HI,HI,SI")])
6923 (define_insn "*addhi_1"
6924 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6925 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6926 (match_operand:HI 2 "general_operand" "rn,rm")))
6927 (clobber (reg:CC FLAGS_REG))]
6928 "TARGET_PARTIAL_REG_STALL
6929 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6931 switch (get_attr_type (insn))
6934 if (operands[2] == const1_rtx)
6935 return "inc{w}\t%0";
6938 gcc_assert (operands[2] == constm1_rtx);
6939 return "dec{w}\t%0";
6943 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6944 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6945 if (CONST_INT_P (operands[2])
6946 && (INTVAL (operands[2]) == 128
6947 || (INTVAL (operands[2]) < 0
6948 && INTVAL (operands[2]) != -128)))
6950 operands[2] = GEN_INT (-INTVAL (operands[2]));
6951 return "sub{w}\t{%2, %0|%0, %2}";
6953 return "add{w}\t{%2, %0|%0, %2}";
6957 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6958 (const_string "incdec")
6959 (const_string "alu")))
6960 (set_attr "mode" "HI")])
6962 (define_insn "*addhi_2"
6963 [(set (reg FLAGS_REG)
6965 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6966 (match_operand:HI 2 "general_operand" "rmn,rn"))
6968 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6969 (plus:HI (match_dup 1) (match_dup 2)))]
6970 "ix86_match_ccmode (insn, CCGOCmode)
6971 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6973 switch (get_attr_type (insn))
6976 if (operands[2] == const1_rtx)
6977 return "inc{w}\t%0";
6980 gcc_assert (operands[2] == constm1_rtx);
6981 return "dec{w}\t%0";
6985 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6986 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6987 if (CONST_INT_P (operands[2])
6988 && (INTVAL (operands[2]) == 128
6989 || (INTVAL (operands[2]) < 0
6990 && INTVAL (operands[2]) != -128)))
6992 operands[2] = GEN_INT (-INTVAL (operands[2]));
6993 return "sub{w}\t{%2, %0|%0, %2}";
6995 return "add{w}\t{%2, %0|%0, %2}";
6999 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7000 (const_string "incdec")
7001 (const_string "alu")))
7002 (set_attr "mode" "HI")])
7004 (define_insn "*addhi_3"
7005 [(set (reg FLAGS_REG)
7006 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7007 (match_operand:HI 1 "nonimmediate_operand" "%0")))
7008 (clobber (match_scratch:HI 0 "=r"))]
7009 "ix86_match_ccmode (insn, CCZmode)
7010 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7012 switch (get_attr_type (insn))
7015 if (operands[2] == const1_rtx)
7016 return "inc{w}\t%0";
7019 gcc_assert (operands[2] == constm1_rtx);
7020 return "dec{w}\t%0";
7024 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7025 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7026 if (CONST_INT_P (operands[2])
7027 && (INTVAL (operands[2]) == 128
7028 || (INTVAL (operands[2]) < 0
7029 && INTVAL (operands[2]) != -128)))
7031 operands[2] = GEN_INT (-INTVAL (operands[2]));
7032 return "sub{w}\t{%2, %0|%0, %2}";
7034 return "add{w}\t{%2, %0|%0, %2}";
7038 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7039 (const_string "incdec")
7040 (const_string "alu")))
7041 (set_attr "mode" "HI")])
7043 ; See comments above addsi_4 for details.
7044 (define_insn "*addhi_4"
7045 [(set (reg FLAGS_REG)
7046 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7047 (match_operand:HI 2 "const_int_operand" "n")))
7048 (clobber (match_scratch:HI 0 "=rm"))]
7049 "ix86_match_ccmode (insn, CCGCmode)
7050 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7052 switch (get_attr_type (insn))
7055 if (operands[2] == constm1_rtx)
7056 return "inc{w}\t%0";
7059 gcc_assert (operands[2] == const1_rtx);
7060 return "dec{w}\t%0";
7064 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7065 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7066 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7067 if ((INTVAL (operands[2]) == -128
7068 || (INTVAL (operands[2]) > 0
7069 && INTVAL (operands[2]) != 128)))
7070 return "sub{w}\t{%2, %0|%0, %2}";
7071 operands[2] = GEN_INT (-INTVAL (operands[2]));
7072 return "add{w}\t{%2, %0|%0, %2}";
7076 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7077 (const_string "incdec")
7078 (const_string "alu")))
7079 (set_attr "mode" "SI")])
7082 (define_insn "*addhi_5"
7083 [(set (reg FLAGS_REG)
7085 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7086 (match_operand:HI 2 "general_operand" "rmn"))
7088 (clobber (match_scratch:HI 0 "=r"))]
7089 "ix86_match_ccmode (insn, CCGOCmode)
7090 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7092 switch (get_attr_type (insn))
7095 if (operands[2] == const1_rtx)
7096 return "inc{w}\t%0";
7099 gcc_assert (operands[2] == constm1_rtx);
7100 return "dec{w}\t%0";
7104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7106 if (CONST_INT_P (operands[2])
7107 && (INTVAL (operands[2]) == 128
7108 || (INTVAL (operands[2]) < 0
7109 && INTVAL (operands[2]) != -128)))
7111 operands[2] = GEN_INT (-INTVAL (operands[2]));
7112 return "sub{w}\t{%2, %0|%0, %2}";
7114 return "add{w}\t{%2, %0|%0, %2}";
7118 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7119 (const_string "incdec")
7120 (const_string "alu")))
7121 (set_attr "mode" "HI")])
7123 (define_expand "addqi3"
7124 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7125 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7126 (match_operand:QI 2 "general_operand" "")))]
7127 "TARGET_QIMODE_MATH"
7128 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7130 ;; %%% Potential partial reg stall on alternative 2. What to do?
7131 (define_insn "*addqi_1_lea"
7132 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7133 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7134 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7135 (clobber (reg:CC FLAGS_REG))]
7136 "!TARGET_PARTIAL_REG_STALL
7137 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7139 int widen = (which_alternative == 2);
7140 switch (get_attr_type (insn))
7145 if (operands[2] == const1_rtx)
7146 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7149 gcc_assert (operands[2] == constm1_rtx);
7150 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7154 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7155 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7156 if (CONST_INT_P (operands[2])
7157 && (INTVAL (operands[2]) == 128
7158 || (INTVAL (operands[2]) < 0
7159 && INTVAL (operands[2]) != -128)))
7161 operands[2] = GEN_INT (-INTVAL (operands[2]));
7163 return "sub{l}\t{%2, %k0|%k0, %2}";
7165 return "sub{b}\t{%2, %0|%0, %2}";
7168 return "add{l}\t{%k2, %k0|%k0, %k2}";
7170 return "add{b}\t{%2, %0|%0, %2}";
7174 (if_then_else (eq_attr "alternative" "3")
7175 (const_string "lea")
7176 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7177 (const_string "incdec")
7178 (const_string "alu"))))
7179 (set_attr "mode" "QI,QI,SI,SI")])
7181 (define_insn "*addqi_1"
7182 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7183 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7184 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7185 (clobber (reg:CC FLAGS_REG))]
7186 "TARGET_PARTIAL_REG_STALL
7187 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7189 int widen = (which_alternative == 2);
7190 switch (get_attr_type (insn))
7193 if (operands[2] == const1_rtx)
7194 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7197 gcc_assert (operands[2] == constm1_rtx);
7198 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7202 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7203 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7204 if (CONST_INT_P (operands[2])
7205 && (INTVAL (operands[2]) == 128
7206 || (INTVAL (operands[2]) < 0
7207 && INTVAL (operands[2]) != -128)))
7209 operands[2] = GEN_INT (-INTVAL (operands[2]));
7211 return "sub{l}\t{%2, %k0|%k0, %2}";
7213 return "sub{b}\t{%2, %0|%0, %2}";
7216 return "add{l}\t{%k2, %k0|%k0, %k2}";
7218 return "add{b}\t{%2, %0|%0, %2}";
7222 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7223 (const_string "incdec")
7224 (const_string "alu")))
7225 (set_attr "mode" "QI,QI,SI")])
7227 (define_insn "*addqi_1_slp"
7228 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7229 (plus:QI (match_dup 0)
7230 (match_operand:QI 1 "general_operand" "qn,qnm")))
7231 (clobber (reg:CC FLAGS_REG))]
7232 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7233 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7235 switch (get_attr_type (insn))
7238 if (operands[1] == const1_rtx)
7239 return "inc{b}\t%0";
7242 gcc_assert (operands[1] == constm1_rtx);
7243 return "dec{b}\t%0";
7247 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7248 if (CONST_INT_P (operands[1])
7249 && INTVAL (operands[1]) < 0)
7251 operands[1] = GEN_INT (-INTVAL (operands[1]));
7252 return "sub{b}\t{%1, %0|%0, %1}";
7254 return "add{b}\t{%1, %0|%0, %1}";
7258 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7259 (const_string "incdec")
7260 (const_string "alu1")))
7261 (set (attr "memory")
7262 (if_then_else (match_operand 1 "memory_operand" "")
7263 (const_string "load")
7264 (const_string "none")))
7265 (set_attr "mode" "QI")])
7267 (define_insn "*addqi_2"
7268 [(set (reg FLAGS_REG)
7270 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7271 (match_operand:QI 2 "general_operand" "qmn,qn"))
7273 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7274 (plus:QI (match_dup 1) (match_dup 2)))]
7275 "ix86_match_ccmode (insn, CCGOCmode)
7276 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7278 switch (get_attr_type (insn))
7281 if (operands[2] == const1_rtx)
7282 return "inc{b}\t%0";
7285 gcc_assert (operands[2] == constm1_rtx
7286 || (CONST_INT_P (operands[2])
7287 && INTVAL (operands[2]) == 255));
7288 return "dec{b}\t%0";
7292 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7293 if (CONST_INT_P (operands[2])
7294 && INTVAL (operands[2]) < 0)
7296 operands[2] = GEN_INT (-INTVAL (operands[2]));
7297 return "sub{b}\t{%2, %0|%0, %2}";
7299 return "add{b}\t{%2, %0|%0, %2}";
7303 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7304 (const_string "incdec")
7305 (const_string "alu")))
7306 (set_attr "mode" "QI")])
7308 (define_insn "*addqi_3"
7309 [(set (reg FLAGS_REG)
7310 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7311 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7312 (clobber (match_scratch:QI 0 "=q"))]
7313 "ix86_match_ccmode (insn, CCZmode)
7314 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7316 switch (get_attr_type (insn))
7319 if (operands[2] == const1_rtx)
7320 return "inc{b}\t%0";
7323 gcc_assert (operands[2] == constm1_rtx
7324 || (CONST_INT_P (operands[2])
7325 && INTVAL (operands[2]) == 255));
7326 return "dec{b}\t%0";
7330 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7331 if (CONST_INT_P (operands[2])
7332 && INTVAL (operands[2]) < 0)
7334 operands[2] = GEN_INT (-INTVAL (operands[2]));
7335 return "sub{b}\t{%2, %0|%0, %2}";
7337 return "add{b}\t{%2, %0|%0, %2}";
7341 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7342 (const_string "incdec")
7343 (const_string "alu")))
7344 (set_attr "mode" "QI")])
7346 ; See comments above addsi_4 for details.
7347 (define_insn "*addqi_4"
7348 [(set (reg FLAGS_REG)
7349 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7350 (match_operand:QI 2 "const_int_operand" "n")))
7351 (clobber (match_scratch:QI 0 "=qm"))]
7352 "ix86_match_ccmode (insn, CCGCmode)
7353 && (INTVAL (operands[2]) & 0xff) != 0x80"
7355 switch (get_attr_type (insn))
7358 if (operands[2] == constm1_rtx
7359 || (CONST_INT_P (operands[2])
7360 && INTVAL (operands[2]) == 255))
7361 return "inc{b}\t%0";
7364 gcc_assert (operands[2] == const1_rtx);
7365 return "dec{b}\t%0";
7369 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7370 if (INTVAL (operands[2]) < 0)
7372 operands[2] = GEN_INT (-INTVAL (operands[2]));
7373 return "add{b}\t{%2, %0|%0, %2}";
7375 return "sub{b}\t{%2, %0|%0, %2}";
7379 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7380 (const_string "incdec")
7381 (const_string "alu")))
7382 (set_attr "mode" "QI")])
7385 (define_insn "*addqi_5"
7386 [(set (reg FLAGS_REG)
7388 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7389 (match_operand:QI 2 "general_operand" "qmn"))
7391 (clobber (match_scratch:QI 0 "=q"))]
7392 "ix86_match_ccmode (insn, CCGOCmode)
7393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7395 switch (get_attr_type (insn))
7398 if (operands[2] == const1_rtx)
7399 return "inc{b}\t%0";
7402 gcc_assert (operands[2] == constm1_rtx
7403 || (CONST_INT_P (operands[2])
7404 && INTVAL (operands[2]) == 255));
7405 return "dec{b}\t%0";
7409 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7410 if (CONST_INT_P (operands[2])
7411 && INTVAL (operands[2]) < 0)
7413 operands[2] = GEN_INT (-INTVAL (operands[2]));
7414 return "sub{b}\t{%2, %0|%0, %2}";
7416 return "add{b}\t{%2, %0|%0, %2}";
7420 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7421 (const_string "incdec")
7422 (const_string "alu")))
7423 (set_attr "mode" "QI")])
7426 (define_insn "addqi_ext_1"
7427 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7432 (match_operand 1 "ext_register_operand" "0")
7435 (match_operand:QI 2 "general_operand" "Qmn")))
7436 (clobber (reg:CC FLAGS_REG))]
7439 switch (get_attr_type (insn))
7442 if (operands[2] == const1_rtx)
7443 return "inc{b}\t%h0";
7446 gcc_assert (operands[2] == constm1_rtx
7447 || (CONST_INT_P (operands[2])
7448 && INTVAL (operands[2]) == 255));
7449 return "dec{b}\t%h0";
7453 return "add{b}\t{%2, %h0|%h0, %2}";
7457 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7458 (const_string "incdec")
7459 (const_string "alu")))
7460 (set_attr "mode" "QI")])
7462 (define_insn "*addqi_ext_1_rex64"
7463 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7468 (match_operand 1 "ext_register_operand" "0")
7471 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7472 (clobber (reg:CC FLAGS_REG))]
7475 switch (get_attr_type (insn))
7478 if (operands[2] == const1_rtx)
7479 return "inc{b}\t%h0";
7482 gcc_assert (operands[2] == constm1_rtx
7483 || (CONST_INT_P (operands[2])
7484 && INTVAL (operands[2]) == 255));
7485 return "dec{b}\t%h0";
7489 return "add{b}\t{%2, %h0|%h0, %2}";
7493 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7494 (const_string "incdec")
7495 (const_string "alu")))
7496 (set_attr "mode" "QI")])
7498 (define_insn "*addqi_ext_2"
7499 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7504 (match_operand 1 "ext_register_operand" "%0")
7508 (match_operand 2 "ext_register_operand" "Q")
7511 (clobber (reg:CC FLAGS_REG))]
7513 "add{b}\t{%h2, %h0|%h0, %h2}"
7514 [(set_attr "type" "alu")
7515 (set_attr "mode" "QI")])
7517 ;; The patterns that match these are at the end of this file.
7519 (define_expand "addxf3"
7520 [(set (match_operand:XF 0 "register_operand" "")
7521 (plus:XF (match_operand:XF 1 "register_operand" "")
7522 (match_operand:XF 2 "register_operand" "")))]
7526 (define_expand "add<mode>3"
7527 [(set (match_operand:MODEF 0 "register_operand" "")
7528 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7529 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7530 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7531 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7534 ;; Subtract instructions
7536 ;; %%% splits for subditi3
7538 (define_expand "subti3"
7539 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7540 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7541 (match_operand:TI 2 "x86_64_general_operand" "")))]
7543 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7545 (define_insn "*subti3_1"
7546 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7547 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7548 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7549 (clobber (reg:CC FLAGS_REG))]
7550 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7554 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7555 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7556 (match_operand:TI 2 "x86_64_general_operand" "")))
7557 (clobber (reg:CC FLAGS_REG))]
7558 "TARGET_64BIT && reload_completed"
7559 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7560 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7561 (parallel [(set (match_dup 3)
7562 (minus:DI (match_dup 4)
7563 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7565 (clobber (reg:CC FLAGS_REG))])]
7566 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7568 ;; %%% splits for subsidi3
7570 (define_expand "subdi3"
7571 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7572 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7573 (match_operand:DI 2 "x86_64_general_operand" "")))]
7575 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7577 (define_insn "*subdi3_1"
7578 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7579 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7580 (match_operand:DI 2 "general_operand" "roiF,riF")))
7581 (clobber (reg:CC FLAGS_REG))]
7582 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7586 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7587 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7588 (match_operand:DI 2 "general_operand" "")))
7589 (clobber (reg:CC FLAGS_REG))]
7590 "!TARGET_64BIT && reload_completed"
7591 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7592 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7593 (parallel [(set (match_dup 3)
7594 (minus:SI (match_dup 4)
7595 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7597 (clobber (reg:CC FLAGS_REG))])]
7598 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7600 (define_insn "subdi3_carry_rex64"
7601 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7602 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7603 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7604 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7605 (clobber (reg:CC FLAGS_REG))]
7606 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7607 "sbb{q}\t{%2, %0|%0, %2}"
7608 [(set_attr "type" "alu")
7609 (set_attr "use_carry" "1")
7610 (set_attr "pent_pair" "pu")
7611 (set_attr "mode" "DI")])
7613 (define_insn "*subdi_1_rex64"
7614 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7615 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7616 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7617 (clobber (reg:CC FLAGS_REG))]
7618 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7619 "sub{q}\t{%2, %0|%0, %2}"
7620 [(set_attr "type" "alu")
7621 (set_attr "mode" "DI")])
7623 (define_insn "*subdi_2_rex64"
7624 [(set (reg FLAGS_REG)
7626 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7627 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7629 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7630 (minus:DI (match_dup 1) (match_dup 2)))]
7631 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7632 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7633 "sub{q}\t{%2, %0|%0, %2}"
7634 [(set_attr "type" "alu")
7635 (set_attr "mode" "DI")])
7637 (define_insn "*subdi_3_rex63"
7638 [(set (reg FLAGS_REG)
7639 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7640 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7641 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7642 (minus:DI (match_dup 1) (match_dup 2)))]
7643 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7644 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7645 "sub{q}\t{%2, %0|%0, %2}"
7646 [(set_attr "type" "alu")
7647 (set_attr "mode" "DI")])
7649 (define_insn "subqi3_carry"
7650 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7651 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7652 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7653 (match_operand:QI 2 "general_operand" "qn,qm"))))
7654 (clobber (reg:CC FLAGS_REG))]
7655 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7656 "sbb{b}\t{%2, %0|%0, %2}"
7657 [(set_attr "type" "alu")
7658 (set_attr "use_carry" "1")
7659 (set_attr "pent_pair" "pu")
7660 (set_attr "mode" "QI")])
7662 (define_insn "subhi3_carry"
7663 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7664 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7665 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7666 (match_operand:HI 2 "general_operand" "rn,rm"))))
7667 (clobber (reg:CC FLAGS_REG))]
7668 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7669 "sbb{w}\t{%2, %0|%0, %2}"
7670 [(set_attr "type" "alu")
7671 (set_attr "use_carry" "1")
7672 (set_attr "pent_pair" "pu")
7673 (set_attr "mode" "HI")])
7675 (define_insn "subsi3_carry"
7676 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7677 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7678 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7679 (match_operand:SI 2 "general_operand" "ri,rm"))))
7680 (clobber (reg:CC FLAGS_REG))]
7681 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7682 "sbb{l}\t{%2, %0|%0, %2}"
7683 [(set_attr "type" "alu")
7684 (set_attr "use_carry" "1")
7685 (set_attr "pent_pair" "pu")
7686 (set_attr "mode" "SI")])
7688 (define_insn "subsi3_carry_zext"
7689 [(set (match_operand:DI 0 "register_operand" "=r")
7691 (minus:SI (match_operand:SI 1 "register_operand" "0")
7692 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7693 (match_operand:SI 2 "general_operand" "g")))))
7694 (clobber (reg:CC FLAGS_REG))]
7695 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7696 "sbb{l}\t{%2, %k0|%k0, %2}"
7697 [(set_attr "type" "alu")
7698 (set_attr "pent_pair" "pu")
7699 (set_attr "mode" "SI")])
7701 (define_expand "subsi3"
7702 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7703 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7704 (match_operand:SI 2 "general_operand" "")))]
7706 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7708 (define_insn "*subsi_1"
7709 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7710 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7711 (match_operand:SI 2 "general_operand" "ri,rm")))
7712 (clobber (reg:CC FLAGS_REG))]
7713 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7714 "sub{l}\t{%2, %0|%0, %2}"
7715 [(set_attr "type" "alu")
7716 (set_attr "mode" "SI")])
7718 (define_insn "*subsi_1_zext"
7719 [(set (match_operand:DI 0 "register_operand" "=r")
7721 (minus:SI (match_operand:SI 1 "register_operand" "0")
7722 (match_operand:SI 2 "general_operand" "g"))))
7723 (clobber (reg:CC FLAGS_REG))]
7724 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7725 "sub{l}\t{%2, %k0|%k0, %2}"
7726 [(set_attr "type" "alu")
7727 (set_attr "mode" "SI")])
7729 (define_insn "*subsi_2"
7730 [(set (reg FLAGS_REG)
7732 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7733 (match_operand:SI 2 "general_operand" "ri,rm"))
7735 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7736 (minus:SI (match_dup 1) (match_dup 2)))]
7737 "ix86_match_ccmode (insn, CCGOCmode)
7738 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7739 "sub{l}\t{%2, %0|%0, %2}"
7740 [(set_attr "type" "alu")
7741 (set_attr "mode" "SI")])
7743 (define_insn "*subsi_2_zext"
7744 [(set (reg FLAGS_REG)
7746 (minus:SI (match_operand:SI 1 "register_operand" "0")
7747 (match_operand:SI 2 "general_operand" "g"))
7749 (set (match_operand:DI 0 "register_operand" "=r")
7751 (minus:SI (match_dup 1)
7753 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7754 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7755 "sub{l}\t{%2, %k0|%k0, %2}"
7756 [(set_attr "type" "alu")
7757 (set_attr "mode" "SI")])
7759 (define_insn "*subsi_3"
7760 [(set (reg FLAGS_REG)
7761 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7762 (match_operand:SI 2 "general_operand" "ri,rm")))
7763 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7764 (minus:SI (match_dup 1) (match_dup 2)))]
7765 "ix86_match_ccmode (insn, CCmode)
7766 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7767 "sub{l}\t{%2, %0|%0, %2}"
7768 [(set_attr "type" "alu")
7769 (set_attr "mode" "SI")])
7771 (define_insn "*subsi_3_zext"
7772 [(set (reg FLAGS_REG)
7773 (compare (match_operand:SI 1 "register_operand" "0")
7774 (match_operand:SI 2 "general_operand" "g")))
7775 (set (match_operand:DI 0 "register_operand" "=r")
7777 (minus:SI (match_dup 1)
7779 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7780 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7781 "sub{l}\t{%2, %1|%1, %2}"
7782 [(set_attr "type" "alu")
7783 (set_attr "mode" "DI")])
7785 (define_expand "subhi3"
7786 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7787 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7788 (match_operand:HI 2 "general_operand" "")))]
7789 "TARGET_HIMODE_MATH"
7790 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7792 (define_insn "*subhi_1"
7793 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7794 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7795 (match_operand:HI 2 "general_operand" "rn,rm")))
7796 (clobber (reg:CC FLAGS_REG))]
7797 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7798 "sub{w}\t{%2, %0|%0, %2}"
7799 [(set_attr "type" "alu")
7800 (set_attr "mode" "HI")])
7802 (define_insn "*subhi_2"
7803 [(set (reg FLAGS_REG)
7805 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7806 (match_operand:HI 2 "general_operand" "rn,rm"))
7808 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7809 (minus:HI (match_dup 1) (match_dup 2)))]
7810 "ix86_match_ccmode (insn, CCGOCmode)
7811 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7812 "sub{w}\t{%2, %0|%0, %2}"
7813 [(set_attr "type" "alu")
7814 (set_attr "mode" "HI")])
7816 (define_insn "*subhi_3"
7817 [(set (reg FLAGS_REG)
7818 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7819 (match_operand:HI 2 "general_operand" "rn,rm")))
7820 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7821 (minus:HI (match_dup 1) (match_dup 2)))]
7822 "ix86_match_ccmode (insn, CCmode)
7823 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7824 "sub{w}\t{%2, %0|%0, %2}"
7825 [(set_attr "type" "alu")
7826 (set_attr "mode" "HI")])
7828 (define_expand "subqi3"
7829 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7830 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7831 (match_operand:QI 2 "general_operand" "")))]
7832 "TARGET_QIMODE_MATH"
7833 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7835 (define_insn "*subqi_1"
7836 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7837 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7838 (match_operand:QI 2 "general_operand" "qn,qm")))
7839 (clobber (reg:CC FLAGS_REG))]
7840 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7841 "sub{b}\t{%2, %0|%0, %2}"
7842 [(set_attr "type" "alu")
7843 (set_attr "mode" "QI")])
7845 (define_insn "*subqi_1_slp"
7846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7847 (minus:QI (match_dup 0)
7848 (match_operand:QI 1 "general_operand" "qn,qm")))
7849 (clobber (reg:CC FLAGS_REG))]
7850 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7851 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7852 "sub{b}\t{%1, %0|%0, %1}"
7853 [(set_attr "type" "alu1")
7854 (set_attr "mode" "QI")])
7856 (define_insn "*subqi_2"
7857 [(set (reg FLAGS_REG)
7859 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7860 (match_operand:QI 2 "general_operand" "qn,qm"))
7862 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7863 (minus:QI (match_dup 1) (match_dup 2)))]
7864 "ix86_match_ccmode (insn, CCGOCmode)
7865 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7866 "sub{b}\t{%2, %0|%0, %2}"
7867 [(set_attr "type" "alu")
7868 (set_attr "mode" "QI")])
7870 (define_insn "*subqi_3"
7871 [(set (reg FLAGS_REG)
7872 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7873 (match_operand:QI 2 "general_operand" "qn,qm")))
7874 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7875 (minus:QI (match_dup 1) (match_dup 2)))]
7876 "ix86_match_ccmode (insn, CCmode)
7877 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7878 "sub{b}\t{%2, %0|%0, %2}"
7879 [(set_attr "type" "alu")
7880 (set_attr "mode" "QI")])
7882 ;; The patterns that match these are at the end of this file.
7884 (define_expand "subxf3"
7885 [(set (match_operand:XF 0 "register_operand" "")
7886 (minus:XF (match_operand:XF 1 "register_operand" "")
7887 (match_operand:XF 2 "register_operand" "")))]
7891 (define_expand "sub<mode>3"
7892 [(set (match_operand:MODEF 0 "register_operand" "")
7893 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7894 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7895 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7896 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7899 ;; Multiply instructions
7901 (define_expand "muldi3"
7902 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7903 (mult:DI (match_operand:DI 1 "register_operand" "")
7904 (match_operand:DI 2 "x86_64_general_operand" "")))
7905 (clobber (reg:CC FLAGS_REG))])]
7910 ;; IMUL reg64, reg64, imm8 Direct
7911 ;; IMUL reg64, mem64, imm8 VectorPath
7912 ;; IMUL reg64, reg64, imm32 Direct
7913 ;; IMUL reg64, mem64, imm32 VectorPath
7914 ;; IMUL reg64, reg64 Direct
7915 ;; IMUL reg64, mem64 Direct
7917 (define_insn "*muldi3_1_rex64"
7918 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7919 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7920 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7921 (clobber (reg:CC FLAGS_REG))]
7923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925 imul{q}\t{%2, %1, %0|%0, %1, %2}
7926 imul{q}\t{%2, %1, %0|%0, %1, %2}
7927 imul{q}\t{%2, %0|%0, %2}"
7928 [(set_attr "type" "imul")
7929 (set_attr "prefix_0f" "0,0,1")
7930 (set (attr "athlon_decode")
7931 (cond [(eq_attr "cpu" "athlon")
7932 (const_string "vector")
7933 (eq_attr "alternative" "1")
7934 (const_string "vector")
7935 (and (eq_attr "alternative" "2")
7936 (match_operand 1 "memory_operand" ""))
7937 (const_string "vector")]
7938 (const_string "direct")))
7939 (set (attr "amdfam10_decode")
7940 (cond [(and (eq_attr "alternative" "0,1")
7941 (match_operand 1 "memory_operand" ""))
7942 (const_string "vector")]
7943 (const_string "direct")))
7944 (set_attr "mode" "DI")])
7946 (define_expand "mulsi3"
7947 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7948 (mult:SI (match_operand:SI 1 "register_operand" "")
7949 (match_operand:SI 2 "general_operand" "")))
7950 (clobber (reg:CC FLAGS_REG))])]
7955 ;; IMUL reg32, reg32, imm8 Direct
7956 ;; IMUL reg32, mem32, imm8 VectorPath
7957 ;; IMUL reg32, reg32, imm32 Direct
7958 ;; IMUL reg32, mem32, imm32 VectorPath
7959 ;; IMUL reg32, reg32 Direct
7960 ;; IMUL reg32, mem32 Direct
7962 (define_insn "*mulsi3_1"
7963 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7964 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7965 (match_operand:SI 2 "general_operand" "K,i,mr")))
7966 (clobber (reg:CC FLAGS_REG))]
7967 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7969 imul{l}\t{%2, %1, %0|%0, %1, %2}
7970 imul{l}\t{%2, %1, %0|%0, %1, %2}
7971 imul{l}\t{%2, %0|%0, %2}"
7972 [(set_attr "type" "imul")
7973 (set_attr "prefix_0f" "0,0,1")
7974 (set (attr "athlon_decode")
7975 (cond [(eq_attr "cpu" "athlon")
7976 (const_string "vector")
7977 (eq_attr "alternative" "1")
7978 (const_string "vector")
7979 (and (eq_attr "alternative" "2")
7980 (match_operand 1 "memory_operand" ""))
7981 (const_string "vector")]
7982 (const_string "direct")))
7983 (set (attr "amdfam10_decode")
7984 (cond [(and (eq_attr "alternative" "0,1")
7985 (match_operand 1 "memory_operand" ""))
7986 (const_string "vector")]
7987 (const_string "direct")))
7988 (set_attr "mode" "SI")])
7990 (define_insn "*mulsi3_1_zext"
7991 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7993 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7994 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7995 (clobber (reg:CC FLAGS_REG))]
7997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7999 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8000 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8001 imul{l}\t{%2, %k0|%k0, %2}"
8002 [(set_attr "type" "imul")
8003 (set_attr "prefix_0f" "0,0,1")
8004 (set (attr "athlon_decode")
8005 (cond [(eq_attr "cpu" "athlon")
8006 (const_string "vector")
8007 (eq_attr "alternative" "1")
8008 (const_string "vector")
8009 (and (eq_attr "alternative" "2")
8010 (match_operand 1 "memory_operand" ""))
8011 (const_string "vector")]
8012 (const_string "direct")))
8013 (set (attr "amdfam10_decode")
8014 (cond [(and (eq_attr "alternative" "0,1")
8015 (match_operand 1 "memory_operand" ""))
8016 (const_string "vector")]
8017 (const_string "direct")))
8018 (set_attr "mode" "SI")])
8020 (define_expand "mulhi3"
8021 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8022 (mult:HI (match_operand:HI 1 "register_operand" "")
8023 (match_operand:HI 2 "general_operand" "")))
8024 (clobber (reg:CC FLAGS_REG))])]
8025 "TARGET_HIMODE_MATH"
8029 ;; IMUL reg16, reg16, imm8 VectorPath
8030 ;; IMUL reg16, mem16, imm8 VectorPath
8031 ;; IMUL reg16, reg16, imm16 VectorPath
8032 ;; IMUL reg16, mem16, imm16 VectorPath
8033 ;; IMUL reg16, reg16 Direct
8034 ;; IMUL reg16, mem16 Direct
8035 (define_insn "*mulhi3_1"
8036 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8037 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8038 (match_operand:HI 2 "general_operand" "K,n,mr")))
8039 (clobber (reg:CC FLAGS_REG))]
8040 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8042 imul{w}\t{%2, %1, %0|%0, %1, %2}
8043 imul{w}\t{%2, %1, %0|%0, %1, %2}
8044 imul{w}\t{%2, %0|%0, %2}"
8045 [(set_attr "type" "imul")
8046 (set_attr "prefix_0f" "0,0,1")
8047 (set (attr "athlon_decode")
8048 (cond [(eq_attr "cpu" "athlon")
8049 (const_string "vector")
8050 (eq_attr "alternative" "1,2")
8051 (const_string "vector")]
8052 (const_string "direct")))
8053 (set (attr "amdfam10_decode")
8054 (cond [(eq_attr "alternative" "0,1")
8055 (const_string "vector")]
8056 (const_string "direct")))
8057 (set_attr "mode" "HI")])
8059 (define_expand "mulqi3"
8060 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8061 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8062 (match_operand:QI 2 "register_operand" "")))
8063 (clobber (reg:CC FLAGS_REG))])]
8064 "TARGET_QIMODE_MATH"
8071 (define_insn "*mulqi3_1"
8072 [(set (match_operand:QI 0 "register_operand" "=a")
8073 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8074 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8075 (clobber (reg:CC FLAGS_REG))]
8077 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8079 [(set_attr "type" "imul")
8080 (set_attr "length_immediate" "0")
8081 (set (attr "athlon_decode")
8082 (if_then_else (eq_attr "cpu" "athlon")
8083 (const_string "vector")
8084 (const_string "direct")))
8085 (set_attr "amdfam10_decode" "direct")
8086 (set_attr "mode" "QI")])
8088 (define_expand "umulqihi3"
8089 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8090 (mult:HI (zero_extend:HI
8091 (match_operand:QI 1 "nonimmediate_operand" ""))
8093 (match_operand:QI 2 "register_operand" ""))))
8094 (clobber (reg:CC FLAGS_REG))])]
8095 "TARGET_QIMODE_MATH"
8098 (define_insn "*umulqihi3_1"
8099 [(set (match_operand:HI 0 "register_operand" "=a")
8100 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8101 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8102 (clobber (reg:CC FLAGS_REG))]
8104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8106 [(set_attr "type" "imul")
8107 (set_attr "length_immediate" "0")
8108 (set (attr "athlon_decode")
8109 (if_then_else (eq_attr "cpu" "athlon")
8110 (const_string "vector")
8111 (const_string "direct")))
8112 (set_attr "amdfam10_decode" "direct")
8113 (set_attr "mode" "QI")])
8115 (define_expand "mulqihi3"
8116 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8117 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8118 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8119 (clobber (reg:CC FLAGS_REG))])]
8120 "TARGET_QIMODE_MATH"
8123 (define_insn "*mulqihi3_insn"
8124 [(set (match_operand:HI 0 "register_operand" "=a")
8125 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8126 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8127 (clobber (reg:CC FLAGS_REG))]
8129 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8131 [(set_attr "type" "imul")
8132 (set_attr "length_immediate" "0")
8133 (set (attr "athlon_decode")
8134 (if_then_else (eq_attr "cpu" "athlon")
8135 (const_string "vector")
8136 (const_string "direct")))
8137 (set_attr "amdfam10_decode" "direct")
8138 (set_attr "mode" "QI")])
8140 (define_expand "umulditi3"
8141 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8142 (mult:TI (zero_extend:TI
8143 (match_operand:DI 1 "nonimmediate_operand" ""))
8145 (match_operand:DI 2 "register_operand" ""))))
8146 (clobber (reg:CC FLAGS_REG))])]
8150 (define_insn "*umulditi3_insn"
8151 [(set (match_operand:TI 0 "register_operand" "=A")
8152 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8153 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8154 (clobber (reg:CC FLAGS_REG))]
8156 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8158 [(set_attr "type" "imul")
8159 (set_attr "length_immediate" "0")
8160 (set (attr "athlon_decode")
8161 (if_then_else (eq_attr "cpu" "athlon")
8162 (const_string "vector")
8163 (const_string "double")))
8164 (set_attr "amdfam10_decode" "double")
8165 (set_attr "mode" "DI")])
8167 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8168 (define_expand "umulsidi3"
8169 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8170 (mult:DI (zero_extend:DI
8171 (match_operand:SI 1 "nonimmediate_operand" ""))
8173 (match_operand:SI 2 "register_operand" ""))))
8174 (clobber (reg:CC FLAGS_REG))])]
8178 (define_insn "*umulsidi3_insn"
8179 [(set (match_operand:DI 0 "register_operand" "=A")
8180 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8181 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8182 (clobber (reg:CC FLAGS_REG))]
8184 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8186 [(set_attr "type" "imul")
8187 (set_attr "length_immediate" "0")
8188 (set (attr "athlon_decode")
8189 (if_then_else (eq_attr "cpu" "athlon")
8190 (const_string "vector")
8191 (const_string "double")))
8192 (set_attr "amdfam10_decode" "double")
8193 (set_attr "mode" "SI")])
8195 (define_expand "mulditi3"
8196 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8197 (mult:TI (sign_extend:TI
8198 (match_operand:DI 1 "nonimmediate_operand" ""))
8200 (match_operand:DI 2 "register_operand" ""))))
8201 (clobber (reg:CC FLAGS_REG))])]
8205 (define_insn "*mulditi3_insn"
8206 [(set (match_operand:TI 0 "register_operand" "=A")
8207 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8208 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8209 (clobber (reg:CC FLAGS_REG))]
8211 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8213 [(set_attr "type" "imul")
8214 (set_attr "length_immediate" "0")
8215 (set (attr "athlon_decode")
8216 (if_then_else (eq_attr "cpu" "athlon")
8217 (const_string "vector")
8218 (const_string "double")))
8219 (set_attr "amdfam10_decode" "double")
8220 (set_attr "mode" "DI")])
8222 (define_expand "mulsidi3"
8223 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8224 (mult:DI (sign_extend:DI
8225 (match_operand:SI 1 "nonimmediate_operand" ""))
8227 (match_operand:SI 2 "register_operand" ""))))
8228 (clobber (reg:CC FLAGS_REG))])]
8232 (define_insn "*mulsidi3_insn"
8233 [(set (match_operand:DI 0 "register_operand" "=A")
8234 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8235 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8236 (clobber (reg:CC FLAGS_REG))]
8238 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8240 [(set_attr "type" "imul")
8241 (set_attr "length_immediate" "0")
8242 (set (attr "athlon_decode")
8243 (if_then_else (eq_attr "cpu" "athlon")
8244 (const_string "vector")
8245 (const_string "double")))
8246 (set_attr "amdfam10_decode" "double")
8247 (set_attr "mode" "SI")])
8249 (define_expand "umuldi3_highpart"
8250 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8253 (mult:TI (zero_extend:TI
8254 (match_operand:DI 1 "nonimmediate_operand" ""))
8256 (match_operand:DI 2 "register_operand" "")))
8258 (clobber (match_scratch:DI 3 ""))
8259 (clobber (reg:CC FLAGS_REG))])]
8263 (define_insn "*umuldi3_highpart_rex64"
8264 [(set (match_operand:DI 0 "register_operand" "=d")
8267 (mult:TI (zero_extend:TI
8268 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8270 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8272 (clobber (match_scratch:DI 3 "=1"))
8273 (clobber (reg:CC FLAGS_REG))]
8275 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8277 [(set_attr "type" "imul")
8278 (set_attr "length_immediate" "0")
8279 (set (attr "athlon_decode")
8280 (if_then_else (eq_attr "cpu" "athlon")
8281 (const_string "vector")
8282 (const_string "double")))
8283 (set_attr "amdfam10_decode" "double")
8284 (set_attr "mode" "DI")])
8286 (define_expand "umulsi3_highpart"
8287 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8290 (mult:DI (zero_extend:DI
8291 (match_operand:SI 1 "nonimmediate_operand" ""))
8293 (match_operand:SI 2 "register_operand" "")))
8295 (clobber (match_scratch:SI 3 ""))
8296 (clobber (reg:CC FLAGS_REG))])]
8300 (define_insn "*umulsi3_highpart_insn"
8301 [(set (match_operand:SI 0 "register_operand" "=d")
8304 (mult:DI (zero_extend:DI
8305 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8307 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8309 (clobber (match_scratch:SI 3 "=1"))
8310 (clobber (reg:CC FLAGS_REG))]
8311 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8313 [(set_attr "type" "imul")
8314 (set_attr "length_immediate" "0")
8315 (set (attr "athlon_decode")
8316 (if_then_else (eq_attr "cpu" "athlon")
8317 (const_string "vector")
8318 (const_string "double")))
8319 (set_attr "amdfam10_decode" "double")
8320 (set_attr "mode" "SI")])
8322 (define_insn "*umulsi3_highpart_zext"
8323 [(set (match_operand:DI 0 "register_operand" "=d")
8324 (zero_extend:DI (truncate:SI
8326 (mult:DI (zero_extend:DI
8327 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8329 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8331 (clobber (match_scratch:SI 3 "=1"))
8332 (clobber (reg:CC FLAGS_REG))]
8334 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8336 [(set_attr "type" "imul")
8337 (set_attr "length_immediate" "0")
8338 (set (attr "athlon_decode")
8339 (if_then_else (eq_attr "cpu" "athlon")
8340 (const_string "vector")
8341 (const_string "double")))
8342 (set_attr "amdfam10_decode" "double")
8343 (set_attr "mode" "SI")])
8345 (define_expand "smuldi3_highpart"
8346 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8349 (mult:TI (sign_extend:TI
8350 (match_operand:DI 1 "nonimmediate_operand" ""))
8352 (match_operand:DI 2 "register_operand" "")))
8354 (clobber (match_scratch:DI 3 ""))
8355 (clobber (reg:CC FLAGS_REG))])]
8359 (define_insn "*smuldi3_highpart_rex64"
8360 [(set (match_operand:DI 0 "register_operand" "=d")
8363 (mult:TI (sign_extend:TI
8364 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8366 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8368 (clobber (match_scratch:DI 3 "=1"))
8369 (clobber (reg:CC FLAGS_REG))]
8371 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8373 [(set_attr "type" "imul")
8374 (set (attr "athlon_decode")
8375 (if_then_else (eq_attr "cpu" "athlon")
8376 (const_string "vector")
8377 (const_string "double")))
8378 (set_attr "amdfam10_decode" "double")
8379 (set_attr "mode" "DI")])
8381 (define_expand "smulsi3_highpart"
8382 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8385 (mult:DI (sign_extend:DI
8386 (match_operand:SI 1 "nonimmediate_operand" ""))
8388 (match_operand:SI 2 "register_operand" "")))
8390 (clobber (match_scratch:SI 3 ""))
8391 (clobber (reg:CC FLAGS_REG))])]
8395 (define_insn "*smulsi3_highpart_insn"
8396 [(set (match_operand:SI 0 "register_operand" "=d")
8399 (mult:DI (sign_extend:DI
8400 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8402 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8404 (clobber (match_scratch:SI 3 "=1"))
8405 (clobber (reg:CC FLAGS_REG))]
8406 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8408 [(set_attr "type" "imul")
8409 (set (attr "athlon_decode")
8410 (if_then_else (eq_attr "cpu" "athlon")
8411 (const_string "vector")
8412 (const_string "double")))
8413 (set_attr "amdfam10_decode" "double")
8414 (set_attr "mode" "SI")])
8416 (define_insn "*smulsi3_highpart_zext"
8417 [(set (match_operand:DI 0 "register_operand" "=d")
8418 (zero_extend:DI (truncate:SI
8420 (mult:DI (sign_extend:DI
8421 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8423 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8425 (clobber (match_scratch:SI 3 "=1"))
8426 (clobber (reg:CC FLAGS_REG))]
8428 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8430 [(set_attr "type" "imul")
8431 (set (attr "athlon_decode")
8432 (if_then_else (eq_attr "cpu" "athlon")
8433 (const_string "vector")
8434 (const_string "double")))
8435 (set_attr "amdfam10_decode" "double")
8436 (set_attr "mode" "SI")])
8438 ;; The patterns that match these are at the end of this file.
8440 (define_expand "mulxf3"
8441 [(set (match_operand:XF 0 "register_operand" "")
8442 (mult:XF (match_operand:XF 1 "register_operand" "")
8443 (match_operand:XF 2 "register_operand" "")))]
8447 (define_expand "mul<mode>3"
8448 [(set (match_operand:MODEF 0 "register_operand" "")
8449 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8450 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8451 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8452 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8455 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8458 ;; Divide instructions
8460 (define_insn "divqi3"
8461 [(set (match_operand:QI 0 "register_operand" "=a")
8462 (div:QI (match_operand:HI 1 "register_operand" "0")
8463 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8464 (clobber (reg:CC FLAGS_REG))]
8465 "TARGET_QIMODE_MATH"
8467 [(set_attr "type" "idiv")
8468 (set_attr "mode" "QI")])
8470 (define_insn "udivqi3"
8471 [(set (match_operand:QI 0 "register_operand" "=a")
8472 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8473 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8474 (clobber (reg:CC FLAGS_REG))]
8475 "TARGET_QIMODE_MATH"
8477 [(set_attr "type" "idiv")
8478 (set_attr "mode" "QI")])
8480 ;; The patterns that match these are at the end of this file.
8482 (define_expand "divxf3"
8483 [(set (match_operand:XF 0 "register_operand" "")
8484 (div:XF (match_operand:XF 1 "register_operand" "")
8485 (match_operand:XF 2 "register_operand" "")))]
8489 (define_expand "divdf3"
8490 [(set (match_operand:DF 0 "register_operand" "")
8491 (div:DF (match_operand:DF 1 "register_operand" "")
8492 (match_operand:DF 2 "nonimmediate_operand" "")))]
8493 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8494 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8497 (define_expand "divsf3"
8498 [(set (match_operand:SF 0 "register_operand" "")
8499 (div:SF (match_operand:SF 1 "register_operand" "")
8500 (match_operand:SF 2 "nonimmediate_operand" "")))]
8501 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8504 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8505 && flag_finite_math_only && !flag_trapping_math
8506 && flag_unsafe_math_optimizations)
8508 ix86_emit_swdivsf (operands[0], operands[1],
8509 operands[2], SFmode);
8514 ;; Remainder instructions.
8516 (define_expand "divmoddi4"
8517 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8518 (div:DI (match_operand:DI 1 "register_operand" "")
8519 (match_operand:DI 2 "nonimmediate_operand" "")))
8520 (set (match_operand:DI 3 "register_operand" "")
8521 (mod:DI (match_dup 1) (match_dup 2)))
8522 (clobber (reg:CC FLAGS_REG))])]
8526 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8527 ;; Penalize eax case slightly because it results in worse scheduling
8529 (define_insn "*divmoddi4_nocltd_rex64"
8530 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8531 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8532 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8533 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8534 (mod:DI (match_dup 2) (match_dup 3)))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8538 [(set_attr "type" "multi")])
8540 (define_insn "*divmoddi4_cltd_rex64"
8541 [(set (match_operand:DI 0 "register_operand" "=a")
8542 (div:DI (match_operand:DI 2 "register_operand" "a")
8543 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8544 (set (match_operand:DI 1 "register_operand" "=&d")
8545 (mod:DI (match_dup 2) (match_dup 3)))
8546 (clobber (reg:CC FLAGS_REG))]
8547 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8549 [(set_attr "type" "multi")])
8551 (define_insn "*divmoddi_noext_rex64"
8552 [(set (match_operand:DI 0 "register_operand" "=a")
8553 (div:DI (match_operand:DI 1 "register_operand" "0")
8554 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8555 (set (match_operand:DI 3 "register_operand" "=d")
8556 (mod:DI (match_dup 1) (match_dup 2)))
8557 (use (match_operand:DI 4 "register_operand" "3"))
8558 (clobber (reg:CC FLAGS_REG))]
8561 [(set_attr "type" "idiv")
8562 (set_attr "mode" "DI")])
8565 [(set (match_operand:DI 0 "register_operand" "")
8566 (div:DI (match_operand:DI 1 "register_operand" "")
8567 (match_operand:DI 2 "nonimmediate_operand" "")))
8568 (set (match_operand:DI 3 "register_operand" "")
8569 (mod:DI (match_dup 1) (match_dup 2)))
8570 (clobber (reg:CC FLAGS_REG))]
8571 "TARGET_64BIT && reload_completed"
8572 [(parallel [(set (match_dup 3)
8573 (ashiftrt:DI (match_dup 4) (const_int 63)))
8574 (clobber (reg:CC FLAGS_REG))])
8575 (parallel [(set (match_dup 0)
8576 (div:DI (reg:DI 0) (match_dup 2)))
8578 (mod:DI (reg:DI 0) (match_dup 2)))
8580 (clobber (reg:CC FLAGS_REG))])]
8582 /* Avoid use of cltd in favor of a mov+shift. */
8583 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8585 if (true_regnum (operands[1]))
8586 emit_move_insn (operands[0], operands[1]);
8588 emit_move_insn (operands[3], operands[1]);
8589 operands[4] = operands[3];
8593 gcc_assert (!true_regnum (operands[1]));
8594 operands[4] = operands[1];
8599 (define_expand "divmodsi4"
8600 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8601 (div:SI (match_operand:SI 1 "register_operand" "")
8602 (match_operand:SI 2 "nonimmediate_operand" "")))
8603 (set (match_operand:SI 3 "register_operand" "")
8604 (mod:SI (match_dup 1) (match_dup 2)))
8605 (clobber (reg:CC FLAGS_REG))])]
8609 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8610 ;; Penalize eax case slightly because it results in worse scheduling
8612 (define_insn "*divmodsi4_nocltd"
8613 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8614 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8615 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8616 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8617 (mod:SI (match_dup 2) (match_dup 3)))
8618 (clobber (reg:CC FLAGS_REG))]
8619 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8621 [(set_attr "type" "multi")])
8623 (define_insn "*divmodsi4_cltd"
8624 [(set (match_operand:SI 0 "register_operand" "=a")
8625 (div:SI (match_operand:SI 2 "register_operand" "a")
8626 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8627 (set (match_operand:SI 1 "register_operand" "=&d")
8628 (mod:SI (match_dup 2) (match_dup 3)))
8629 (clobber (reg:CC FLAGS_REG))]
8630 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8632 [(set_attr "type" "multi")])
8634 (define_insn "*divmodsi_noext"
8635 [(set (match_operand:SI 0 "register_operand" "=a")
8636 (div:SI (match_operand:SI 1 "register_operand" "0")
8637 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8638 (set (match_operand:SI 3 "register_operand" "=d")
8639 (mod:SI (match_dup 1) (match_dup 2)))
8640 (use (match_operand:SI 4 "register_operand" "3"))
8641 (clobber (reg:CC FLAGS_REG))]
8644 [(set_attr "type" "idiv")
8645 (set_attr "mode" "SI")])
8648 [(set (match_operand:SI 0 "register_operand" "")
8649 (div:SI (match_operand:SI 1 "register_operand" "")
8650 (match_operand:SI 2 "nonimmediate_operand" "")))
8651 (set (match_operand:SI 3 "register_operand" "")
8652 (mod:SI (match_dup 1) (match_dup 2)))
8653 (clobber (reg:CC FLAGS_REG))]
8655 [(parallel [(set (match_dup 3)
8656 (ashiftrt:SI (match_dup 4) (const_int 31)))
8657 (clobber (reg:CC FLAGS_REG))])
8658 (parallel [(set (match_dup 0)
8659 (div:SI (reg:SI 0) (match_dup 2)))
8661 (mod:SI (reg:SI 0) (match_dup 2)))
8663 (clobber (reg:CC FLAGS_REG))])]
8665 /* Avoid use of cltd in favor of a mov+shift. */
8666 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8668 if (true_regnum (operands[1]))
8669 emit_move_insn (operands[0], operands[1]);
8671 emit_move_insn (operands[3], operands[1]);
8672 operands[4] = operands[3];
8676 gcc_assert (!true_regnum (operands[1]));
8677 operands[4] = operands[1];
8681 (define_insn "divmodhi4"
8682 [(set (match_operand:HI 0 "register_operand" "=a")
8683 (div:HI (match_operand:HI 1 "register_operand" "0")
8684 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8685 (set (match_operand:HI 3 "register_operand" "=&d")
8686 (mod:HI (match_dup 1) (match_dup 2)))
8687 (clobber (reg:CC FLAGS_REG))]
8688 "TARGET_HIMODE_MATH"
8690 [(set_attr "type" "multi")
8691 (set_attr "length_immediate" "0")
8692 (set_attr "mode" "SI")])
8694 (define_insn "udivmoddi4"
8695 [(set (match_operand:DI 0 "register_operand" "=a")
8696 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8697 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8698 (set (match_operand:DI 3 "register_operand" "=&d")
8699 (umod:DI (match_dup 1) (match_dup 2)))
8700 (clobber (reg:CC FLAGS_REG))]
8702 "xor{q}\t%3, %3\;div{q}\t%2"
8703 [(set_attr "type" "multi")
8704 (set_attr "length_immediate" "0")
8705 (set_attr "mode" "DI")])
8707 (define_insn "*udivmoddi4_noext"
8708 [(set (match_operand:DI 0 "register_operand" "=a")
8709 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8710 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8711 (set (match_operand:DI 3 "register_operand" "=d")
8712 (umod:DI (match_dup 1) (match_dup 2)))
8714 (clobber (reg:CC FLAGS_REG))]
8717 [(set_attr "type" "idiv")
8718 (set_attr "mode" "DI")])
8721 [(set (match_operand:DI 0 "register_operand" "")
8722 (udiv:DI (match_operand:DI 1 "register_operand" "")
8723 (match_operand:DI 2 "nonimmediate_operand" "")))
8724 (set (match_operand:DI 3 "register_operand" "")
8725 (umod:DI (match_dup 1) (match_dup 2)))
8726 (clobber (reg:CC FLAGS_REG))]
8727 "TARGET_64BIT && reload_completed"
8728 [(set (match_dup 3) (const_int 0))
8729 (parallel [(set (match_dup 0)
8730 (udiv:DI (match_dup 1) (match_dup 2)))
8732 (umod:DI (match_dup 1) (match_dup 2)))
8734 (clobber (reg:CC FLAGS_REG))])]
8737 (define_insn "udivmodsi4"
8738 [(set (match_operand:SI 0 "register_operand" "=a")
8739 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8740 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8741 (set (match_operand:SI 3 "register_operand" "=&d")
8742 (umod:SI (match_dup 1) (match_dup 2)))
8743 (clobber (reg:CC FLAGS_REG))]
8745 "xor{l}\t%3, %3\;div{l}\t%2"
8746 [(set_attr "type" "multi")
8747 (set_attr "length_immediate" "0")
8748 (set_attr "mode" "SI")])
8750 (define_insn "*udivmodsi4_noext"
8751 [(set (match_operand:SI 0 "register_operand" "=a")
8752 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8753 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8754 (set (match_operand:SI 3 "register_operand" "=d")
8755 (umod:SI (match_dup 1) (match_dup 2)))
8757 (clobber (reg:CC FLAGS_REG))]
8760 [(set_attr "type" "idiv")
8761 (set_attr "mode" "SI")])
8764 [(set (match_operand:SI 0 "register_operand" "")
8765 (udiv:SI (match_operand:SI 1 "register_operand" "")
8766 (match_operand:SI 2 "nonimmediate_operand" "")))
8767 (set (match_operand:SI 3 "register_operand" "")
8768 (umod:SI (match_dup 1) (match_dup 2)))
8769 (clobber (reg:CC FLAGS_REG))]
8771 [(set (match_dup 3) (const_int 0))
8772 (parallel [(set (match_dup 0)
8773 (udiv:SI (match_dup 1) (match_dup 2)))
8775 (umod:SI (match_dup 1) (match_dup 2)))
8777 (clobber (reg:CC FLAGS_REG))])]
8780 (define_expand "udivmodhi4"
8781 [(set (match_dup 4) (const_int 0))
8782 (parallel [(set (match_operand:HI 0 "register_operand" "")
8783 (udiv:HI (match_operand:HI 1 "register_operand" "")
8784 (match_operand:HI 2 "nonimmediate_operand" "")))
8785 (set (match_operand:HI 3 "register_operand" "")
8786 (umod:HI (match_dup 1) (match_dup 2)))
8788 (clobber (reg:CC FLAGS_REG))])]
8789 "TARGET_HIMODE_MATH"
8790 "operands[4] = gen_reg_rtx (HImode);")
8792 (define_insn "*udivmodhi_noext"
8793 [(set (match_operand:HI 0 "register_operand" "=a")
8794 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8795 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8796 (set (match_operand:HI 3 "register_operand" "=d")
8797 (umod:HI (match_dup 1) (match_dup 2)))
8798 (use (match_operand:HI 4 "register_operand" "3"))
8799 (clobber (reg:CC FLAGS_REG))]
8802 [(set_attr "type" "idiv")
8803 (set_attr "mode" "HI")])
8805 ;; We cannot use div/idiv for double division, because it causes
8806 ;; "division by zero" on the overflow and that's not what we expect
8807 ;; from truncate. Because true (non truncating) double division is
8808 ;; never generated, we can't create this insn anyway.
8811 ; [(set (match_operand:SI 0 "register_operand" "=a")
8813 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8815 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8816 ; (set (match_operand:SI 3 "register_operand" "=d")
8818 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8819 ; (clobber (reg:CC FLAGS_REG))]
8821 ; "div{l}\t{%2, %0|%0, %2}"
8822 ; [(set_attr "type" "idiv")])
8824 ;;- Logical AND instructions
8826 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8827 ;; Note that this excludes ah.
8829 (define_insn "*testdi_1_rex64"
8830 [(set (reg FLAGS_REG)
8832 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8833 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8835 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8836 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8838 test{l}\t{%k1, %k0|%k0, %k1}
8839 test{l}\t{%k1, %k0|%k0, %k1}
8840 test{q}\t{%1, %0|%0, %1}
8841 test{q}\t{%1, %0|%0, %1}
8842 test{q}\t{%1, %0|%0, %1}"
8843 [(set_attr "type" "test")
8844 (set_attr "modrm" "0,1,0,1,1")
8845 (set_attr "mode" "SI,SI,DI,DI,DI")
8846 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8848 (define_insn "testsi_1"
8849 [(set (reg FLAGS_REG)
8851 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8852 (match_operand:SI 1 "general_operand" "i,i,ri"))
8854 "ix86_match_ccmode (insn, CCNOmode)
8855 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8856 "test{l}\t{%1, %0|%0, %1}"
8857 [(set_attr "type" "test")
8858 (set_attr "modrm" "0,1,1")
8859 (set_attr "mode" "SI")
8860 (set_attr "pent_pair" "uv,np,uv")])
8862 (define_expand "testsi_ccno_1"
8863 [(set (reg:CCNO FLAGS_REG)
8865 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8866 (match_operand:SI 1 "nonmemory_operand" ""))
8871 (define_insn "*testhi_1"
8872 [(set (reg FLAGS_REG)
8873 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8874 (match_operand:HI 1 "general_operand" "n,n,rn"))
8876 "ix86_match_ccmode (insn, CCNOmode)
8877 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8878 "test{w}\t{%1, %0|%0, %1}"
8879 [(set_attr "type" "test")
8880 (set_attr "modrm" "0,1,1")
8881 (set_attr "mode" "HI")
8882 (set_attr "pent_pair" "uv,np,uv")])
8884 (define_expand "testqi_ccz_1"
8885 [(set (reg:CCZ FLAGS_REG)
8886 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8887 (match_operand:QI 1 "nonmemory_operand" ""))
8892 (define_insn "*testqi_1_maybe_si"
8893 [(set (reg FLAGS_REG)
8896 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8897 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8899 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8900 && ix86_match_ccmode (insn,
8901 CONST_INT_P (operands[1])
8902 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8904 if (which_alternative == 3)
8906 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8907 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8908 return "test{l}\t{%1, %k0|%k0, %1}";
8910 return "test{b}\t{%1, %0|%0, %1}";
8912 [(set_attr "type" "test")
8913 (set_attr "modrm" "0,1,1,1")
8914 (set_attr "mode" "QI,QI,QI,SI")
8915 (set_attr "pent_pair" "uv,np,uv,np")])
8917 (define_insn "*testqi_1"
8918 [(set (reg FLAGS_REG)
8921 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8922 (match_operand:QI 1 "general_operand" "n,n,qn"))
8924 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8925 && ix86_match_ccmode (insn, CCNOmode)"
8926 "test{b}\t{%1, %0|%0, %1}"
8927 [(set_attr "type" "test")
8928 (set_attr "modrm" "0,1,1")
8929 (set_attr "mode" "QI")
8930 (set_attr "pent_pair" "uv,np,uv")])
8932 (define_expand "testqi_ext_ccno_0"
8933 [(set (reg:CCNO FLAGS_REG)
8937 (match_operand 0 "ext_register_operand" "")
8940 (match_operand 1 "const_int_operand" ""))
8945 (define_insn "*testqi_ext_0"
8946 [(set (reg FLAGS_REG)
8950 (match_operand 0 "ext_register_operand" "Q")
8953 (match_operand 1 "const_int_operand" "n"))
8955 "ix86_match_ccmode (insn, CCNOmode)"
8956 "test{b}\t{%1, %h0|%h0, %1}"
8957 [(set_attr "type" "test")
8958 (set_attr "mode" "QI")
8959 (set_attr "length_immediate" "1")
8960 (set_attr "pent_pair" "np")])
8962 (define_insn "*testqi_ext_1"
8963 [(set (reg FLAGS_REG)
8967 (match_operand 0 "ext_register_operand" "Q")
8971 (match_operand:QI 1 "general_operand" "Qm")))
8973 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8974 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8975 "test{b}\t{%1, %h0|%h0, %1}"
8976 [(set_attr "type" "test")
8977 (set_attr "mode" "QI")])
8979 (define_insn "*testqi_ext_1_rex64"
8980 [(set (reg FLAGS_REG)
8984 (match_operand 0 "ext_register_operand" "Q")
8988 (match_operand:QI 1 "register_operand" "Q")))
8990 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8991 "test{b}\t{%1, %h0|%h0, %1}"
8992 [(set_attr "type" "test")
8993 (set_attr "mode" "QI")])
8995 (define_insn "*testqi_ext_2"
8996 [(set (reg FLAGS_REG)
9000 (match_operand 0 "ext_register_operand" "Q")
9004 (match_operand 1 "ext_register_operand" "Q")
9008 "ix86_match_ccmode (insn, CCNOmode)"
9009 "test{b}\t{%h1, %h0|%h0, %h1}"
9010 [(set_attr "type" "test")
9011 (set_attr "mode" "QI")])
9013 ;; Combine likes to form bit extractions for some tests. Humor it.
9014 (define_insn "*testqi_ext_3"
9015 [(set (reg FLAGS_REG)
9016 (compare (zero_extract:SI
9017 (match_operand 0 "nonimmediate_operand" "rm")
9018 (match_operand:SI 1 "const_int_operand" "")
9019 (match_operand:SI 2 "const_int_operand" ""))
9021 "ix86_match_ccmode (insn, CCNOmode)
9022 && INTVAL (operands[1]) > 0
9023 && INTVAL (operands[2]) >= 0
9024 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9025 && (GET_MODE (operands[0]) == SImode
9026 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9027 || GET_MODE (operands[0]) == HImode
9028 || GET_MODE (operands[0]) == QImode)"
9031 (define_insn "*testqi_ext_3_rex64"
9032 [(set (reg FLAGS_REG)
9033 (compare (zero_extract:DI
9034 (match_operand 0 "nonimmediate_operand" "rm")
9035 (match_operand:DI 1 "const_int_operand" "")
9036 (match_operand:DI 2 "const_int_operand" ""))
9039 && ix86_match_ccmode (insn, CCNOmode)
9040 && INTVAL (operands[1]) > 0
9041 && INTVAL (operands[2]) >= 0
9042 /* Ensure that resulting mask is zero or sign extended operand. */
9043 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9044 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9045 && INTVAL (operands[1]) > 32))
9046 && (GET_MODE (operands[0]) == SImode
9047 || GET_MODE (operands[0]) == DImode
9048 || GET_MODE (operands[0]) == HImode
9049 || GET_MODE (operands[0]) == QImode)"
9053 [(set (match_operand 0 "flags_reg_operand" "")
9054 (match_operator 1 "compare_operator"
9056 (match_operand 2 "nonimmediate_operand" "")
9057 (match_operand 3 "const_int_operand" "")
9058 (match_operand 4 "const_int_operand" ""))
9060 "ix86_match_ccmode (insn, CCNOmode)"
9061 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9063 rtx val = operands[2];
9064 HOST_WIDE_INT len = INTVAL (operands[3]);
9065 HOST_WIDE_INT pos = INTVAL (operands[4]);
9067 enum machine_mode mode, submode;
9069 mode = GET_MODE (val);
9072 /* ??? Combine likes to put non-volatile mem extractions in QImode
9073 no matter the size of the test. So find a mode that works. */
9074 if (! MEM_VOLATILE_P (val))
9076 mode = smallest_mode_for_size (pos + len, MODE_INT);
9077 val = adjust_address (val, mode, 0);
9080 else if (GET_CODE (val) == SUBREG
9081 && (submode = GET_MODE (SUBREG_REG (val)),
9082 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9083 && pos + len <= GET_MODE_BITSIZE (submode))
9085 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9087 val = SUBREG_REG (val);
9089 else if (mode == HImode && pos + len <= 8)
9091 /* Small HImode tests can be converted to QImode. */
9093 val = gen_lowpart (QImode, val);
9096 if (len == HOST_BITS_PER_WIDE_INT)
9099 mask = ((HOST_WIDE_INT)1 << len) - 1;
9102 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9105 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9106 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9107 ;; this is relatively important trick.
9108 ;; Do the conversion only post-reload to avoid limiting of the register class
9111 [(set (match_operand 0 "flags_reg_operand" "")
9112 (match_operator 1 "compare_operator"
9113 [(and (match_operand 2 "register_operand" "")
9114 (match_operand 3 "const_int_operand" ""))
9117 && QI_REG_P (operands[2])
9118 && GET_MODE (operands[2]) != QImode
9119 && ((ix86_match_ccmode (insn, CCZmode)
9120 && !(INTVAL (operands[3]) & ~(255 << 8)))
9121 || (ix86_match_ccmode (insn, CCNOmode)
9122 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9125 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9128 "operands[2] = gen_lowpart (SImode, operands[2]);
9129 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9132 [(set (match_operand 0 "flags_reg_operand" "")
9133 (match_operator 1 "compare_operator"
9134 [(and (match_operand 2 "nonimmediate_operand" "")
9135 (match_operand 3 "const_int_operand" ""))
9138 && GET_MODE (operands[2]) != QImode
9139 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9140 && ((ix86_match_ccmode (insn, CCZmode)
9141 && !(INTVAL (operands[3]) & ~255))
9142 || (ix86_match_ccmode (insn, CCNOmode)
9143 && !(INTVAL (operands[3]) & ~127)))"
9145 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9147 "operands[2] = gen_lowpart (QImode, operands[2]);
9148 operands[3] = gen_lowpart (QImode, operands[3]);")
9151 ;; %%% This used to optimize known byte-wide and operations to memory,
9152 ;; and sometimes to QImode registers. If this is considered useful,
9153 ;; it should be done with splitters.
9155 (define_expand "anddi3"
9156 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9157 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9158 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9160 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9162 (define_insn "*anddi_1_rex64"
9163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9164 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9165 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9166 (clobber (reg:CC FLAGS_REG))]
9167 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9169 switch (get_attr_type (insn))
9173 enum machine_mode mode;
9175 gcc_assert (CONST_INT_P (operands[2]));
9176 if (INTVAL (operands[2]) == 0xff)
9180 gcc_assert (INTVAL (operands[2]) == 0xffff);
9184 operands[1] = gen_lowpart (mode, operands[1]);
9186 return "movz{bq|x}\t{%1,%0|%0, %1}";
9188 return "movz{wq|x}\t{%1,%0|%0, %1}";
9192 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9193 if (get_attr_mode (insn) == MODE_SI)
9194 return "and{l}\t{%k2, %k0|%k0, %k2}";
9196 return "and{q}\t{%2, %0|%0, %2}";
9199 [(set_attr "type" "alu,alu,alu,imovx")
9200 (set_attr "length_immediate" "*,*,*,0")
9201 (set_attr "mode" "SI,DI,DI,DI")])
9203 (define_insn "*anddi_2"
9204 [(set (reg FLAGS_REG)
9205 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9206 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9208 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9209 (and:DI (match_dup 1) (match_dup 2)))]
9210 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9211 && ix86_binary_operator_ok (AND, DImode, operands)"
9213 and{l}\t{%k2, %k0|%k0, %k2}
9214 and{q}\t{%2, %0|%0, %2}
9215 and{q}\t{%2, %0|%0, %2}"
9216 [(set_attr "type" "alu")
9217 (set_attr "mode" "SI,DI,DI")])
9219 (define_expand "andsi3"
9220 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9221 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9222 (match_operand:SI 2 "general_operand" "")))]
9224 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9226 (define_insn "*andsi_1"
9227 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9228 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9229 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9230 (clobber (reg:CC FLAGS_REG))]
9231 "ix86_binary_operator_ok (AND, SImode, operands)"
9233 switch (get_attr_type (insn))
9237 enum machine_mode mode;
9239 gcc_assert (CONST_INT_P (operands[2]));
9240 if (INTVAL (operands[2]) == 0xff)
9244 gcc_assert (INTVAL (operands[2]) == 0xffff);
9248 operands[1] = gen_lowpart (mode, operands[1]);
9250 return "movz{bl|x}\t{%1,%0|%0, %1}";
9252 return "movz{wl|x}\t{%1,%0|%0, %1}";
9256 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9257 return "and{l}\t{%2, %0|%0, %2}";
9260 [(set_attr "type" "alu,alu,imovx")
9261 (set_attr "length_immediate" "*,*,0")
9262 (set_attr "mode" "SI")])
9265 [(set (match_operand 0 "register_operand" "")
9267 (const_int -65536)))
9268 (clobber (reg:CC FLAGS_REG))]
9269 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9270 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9271 "operands[1] = gen_lowpart (HImode, operands[0]);")
9274 [(set (match_operand 0 "ext_register_operand" "")
9277 (clobber (reg:CC FLAGS_REG))]
9278 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9279 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9280 "operands[1] = gen_lowpart (QImode, operands[0]);")
9283 [(set (match_operand 0 "ext_register_operand" "")
9285 (const_int -65281)))
9286 (clobber (reg:CC FLAGS_REG))]
9287 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9288 [(parallel [(set (zero_extract:SI (match_dup 0)
9292 (zero_extract:SI (match_dup 0)
9295 (zero_extract:SI (match_dup 0)
9298 (clobber (reg:CC FLAGS_REG))])]
9299 "operands[0] = gen_lowpart (SImode, operands[0]);")
9301 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9302 (define_insn "*andsi_1_zext"
9303 [(set (match_operand:DI 0 "register_operand" "=r")
9305 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9306 (match_operand:SI 2 "general_operand" "g"))))
9307 (clobber (reg:CC FLAGS_REG))]
9308 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9309 "and{l}\t{%2, %k0|%k0, %2}"
9310 [(set_attr "type" "alu")
9311 (set_attr "mode" "SI")])
9313 (define_insn "*andsi_2"
9314 [(set (reg FLAGS_REG)
9315 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9316 (match_operand:SI 2 "general_operand" "g,ri"))
9318 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9319 (and:SI (match_dup 1) (match_dup 2)))]
9320 "ix86_match_ccmode (insn, CCNOmode)
9321 && ix86_binary_operator_ok (AND, SImode, operands)"
9322 "and{l}\t{%2, %0|%0, %2}"
9323 [(set_attr "type" "alu")
9324 (set_attr "mode" "SI")])
9326 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9327 (define_insn "*andsi_2_zext"
9328 [(set (reg FLAGS_REG)
9329 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9330 (match_operand:SI 2 "general_operand" "g"))
9332 (set (match_operand:DI 0 "register_operand" "=r")
9333 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9334 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9335 && ix86_binary_operator_ok (AND, SImode, operands)"
9336 "and{l}\t{%2, %k0|%k0, %2}"
9337 [(set_attr "type" "alu")
9338 (set_attr "mode" "SI")])
9340 (define_expand "andhi3"
9341 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9342 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9343 (match_operand:HI 2 "general_operand" "")))]
9344 "TARGET_HIMODE_MATH"
9345 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9347 (define_insn "*andhi_1"
9348 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9349 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9350 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9351 (clobber (reg:CC FLAGS_REG))]
9352 "ix86_binary_operator_ok (AND, HImode, operands)"
9354 switch (get_attr_type (insn))
9357 gcc_assert (CONST_INT_P (operands[2]));
9358 gcc_assert (INTVAL (operands[2]) == 0xff);
9359 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9362 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9364 return "and{w}\t{%2, %0|%0, %2}";
9367 [(set_attr "type" "alu,alu,imovx")
9368 (set_attr "length_immediate" "*,*,0")
9369 (set_attr "mode" "HI,HI,SI")])
9371 (define_insn "*andhi_2"
9372 [(set (reg FLAGS_REG)
9373 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9374 (match_operand:HI 2 "general_operand" "rmn,rn"))
9376 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9377 (and:HI (match_dup 1) (match_dup 2)))]
9378 "ix86_match_ccmode (insn, CCNOmode)
9379 && ix86_binary_operator_ok (AND, HImode, operands)"
9380 "and{w}\t{%2, %0|%0, %2}"
9381 [(set_attr "type" "alu")
9382 (set_attr "mode" "HI")])
9384 (define_expand "andqi3"
9385 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9386 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9387 (match_operand:QI 2 "general_operand" "")))]
9388 "TARGET_QIMODE_MATH"
9389 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9391 ;; %%% Potential partial reg stall on alternative 2. What to do?
9392 (define_insn "*andqi_1"
9393 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9394 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9395 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9396 (clobber (reg:CC FLAGS_REG))]
9397 "ix86_binary_operator_ok (AND, QImode, operands)"
9399 and{b}\t{%2, %0|%0, %2}
9400 and{b}\t{%2, %0|%0, %2}
9401 and{l}\t{%k2, %k0|%k0, %k2}"
9402 [(set_attr "type" "alu")
9403 (set_attr "mode" "QI,QI,SI")])
9405 (define_insn "*andqi_1_slp"
9406 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9407 (and:QI (match_dup 0)
9408 (match_operand:QI 1 "general_operand" "qn,qmn")))
9409 (clobber (reg:CC FLAGS_REG))]
9410 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9411 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9412 "and{b}\t{%1, %0|%0, %1}"
9413 [(set_attr "type" "alu1")
9414 (set_attr "mode" "QI")])
9416 (define_insn "*andqi_2_maybe_si"
9417 [(set (reg FLAGS_REG)
9419 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9420 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9422 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9423 (and:QI (match_dup 1) (match_dup 2)))]
9424 "ix86_binary_operator_ok (AND, QImode, operands)
9425 && ix86_match_ccmode (insn,
9426 CONST_INT_P (operands[2])
9427 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9429 if (which_alternative == 2)
9431 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9432 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9433 return "and{l}\t{%2, %k0|%k0, %2}";
9435 return "and{b}\t{%2, %0|%0, %2}";
9437 [(set_attr "type" "alu")
9438 (set_attr "mode" "QI,QI,SI")])
9440 (define_insn "*andqi_2"
9441 [(set (reg FLAGS_REG)
9443 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9444 (match_operand:QI 2 "general_operand" "qmn,qn"))
9446 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9447 (and:QI (match_dup 1) (match_dup 2)))]
9448 "ix86_match_ccmode (insn, CCNOmode)
9449 && ix86_binary_operator_ok (AND, QImode, operands)"
9450 "and{b}\t{%2, %0|%0, %2}"
9451 [(set_attr "type" "alu")
9452 (set_attr "mode" "QI")])
9454 (define_insn "*andqi_2_slp"
9455 [(set (reg FLAGS_REG)
9457 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9458 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9460 (set (strict_low_part (match_dup 0))
9461 (and:QI (match_dup 0) (match_dup 1)))]
9462 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9463 && ix86_match_ccmode (insn, CCNOmode)
9464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9465 "and{b}\t{%1, %0|%0, %1}"
9466 [(set_attr "type" "alu1")
9467 (set_attr "mode" "QI")])
9469 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9470 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9471 ;; for a QImode operand, which of course failed.
9473 (define_insn "andqi_ext_0"
9474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9479 (match_operand 1 "ext_register_operand" "0")
9482 (match_operand 2 "const_int_operand" "n")))
9483 (clobber (reg:CC FLAGS_REG))]
9485 "and{b}\t{%2, %h0|%h0, %2}"
9486 [(set_attr "type" "alu")
9487 (set_attr "length_immediate" "1")
9488 (set_attr "mode" "QI")])
9490 ;; Generated by peephole translating test to and. This shows up
9491 ;; often in fp comparisons.
9493 (define_insn "*andqi_ext_0_cc"
9494 [(set (reg FLAGS_REG)
9498 (match_operand 1 "ext_register_operand" "0")
9501 (match_operand 2 "const_int_operand" "n"))
9503 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9512 "ix86_match_ccmode (insn, CCNOmode)"
9513 "and{b}\t{%2, %h0|%h0, %2}"
9514 [(set_attr "type" "alu")
9515 (set_attr "length_immediate" "1")
9516 (set_attr "mode" "QI")])
9518 (define_insn "*andqi_ext_1"
9519 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9524 (match_operand 1 "ext_register_operand" "0")
9528 (match_operand:QI 2 "general_operand" "Qm"))))
9529 (clobber (reg:CC FLAGS_REG))]
9531 "and{b}\t{%2, %h0|%h0, %2}"
9532 [(set_attr "type" "alu")
9533 (set_attr "length_immediate" "0")
9534 (set_attr "mode" "QI")])
9536 (define_insn "*andqi_ext_1_rex64"
9537 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9542 (match_operand 1 "ext_register_operand" "0")
9546 (match_operand 2 "ext_register_operand" "Q"))))
9547 (clobber (reg:CC FLAGS_REG))]
9549 "and{b}\t{%2, %h0|%h0, %2}"
9550 [(set_attr "type" "alu")
9551 (set_attr "length_immediate" "0")
9552 (set_attr "mode" "QI")])
9554 (define_insn "*andqi_ext_2"
9555 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9560 (match_operand 1 "ext_register_operand" "%0")
9564 (match_operand 2 "ext_register_operand" "Q")
9567 (clobber (reg:CC FLAGS_REG))]
9569 "and{b}\t{%h2, %h0|%h0, %h2}"
9570 [(set_attr "type" "alu")
9571 (set_attr "length_immediate" "0")
9572 (set_attr "mode" "QI")])
9574 ;; Convert wide AND instructions with immediate operand to shorter QImode
9575 ;; equivalents when possible.
9576 ;; Don't do the splitting with memory operands, since it introduces risk
9577 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9578 ;; for size, but that can (should?) be handled by generic code instead.
9580 [(set (match_operand 0 "register_operand" "")
9581 (and (match_operand 1 "register_operand" "")
9582 (match_operand 2 "const_int_operand" "")))
9583 (clobber (reg:CC FLAGS_REG))]
9585 && QI_REG_P (operands[0])
9586 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9587 && !(~INTVAL (operands[2]) & ~(255 << 8))
9588 && GET_MODE (operands[0]) != QImode"
9589 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9590 (and:SI (zero_extract:SI (match_dup 1)
9591 (const_int 8) (const_int 8))
9593 (clobber (reg:CC FLAGS_REG))])]
9594 "operands[0] = gen_lowpart (SImode, operands[0]);
9595 operands[1] = gen_lowpart (SImode, operands[1]);
9596 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9598 ;; Since AND can be encoded with sign extended immediate, this is only
9599 ;; profitable when 7th bit is not set.
9601 [(set (match_operand 0 "register_operand" "")
9602 (and (match_operand 1 "general_operand" "")
9603 (match_operand 2 "const_int_operand" "")))
9604 (clobber (reg:CC FLAGS_REG))]
9606 && ANY_QI_REG_P (operands[0])
9607 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9608 && !(~INTVAL (operands[2]) & ~255)
9609 && !(INTVAL (operands[2]) & 128)
9610 && GET_MODE (operands[0]) != QImode"
9611 [(parallel [(set (strict_low_part (match_dup 0))
9612 (and:QI (match_dup 1)
9614 (clobber (reg:CC FLAGS_REG))])]
9615 "operands[0] = gen_lowpart (QImode, operands[0]);
9616 operands[1] = gen_lowpart (QImode, operands[1]);
9617 operands[2] = gen_lowpart (QImode, operands[2]);")
9619 ;; Logical inclusive OR instructions
9621 ;; %%% This used to optimize known byte-wide and operations to memory.
9622 ;; If this is considered useful, it should be done with splitters.
9624 (define_expand "iordi3"
9625 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9626 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9627 (match_operand:DI 2 "x86_64_general_operand" "")))]
9629 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9631 (define_insn "*iordi_1_rex64"
9632 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9633 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9634 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9635 (clobber (reg:CC FLAGS_REG))]
9637 && ix86_binary_operator_ok (IOR, DImode, operands)"
9638 "or{q}\t{%2, %0|%0, %2}"
9639 [(set_attr "type" "alu")
9640 (set_attr "mode" "DI")])
9642 (define_insn "*iordi_2_rex64"
9643 [(set (reg FLAGS_REG)
9644 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9645 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9647 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9648 (ior:DI (match_dup 1) (match_dup 2)))]
9650 && ix86_match_ccmode (insn, CCNOmode)
9651 && ix86_binary_operator_ok (IOR, DImode, operands)"
9652 "or{q}\t{%2, %0|%0, %2}"
9653 [(set_attr "type" "alu")
9654 (set_attr "mode" "DI")])
9656 (define_insn "*iordi_3_rex64"
9657 [(set (reg FLAGS_REG)
9658 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9659 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9661 (clobber (match_scratch:DI 0 "=r"))]
9663 && ix86_match_ccmode (insn, CCNOmode)
9664 && ix86_binary_operator_ok (IOR, DImode, operands)"
9665 "or{q}\t{%2, %0|%0, %2}"
9666 [(set_attr "type" "alu")
9667 (set_attr "mode" "DI")])
9670 (define_expand "iorsi3"
9671 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9672 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9673 (match_operand:SI 2 "general_operand" "")))]
9675 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9677 (define_insn "*iorsi_1"
9678 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9679 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9680 (match_operand:SI 2 "general_operand" "ri,g")))
9681 (clobber (reg:CC FLAGS_REG))]
9682 "ix86_binary_operator_ok (IOR, SImode, operands)"
9683 "or{l}\t{%2, %0|%0, %2}"
9684 [(set_attr "type" "alu")
9685 (set_attr "mode" "SI")])
9687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9688 (define_insn "*iorsi_1_zext"
9689 [(set (match_operand:DI 0 "register_operand" "=r")
9691 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9692 (match_operand:SI 2 "general_operand" "g"))))
9693 (clobber (reg:CC FLAGS_REG))]
9694 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9695 "or{l}\t{%2, %k0|%k0, %2}"
9696 [(set_attr "type" "alu")
9697 (set_attr "mode" "SI")])
9699 (define_insn "*iorsi_1_zext_imm"
9700 [(set (match_operand:DI 0 "register_operand" "=r")
9701 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9702 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9703 (clobber (reg:CC FLAGS_REG))]
9705 "or{l}\t{%2, %k0|%k0, %2}"
9706 [(set_attr "type" "alu")
9707 (set_attr "mode" "SI")])
9709 (define_insn "*iorsi_2"
9710 [(set (reg FLAGS_REG)
9711 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9712 (match_operand:SI 2 "general_operand" "g,ri"))
9714 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9715 (ior:SI (match_dup 1) (match_dup 2)))]
9716 "ix86_match_ccmode (insn, CCNOmode)
9717 && ix86_binary_operator_ok (IOR, SImode, operands)"
9718 "or{l}\t{%2, %0|%0, %2}"
9719 [(set_attr "type" "alu")
9720 (set_attr "mode" "SI")])
9722 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9723 ;; ??? Special case for immediate operand is missing - it is tricky.
9724 (define_insn "*iorsi_2_zext"
9725 [(set (reg FLAGS_REG)
9726 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9727 (match_operand:SI 2 "general_operand" "g"))
9729 (set (match_operand:DI 0 "register_operand" "=r")
9730 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9731 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9732 && ix86_binary_operator_ok (IOR, SImode, operands)"
9733 "or{l}\t{%2, %k0|%k0, %2}"
9734 [(set_attr "type" "alu")
9735 (set_attr "mode" "SI")])
9737 (define_insn "*iorsi_2_zext_imm"
9738 [(set (reg FLAGS_REG)
9739 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9740 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9742 (set (match_operand:DI 0 "register_operand" "=r")
9743 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9744 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9745 && ix86_binary_operator_ok (IOR, SImode, operands)"
9746 "or{l}\t{%2, %k0|%k0, %2}"
9747 [(set_attr "type" "alu")
9748 (set_attr "mode" "SI")])
9750 (define_insn "*iorsi_3"
9751 [(set (reg FLAGS_REG)
9752 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9753 (match_operand:SI 2 "general_operand" "g"))
9755 (clobber (match_scratch:SI 0 "=r"))]
9756 "ix86_match_ccmode (insn, CCNOmode)
9757 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9758 "or{l}\t{%2, %0|%0, %2}"
9759 [(set_attr "type" "alu")
9760 (set_attr "mode" "SI")])
9762 (define_expand "iorhi3"
9763 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9764 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9765 (match_operand:HI 2 "general_operand" "")))]
9766 "TARGET_HIMODE_MATH"
9767 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9769 (define_insn "*iorhi_1"
9770 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9771 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9772 (match_operand:HI 2 "general_operand" "rmn,rn")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "ix86_binary_operator_ok (IOR, HImode, operands)"
9775 "or{w}\t{%2, %0|%0, %2}"
9776 [(set_attr "type" "alu")
9777 (set_attr "mode" "HI")])
9779 (define_insn "*iorhi_2"
9780 [(set (reg FLAGS_REG)
9781 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9782 (match_operand:HI 2 "general_operand" "rmn,rn"))
9784 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9785 (ior:HI (match_dup 1) (match_dup 2)))]
9786 "ix86_match_ccmode (insn, CCNOmode)
9787 && ix86_binary_operator_ok (IOR, HImode, operands)"
9788 "or{w}\t{%2, %0|%0, %2}"
9789 [(set_attr "type" "alu")
9790 (set_attr "mode" "HI")])
9792 (define_insn "*iorhi_3"
9793 [(set (reg FLAGS_REG)
9794 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9795 (match_operand:HI 2 "general_operand" "rmn"))
9797 (clobber (match_scratch:HI 0 "=r"))]
9798 "ix86_match_ccmode (insn, CCNOmode)
9799 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9800 "or{w}\t{%2, %0|%0, %2}"
9801 [(set_attr "type" "alu")
9802 (set_attr "mode" "HI")])
9804 (define_expand "iorqi3"
9805 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9806 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9807 (match_operand:QI 2 "general_operand" "")))]
9808 "TARGET_QIMODE_MATH"
9809 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9811 ;; %%% Potential partial reg stall on alternative 2. What to do?
9812 (define_insn "*iorqi_1"
9813 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9814 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9815 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9816 (clobber (reg:CC FLAGS_REG))]
9817 "ix86_binary_operator_ok (IOR, QImode, operands)"
9819 or{b}\t{%2, %0|%0, %2}
9820 or{b}\t{%2, %0|%0, %2}
9821 or{l}\t{%k2, %k0|%k0, %k2}"
9822 [(set_attr "type" "alu")
9823 (set_attr "mode" "QI,QI,SI")])
9825 (define_insn "*iorqi_1_slp"
9826 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9827 (ior:QI (match_dup 0)
9828 (match_operand:QI 1 "general_operand" "qmn,qn")))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9831 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9832 "or{b}\t{%1, %0|%0, %1}"
9833 [(set_attr "type" "alu1")
9834 (set_attr "mode" "QI")])
9836 (define_insn "*iorqi_2"
9837 [(set (reg FLAGS_REG)
9838 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9839 (match_operand:QI 2 "general_operand" "qmn,qn"))
9841 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9842 (ior:QI (match_dup 1) (match_dup 2)))]
9843 "ix86_match_ccmode (insn, CCNOmode)
9844 && ix86_binary_operator_ok (IOR, QImode, operands)"
9845 "or{b}\t{%2, %0|%0, %2}"
9846 [(set_attr "type" "alu")
9847 (set_attr "mode" "QI")])
9849 (define_insn "*iorqi_2_slp"
9850 [(set (reg FLAGS_REG)
9851 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9852 (match_operand:QI 1 "general_operand" "qmn,qn"))
9854 (set (strict_low_part (match_dup 0))
9855 (ior:QI (match_dup 0) (match_dup 1)))]
9856 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9857 && ix86_match_ccmode (insn, CCNOmode)
9858 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9859 "or{b}\t{%1, %0|%0, %1}"
9860 [(set_attr "type" "alu1")
9861 (set_attr "mode" "QI")])
9863 (define_insn "*iorqi_3"
9864 [(set (reg FLAGS_REG)
9865 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9866 (match_operand:QI 2 "general_operand" "qmn"))
9868 (clobber (match_scratch:QI 0 "=q"))]
9869 "ix86_match_ccmode (insn, CCNOmode)
9870 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9871 "or{b}\t{%2, %0|%0, %2}"
9872 [(set_attr "type" "alu")
9873 (set_attr "mode" "QI")])
9875 (define_insn "*iorqi_ext_0"
9876 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9881 (match_operand 1 "ext_register_operand" "0")
9884 (match_operand 2 "const_int_operand" "n")))
9885 (clobber (reg:CC FLAGS_REG))]
9886 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9887 "or{b}\t{%2, %h0|%h0, %2}"
9888 [(set_attr "type" "alu")
9889 (set_attr "length_immediate" "1")
9890 (set_attr "mode" "QI")])
9892 (define_insn "*iorqi_ext_1"
9893 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9898 (match_operand 1 "ext_register_operand" "0")
9902 (match_operand:QI 2 "general_operand" "Qm"))))
9903 (clobber (reg:CC FLAGS_REG))]
9905 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9906 "or{b}\t{%2, %h0|%h0, %2}"
9907 [(set_attr "type" "alu")
9908 (set_attr "length_immediate" "0")
9909 (set_attr "mode" "QI")])
9911 (define_insn "*iorqi_ext_1_rex64"
9912 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9917 (match_operand 1 "ext_register_operand" "0")
9921 (match_operand 2 "ext_register_operand" "Q"))))
9922 (clobber (reg:CC FLAGS_REG))]
9924 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9925 "or{b}\t{%2, %h0|%h0, %2}"
9926 [(set_attr "type" "alu")
9927 (set_attr "length_immediate" "0")
9928 (set_attr "mode" "QI")])
9930 (define_insn "*iorqi_ext_2"
9931 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9935 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9938 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9941 (clobber (reg:CC FLAGS_REG))]
9942 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9943 "ior{b}\t{%h2, %h0|%h0, %h2}"
9944 [(set_attr "type" "alu")
9945 (set_attr "length_immediate" "0")
9946 (set_attr "mode" "QI")])
9949 [(set (match_operand 0 "register_operand" "")
9950 (ior (match_operand 1 "register_operand" "")
9951 (match_operand 2 "const_int_operand" "")))
9952 (clobber (reg:CC FLAGS_REG))]
9954 && QI_REG_P (operands[0])
9955 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9956 && !(INTVAL (operands[2]) & ~(255 << 8))
9957 && GET_MODE (operands[0]) != QImode"
9958 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9959 (ior:SI (zero_extract:SI (match_dup 1)
9960 (const_int 8) (const_int 8))
9962 (clobber (reg:CC FLAGS_REG))])]
9963 "operands[0] = gen_lowpart (SImode, operands[0]);
9964 operands[1] = gen_lowpart (SImode, operands[1]);
9965 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9967 ;; Since OR can be encoded with sign extended immediate, this is only
9968 ;; profitable when 7th bit is set.
9970 [(set (match_operand 0 "register_operand" "")
9971 (ior (match_operand 1 "general_operand" "")
9972 (match_operand 2 "const_int_operand" "")))
9973 (clobber (reg:CC FLAGS_REG))]
9975 && ANY_QI_REG_P (operands[0])
9976 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9977 && !(INTVAL (operands[2]) & ~255)
9978 && (INTVAL (operands[2]) & 128)
9979 && GET_MODE (operands[0]) != QImode"
9980 [(parallel [(set (strict_low_part (match_dup 0))
9981 (ior:QI (match_dup 1)
9983 (clobber (reg:CC FLAGS_REG))])]
9984 "operands[0] = gen_lowpart (QImode, operands[0]);
9985 operands[1] = gen_lowpart (QImode, operands[1]);
9986 operands[2] = gen_lowpart (QImode, operands[2]);")
9988 ;; Logical XOR instructions
9990 ;; %%% This used to optimize known byte-wide and operations to memory.
9991 ;; If this is considered useful, it should be done with splitters.
9993 (define_expand "xordi3"
9994 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9995 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9996 (match_operand:DI 2 "x86_64_general_operand" "")))]
9998 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10000 (define_insn "*xordi_1_rex64"
10001 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10002 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10003 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10004 (clobber (reg:CC FLAGS_REG))]
10006 && ix86_binary_operator_ok (XOR, DImode, operands)"
10007 "xor{q}\t{%2, %0|%0, %2}"
10008 [(set_attr "type" "alu")
10009 (set_attr "mode" "DI")])
10011 (define_insn "*xordi_2_rex64"
10012 [(set (reg FLAGS_REG)
10013 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10014 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10016 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10017 (xor:DI (match_dup 1) (match_dup 2)))]
10019 && ix86_match_ccmode (insn, CCNOmode)
10020 && ix86_binary_operator_ok (XOR, DImode, operands)"
10021 "xor{q}\t{%2, %0|%0, %2}"
10022 [(set_attr "type" "alu")
10023 (set_attr "mode" "DI")])
10025 (define_insn "*xordi_3_rex64"
10026 [(set (reg FLAGS_REG)
10027 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10028 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10030 (clobber (match_scratch:DI 0 "=r"))]
10032 && ix86_match_ccmode (insn, CCNOmode)
10033 && ix86_binary_operator_ok (XOR, DImode, operands)"
10034 "xor{q}\t{%2, %0|%0, %2}"
10035 [(set_attr "type" "alu")
10036 (set_attr "mode" "DI")])
10038 (define_expand "xorsi3"
10039 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10040 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10041 (match_operand:SI 2 "general_operand" "")))]
10043 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10045 (define_insn "*xorsi_1"
10046 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10047 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10048 (match_operand:SI 2 "general_operand" "ri,rm")))
10049 (clobber (reg:CC FLAGS_REG))]
10050 "ix86_binary_operator_ok (XOR, SImode, operands)"
10051 "xor{l}\t{%2, %0|%0, %2}"
10052 [(set_attr "type" "alu")
10053 (set_attr "mode" "SI")])
10055 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10056 ;; Add speccase for immediates
10057 (define_insn "*xorsi_1_zext"
10058 [(set (match_operand:DI 0 "register_operand" "=r")
10060 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10061 (match_operand:SI 2 "general_operand" "g"))))
10062 (clobber (reg:CC FLAGS_REG))]
10063 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10064 "xor{l}\t{%2, %k0|%k0, %2}"
10065 [(set_attr "type" "alu")
10066 (set_attr "mode" "SI")])
10068 (define_insn "*xorsi_1_zext_imm"
10069 [(set (match_operand:DI 0 "register_operand" "=r")
10070 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10071 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10072 (clobber (reg:CC FLAGS_REG))]
10073 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10074 "xor{l}\t{%2, %k0|%k0, %2}"
10075 [(set_attr "type" "alu")
10076 (set_attr "mode" "SI")])
10078 (define_insn "*xorsi_2"
10079 [(set (reg FLAGS_REG)
10080 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10081 (match_operand:SI 2 "general_operand" "g,ri"))
10083 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10084 (xor:SI (match_dup 1) (match_dup 2)))]
10085 "ix86_match_ccmode (insn, CCNOmode)
10086 && ix86_binary_operator_ok (XOR, SImode, operands)"
10087 "xor{l}\t{%2, %0|%0, %2}"
10088 [(set_attr "type" "alu")
10089 (set_attr "mode" "SI")])
10091 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10092 ;; ??? Special case for immediate operand is missing - it is tricky.
10093 (define_insn "*xorsi_2_zext"
10094 [(set (reg FLAGS_REG)
10095 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10096 (match_operand:SI 2 "general_operand" "g"))
10098 (set (match_operand:DI 0 "register_operand" "=r")
10099 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10100 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10101 && ix86_binary_operator_ok (XOR, SImode, operands)"
10102 "xor{l}\t{%2, %k0|%k0, %2}"
10103 [(set_attr "type" "alu")
10104 (set_attr "mode" "SI")])
10106 (define_insn "*xorsi_2_zext_imm"
10107 [(set (reg FLAGS_REG)
10108 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10109 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10111 (set (match_operand:DI 0 "register_operand" "=r")
10112 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10113 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10114 && ix86_binary_operator_ok (XOR, SImode, operands)"
10115 "xor{l}\t{%2, %k0|%k0, %2}"
10116 [(set_attr "type" "alu")
10117 (set_attr "mode" "SI")])
10119 (define_insn "*xorsi_3"
10120 [(set (reg FLAGS_REG)
10121 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10122 (match_operand:SI 2 "general_operand" "g"))
10124 (clobber (match_scratch:SI 0 "=r"))]
10125 "ix86_match_ccmode (insn, CCNOmode)
10126 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10127 "xor{l}\t{%2, %0|%0, %2}"
10128 [(set_attr "type" "alu")
10129 (set_attr "mode" "SI")])
10131 (define_expand "xorhi3"
10132 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10133 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10134 (match_operand:HI 2 "general_operand" "")))]
10135 "TARGET_HIMODE_MATH"
10136 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10138 (define_insn "*xorhi_1"
10139 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10140 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10141 (match_operand:HI 2 "general_operand" "rmn,rn")))
10142 (clobber (reg:CC FLAGS_REG))]
10143 "ix86_binary_operator_ok (XOR, HImode, operands)"
10144 "xor{w}\t{%2, %0|%0, %2}"
10145 [(set_attr "type" "alu")
10146 (set_attr "mode" "HI")])
10148 (define_insn "*xorhi_2"
10149 [(set (reg FLAGS_REG)
10150 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10151 (match_operand:HI 2 "general_operand" "rmn,rn"))
10153 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10154 (xor:HI (match_dup 1) (match_dup 2)))]
10155 "ix86_match_ccmode (insn, CCNOmode)
10156 && ix86_binary_operator_ok (XOR, HImode, operands)"
10157 "xor{w}\t{%2, %0|%0, %2}"
10158 [(set_attr "type" "alu")
10159 (set_attr "mode" "HI")])
10161 (define_insn "*xorhi_3"
10162 [(set (reg FLAGS_REG)
10163 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10164 (match_operand:HI 2 "general_operand" "rmn"))
10166 (clobber (match_scratch:HI 0 "=r"))]
10167 "ix86_match_ccmode (insn, CCNOmode)
10168 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10169 "xor{w}\t{%2, %0|%0, %2}"
10170 [(set_attr "type" "alu")
10171 (set_attr "mode" "HI")])
10173 (define_expand "xorqi3"
10174 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10175 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10176 (match_operand:QI 2 "general_operand" "")))]
10177 "TARGET_QIMODE_MATH"
10178 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10180 ;; %%% Potential partial reg stall on alternative 2. What to do?
10181 (define_insn "*xorqi_1"
10182 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10183 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10184 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10185 (clobber (reg:CC FLAGS_REG))]
10186 "ix86_binary_operator_ok (XOR, QImode, operands)"
10188 xor{b}\t{%2, %0|%0, %2}
10189 xor{b}\t{%2, %0|%0, %2}
10190 xor{l}\t{%k2, %k0|%k0, %k2}"
10191 [(set_attr "type" "alu")
10192 (set_attr "mode" "QI,QI,SI")])
10194 (define_insn "*xorqi_1_slp"
10195 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10196 (xor:QI (match_dup 0)
10197 (match_operand:QI 1 "general_operand" "qn,qmn")))
10198 (clobber (reg:CC FLAGS_REG))]
10199 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10200 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10201 "xor{b}\t{%1, %0|%0, %1}"
10202 [(set_attr "type" "alu1")
10203 (set_attr "mode" "QI")])
10205 (define_insn "*xorqi_ext_0"
10206 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10211 (match_operand 1 "ext_register_operand" "0")
10214 (match_operand 2 "const_int_operand" "n")))
10215 (clobber (reg:CC FLAGS_REG))]
10216 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10217 "xor{b}\t{%2, %h0|%h0, %2}"
10218 [(set_attr "type" "alu")
10219 (set_attr "length_immediate" "1")
10220 (set_attr "mode" "QI")])
10222 (define_insn "*xorqi_ext_1"
10223 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10228 (match_operand 1 "ext_register_operand" "0")
10232 (match_operand:QI 2 "general_operand" "Qm"))))
10233 (clobber (reg:CC FLAGS_REG))]
10235 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10236 "xor{b}\t{%2, %h0|%h0, %2}"
10237 [(set_attr "type" "alu")
10238 (set_attr "length_immediate" "0")
10239 (set_attr "mode" "QI")])
10241 (define_insn "*xorqi_ext_1_rex64"
10242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10247 (match_operand 1 "ext_register_operand" "0")
10251 (match_operand 2 "ext_register_operand" "Q"))))
10252 (clobber (reg:CC FLAGS_REG))]
10254 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10255 "xor{b}\t{%2, %h0|%h0, %2}"
10256 [(set_attr "type" "alu")
10257 (set_attr "length_immediate" "0")
10258 (set_attr "mode" "QI")])
10260 (define_insn "*xorqi_ext_2"
10261 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10265 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10268 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10271 (clobber (reg:CC FLAGS_REG))]
10272 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10273 "xor{b}\t{%h2, %h0|%h0, %h2}"
10274 [(set_attr "type" "alu")
10275 (set_attr "length_immediate" "0")
10276 (set_attr "mode" "QI")])
10278 (define_insn "*xorqi_cc_1"
10279 [(set (reg FLAGS_REG)
10281 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10282 (match_operand:QI 2 "general_operand" "qmn,qn"))
10284 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10285 (xor:QI (match_dup 1) (match_dup 2)))]
10286 "ix86_match_ccmode (insn, CCNOmode)
10287 && ix86_binary_operator_ok (XOR, QImode, operands)"
10288 "xor{b}\t{%2, %0|%0, %2}"
10289 [(set_attr "type" "alu")
10290 (set_attr "mode" "QI")])
10292 (define_insn "*xorqi_2_slp"
10293 [(set (reg FLAGS_REG)
10294 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10295 (match_operand:QI 1 "general_operand" "qmn,qn"))
10297 (set (strict_low_part (match_dup 0))
10298 (xor:QI (match_dup 0) (match_dup 1)))]
10299 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10300 && ix86_match_ccmode (insn, CCNOmode)
10301 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10302 "xor{b}\t{%1, %0|%0, %1}"
10303 [(set_attr "type" "alu1")
10304 (set_attr "mode" "QI")])
10306 (define_insn "*xorqi_cc_2"
10307 [(set (reg FLAGS_REG)
10309 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10310 (match_operand:QI 2 "general_operand" "qmn"))
10312 (clobber (match_scratch:QI 0 "=q"))]
10313 "ix86_match_ccmode (insn, CCNOmode)
10314 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10315 "xor{b}\t{%2, %0|%0, %2}"
10316 [(set_attr "type" "alu")
10317 (set_attr "mode" "QI")])
10319 (define_insn "*xorqi_cc_ext_1"
10320 [(set (reg FLAGS_REG)
10324 (match_operand 1 "ext_register_operand" "0")
10327 (match_operand:QI 2 "general_operand" "qmn"))
10329 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10333 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10335 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10336 "xor{b}\t{%2, %h0|%h0, %2}"
10337 [(set_attr "type" "alu")
10338 (set_attr "mode" "QI")])
10340 (define_insn "*xorqi_cc_ext_1_rex64"
10341 [(set (reg FLAGS_REG)
10345 (match_operand 1 "ext_register_operand" "0")
10348 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10350 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10354 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10356 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10357 "xor{b}\t{%2, %h0|%h0, %2}"
10358 [(set_attr "type" "alu")
10359 (set_attr "mode" "QI")])
10361 (define_expand "xorqi_cc_ext_1"
10363 (set (reg:CCNO FLAGS_REG)
10367 (match_operand 1 "ext_register_operand" "")
10370 (match_operand:QI 2 "general_operand" ""))
10372 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10376 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10382 [(set (match_operand 0 "register_operand" "")
10383 (xor (match_operand 1 "register_operand" "")
10384 (match_operand 2 "const_int_operand" "")))
10385 (clobber (reg:CC FLAGS_REG))]
10387 && QI_REG_P (operands[0])
10388 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10389 && !(INTVAL (operands[2]) & ~(255 << 8))
10390 && GET_MODE (operands[0]) != QImode"
10391 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10392 (xor:SI (zero_extract:SI (match_dup 1)
10393 (const_int 8) (const_int 8))
10395 (clobber (reg:CC FLAGS_REG))])]
10396 "operands[0] = gen_lowpart (SImode, operands[0]);
10397 operands[1] = gen_lowpart (SImode, operands[1]);
10398 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10400 ;; Since XOR can be encoded with sign extended immediate, this is only
10401 ;; profitable when 7th bit is set.
10403 [(set (match_operand 0 "register_operand" "")
10404 (xor (match_operand 1 "general_operand" "")
10405 (match_operand 2 "const_int_operand" "")))
10406 (clobber (reg:CC FLAGS_REG))]
10408 && ANY_QI_REG_P (operands[0])
10409 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10410 && !(INTVAL (operands[2]) & ~255)
10411 && (INTVAL (operands[2]) & 128)
10412 && GET_MODE (operands[0]) != QImode"
10413 [(parallel [(set (strict_low_part (match_dup 0))
10414 (xor:QI (match_dup 1)
10416 (clobber (reg:CC FLAGS_REG))])]
10417 "operands[0] = gen_lowpart (QImode, operands[0]);
10418 operands[1] = gen_lowpart (QImode, operands[1]);
10419 operands[2] = gen_lowpart (QImode, operands[2]);")
10421 ;; Negation instructions
10423 (define_expand "negti2"
10424 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10425 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10427 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10429 (define_insn "*negti2_1"
10430 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10431 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10432 (clobber (reg:CC FLAGS_REG))]
10434 && ix86_unary_operator_ok (NEG, TImode, operands)"
10438 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10439 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10440 (clobber (reg:CC FLAGS_REG))]
10441 "TARGET_64BIT && reload_completed"
10443 [(set (reg:CCZ FLAGS_REG)
10444 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10445 (set (match_dup 0) (neg:DI (match_dup 1)))])
10447 [(set (match_dup 2)
10448 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10451 (clobber (reg:CC FLAGS_REG))])
10453 [(set (match_dup 2)
10454 (neg:DI (match_dup 2)))
10455 (clobber (reg:CC FLAGS_REG))])]
10456 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10458 (define_expand "negdi2"
10459 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10460 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10462 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10464 (define_insn "*negdi2_1"
10465 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10466 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10467 (clobber (reg:CC FLAGS_REG))]
10469 && ix86_unary_operator_ok (NEG, DImode, operands)"
10473 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10474 (neg:DI (match_operand:DI 1 "general_operand" "")))
10475 (clobber (reg:CC FLAGS_REG))]
10476 "!TARGET_64BIT && reload_completed"
10478 [(set (reg:CCZ FLAGS_REG)
10479 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10480 (set (match_dup 0) (neg:SI (match_dup 1)))])
10482 [(set (match_dup 2)
10483 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10486 (clobber (reg:CC FLAGS_REG))])
10488 [(set (match_dup 2)
10489 (neg:SI (match_dup 2)))
10490 (clobber (reg:CC FLAGS_REG))])]
10491 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10493 (define_insn "*negdi2_1_rex64"
10494 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10495 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10496 (clobber (reg:CC FLAGS_REG))]
10497 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10499 [(set_attr "type" "negnot")
10500 (set_attr "mode" "DI")])
10502 ;; The problem with neg is that it does not perform (compare x 0),
10503 ;; it really performs (compare 0 x), which leaves us with the zero
10504 ;; flag being the only useful item.
10506 (define_insn "*negdi2_cmpz_rex64"
10507 [(set (reg:CCZ FLAGS_REG)
10508 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10510 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10511 (neg:DI (match_dup 1)))]
10512 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10514 [(set_attr "type" "negnot")
10515 (set_attr "mode" "DI")])
10518 (define_expand "negsi2"
10519 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10520 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10522 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10524 (define_insn "*negsi2_1"
10525 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10526 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "ix86_unary_operator_ok (NEG, SImode, operands)"
10530 [(set_attr "type" "negnot")
10531 (set_attr "mode" "SI")])
10533 ;; Combine is quite creative about this pattern.
10534 (define_insn "*negsi2_1_zext"
10535 [(set (match_operand:DI 0 "register_operand" "=r")
10536 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10539 (clobber (reg:CC FLAGS_REG))]
10540 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10542 [(set_attr "type" "negnot")
10543 (set_attr "mode" "SI")])
10545 ;; The problem with neg is that it does not perform (compare x 0),
10546 ;; it really performs (compare 0 x), which leaves us with the zero
10547 ;; flag being the only useful item.
10549 (define_insn "*negsi2_cmpz"
10550 [(set (reg:CCZ FLAGS_REG)
10551 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10553 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10554 (neg:SI (match_dup 1)))]
10555 "ix86_unary_operator_ok (NEG, SImode, operands)"
10557 [(set_attr "type" "negnot")
10558 (set_attr "mode" "SI")])
10560 (define_insn "*negsi2_cmpz_zext"
10561 [(set (reg:CCZ FLAGS_REG)
10562 (compare:CCZ (lshiftrt:DI
10564 (match_operand:DI 1 "register_operand" "0")
10568 (set (match_operand:DI 0 "register_operand" "=r")
10569 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10572 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10574 [(set_attr "type" "negnot")
10575 (set_attr "mode" "SI")])
10577 (define_expand "neghi2"
10578 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10579 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10580 "TARGET_HIMODE_MATH"
10581 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10583 (define_insn "*neghi2_1"
10584 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10585 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10586 (clobber (reg:CC FLAGS_REG))]
10587 "ix86_unary_operator_ok (NEG, HImode, operands)"
10589 [(set_attr "type" "negnot")
10590 (set_attr "mode" "HI")])
10592 (define_insn "*neghi2_cmpz"
10593 [(set (reg:CCZ FLAGS_REG)
10594 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10596 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10597 (neg:HI (match_dup 1)))]
10598 "ix86_unary_operator_ok (NEG, HImode, operands)"
10600 [(set_attr "type" "negnot")
10601 (set_attr "mode" "HI")])
10603 (define_expand "negqi2"
10604 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10605 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10606 "TARGET_QIMODE_MATH"
10607 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10609 (define_insn "*negqi2_1"
10610 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10611 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10612 (clobber (reg:CC FLAGS_REG))]
10613 "ix86_unary_operator_ok (NEG, QImode, operands)"
10615 [(set_attr "type" "negnot")
10616 (set_attr "mode" "QI")])
10618 (define_insn "*negqi2_cmpz"
10619 [(set (reg:CCZ FLAGS_REG)
10620 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10622 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10623 (neg:QI (match_dup 1)))]
10624 "ix86_unary_operator_ok (NEG, QImode, operands)"
10626 [(set_attr "type" "negnot")
10627 (set_attr "mode" "QI")])
10629 ;; Changing of sign for FP values is doable using integer unit too.
10631 (define_expand "<code><mode>2"
10632 [(set (match_operand:X87MODEF 0 "register_operand" "")
10633 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10634 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10635 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10637 (define_insn "*absneg<mode>2_mixed"
10638 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10639 (match_operator:MODEF 3 "absneg_operator"
10640 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10641 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10642 (clobber (reg:CC FLAGS_REG))]
10643 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10646 (define_insn "*absneg<mode>2_sse"
10647 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10648 (match_operator:MODEF 3 "absneg_operator"
10649 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10650 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10651 (clobber (reg:CC FLAGS_REG))]
10652 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10655 (define_insn "*absneg<mode>2_i387"
10656 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10657 (match_operator:X87MODEF 3 "absneg_operator"
10658 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10659 (use (match_operand 2 "" ""))
10660 (clobber (reg:CC FLAGS_REG))]
10661 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10664 (define_expand "<code>tf2"
10665 [(set (match_operand:TF 0 "register_operand" "")
10666 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10668 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10670 (define_insn "*absnegtf2_sse"
10671 [(set (match_operand:TF 0 "register_operand" "=x,x")
10672 (match_operator:TF 3 "absneg_operator"
10673 [(match_operand:TF 1 "register_operand" "0,x")]))
10674 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10675 (clobber (reg:CC FLAGS_REG))]
10679 ;; Splitters for fp abs and neg.
10682 [(set (match_operand 0 "fp_register_operand" "")
10683 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10684 (use (match_operand 2 "" ""))
10685 (clobber (reg:CC FLAGS_REG))]
10687 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10690 [(set (match_operand 0 "register_operand" "")
10691 (match_operator 3 "absneg_operator"
10692 [(match_operand 1 "register_operand" "")]))
10693 (use (match_operand 2 "nonimmediate_operand" ""))
10694 (clobber (reg:CC FLAGS_REG))]
10695 "reload_completed && SSE_REG_P (operands[0])"
10696 [(set (match_dup 0) (match_dup 3))]
10698 enum machine_mode mode = GET_MODE (operands[0]);
10699 enum machine_mode vmode = GET_MODE (operands[2]);
10702 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10703 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10704 if (operands_match_p (operands[0], operands[2]))
10707 operands[1] = operands[2];
10710 if (GET_CODE (operands[3]) == ABS)
10711 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10713 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10718 [(set (match_operand:SF 0 "register_operand" "")
10719 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10720 (use (match_operand:V4SF 2 "" ""))
10721 (clobber (reg:CC FLAGS_REG))]
10723 [(parallel [(set (match_dup 0) (match_dup 1))
10724 (clobber (reg:CC FLAGS_REG))])]
10727 operands[0] = gen_lowpart (SImode, operands[0]);
10728 if (GET_CODE (operands[1]) == ABS)
10730 tmp = gen_int_mode (0x7fffffff, SImode);
10731 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10735 tmp = gen_int_mode (0x80000000, SImode);
10736 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10742 [(set (match_operand:DF 0 "register_operand" "")
10743 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10744 (use (match_operand 2 "" ""))
10745 (clobber (reg:CC FLAGS_REG))]
10747 [(parallel [(set (match_dup 0) (match_dup 1))
10748 (clobber (reg:CC FLAGS_REG))])]
10753 tmp = gen_lowpart (DImode, operands[0]);
10754 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10757 if (GET_CODE (operands[1]) == ABS)
10760 tmp = gen_rtx_NOT (DImode, tmp);
10764 operands[0] = gen_highpart (SImode, operands[0]);
10765 if (GET_CODE (operands[1]) == ABS)
10767 tmp = gen_int_mode (0x7fffffff, SImode);
10768 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10772 tmp = gen_int_mode (0x80000000, SImode);
10773 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10780 [(set (match_operand:XF 0 "register_operand" "")
10781 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10782 (use (match_operand 2 "" ""))
10783 (clobber (reg:CC FLAGS_REG))]
10785 [(parallel [(set (match_dup 0) (match_dup 1))
10786 (clobber (reg:CC FLAGS_REG))])]
10789 operands[0] = gen_rtx_REG (SImode,
10790 true_regnum (operands[0])
10791 + (TARGET_64BIT ? 1 : 2));
10792 if (GET_CODE (operands[1]) == ABS)
10794 tmp = GEN_INT (0x7fff);
10795 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10799 tmp = GEN_INT (0x8000);
10800 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10805 ;; Conditionalize these after reload. If they match before reload, we
10806 ;; lose the clobber and ability to use integer instructions.
10808 (define_insn "*<code><mode>2_1"
10809 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10810 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10812 && (reload_completed
10813 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10815 [(set_attr "type" "fsgn")
10816 (set_attr "mode" "<MODE>")])
10818 (define_insn "*<code>extendsfdf2"
10819 [(set (match_operand:DF 0 "register_operand" "=f")
10820 (absneg:DF (float_extend:DF
10821 (match_operand:SF 1 "register_operand" "0"))))]
10822 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10824 [(set_attr "type" "fsgn")
10825 (set_attr "mode" "DF")])
10827 (define_insn "*<code>extendsfxf2"
10828 [(set (match_operand:XF 0 "register_operand" "=f")
10829 (absneg:XF (float_extend:XF
10830 (match_operand:SF 1 "register_operand" "0"))))]
10833 [(set_attr "type" "fsgn")
10834 (set_attr "mode" "XF")])
10836 (define_insn "*<code>extenddfxf2"
10837 [(set (match_operand:XF 0 "register_operand" "=f")
10838 (absneg:XF (float_extend:XF
10839 (match_operand:DF 1 "register_operand" "0"))))]
10842 [(set_attr "type" "fsgn")
10843 (set_attr "mode" "XF")])
10845 ;; Copysign instructions
10847 (define_mode_iterator CSGNMODE [SF DF TF])
10848 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10850 (define_expand "copysign<mode>3"
10851 [(match_operand:CSGNMODE 0 "register_operand" "")
10852 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10853 (match_operand:CSGNMODE 2 "register_operand" "")]
10854 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10855 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10857 ix86_expand_copysign (operands);
10861 (define_insn_and_split "copysign<mode>3_const"
10862 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10864 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10865 (match_operand:CSGNMODE 2 "register_operand" "0")
10866 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10868 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10869 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10871 "&& reload_completed"
10874 ix86_split_copysign_const (operands);
10878 (define_insn "copysign<mode>3_var"
10879 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10881 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10882 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10883 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10884 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10886 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10887 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10888 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10892 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10894 [(match_operand:CSGNMODE 2 "register_operand" "")
10895 (match_operand:CSGNMODE 3 "register_operand" "")
10896 (match_operand:<CSGNVMODE> 4 "" "")
10897 (match_operand:<CSGNVMODE> 5 "" "")]
10899 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10900 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10901 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10902 && reload_completed"
10905 ix86_split_copysign_var (operands);
10909 ;; One complement instructions
10911 (define_expand "one_cmpldi2"
10912 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10913 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10915 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10917 (define_insn "*one_cmpldi2_1_rex64"
10918 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10919 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10920 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10922 [(set_attr "type" "negnot")
10923 (set_attr "mode" "DI")])
10925 (define_insn "*one_cmpldi2_2_rex64"
10926 [(set (reg FLAGS_REG)
10927 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10929 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10930 (not:DI (match_dup 1)))]
10931 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10932 && ix86_unary_operator_ok (NOT, DImode, operands)"
10934 [(set_attr "type" "alu1")
10935 (set_attr "mode" "DI")])
10938 [(set (match_operand 0 "flags_reg_operand" "")
10939 (match_operator 2 "compare_operator"
10940 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10942 (set (match_operand:DI 1 "nonimmediate_operand" "")
10943 (not:DI (match_dup 3)))]
10944 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10945 [(parallel [(set (match_dup 0)
10947 [(xor:DI (match_dup 3) (const_int -1))
10950 (xor:DI (match_dup 3) (const_int -1)))])]
10953 (define_expand "one_cmplsi2"
10954 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10955 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10957 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10959 (define_insn "*one_cmplsi2_1"
10960 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10961 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10962 "ix86_unary_operator_ok (NOT, SImode, operands)"
10964 [(set_attr "type" "negnot")
10965 (set_attr "mode" "SI")])
10967 ;; ??? Currently never generated - xor is used instead.
10968 (define_insn "*one_cmplsi2_1_zext"
10969 [(set (match_operand:DI 0 "register_operand" "=r")
10970 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10971 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10973 [(set_attr "type" "negnot")
10974 (set_attr "mode" "SI")])
10976 (define_insn "*one_cmplsi2_2"
10977 [(set (reg FLAGS_REG)
10978 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10980 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10981 (not:SI (match_dup 1)))]
10982 "ix86_match_ccmode (insn, CCNOmode)
10983 && ix86_unary_operator_ok (NOT, SImode, operands)"
10985 [(set_attr "type" "alu1")
10986 (set_attr "mode" "SI")])
10989 [(set (match_operand 0 "flags_reg_operand" "")
10990 (match_operator 2 "compare_operator"
10991 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10993 (set (match_operand:SI 1 "nonimmediate_operand" "")
10994 (not:SI (match_dup 3)))]
10995 "ix86_match_ccmode (insn, CCNOmode)"
10996 [(parallel [(set (match_dup 0)
10997 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11000 (xor:SI (match_dup 3) (const_int -1)))])]
11003 ;; ??? Currently never generated - xor is used instead.
11004 (define_insn "*one_cmplsi2_2_zext"
11005 [(set (reg FLAGS_REG)
11006 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11008 (set (match_operand:DI 0 "register_operand" "=r")
11009 (zero_extend:DI (not:SI (match_dup 1))))]
11010 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11011 && ix86_unary_operator_ok (NOT, SImode, operands)"
11013 [(set_attr "type" "alu1")
11014 (set_attr "mode" "SI")])
11017 [(set (match_operand 0 "flags_reg_operand" "")
11018 (match_operator 2 "compare_operator"
11019 [(not:SI (match_operand:SI 3 "register_operand" ""))
11021 (set (match_operand:DI 1 "register_operand" "")
11022 (zero_extend:DI (not:SI (match_dup 3))))]
11023 "ix86_match_ccmode (insn, CCNOmode)"
11024 [(parallel [(set (match_dup 0)
11025 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11028 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11031 (define_expand "one_cmplhi2"
11032 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11033 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11034 "TARGET_HIMODE_MATH"
11035 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11037 (define_insn "*one_cmplhi2_1"
11038 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11039 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11040 "ix86_unary_operator_ok (NOT, HImode, operands)"
11042 [(set_attr "type" "negnot")
11043 (set_attr "mode" "HI")])
11045 (define_insn "*one_cmplhi2_2"
11046 [(set (reg FLAGS_REG)
11047 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11049 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11050 (not:HI (match_dup 1)))]
11051 "ix86_match_ccmode (insn, CCNOmode)
11052 && ix86_unary_operator_ok (NEG, HImode, operands)"
11054 [(set_attr "type" "alu1")
11055 (set_attr "mode" "HI")])
11058 [(set (match_operand 0 "flags_reg_operand" "")
11059 (match_operator 2 "compare_operator"
11060 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11062 (set (match_operand:HI 1 "nonimmediate_operand" "")
11063 (not:HI (match_dup 3)))]
11064 "ix86_match_ccmode (insn, CCNOmode)"
11065 [(parallel [(set (match_dup 0)
11066 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11069 (xor:HI (match_dup 3) (const_int -1)))])]
11072 ;; %%% Potential partial reg stall on alternative 1. What to do?
11073 (define_expand "one_cmplqi2"
11074 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11075 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11076 "TARGET_QIMODE_MATH"
11077 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11079 (define_insn "*one_cmplqi2_1"
11080 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11081 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11082 "ix86_unary_operator_ok (NOT, QImode, operands)"
11086 [(set_attr "type" "negnot")
11087 (set_attr "mode" "QI,SI")])
11089 (define_insn "*one_cmplqi2_2"
11090 [(set (reg FLAGS_REG)
11091 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11093 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11094 (not:QI (match_dup 1)))]
11095 "ix86_match_ccmode (insn, CCNOmode)
11096 && ix86_unary_operator_ok (NOT, QImode, operands)"
11098 [(set_attr "type" "alu1")
11099 (set_attr "mode" "QI")])
11102 [(set (match_operand 0 "flags_reg_operand" "")
11103 (match_operator 2 "compare_operator"
11104 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11106 (set (match_operand:QI 1 "nonimmediate_operand" "")
11107 (not:QI (match_dup 3)))]
11108 "ix86_match_ccmode (insn, CCNOmode)"
11109 [(parallel [(set (match_dup 0)
11110 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11113 (xor:QI (match_dup 3) (const_int -1)))])]
11116 ;; Arithmetic shift instructions
11118 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11119 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11120 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11121 ;; from the assembler input.
11123 ;; This instruction shifts the target reg/mem as usual, but instead of
11124 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11125 ;; is a left shift double, bits are taken from the high order bits of
11126 ;; reg, else if the insn is a shift right double, bits are taken from the
11127 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11128 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11130 ;; Since sh[lr]d does not change the `reg' operand, that is done
11131 ;; separately, making all shifts emit pairs of shift double and normal
11132 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11133 ;; support a 63 bit shift, each shift where the count is in a reg expands
11134 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11136 ;; If the shift count is a constant, we need never emit more than one
11137 ;; shift pair, instead using moves and sign extension for counts greater
11140 (define_expand "ashlti3"
11141 [(set (match_operand:TI 0 "register_operand" "")
11142 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11143 (match_operand:QI 2 "nonmemory_operand" "")))]
11145 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11147 ;; This pattern must be defined before *ashlti3_1 to prevent
11148 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11150 (define_insn "*avx_ashlti3"
11151 [(set (match_operand:TI 0 "register_operand" "=x")
11152 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11153 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11156 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11157 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11159 [(set_attr "type" "sseishft")
11160 (set_attr "prefix" "vex")
11161 (set_attr "mode" "TI")])
11163 (define_insn "sse2_ashlti3"
11164 [(set (match_operand:TI 0 "register_operand" "=x")
11165 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11166 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11169 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11170 return "pslldq\t{%2, %0|%0, %2}";
11172 [(set_attr "type" "sseishft")
11173 (set_attr "prefix_data16" "1")
11174 (set_attr "mode" "TI")])
11176 (define_insn "*ashlti3_1"
11177 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11178 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11179 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11180 (clobber (reg:CC FLAGS_REG))]
11183 [(set_attr "type" "multi")])
11186 [(match_scratch:DI 3 "r")
11187 (parallel [(set (match_operand:TI 0 "register_operand" "")
11188 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11189 (match_operand:QI 2 "nonmemory_operand" "")))
11190 (clobber (reg:CC FLAGS_REG))])
11194 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11197 [(set (match_operand:TI 0 "register_operand" "")
11198 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11199 (match_operand:QI 2 "nonmemory_operand" "")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11202 ? epilogue_completed : reload_completed)"
11204 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11206 (define_insn "x86_64_shld"
11207 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11208 (ior:DI (ashift:DI (match_dup 0)
11209 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11210 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11211 (minus:QI (const_int 64) (match_dup 2)))))
11212 (clobber (reg:CC FLAGS_REG))]
11214 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11215 [(set_attr "type" "ishift")
11216 (set_attr "prefix_0f" "1")
11217 (set_attr "mode" "DI")
11218 (set_attr "athlon_decode" "vector")
11219 (set_attr "amdfam10_decode" "vector")])
11221 (define_expand "x86_64_shift_adj_1"
11222 [(set (reg:CCZ FLAGS_REG)
11223 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11226 (set (match_operand:DI 0 "register_operand" "")
11227 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11228 (match_operand:DI 1 "register_operand" "")
11231 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11232 (match_operand:DI 3 "register_operand" "r")
11237 (define_expand "x86_64_shift_adj_2"
11238 [(use (match_operand:DI 0 "register_operand" ""))
11239 (use (match_operand:DI 1 "register_operand" ""))
11240 (use (match_operand:QI 2 "register_operand" ""))]
11243 rtx label = gen_label_rtx ();
11246 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11248 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11249 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11250 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11251 gen_rtx_LABEL_REF (VOIDmode, label),
11253 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11254 JUMP_LABEL (tmp) = label;
11256 emit_move_insn (operands[0], operands[1]);
11257 ix86_expand_clear (operands[1]);
11259 emit_label (label);
11260 LABEL_NUSES (label) = 1;
11265 (define_expand "ashldi3"
11266 [(set (match_operand:DI 0 "shiftdi_operand" "")
11267 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11268 (match_operand:QI 2 "nonmemory_operand" "")))]
11270 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11272 (define_insn "*ashldi3_1_rex64"
11273 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11274 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11275 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11276 (clobber (reg:CC FLAGS_REG))]
11277 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11279 switch (get_attr_type (insn))
11282 gcc_assert (operands[2] == const1_rtx);
11283 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11284 return "add{q}\t%0, %0";
11287 gcc_assert (CONST_INT_P (operands[2]));
11288 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11289 operands[1] = gen_rtx_MULT (DImode, operands[1],
11290 GEN_INT (1 << INTVAL (operands[2])));
11291 return "lea{q}\t{%a1, %0|%0, %a1}";
11294 if (REG_P (operands[2]))
11295 return "sal{q}\t{%b2, %0|%0, %b2}";
11296 else if (operands[2] == const1_rtx
11297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11298 return "sal{q}\t%0";
11300 return "sal{q}\t{%2, %0|%0, %2}";
11303 [(set (attr "type")
11304 (cond [(eq_attr "alternative" "1")
11305 (const_string "lea")
11306 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11308 (match_operand 0 "register_operand" ""))
11309 (match_operand 2 "const1_operand" ""))
11310 (const_string "alu")
11312 (const_string "ishift")))
11313 (set_attr "mode" "DI")])
11315 ;; Convert lea to the lea pattern to avoid flags dependency.
11317 [(set (match_operand:DI 0 "register_operand" "")
11318 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11319 (match_operand:QI 2 "immediate_operand" "")))
11320 (clobber (reg:CC FLAGS_REG))]
11321 "TARGET_64BIT && reload_completed
11322 && true_regnum (operands[0]) != true_regnum (operands[1])"
11323 [(set (match_dup 0)
11324 (mult:DI (match_dup 1)
11326 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11328 ;; This pattern can't accept a variable shift count, since shifts by
11329 ;; zero don't affect the flags. We assume that shifts by constant
11330 ;; zero are optimized away.
11331 (define_insn "*ashldi3_cmp_rex64"
11332 [(set (reg FLAGS_REG)
11334 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11335 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11337 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11338 (ashift:DI (match_dup 1) (match_dup 2)))]
11340 && (optimize_function_for_size_p (cfun)
11341 || !TARGET_PARTIAL_FLAG_REG_STALL
11342 || (operands[2] == const1_rtx
11344 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11345 && ix86_match_ccmode (insn, CCGOCmode)
11346 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11348 switch (get_attr_type (insn))
11351 gcc_assert (operands[2] == const1_rtx);
11352 return "add{q}\t%0, %0";
11355 if (REG_P (operands[2]))
11356 return "sal{q}\t{%b2, %0|%0, %b2}";
11357 else if (operands[2] == const1_rtx
11358 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11359 return "sal{q}\t%0";
11361 return "sal{q}\t{%2, %0|%0, %2}";
11364 [(set (attr "type")
11365 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11367 (match_operand 0 "register_operand" ""))
11368 (match_operand 2 "const1_operand" ""))
11369 (const_string "alu")
11371 (const_string "ishift")))
11372 (set_attr "mode" "DI")])
11374 (define_insn "*ashldi3_cconly_rex64"
11375 [(set (reg FLAGS_REG)
11377 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11378 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11380 (clobber (match_scratch:DI 0 "=r"))]
11382 && (optimize_function_for_size_p (cfun)
11383 || !TARGET_PARTIAL_FLAG_REG_STALL
11384 || (operands[2] == const1_rtx
11386 || TARGET_DOUBLE_WITH_ADD)))
11387 && ix86_match_ccmode (insn, CCGOCmode)
11388 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11390 switch (get_attr_type (insn))
11393 gcc_assert (operands[2] == const1_rtx);
11394 return "add{q}\t%0, %0";
11397 if (REG_P (operands[2]))
11398 return "sal{q}\t{%b2, %0|%0, %b2}";
11399 else if (operands[2] == const1_rtx
11400 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11401 return "sal{q}\t%0";
11403 return "sal{q}\t{%2, %0|%0, %2}";
11406 [(set (attr "type")
11407 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11409 (match_operand 0 "register_operand" ""))
11410 (match_operand 2 "const1_operand" ""))
11411 (const_string "alu")
11413 (const_string "ishift")))
11414 (set_attr "mode" "DI")])
11416 (define_insn "*ashldi3_1"
11417 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11418 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11419 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11420 (clobber (reg:CC FLAGS_REG))]
11423 [(set_attr "type" "multi")])
11425 ;; By default we don't ask for a scratch register, because when DImode
11426 ;; values are manipulated, registers are already at a premium. But if
11427 ;; we have one handy, we won't turn it away.
11429 [(match_scratch:SI 3 "r")
11430 (parallel [(set (match_operand:DI 0 "register_operand" "")
11431 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11432 (match_operand:QI 2 "nonmemory_operand" "")))
11433 (clobber (reg:CC FLAGS_REG))])
11435 "!TARGET_64BIT && TARGET_CMOVE"
11437 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11440 [(set (match_operand:DI 0 "register_operand" "")
11441 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11442 (match_operand:QI 2 "nonmemory_operand" "")))
11443 (clobber (reg:CC FLAGS_REG))]
11444 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11445 ? epilogue_completed : reload_completed)"
11447 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11449 (define_insn "x86_shld"
11450 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11451 (ior:SI (ashift:SI (match_dup 0)
11452 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11453 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11454 (minus:QI (const_int 32) (match_dup 2)))))
11455 (clobber (reg:CC FLAGS_REG))]
11457 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11458 [(set_attr "type" "ishift")
11459 (set_attr "prefix_0f" "1")
11460 (set_attr "mode" "SI")
11461 (set_attr "pent_pair" "np")
11462 (set_attr "athlon_decode" "vector")
11463 (set_attr "amdfam10_decode" "vector")])
11465 (define_expand "x86_shift_adj_1"
11466 [(set (reg:CCZ FLAGS_REG)
11467 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11470 (set (match_operand:SI 0 "register_operand" "")
11471 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11472 (match_operand:SI 1 "register_operand" "")
11475 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11476 (match_operand:SI 3 "register_operand" "r")
11481 (define_expand "x86_shift_adj_2"
11482 [(use (match_operand:SI 0 "register_operand" ""))
11483 (use (match_operand:SI 1 "register_operand" ""))
11484 (use (match_operand:QI 2 "register_operand" ""))]
11487 rtx label = gen_label_rtx ();
11490 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11492 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11493 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11494 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11495 gen_rtx_LABEL_REF (VOIDmode, label),
11497 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11498 JUMP_LABEL (tmp) = label;
11500 emit_move_insn (operands[0], operands[1]);
11501 ix86_expand_clear (operands[1]);
11503 emit_label (label);
11504 LABEL_NUSES (label) = 1;
11509 (define_expand "ashlsi3"
11510 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11511 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11512 (match_operand:QI 2 "nonmemory_operand" "")))]
11514 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11516 (define_insn "*ashlsi3_1"
11517 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11518 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11519 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11520 (clobber (reg:CC FLAGS_REG))]
11521 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11523 switch (get_attr_type (insn))
11526 gcc_assert (operands[2] == const1_rtx);
11527 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11528 return "add{l}\t%0, %0";
11534 if (REG_P (operands[2]))
11535 return "sal{l}\t{%b2, %0|%0, %b2}";
11536 else if (operands[2] == const1_rtx
11537 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11538 return "sal{l}\t%0";
11540 return "sal{l}\t{%2, %0|%0, %2}";
11543 [(set (attr "type")
11544 (cond [(eq_attr "alternative" "1")
11545 (const_string "lea")
11546 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11548 (match_operand 0 "register_operand" ""))
11549 (match_operand 2 "const1_operand" ""))
11550 (const_string "alu")
11552 (const_string "ishift")))
11553 (set_attr "mode" "SI")])
11555 ;; Convert lea to the lea pattern to avoid flags dependency.
11557 [(set (match_operand 0 "register_operand" "")
11558 (ashift (match_operand 1 "index_register_operand" "")
11559 (match_operand:QI 2 "const_int_operand" "")))
11560 (clobber (reg:CC FLAGS_REG))]
11562 && true_regnum (operands[0]) != true_regnum (operands[1])
11563 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11567 enum machine_mode mode = GET_MODE (operands[0]);
11569 if (GET_MODE_SIZE (mode) < 4)
11570 operands[0] = gen_lowpart (SImode, operands[0]);
11572 operands[1] = gen_lowpart (Pmode, operands[1]);
11573 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11575 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11576 if (Pmode != SImode)
11577 pat = gen_rtx_SUBREG (SImode, pat, 0);
11578 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11582 ;; Rare case of shifting RSP is handled by generating move and shift
11584 [(set (match_operand 0 "register_operand" "")
11585 (ashift (match_operand 1 "register_operand" "")
11586 (match_operand:QI 2 "const_int_operand" "")))
11587 (clobber (reg:CC FLAGS_REG))]
11589 && true_regnum (operands[0]) != true_regnum (operands[1])"
11593 emit_move_insn (operands[0], operands[1]);
11594 pat = gen_rtx_SET (VOIDmode, operands[0],
11595 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11596 operands[0], operands[2]));
11597 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11598 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11602 (define_insn "*ashlsi3_1_zext"
11603 [(set (match_operand:DI 0 "register_operand" "=r,r")
11604 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11605 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11606 (clobber (reg:CC FLAGS_REG))]
11607 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11609 switch (get_attr_type (insn))
11612 gcc_assert (operands[2] == const1_rtx);
11613 return "add{l}\t%k0, %k0";
11619 if (REG_P (operands[2]))
11620 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11621 else if (operands[2] == const1_rtx
11622 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11623 return "sal{l}\t%k0";
11625 return "sal{l}\t{%2, %k0|%k0, %2}";
11628 [(set (attr "type")
11629 (cond [(eq_attr "alternative" "1")
11630 (const_string "lea")
11631 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11633 (match_operand 2 "const1_operand" ""))
11634 (const_string "alu")
11636 (const_string "ishift")))
11637 (set_attr "mode" "SI")])
11639 ;; Convert lea to the lea pattern to avoid flags dependency.
11641 [(set (match_operand:DI 0 "register_operand" "")
11642 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11643 (match_operand:QI 2 "const_int_operand" ""))))
11644 (clobber (reg:CC FLAGS_REG))]
11645 "TARGET_64BIT && reload_completed
11646 && true_regnum (operands[0]) != true_regnum (operands[1])"
11647 [(set (match_dup 0) (zero_extend:DI
11648 (subreg:SI (mult:SI (match_dup 1)
11649 (match_dup 2)) 0)))]
11651 operands[1] = gen_lowpart (Pmode, operands[1]);
11652 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11655 ;; This pattern can't accept a variable shift count, since shifts by
11656 ;; zero don't affect the flags. We assume that shifts by constant
11657 ;; zero are optimized away.
11658 (define_insn "*ashlsi3_cmp"
11659 [(set (reg FLAGS_REG)
11661 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11662 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11664 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11665 (ashift:SI (match_dup 1) (match_dup 2)))]
11666 "(optimize_function_for_size_p (cfun)
11667 || !TARGET_PARTIAL_FLAG_REG_STALL
11668 || (operands[2] == const1_rtx
11670 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11671 && ix86_match_ccmode (insn, CCGOCmode)
11672 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11674 switch (get_attr_type (insn))
11677 gcc_assert (operands[2] == const1_rtx);
11678 return "add{l}\t%0, %0";
11681 if (REG_P (operands[2]))
11682 return "sal{l}\t{%b2, %0|%0, %b2}";
11683 else if (operands[2] == const1_rtx
11684 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11685 return "sal{l}\t%0";
11687 return "sal{l}\t{%2, %0|%0, %2}";
11690 [(set (attr "type")
11691 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11693 (match_operand 0 "register_operand" ""))
11694 (match_operand 2 "const1_operand" ""))
11695 (const_string "alu")
11697 (const_string "ishift")))
11698 (set_attr "mode" "SI")])
11700 (define_insn "*ashlsi3_cconly"
11701 [(set (reg FLAGS_REG)
11703 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11704 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11706 (clobber (match_scratch:SI 0 "=r"))]
11707 "(optimize_function_for_size_p (cfun)
11708 || !TARGET_PARTIAL_FLAG_REG_STALL
11709 || (operands[2] == const1_rtx
11711 || TARGET_DOUBLE_WITH_ADD)))
11712 && ix86_match_ccmode (insn, CCGOCmode)
11713 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11715 switch (get_attr_type (insn))
11718 gcc_assert (operands[2] == const1_rtx);
11719 return "add{l}\t%0, %0";
11722 if (REG_P (operands[2]))
11723 return "sal{l}\t{%b2, %0|%0, %b2}";
11724 else if (operands[2] == const1_rtx
11725 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11726 return "sal{l}\t%0";
11728 return "sal{l}\t{%2, %0|%0, %2}";
11731 [(set (attr "type")
11732 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11734 (match_operand 0 "register_operand" ""))
11735 (match_operand 2 "const1_operand" ""))
11736 (const_string "alu")
11738 (const_string "ishift")))
11739 (set_attr "mode" "SI")])
11741 (define_insn "*ashlsi3_cmp_zext"
11742 [(set (reg FLAGS_REG)
11744 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11745 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11747 (set (match_operand:DI 0 "register_operand" "=r")
11748 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11750 && (optimize_function_for_size_p (cfun)
11751 || !TARGET_PARTIAL_FLAG_REG_STALL
11752 || (operands[2] == const1_rtx
11754 || TARGET_DOUBLE_WITH_ADD)))
11755 && ix86_match_ccmode (insn, CCGOCmode)
11756 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11758 switch (get_attr_type (insn))
11761 gcc_assert (operands[2] == const1_rtx);
11762 return "add{l}\t%k0, %k0";
11765 if (REG_P (operands[2]))
11766 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11767 else if (operands[2] == const1_rtx
11768 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11769 return "sal{l}\t%k0";
11771 return "sal{l}\t{%2, %k0|%k0, %2}";
11774 [(set (attr "type")
11775 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11777 (match_operand 2 "const1_operand" ""))
11778 (const_string "alu")
11780 (const_string "ishift")))
11781 (set_attr "mode" "SI")])
11783 (define_expand "ashlhi3"
11784 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11785 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11786 (match_operand:QI 2 "nonmemory_operand" "")))]
11787 "TARGET_HIMODE_MATH"
11788 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11790 (define_insn "*ashlhi3_1_lea"
11791 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11792 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11793 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11794 (clobber (reg:CC FLAGS_REG))]
11795 "!TARGET_PARTIAL_REG_STALL
11796 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11798 switch (get_attr_type (insn))
11803 gcc_assert (operands[2] == const1_rtx);
11804 return "add{w}\t%0, %0";
11807 if (REG_P (operands[2]))
11808 return "sal{w}\t{%b2, %0|%0, %b2}";
11809 else if (operands[2] == const1_rtx
11810 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11811 return "sal{w}\t%0";
11813 return "sal{w}\t{%2, %0|%0, %2}";
11816 [(set (attr "type")
11817 (cond [(eq_attr "alternative" "1")
11818 (const_string "lea")
11819 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11821 (match_operand 0 "register_operand" ""))
11822 (match_operand 2 "const1_operand" ""))
11823 (const_string "alu")
11825 (const_string "ishift")))
11826 (set_attr "mode" "HI,SI")])
11828 (define_insn "*ashlhi3_1"
11829 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11830 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11831 (match_operand:QI 2 "nonmemory_operand" "cI")))
11832 (clobber (reg:CC FLAGS_REG))]
11833 "TARGET_PARTIAL_REG_STALL
11834 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11836 switch (get_attr_type (insn))
11839 gcc_assert (operands[2] == const1_rtx);
11840 return "add{w}\t%0, %0";
11843 if (REG_P (operands[2]))
11844 return "sal{w}\t{%b2, %0|%0, %b2}";
11845 else if (operands[2] == const1_rtx
11846 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11847 return "sal{w}\t%0";
11849 return "sal{w}\t{%2, %0|%0, %2}";
11852 [(set (attr "type")
11853 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11855 (match_operand 0 "register_operand" ""))
11856 (match_operand 2 "const1_operand" ""))
11857 (const_string "alu")
11859 (const_string "ishift")))
11860 (set_attr "mode" "HI")])
11862 ;; This pattern can't accept a variable shift count, since shifts by
11863 ;; zero don't affect the flags. We assume that shifts by constant
11864 ;; zero are optimized away.
11865 (define_insn "*ashlhi3_cmp"
11866 [(set (reg FLAGS_REG)
11868 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11869 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11871 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11872 (ashift:HI (match_dup 1) (match_dup 2)))]
11873 "(optimize_function_for_size_p (cfun)
11874 || !TARGET_PARTIAL_FLAG_REG_STALL
11875 || (operands[2] == const1_rtx
11877 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11878 && ix86_match_ccmode (insn, CCGOCmode)
11879 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11881 switch (get_attr_type (insn))
11884 gcc_assert (operands[2] == const1_rtx);
11885 return "add{w}\t%0, %0";
11888 if (REG_P (operands[2]))
11889 return "sal{w}\t{%b2, %0|%0, %b2}";
11890 else if (operands[2] == const1_rtx
11891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11892 return "sal{w}\t%0";
11894 return "sal{w}\t{%2, %0|%0, %2}";
11897 [(set (attr "type")
11898 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11900 (match_operand 0 "register_operand" ""))
11901 (match_operand 2 "const1_operand" ""))
11902 (const_string "alu")
11904 (const_string "ishift")))
11905 (set_attr "mode" "HI")])
11907 (define_insn "*ashlhi3_cconly"
11908 [(set (reg FLAGS_REG)
11910 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11911 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11913 (clobber (match_scratch:HI 0 "=r"))]
11914 "(optimize_function_for_size_p (cfun)
11915 || !TARGET_PARTIAL_FLAG_REG_STALL
11916 || (operands[2] == const1_rtx
11918 || TARGET_DOUBLE_WITH_ADD)))
11919 && ix86_match_ccmode (insn, CCGOCmode)
11920 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11922 switch (get_attr_type (insn))
11925 gcc_assert (operands[2] == const1_rtx);
11926 return "add{w}\t%0, %0";
11929 if (REG_P (operands[2]))
11930 return "sal{w}\t{%b2, %0|%0, %b2}";
11931 else if (operands[2] == const1_rtx
11932 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11933 return "sal{w}\t%0";
11935 return "sal{w}\t{%2, %0|%0, %2}";
11938 [(set (attr "type")
11939 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11941 (match_operand 0 "register_operand" ""))
11942 (match_operand 2 "const1_operand" ""))
11943 (const_string "alu")
11945 (const_string "ishift")))
11946 (set_attr "mode" "HI")])
11948 (define_expand "ashlqi3"
11949 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11950 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11951 (match_operand:QI 2 "nonmemory_operand" "")))]
11952 "TARGET_QIMODE_MATH"
11953 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11955 ;; %%% Potential partial reg stall on alternative 2. What to do?
11957 (define_insn "*ashlqi3_1_lea"
11958 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11959 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11960 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11961 (clobber (reg:CC FLAGS_REG))]
11962 "!TARGET_PARTIAL_REG_STALL
11963 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11965 switch (get_attr_type (insn))
11970 gcc_assert (operands[2] == const1_rtx);
11971 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11972 return "add{l}\t%k0, %k0";
11974 return "add{b}\t%0, %0";
11977 if (REG_P (operands[2]))
11979 if (get_attr_mode (insn) == MODE_SI)
11980 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11982 return "sal{b}\t{%b2, %0|%0, %b2}";
11984 else if (operands[2] == const1_rtx
11985 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11987 if (get_attr_mode (insn) == MODE_SI)
11988 return "sal{l}\t%0";
11990 return "sal{b}\t%0";
11994 if (get_attr_mode (insn) == MODE_SI)
11995 return "sal{l}\t{%2, %k0|%k0, %2}";
11997 return "sal{b}\t{%2, %0|%0, %2}";
12001 [(set (attr "type")
12002 (cond [(eq_attr "alternative" "2")
12003 (const_string "lea")
12004 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12006 (match_operand 0 "register_operand" ""))
12007 (match_operand 2 "const1_operand" ""))
12008 (const_string "alu")
12010 (const_string "ishift")))
12011 (set_attr "mode" "QI,SI,SI")])
12013 (define_insn "*ashlqi3_1"
12014 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12015 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12016 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12017 (clobber (reg:CC FLAGS_REG))]
12018 "TARGET_PARTIAL_REG_STALL
12019 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12021 switch (get_attr_type (insn))
12024 gcc_assert (operands[2] == const1_rtx);
12025 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12026 return "add{l}\t%k0, %k0";
12028 return "add{b}\t%0, %0";
12031 if (REG_P (operands[2]))
12033 if (get_attr_mode (insn) == MODE_SI)
12034 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12036 return "sal{b}\t{%b2, %0|%0, %b2}";
12038 else if (operands[2] == const1_rtx
12039 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12041 if (get_attr_mode (insn) == MODE_SI)
12042 return "sal{l}\t%0";
12044 return "sal{b}\t%0";
12048 if (get_attr_mode (insn) == MODE_SI)
12049 return "sal{l}\t{%2, %k0|%k0, %2}";
12051 return "sal{b}\t{%2, %0|%0, %2}";
12055 [(set (attr "type")
12056 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12058 (match_operand 0 "register_operand" ""))
12059 (match_operand 2 "const1_operand" ""))
12060 (const_string "alu")
12062 (const_string "ishift")))
12063 (set_attr "mode" "QI,SI")])
12065 ;; This pattern can't accept a variable shift count, since shifts by
12066 ;; zero don't affect the flags. We assume that shifts by constant
12067 ;; zero are optimized away.
12068 (define_insn "*ashlqi3_cmp"
12069 [(set (reg FLAGS_REG)
12071 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12072 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12074 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12075 (ashift:QI (match_dup 1) (match_dup 2)))]
12076 "(optimize_function_for_size_p (cfun)
12077 || !TARGET_PARTIAL_FLAG_REG_STALL
12078 || (operands[2] == const1_rtx
12080 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12081 && ix86_match_ccmode (insn, CCGOCmode)
12082 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12084 switch (get_attr_type (insn))
12087 gcc_assert (operands[2] == const1_rtx);
12088 return "add{b}\t%0, %0";
12091 if (REG_P (operands[2]))
12092 return "sal{b}\t{%b2, %0|%0, %b2}";
12093 else if (operands[2] == const1_rtx
12094 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12095 return "sal{b}\t%0";
12097 return "sal{b}\t{%2, %0|%0, %2}";
12100 [(set (attr "type")
12101 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12103 (match_operand 0 "register_operand" ""))
12104 (match_operand 2 "const1_operand" ""))
12105 (const_string "alu")
12107 (const_string "ishift")))
12108 (set_attr "mode" "QI")])
12110 (define_insn "*ashlqi3_cconly"
12111 [(set (reg FLAGS_REG)
12113 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12114 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12116 (clobber (match_scratch:QI 0 "=q"))]
12117 "(optimize_function_for_size_p (cfun)
12118 || !TARGET_PARTIAL_FLAG_REG_STALL
12119 || (operands[2] == const1_rtx
12121 || TARGET_DOUBLE_WITH_ADD)))
12122 && ix86_match_ccmode (insn, CCGOCmode)
12123 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12125 switch (get_attr_type (insn))
12128 gcc_assert (operands[2] == const1_rtx);
12129 return "add{b}\t%0, %0";
12132 if (REG_P (operands[2]))
12133 return "sal{b}\t{%b2, %0|%0, %b2}";
12134 else if (operands[2] == const1_rtx
12135 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12136 return "sal{b}\t%0";
12138 return "sal{b}\t{%2, %0|%0, %2}";
12141 [(set (attr "type")
12142 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12144 (match_operand 0 "register_operand" ""))
12145 (match_operand 2 "const1_operand" ""))
12146 (const_string "alu")
12148 (const_string "ishift")))
12149 (set_attr "mode" "QI")])
12151 ;; See comment above `ashldi3' about how this works.
12153 (define_expand "ashrti3"
12154 [(set (match_operand:TI 0 "register_operand" "")
12155 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12156 (match_operand:QI 2 "nonmemory_operand" "")))]
12158 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12160 (define_insn "*ashrti3_1"
12161 [(set (match_operand:TI 0 "register_operand" "=r")
12162 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12163 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12164 (clobber (reg:CC FLAGS_REG))]
12167 [(set_attr "type" "multi")])
12170 [(match_scratch:DI 3 "r")
12171 (parallel [(set (match_operand:TI 0 "register_operand" "")
12172 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12173 (match_operand:QI 2 "nonmemory_operand" "")))
12174 (clobber (reg:CC FLAGS_REG))])
12178 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12181 [(set (match_operand:TI 0 "register_operand" "")
12182 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12183 (match_operand:QI 2 "nonmemory_operand" "")))
12184 (clobber (reg:CC FLAGS_REG))]
12185 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12186 ? epilogue_completed : reload_completed)"
12188 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12190 (define_insn "x86_64_shrd"
12191 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12192 (ior:DI (ashiftrt:DI (match_dup 0)
12193 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12194 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12195 (minus:QI (const_int 64) (match_dup 2)))))
12196 (clobber (reg:CC FLAGS_REG))]
12198 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12199 [(set_attr "type" "ishift")
12200 (set_attr "prefix_0f" "1")
12201 (set_attr "mode" "DI")
12202 (set_attr "athlon_decode" "vector")
12203 (set_attr "amdfam10_decode" "vector")])
12205 (define_expand "ashrdi3"
12206 [(set (match_operand:DI 0 "shiftdi_operand" "")
12207 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12208 (match_operand:QI 2 "nonmemory_operand" "")))]
12210 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12212 (define_expand "x86_64_shift_adj_3"
12213 [(use (match_operand:DI 0 "register_operand" ""))
12214 (use (match_operand:DI 1 "register_operand" ""))
12215 (use (match_operand:QI 2 "register_operand" ""))]
12218 rtx label = gen_label_rtx ();
12221 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12223 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12224 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12225 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12226 gen_rtx_LABEL_REF (VOIDmode, label),
12228 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12229 JUMP_LABEL (tmp) = label;
12231 emit_move_insn (operands[0], operands[1]);
12232 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12234 emit_label (label);
12235 LABEL_NUSES (label) = 1;
12240 (define_insn "ashrdi3_63_rex64"
12241 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12242 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12243 (match_operand:DI 2 "const_int_operand" "i,i")))
12244 (clobber (reg:CC FLAGS_REG))]
12245 "TARGET_64BIT && INTVAL (operands[2]) == 63
12246 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12247 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12250 sar{q}\t{%2, %0|%0, %2}"
12251 [(set_attr "type" "imovx,ishift")
12252 (set_attr "prefix_0f" "0,*")
12253 (set_attr "length_immediate" "0,*")
12254 (set_attr "modrm" "0,1")
12255 (set_attr "mode" "DI")])
12257 (define_insn "*ashrdi3_1_one_bit_rex64"
12258 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12259 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12260 (match_operand:QI 2 "const1_operand" "")))
12261 (clobber (reg:CC FLAGS_REG))]
12263 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12264 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12266 [(set_attr "type" "ishift")
12267 (set (attr "length")
12268 (if_then_else (match_operand:DI 0 "register_operand" "")
12270 (const_string "*")))])
12272 (define_insn "*ashrdi3_1_rex64"
12273 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12274 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12275 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12276 (clobber (reg:CC FLAGS_REG))]
12277 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12279 sar{q}\t{%2, %0|%0, %2}
12280 sar{q}\t{%b2, %0|%0, %b2}"
12281 [(set_attr "type" "ishift")
12282 (set_attr "mode" "DI")])
12284 ;; This pattern can't accept a variable shift count, since shifts by
12285 ;; zero don't affect the flags. We assume that shifts by constant
12286 ;; zero are optimized away.
12287 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12288 [(set (reg FLAGS_REG)
12290 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12291 (match_operand:QI 2 "const1_operand" ""))
12293 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12294 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12296 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12297 && ix86_match_ccmode (insn, CCGOCmode)
12298 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12300 [(set_attr "type" "ishift")
12301 (set (attr "length")
12302 (if_then_else (match_operand:DI 0 "register_operand" "")
12304 (const_string "*")))])
12306 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12307 [(set (reg FLAGS_REG)
12309 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12310 (match_operand:QI 2 "const1_operand" ""))
12312 (clobber (match_scratch:DI 0 "=r"))]
12314 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12315 && ix86_match_ccmode (insn, CCGOCmode)
12316 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12318 [(set_attr "type" "ishift")
12319 (set_attr "length" "2")])
12321 ;; This pattern can't accept a variable shift count, since shifts by
12322 ;; zero don't affect the flags. We assume that shifts by constant
12323 ;; zero are optimized away.
12324 (define_insn "*ashrdi3_cmp_rex64"
12325 [(set (reg FLAGS_REG)
12327 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12328 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12330 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12331 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12333 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12334 && ix86_match_ccmode (insn, CCGOCmode)
12335 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12336 "sar{q}\t{%2, %0|%0, %2}"
12337 [(set_attr "type" "ishift")
12338 (set_attr "mode" "DI")])
12340 (define_insn "*ashrdi3_cconly_rex64"
12341 [(set (reg FLAGS_REG)
12343 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12344 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12346 (clobber (match_scratch:DI 0 "=r"))]
12348 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12349 && ix86_match_ccmode (insn, CCGOCmode)
12350 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12351 "sar{q}\t{%2, %0|%0, %2}"
12352 [(set_attr "type" "ishift")
12353 (set_attr "mode" "DI")])
12355 (define_insn "*ashrdi3_1"
12356 [(set (match_operand:DI 0 "register_operand" "=r")
12357 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12358 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12359 (clobber (reg:CC FLAGS_REG))]
12362 [(set_attr "type" "multi")])
12364 ;; By default we don't ask for a scratch register, because when DImode
12365 ;; values are manipulated, registers are already at a premium. But if
12366 ;; we have one handy, we won't turn it away.
12368 [(match_scratch:SI 3 "r")
12369 (parallel [(set (match_operand:DI 0 "register_operand" "")
12370 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12371 (match_operand:QI 2 "nonmemory_operand" "")))
12372 (clobber (reg:CC FLAGS_REG))])
12374 "!TARGET_64BIT && TARGET_CMOVE"
12376 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12379 [(set (match_operand:DI 0 "register_operand" "")
12380 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12381 (match_operand:QI 2 "nonmemory_operand" "")))
12382 (clobber (reg:CC FLAGS_REG))]
12383 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12384 ? epilogue_completed : reload_completed)"
12386 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12388 (define_insn "x86_shrd"
12389 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12390 (ior:SI (ashiftrt:SI (match_dup 0)
12391 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12392 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12393 (minus:QI (const_int 32) (match_dup 2)))))
12394 (clobber (reg:CC FLAGS_REG))]
12396 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12397 [(set_attr "type" "ishift")
12398 (set_attr "prefix_0f" "1")
12399 (set_attr "pent_pair" "np")
12400 (set_attr "mode" "SI")])
12402 (define_expand "x86_shift_adj_3"
12403 [(use (match_operand:SI 0 "register_operand" ""))
12404 (use (match_operand:SI 1 "register_operand" ""))
12405 (use (match_operand:QI 2 "register_operand" ""))]
12408 rtx label = gen_label_rtx ();
12411 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12413 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12414 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12415 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12416 gen_rtx_LABEL_REF (VOIDmode, label),
12418 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12419 JUMP_LABEL (tmp) = label;
12421 emit_move_insn (operands[0], operands[1]);
12422 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12424 emit_label (label);
12425 LABEL_NUSES (label) = 1;
12430 (define_expand "ashrsi3_31"
12431 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12432 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12433 (match_operand:SI 2 "const_int_operand" "i,i")))
12434 (clobber (reg:CC FLAGS_REG))])]
12437 (define_insn "*ashrsi3_31"
12438 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12439 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12440 (match_operand:SI 2 "const_int_operand" "i,i")))
12441 (clobber (reg:CC FLAGS_REG))]
12442 "INTVAL (operands[2]) == 31
12443 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12444 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12447 sar{l}\t{%2, %0|%0, %2}"
12448 [(set_attr "type" "imovx,ishift")
12449 (set_attr "prefix_0f" "0,*")
12450 (set_attr "length_immediate" "0,*")
12451 (set_attr "modrm" "0,1")
12452 (set_attr "mode" "SI")])
12454 (define_insn "*ashrsi3_31_zext"
12455 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12456 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12457 (match_operand:SI 2 "const_int_operand" "i,i"))))
12458 (clobber (reg:CC FLAGS_REG))]
12459 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12460 && INTVAL (operands[2]) == 31
12461 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12464 sar{l}\t{%2, %k0|%k0, %2}"
12465 [(set_attr "type" "imovx,ishift")
12466 (set_attr "prefix_0f" "0,*")
12467 (set_attr "length_immediate" "0,*")
12468 (set_attr "modrm" "0,1")
12469 (set_attr "mode" "SI")])
12471 (define_expand "ashrsi3"
12472 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12473 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12474 (match_operand:QI 2 "nonmemory_operand" "")))]
12476 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12478 (define_insn "*ashrsi3_1_one_bit"
12479 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12480 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12481 (match_operand:QI 2 "const1_operand" "")))
12482 (clobber (reg:CC FLAGS_REG))]
12483 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12484 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12486 [(set_attr "type" "ishift")
12487 (set (attr "length")
12488 (if_then_else (match_operand:SI 0 "register_operand" "")
12490 (const_string "*")))])
12492 (define_insn "*ashrsi3_1_one_bit_zext"
12493 [(set (match_operand:DI 0 "register_operand" "=r")
12494 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12495 (match_operand:QI 2 "const1_operand" ""))))
12496 (clobber (reg:CC FLAGS_REG))]
12498 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12499 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12501 [(set_attr "type" "ishift")
12502 (set_attr "length" "2")])
12504 (define_insn "*ashrsi3_1"
12505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12506 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12507 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12508 (clobber (reg:CC FLAGS_REG))]
12509 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12511 sar{l}\t{%2, %0|%0, %2}
12512 sar{l}\t{%b2, %0|%0, %b2}"
12513 [(set_attr "type" "ishift")
12514 (set_attr "mode" "SI")])
12516 (define_insn "*ashrsi3_1_zext"
12517 [(set (match_operand:DI 0 "register_operand" "=r,r")
12518 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12519 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12520 (clobber (reg:CC FLAGS_REG))]
12521 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12523 sar{l}\t{%2, %k0|%k0, %2}
12524 sar{l}\t{%b2, %k0|%k0, %b2}"
12525 [(set_attr "type" "ishift")
12526 (set_attr "mode" "SI")])
12528 ;; This pattern can't accept a variable shift count, since shifts by
12529 ;; zero don't affect the flags. We assume that shifts by constant
12530 ;; zero are optimized away.
12531 (define_insn "*ashrsi3_one_bit_cmp"
12532 [(set (reg FLAGS_REG)
12534 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12535 (match_operand:QI 2 "const1_operand" ""))
12537 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12538 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12539 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12540 && ix86_match_ccmode (insn, CCGOCmode)
12541 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12543 [(set_attr "type" "ishift")
12544 (set (attr "length")
12545 (if_then_else (match_operand:SI 0 "register_operand" "")
12547 (const_string "*")))])
12549 (define_insn "*ashrsi3_one_bit_cconly"
12550 [(set (reg FLAGS_REG)
12552 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12553 (match_operand:QI 2 "const1_operand" ""))
12555 (clobber (match_scratch:SI 0 "=r"))]
12556 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12557 && ix86_match_ccmode (insn, CCGOCmode)
12558 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12560 [(set_attr "type" "ishift")
12561 (set_attr "length" "2")])
12563 (define_insn "*ashrsi3_one_bit_cmp_zext"
12564 [(set (reg FLAGS_REG)
12566 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12567 (match_operand:QI 2 "const1_operand" ""))
12569 (set (match_operand:DI 0 "register_operand" "=r")
12570 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12572 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12573 && ix86_match_ccmode (insn, CCmode)
12574 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12576 [(set_attr "type" "ishift")
12577 (set_attr "length" "2")])
12579 ;; This pattern can't accept a variable shift count, since shifts by
12580 ;; zero don't affect the flags. We assume that shifts by constant
12581 ;; zero are optimized away.
12582 (define_insn "*ashrsi3_cmp"
12583 [(set (reg FLAGS_REG)
12585 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12586 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12588 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12589 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12590 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12591 && ix86_match_ccmode (insn, CCGOCmode)
12592 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12593 "sar{l}\t{%2, %0|%0, %2}"
12594 [(set_attr "type" "ishift")
12595 (set_attr "mode" "SI")])
12597 (define_insn "*ashrsi3_cconly"
12598 [(set (reg FLAGS_REG)
12600 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12601 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12603 (clobber (match_scratch:SI 0 "=r"))]
12604 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12605 && ix86_match_ccmode (insn, CCGOCmode)
12606 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12607 "sar{l}\t{%2, %0|%0, %2}"
12608 [(set_attr "type" "ishift")
12609 (set_attr "mode" "SI")])
12611 (define_insn "*ashrsi3_cmp_zext"
12612 [(set (reg FLAGS_REG)
12614 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12615 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12617 (set (match_operand:DI 0 "register_operand" "=r")
12618 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12620 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12621 && ix86_match_ccmode (insn, CCGOCmode)
12622 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12623 "sar{l}\t{%2, %k0|%k0, %2}"
12624 [(set_attr "type" "ishift")
12625 (set_attr "mode" "SI")])
12627 (define_expand "ashrhi3"
12628 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12629 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12630 (match_operand:QI 2 "nonmemory_operand" "")))]
12631 "TARGET_HIMODE_MATH"
12632 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12634 (define_insn "*ashrhi3_1_one_bit"
12635 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12636 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12637 (match_operand:QI 2 "const1_operand" "")))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12640 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12642 [(set_attr "type" "ishift")
12643 (set (attr "length")
12644 (if_then_else (match_operand 0 "register_operand" "")
12646 (const_string "*")))])
12648 (define_insn "*ashrhi3_1"
12649 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12650 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12651 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12652 (clobber (reg:CC FLAGS_REG))]
12653 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12655 sar{w}\t{%2, %0|%0, %2}
12656 sar{w}\t{%b2, %0|%0, %b2}"
12657 [(set_attr "type" "ishift")
12658 (set_attr "mode" "HI")])
12660 ;; This pattern can't accept a variable shift count, since shifts by
12661 ;; zero don't affect the flags. We assume that shifts by constant
12662 ;; zero are optimized away.
12663 (define_insn "*ashrhi3_one_bit_cmp"
12664 [(set (reg FLAGS_REG)
12666 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12667 (match_operand:QI 2 "const1_operand" ""))
12669 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12670 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12671 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12672 && ix86_match_ccmode (insn, CCGOCmode)
12673 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12675 [(set_attr "type" "ishift")
12676 (set (attr "length")
12677 (if_then_else (match_operand 0 "register_operand" "")
12679 (const_string "*")))])
12681 (define_insn "*ashrhi3_one_bit_cconly"
12682 [(set (reg FLAGS_REG)
12684 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12685 (match_operand:QI 2 "const1_operand" ""))
12687 (clobber (match_scratch:HI 0 "=r"))]
12688 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12689 && ix86_match_ccmode (insn, CCGOCmode)
12690 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12692 [(set_attr "type" "ishift")
12693 (set_attr "length" "2")])
12695 ;; This pattern can't accept a variable shift count, since shifts by
12696 ;; zero don't affect the flags. We assume that shifts by constant
12697 ;; zero are optimized away.
12698 (define_insn "*ashrhi3_cmp"
12699 [(set (reg FLAGS_REG)
12701 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12702 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12704 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12705 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12706 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12707 && ix86_match_ccmode (insn, CCGOCmode)
12708 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12709 "sar{w}\t{%2, %0|%0, %2}"
12710 [(set_attr "type" "ishift")
12711 (set_attr "mode" "HI")])
12713 (define_insn "*ashrhi3_cconly"
12714 [(set (reg FLAGS_REG)
12716 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12717 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12719 (clobber (match_scratch:HI 0 "=r"))]
12720 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12721 && ix86_match_ccmode (insn, CCGOCmode)
12722 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12723 "sar{w}\t{%2, %0|%0, %2}"
12724 [(set_attr "type" "ishift")
12725 (set_attr "mode" "HI")])
12727 (define_expand "ashrqi3"
12728 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12729 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12730 (match_operand:QI 2 "nonmemory_operand" "")))]
12731 "TARGET_QIMODE_MATH"
12732 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12734 (define_insn "*ashrqi3_1_one_bit"
12735 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12736 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12737 (match_operand:QI 2 "const1_operand" "")))
12738 (clobber (reg:CC FLAGS_REG))]
12739 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12740 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12742 [(set_attr "type" "ishift")
12743 (set (attr "length")
12744 (if_then_else (match_operand 0 "register_operand" "")
12746 (const_string "*")))])
12748 (define_insn "*ashrqi3_1_one_bit_slp"
12749 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12750 (ashiftrt:QI (match_dup 0)
12751 (match_operand:QI 1 "const1_operand" "")))
12752 (clobber (reg:CC FLAGS_REG))]
12753 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12754 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12755 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12757 [(set_attr "type" "ishift1")
12758 (set (attr "length")
12759 (if_then_else (match_operand 0 "register_operand" "")
12761 (const_string "*")))])
12763 (define_insn "*ashrqi3_1"
12764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12765 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12766 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12767 (clobber (reg:CC FLAGS_REG))]
12768 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12770 sar{b}\t{%2, %0|%0, %2}
12771 sar{b}\t{%b2, %0|%0, %b2}"
12772 [(set_attr "type" "ishift")
12773 (set_attr "mode" "QI")])
12775 (define_insn "*ashrqi3_1_slp"
12776 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12777 (ashiftrt:QI (match_dup 0)
12778 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12779 (clobber (reg:CC FLAGS_REG))]
12780 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12783 sar{b}\t{%1, %0|%0, %1}
12784 sar{b}\t{%b1, %0|%0, %b1}"
12785 [(set_attr "type" "ishift1")
12786 (set_attr "mode" "QI")])
12788 ;; This pattern can't accept a variable shift count, since shifts by
12789 ;; zero don't affect the flags. We assume that shifts by constant
12790 ;; zero are optimized away.
12791 (define_insn "*ashrqi3_one_bit_cmp"
12792 [(set (reg FLAGS_REG)
12794 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12795 (match_operand:QI 2 "const1_operand" "I"))
12797 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12798 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12799 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12800 && ix86_match_ccmode (insn, CCGOCmode)
12801 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12803 [(set_attr "type" "ishift")
12804 (set (attr "length")
12805 (if_then_else (match_operand 0 "register_operand" "")
12807 (const_string "*")))])
12809 (define_insn "*ashrqi3_one_bit_cconly"
12810 [(set (reg FLAGS_REG)
12812 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12813 (match_operand:QI 2 "const1_operand" ""))
12815 (clobber (match_scratch:QI 0 "=q"))]
12816 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12817 && ix86_match_ccmode (insn, CCGOCmode)
12818 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12820 [(set_attr "type" "ishift")
12821 (set_attr "length" "2")])
12823 ;; This pattern can't accept a variable shift count, since shifts by
12824 ;; zero don't affect the flags. We assume that shifts by constant
12825 ;; zero are optimized away.
12826 (define_insn "*ashrqi3_cmp"
12827 [(set (reg FLAGS_REG)
12829 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12830 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12832 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12833 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12834 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12835 && ix86_match_ccmode (insn, CCGOCmode)
12836 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12837 "sar{b}\t{%2, %0|%0, %2}"
12838 [(set_attr "type" "ishift")
12839 (set_attr "mode" "QI")])
12841 (define_insn "*ashrqi3_cconly"
12842 [(set (reg FLAGS_REG)
12844 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12845 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12847 (clobber (match_scratch:QI 0 "=q"))]
12848 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12849 && ix86_match_ccmode (insn, CCGOCmode)
12850 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12851 "sar{b}\t{%2, %0|%0, %2}"
12852 [(set_attr "type" "ishift")
12853 (set_attr "mode" "QI")])
12856 ;; Logical shift instructions
12858 ;; See comment above `ashldi3' about how this works.
12860 (define_expand "lshrti3"
12861 [(set (match_operand:TI 0 "register_operand" "")
12862 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12863 (match_operand:QI 2 "nonmemory_operand" "")))]
12865 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12867 ;; This pattern must be defined before *lshrti3_1 to prevent
12868 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12870 (define_insn "*avx_lshrti3"
12871 [(set (match_operand:TI 0 "register_operand" "=x")
12872 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12873 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12876 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12877 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12879 [(set_attr "type" "sseishft")
12880 (set_attr "prefix" "vex")
12881 (set_attr "mode" "TI")])
12883 (define_insn "sse2_lshrti3"
12884 [(set (match_operand:TI 0 "register_operand" "=x")
12885 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12886 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12889 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12890 return "psrldq\t{%2, %0|%0, %2}";
12892 [(set_attr "type" "sseishft")
12893 (set_attr "prefix_data16" "1")
12894 (set_attr "mode" "TI")])
12896 (define_insn "*lshrti3_1"
12897 [(set (match_operand:TI 0 "register_operand" "=r")
12898 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12899 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12900 (clobber (reg:CC FLAGS_REG))]
12903 [(set_attr "type" "multi")])
12906 [(match_scratch:DI 3 "r")
12907 (parallel [(set (match_operand:TI 0 "register_operand" "")
12908 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12909 (match_operand:QI 2 "nonmemory_operand" "")))
12910 (clobber (reg:CC FLAGS_REG))])
12914 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12917 [(set (match_operand:TI 0 "register_operand" "")
12918 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12919 (match_operand:QI 2 "nonmemory_operand" "")))
12920 (clobber (reg:CC FLAGS_REG))]
12921 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12922 ? epilogue_completed : reload_completed)"
12924 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12926 (define_expand "lshrdi3"
12927 [(set (match_operand:DI 0 "shiftdi_operand" "")
12928 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12929 (match_operand:QI 2 "nonmemory_operand" "")))]
12931 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12933 (define_insn "*lshrdi3_1_one_bit_rex64"
12934 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12935 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12936 (match_operand:QI 2 "const1_operand" "")))
12937 (clobber (reg:CC FLAGS_REG))]
12939 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12940 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12942 [(set_attr "type" "ishift")
12943 (set (attr "length")
12944 (if_then_else (match_operand:DI 0 "register_operand" "")
12946 (const_string "*")))])
12948 (define_insn "*lshrdi3_1_rex64"
12949 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12950 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12951 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12955 shr{q}\t{%2, %0|%0, %2}
12956 shr{q}\t{%b2, %0|%0, %b2}"
12957 [(set_attr "type" "ishift")
12958 (set_attr "mode" "DI")])
12960 ;; This pattern can't accept a variable shift count, since shifts by
12961 ;; zero don't affect the flags. We assume that shifts by constant
12962 ;; zero are optimized away.
12963 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12964 [(set (reg FLAGS_REG)
12966 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12967 (match_operand:QI 2 "const1_operand" ""))
12969 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12970 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12972 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12973 && ix86_match_ccmode (insn, CCGOCmode)
12974 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12976 [(set_attr "type" "ishift")
12977 (set (attr "length")
12978 (if_then_else (match_operand:DI 0 "register_operand" "")
12980 (const_string "*")))])
12982 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12983 [(set (reg FLAGS_REG)
12985 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12986 (match_operand:QI 2 "const1_operand" ""))
12988 (clobber (match_scratch:DI 0 "=r"))]
12990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12991 && ix86_match_ccmode (insn, CCGOCmode)
12992 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12994 [(set_attr "type" "ishift")
12995 (set_attr "length" "2")])
12997 ;; This pattern can't accept a variable shift count, since shifts by
12998 ;; zero don't affect the flags. We assume that shifts by constant
12999 ;; zero are optimized away.
13000 (define_insn "*lshrdi3_cmp_rex64"
13001 [(set (reg FLAGS_REG)
13003 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13004 (match_operand:QI 2 "const_1_to_63_operand" "J"))
13006 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13007 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13009 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13010 && ix86_match_ccmode (insn, CCGOCmode)
13011 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13012 "shr{q}\t{%2, %0|%0, %2}"
13013 [(set_attr "type" "ishift")
13014 (set_attr "mode" "DI")])
13016 (define_insn "*lshrdi3_cconly_rex64"
13017 [(set (reg FLAGS_REG)
13019 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13020 (match_operand:QI 2 "const_1_to_63_operand" "J"))
13022 (clobber (match_scratch:DI 0 "=r"))]
13024 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13025 && ix86_match_ccmode (insn, CCGOCmode)
13026 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027 "shr{q}\t{%2, %0|%0, %2}"
13028 [(set_attr "type" "ishift")
13029 (set_attr "mode" "DI")])
13031 (define_insn "*lshrdi3_1"
13032 [(set (match_operand:DI 0 "register_operand" "=r")
13033 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13034 (match_operand:QI 2 "nonmemory_operand" "Jc")))
13035 (clobber (reg:CC FLAGS_REG))]
13038 [(set_attr "type" "multi")])
13040 ;; By default we don't ask for a scratch register, because when DImode
13041 ;; values are manipulated, registers are already at a premium. But if
13042 ;; we have one handy, we won't turn it away.
13044 [(match_scratch:SI 3 "r")
13045 (parallel [(set (match_operand:DI 0 "register_operand" "")
13046 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13047 (match_operand:QI 2 "nonmemory_operand" "")))
13048 (clobber (reg:CC FLAGS_REG))])
13050 "!TARGET_64BIT && TARGET_CMOVE"
13052 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13055 [(set (match_operand:DI 0 "register_operand" "")
13056 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13057 (match_operand:QI 2 "nonmemory_operand" "")))
13058 (clobber (reg:CC FLAGS_REG))]
13059 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13060 ? epilogue_completed : reload_completed)"
13062 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13064 (define_expand "lshrsi3"
13065 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13066 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13067 (match_operand:QI 2 "nonmemory_operand" "")))]
13069 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13071 (define_insn "*lshrsi3_1_one_bit"
13072 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13073 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13074 (match_operand:QI 2 "const1_operand" "")))
13075 (clobber (reg:CC FLAGS_REG))]
13076 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13077 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13079 [(set_attr "type" "ishift")
13080 (set (attr "length")
13081 (if_then_else (match_operand:SI 0 "register_operand" "")
13083 (const_string "*")))])
13085 (define_insn "*lshrsi3_1_one_bit_zext"
13086 [(set (match_operand:DI 0 "register_operand" "=r")
13087 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13088 (match_operand:QI 2 "const1_operand" "")))
13089 (clobber (reg:CC FLAGS_REG))]
13091 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13092 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13094 [(set_attr "type" "ishift")
13095 (set_attr "length" "2")])
13097 (define_insn "*lshrsi3_1"
13098 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13099 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13100 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13101 (clobber (reg:CC FLAGS_REG))]
13102 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13104 shr{l}\t{%2, %0|%0, %2}
13105 shr{l}\t{%b2, %0|%0, %b2}"
13106 [(set_attr "type" "ishift")
13107 (set_attr "mode" "SI")])
13109 (define_insn "*lshrsi3_1_zext"
13110 [(set (match_operand:DI 0 "register_operand" "=r,r")
13112 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13113 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13114 (clobber (reg:CC FLAGS_REG))]
13115 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13117 shr{l}\t{%2, %k0|%k0, %2}
13118 shr{l}\t{%b2, %k0|%k0, %b2}"
13119 [(set_attr "type" "ishift")
13120 (set_attr "mode" "SI")])
13122 ;; This pattern can't accept a variable shift count, since shifts by
13123 ;; zero don't affect the flags. We assume that shifts by constant
13124 ;; zero are optimized away.
13125 (define_insn "*lshrsi3_one_bit_cmp"
13126 [(set (reg FLAGS_REG)
13128 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13129 (match_operand:QI 2 "const1_operand" ""))
13131 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13132 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13133 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13134 && ix86_match_ccmode (insn, CCGOCmode)
13135 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13137 [(set_attr "type" "ishift")
13138 (set (attr "length")
13139 (if_then_else (match_operand:SI 0 "register_operand" "")
13141 (const_string "*")))])
13143 (define_insn "*lshrsi3_one_bit_cconly"
13144 [(set (reg FLAGS_REG)
13146 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13147 (match_operand:QI 2 "const1_operand" ""))
13149 (clobber (match_scratch:SI 0 "=r"))]
13150 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13151 && ix86_match_ccmode (insn, CCGOCmode)
13152 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13154 [(set_attr "type" "ishift")
13155 (set_attr "length" "2")])
13157 (define_insn "*lshrsi3_cmp_one_bit_zext"
13158 [(set (reg FLAGS_REG)
13160 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13161 (match_operand:QI 2 "const1_operand" ""))
13163 (set (match_operand:DI 0 "register_operand" "=r")
13164 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13166 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13167 && ix86_match_ccmode (insn, CCGOCmode)
13168 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13170 [(set_attr "type" "ishift")
13171 (set_attr "length" "2")])
13173 ;; This pattern can't accept a variable shift count, since shifts by
13174 ;; zero don't affect the flags. We assume that shifts by constant
13175 ;; zero are optimized away.
13176 (define_insn "*lshrsi3_cmp"
13177 [(set (reg FLAGS_REG)
13179 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13180 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13182 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13183 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13184 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13185 && ix86_match_ccmode (insn, CCGOCmode)
13186 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13187 "shr{l}\t{%2, %0|%0, %2}"
13188 [(set_attr "type" "ishift")
13189 (set_attr "mode" "SI")])
13191 (define_insn "*lshrsi3_cconly"
13192 [(set (reg FLAGS_REG)
13194 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13195 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13197 (clobber (match_scratch:SI 0 "=r"))]
13198 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13199 && ix86_match_ccmode (insn, CCGOCmode)
13200 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13201 "shr{l}\t{%2, %0|%0, %2}"
13202 [(set_attr "type" "ishift")
13203 (set_attr "mode" "SI")])
13205 (define_insn "*lshrsi3_cmp_zext"
13206 [(set (reg FLAGS_REG)
13208 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13209 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13211 (set (match_operand:DI 0 "register_operand" "=r")
13212 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13214 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13215 && ix86_match_ccmode (insn, CCGOCmode)
13216 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13217 "shr{l}\t{%2, %k0|%k0, %2}"
13218 [(set_attr "type" "ishift")
13219 (set_attr "mode" "SI")])
13221 (define_expand "lshrhi3"
13222 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13223 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13224 (match_operand:QI 2 "nonmemory_operand" "")))]
13225 "TARGET_HIMODE_MATH"
13226 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13228 (define_insn "*lshrhi3_1_one_bit"
13229 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13230 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13231 (match_operand:QI 2 "const1_operand" "")))
13232 (clobber (reg:CC FLAGS_REG))]
13233 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13234 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13236 [(set_attr "type" "ishift")
13237 (set (attr "length")
13238 (if_then_else (match_operand 0 "register_operand" "")
13240 (const_string "*")))])
13242 (define_insn "*lshrhi3_1"
13243 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13244 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13245 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13246 (clobber (reg:CC FLAGS_REG))]
13247 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13249 shr{w}\t{%2, %0|%0, %2}
13250 shr{w}\t{%b2, %0|%0, %b2}"
13251 [(set_attr "type" "ishift")
13252 (set_attr "mode" "HI")])
13254 ;; This pattern can't accept a variable shift count, since shifts by
13255 ;; zero don't affect the flags. We assume that shifts by constant
13256 ;; zero are optimized away.
13257 (define_insn "*lshrhi3_one_bit_cmp"
13258 [(set (reg FLAGS_REG)
13260 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13261 (match_operand:QI 2 "const1_operand" ""))
13263 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13264 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13265 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13266 && ix86_match_ccmode (insn, CCGOCmode)
13267 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13269 [(set_attr "type" "ishift")
13270 (set (attr "length")
13271 (if_then_else (match_operand:SI 0 "register_operand" "")
13273 (const_string "*")))])
13275 (define_insn "*lshrhi3_one_bit_cconly"
13276 [(set (reg FLAGS_REG)
13278 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13279 (match_operand:QI 2 "const1_operand" ""))
13281 (clobber (match_scratch:HI 0 "=r"))]
13282 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13283 && ix86_match_ccmode (insn, CCGOCmode)
13284 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13286 [(set_attr "type" "ishift")
13287 (set_attr "length" "2")])
13289 ;; This pattern can't accept a variable shift count, since shifts by
13290 ;; zero don't affect the flags. We assume that shifts by constant
13291 ;; zero are optimized away.
13292 (define_insn "*lshrhi3_cmp"
13293 [(set (reg FLAGS_REG)
13295 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13296 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13298 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13299 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13300 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13301 && ix86_match_ccmode (insn, CCGOCmode)
13302 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13303 "shr{w}\t{%2, %0|%0, %2}"
13304 [(set_attr "type" "ishift")
13305 (set_attr "mode" "HI")])
13307 (define_insn "*lshrhi3_cconly"
13308 [(set (reg FLAGS_REG)
13310 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13311 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13313 (clobber (match_scratch:HI 0 "=r"))]
13314 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13315 && ix86_match_ccmode (insn, CCGOCmode)
13316 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13317 "shr{w}\t{%2, %0|%0, %2}"
13318 [(set_attr "type" "ishift")
13319 (set_attr "mode" "HI")])
13321 (define_expand "lshrqi3"
13322 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13323 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13324 (match_operand:QI 2 "nonmemory_operand" "")))]
13325 "TARGET_QIMODE_MATH"
13326 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13328 (define_insn "*lshrqi3_1_one_bit"
13329 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13330 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13331 (match_operand:QI 2 "const1_operand" "")))
13332 (clobber (reg:CC FLAGS_REG))]
13333 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13334 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13336 [(set_attr "type" "ishift")
13337 (set (attr "length")
13338 (if_then_else (match_operand 0 "register_operand" "")
13340 (const_string "*")))])
13342 (define_insn "*lshrqi3_1_one_bit_slp"
13343 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13344 (lshiftrt:QI (match_dup 0)
13345 (match_operand:QI 1 "const1_operand" "")))
13346 (clobber (reg:CC FLAGS_REG))]
13347 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13350 [(set_attr "type" "ishift1")
13351 (set (attr "length")
13352 (if_then_else (match_operand 0 "register_operand" "")
13354 (const_string "*")))])
13356 (define_insn "*lshrqi3_1"
13357 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13358 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13359 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13360 (clobber (reg:CC FLAGS_REG))]
13361 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13363 shr{b}\t{%2, %0|%0, %2}
13364 shr{b}\t{%b2, %0|%0, %b2}"
13365 [(set_attr "type" "ishift")
13366 (set_attr "mode" "QI")])
13368 (define_insn "*lshrqi3_1_slp"
13369 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13370 (lshiftrt:QI (match_dup 0)
13371 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13372 (clobber (reg:CC FLAGS_REG))]
13373 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13374 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13376 shr{b}\t{%1, %0|%0, %1}
13377 shr{b}\t{%b1, %0|%0, %b1}"
13378 [(set_attr "type" "ishift1")
13379 (set_attr "mode" "QI")])
13381 ;; This pattern can't accept a variable shift count, since shifts by
13382 ;; zero don't affect the flags. We assume that shifts by constant
13383 ;; zero are optimized away.
13384 (define_insn "*lshrqi2_one_bit_cmp"
13385 [(set (reg FLAGS_REG)
13387 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13388 (match_operand:QI 2 "const1_operand" ""))
13390 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13391 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13392 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13393 && ix86_match_ccmode (insn, CCGOCmode)
13394 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13396 [(set_attr "type" "ishift")
13397 (set (attr "length")
13398 (if_then_else (match_operand:SI 0 "register_operand" "")
13400 (const_string "*")))])
13402 (define_insn "*lshrqi2_one_bit_cconly"
13403 [(set (reg FLAGS_REG)
13405 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13406 (match_operand:QI 2 "const1_operand" ""))
13408 (clobber (match_scratch:QI 0 "=q"))]
13409 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13410 && ix86_match_ccmode (insn, CCGOCmode)
13411 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13413 [(set_attr "type" "ishift")
13414 (set_attr "length" "2")])
13416 ;; This pattern can't accept a variable shift count, since shifts by
13417 ;; zero don't affect the flags. We assume that shifts by constant
13418 ;; zero are optimized away.
13419 (define_insn "*lshrqi2_cmp"
13420 [(set (reg FLAGS_REG)
13422 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13423 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13425 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13426 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13427 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13428 && ix86_match_ccmode (insn, CCGOCmode)
13429 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13430 "shr{b}\t{%2, %0|%0, %2}"
13431 [(set_attr "type" "ishift")
13432 (set_attr "mode" "QI")])
13434 (define_insn "*lshrqi2_cconly"
13435 [(set (reg FLAGS_REG)
13437 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13438 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13440 (clobber (match_scratch:QI 0 "=q"))]
13441 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13442 && ix86_match_ccmode (insn, CCGOCmode)
13443 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13444 "shr{b}\t{%2, %0|%0, %2}"
13445 [(set_attr "type" "ishift")
13446 (set_attr "mode" "QI")])
13448 ;; Rotate instructions
13450 (define_expand "rotldi3"
13451 [(set (match_operand:DI 0 "shiftdi_operand" "")
13452 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13453 (match_operand:QI 2 "nonmemory_operand" "")))]
13458 ix86_expand_binary_operator (ROTATE, DImode, operands);
13461 if (!const_1_to_31_operand (operands[2], VOIDmode))
13463 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13467 ;; Implement rotation using two double-precision shift instructions
13468 ;; and a scratch register.
13469 (define_insn_and_split "ix86_rotldi3"
13470 [(set (match_operand:DI 0 "register_operand" "=r")
13471 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13472 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13473 (clobber (reg:CC FLAGS_REG))
13474 (clobber (match_scratch:SI 3 "=&r"))]
13477 "&& reload_completed"
13478 [(set (match_dup 3) (match_dup 4))
13480 [(set (match_dup 4)
13481 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13482 (lshiftrt:SI (match_dup 5)
13483 (minus:QI (const_int 32) (match_dup 2)))))
13484 (clobber (reg:CC FLAGS_REG))])
13486 [(set (match_dup 5)
13487 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13488 (lshiftrt:SI (match_dup 3)
13489 (minus:QI (const_int 32) (match_dup 2)))))
13490 (clobber (reg:CC FLAGS_REG))])]
13491 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13493 (define_insn "*rotlsi3_1_one_bit_rex64"
13494 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13495 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13496 (match_operand:QI 2 "const1_operand" "")))
13497 (clobber (reg:CC FLAGS_REG))]
13499 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13500 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13502 [(set_attr "type" "rotate")
13503 (set (attr "length")
13504 (if_then_else (match_operand:DI 0 "register_operand" "")
13506 (const_string "*")))])
13508 (define_insn "*rotldi3_1_rex64"
13509 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13510 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13511 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13512 (clobber (reg:CC FLAGS_REG))]
13513 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13515 rol{q}\t{%2, %0|%0, %2}
13516 rol{q}\t{%b2, %0|%0, %b2}"
13517 [(set_attr "type" "rotate")
13518 (set_attr "mode" "DI")])
13520 (define_expand "rotlsi3"
13521 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13522 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13523 (match_operand:QI 2 "nonmemory_operand" "")))]
13525 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13527 (define_insn "*rotlsi3_1_one_bit"
13528 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13529 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13530 (match_operand:QI 2 "const1_operand" "")))
13531 (clobber (reg:CC FLAGS_REG))]
13532 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13533 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13535 [(set_attr "type" "rotate")
13536 (set (attr "length")
13537 (if_then_else (match_operand:SI 0 "register_operand" "")
13539 (const_string "*")))])
13541 (define_insn "*rotlsi3_1_one_bit_zext"
13542 [(set (match_operand:DI 0 "register_operand" "=r")
13544 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13545 (match_operand:QI 2 "const1_operand" ""))))
13546 (clobber (reg:CC FLAGS_REG))]
13548 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13549 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13551 [(set_attr "type" "rotate")
13552 (set_attr "length" "2")])
13554 (define_insn "*rotlsi3_1"
13555 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13556 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13557 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13558 (clobber (reg:CC FLAGS_REG))]
13559 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13561 rol{l}\t{%2, %0|%0, %2}
13562 rol{l}\t{%b2, %0|%0, %b2}"
13563 [(set_attr "type" "rotate")
13564 (set_attr "mode" "SI")])
13566 (define_insn "*rotlsi3_1_zext"
13567 [(set (match_operand:DI 0 "register_operand" "=r,r")
13569 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13570 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13571 (clobber (reg:CC FLAGS_REG))]
13572 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13574 rol{l}\t{%2, %k0|%k0, %2}
13575 rol{l}\t{%b2, %k0|%k0, %b2}"
13576 [(set_attr "type" "rotate")
13577 (set_attr "mode" "SI")])
13579 (define_expand "rotlhi3"
13580 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13581 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13582 (match_operand:QI 2 "nonmemory_operand" "")))]
13583 "TARGET_HIMODE_MATH"
13584 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13586 (define_insn "*rotlhi3_1_one_bit"
13587 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13588 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13589 (match_operand:QI 2 "const1_operand" "")))
13590 (clobber (reg:CC FLAGS_REG))]
13591 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13592 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13594 [(set_attr "type" "rotate")
13595 (set (attr "length")
13596 (if_then_else (match_operand 0 "register_operand" "")
13598 (const_string "*")))])
13600 (define_insn "*rotlhi3_1"
13601 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13602 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13603 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13604 (clobber (reg:CC FLAGS_REG))]
13605 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13607 rol{w}\t{%2, %0|%0, %2}
13608 rol{w}\t{%b2, %0|%0, %b2}"
13609 [(set_attr "type" "rotate")
13610 (set_attr "mode" "HI")])
13613 [(set (match_operand:HI 0 "register_operand" "")
13614 (rotate:HI (match_dup 0) (const_int 8)))
13615 (clobber (reg:CC FLAGS_REG))]
13617 [(parallel [(set (strict_low_part (match_dup 0))
13618 (bswap:HI (match_dup 0)))
13619 (clobber (reg:CC FLAGS_REG))])]
13622 (define_expand "rotlqi3"
13623 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13624 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13625 (match_operand:QI 2 "nonmemory_operand" "")))]
13626 "TARGET_QIMODE_MATH"
13627 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13629 (define_insn "*rotlqi3_1_one_bit_slp"
13630 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13631 (rotate:QI (match_dup 0)
13632 (match_operand:QI 1 "const1_operand" "")))
13633 (clobber (reg:CC FLAGS_REG))]
13634 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13635 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13637 [(set_attr "type" "rotate1")
13638 (set (attr "length")
13639 (if_then_else (match_operand 0 "register_operand" "")
13641 (const_string "*")))])
13643 (define_insn "*rotlqi3_1_one_bit"
13644 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13645 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13646 (match_operand:QI 2 "const1_operand" "")))
13647 (clobber (reg:CC FLAGS_REG))]
13648 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13649 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13651 [(set_attr "type" "rotate")
13652 (set (attr "length")
13653 (if_then_else (match_operand 0 "register_operand" "")
13655 (const_string "*")))])
13657 (define_insn "*rotlqi3_1_slp"
13658 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13659 (rotate:QI (match_dup 0)
13660 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13661 (clobber (reg:CC FLAGS_REG))]
13662 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13663 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13665 rol{b}\t{%1, %0|%0, %1}
13666 rol{b}\t{%b1, %0|%0, %b1}"
13667 [(set_attr "type" "rotate1")
13668 (set_attr "mode" "QI")])
13670 (define_insn "*rotlqi3_1"
13671 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13672 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13673 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13674 (clobber (reg:CC FLAGS_REG))]
13675 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13677 rol{b}\t{%2, %0|%0, %2}
13678 rol{b}\t{%b2, %0|%0, %b2}"
13679 [(set_attr "type" "rotate")
13680 (set_attr "mode" "QI")])
13682 (define_expand "rotrdi3"
13683 [(set (match_operand:DI 0 "shiftdi_operand" "")
13684 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13685 (match_operand:QI 2 "nonmemory_operand" "")))]
13690 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13693 if (!const_1_to_31_operand (operands[2], VOIDmode))
13695 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13699 ;; Implement rotation using two double-precision shift instructions
13700 ;; and a scratch register.
13701 (define_insn_and_split "ix86_rotrdi3"
13702 [(set (match_operand:DI 0 "register_operand" "=r")
13703 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13704 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13705 (clobber (reg:CC FLAGS_REG))
13706 (clobber (match_scratch:SI 3 "=&r"))]
13709 "&& reload_completed"
13710 [(set (match_dup 3) (match_dup 4))
13712 [(set (match_dup 4)
13713 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13714 (ashift:SI (match_dup 5)
13715 (minus:QI (const_int 32) (match_dup 2)))))
13716 (clobber (reg:CC FLAGS_REG))])
13718 [(set (match_dup 5)
13719 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13720 (ashift:SI (match_dup 3)
13721 (minus:QI (const_int 32) (match_dup 2)))))
13722 (clobber (reg:CC FLAGS_REG))])]
13723 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13725 (define_insn "*rotrdi3_1_one_bit_rex64"
13726 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13727 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13728 (match_operand:QI 2 "const1_operand" "")))
13729 (clobber (reg:CC FLAGS_REG))]
13731 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13732 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13734 [(set_attr "type" "rotate")
13735 (set (attr "length")
13736 (if_then_else (match_operand:DI 0 "register_operand" "")
13738 (const_string "*")))])
13740 (define_insn "*rotrdi3_1_rex64"
13741 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13742 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13743 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13744 (clobber (reg:CC FLAGS_REG))]
13745 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13747 ror{q}\t{%2, %0|%0, %2}
13748 ror{q}\t{%b2, %0|%0, %b2}"
13749 [(set_attr "type" "rotate")
13750 (set_attr "mode" "DI")])
13752 (define_expand "rotrsi3"
13753 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13754 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13755 (match_operand:QI 2 "nonmemory_operand" "")))]
13757 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13759 (define_insn "*rotrsi3_1_one_bit"
13760 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13761 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13762 (match_operand:QI 2 "const1_operand" "")))
13763 (clobber (reg:CC FLAGS_REG))]
13764 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13765 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13767 [(set_attr "type" "rotate")
13768 (set (attr "length")
13769 (if_then_else (match_operand:SI 0 "register_operand" "")
13771 (const_string "*")))])
13773 (define_insn "*rotrsi3_1_one_bit_zext"
13774 [(set (match_operand:DI 0 "register_operand" "=r")
13776 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13777 (match_operand:QI 2 "const1_operand" ""))))
13778 (clobber (reg:CC FLAGS_REG))]
13780 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13781 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13783 [(set_attr "type" "rotate")
13784 (set (attr "length")
13785 (if_then_else (match_operand:SI 0 "register_operand" "")
13787 (const_string "*")))])
13789 (define_insn "*rotrsi3_1"
13790 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13791 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13792 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13793 (clobber (reg:CC FLAGS_REG))]
13794 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13796 ror{l}\t{%2, %0|%0, %2}
13797 ror{l}\t{%b2, %0|%0, %b2}"
13798 [(set_attr "type" "rotate")
13799 (set_attr "mode" "SI")])
13801 (define_insn "*rotrsi3_1_zext"
13802 [(set (match_operand:DI 0 "register_operand" "=r,r")
13804 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13805 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13806 (clobber (reg:CC FLAGS_REG))]
13807 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13809 ror{l}\t{%2, %k0|%k0, %2}
13810 ror{l}\t{%b2, %k0|%k0, %b2}"
13811 [(set_attr "type" "rotate")
13812 (set_attr "mode" "SI")])
13814 (define_expand "rotrhi3"
13815 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13816 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13817 (match_operand:QI 2 "nonmemory_operand" "")))]
13818 "TARGET_HIMODE_MATH"
13819 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13821 (define_insn "*rotrhi3_one_bit"
13822 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13823 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13824 (match_operand:QI 2 "const1_operand" "")))
13825 (clobber (reg:CC FLAGS_REG))]
13826 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13827 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13829 [(set_attr "type" "rotate")
13830 (set (attr "length")
13831 (if_then_else (match_operand 0 "register_operand" "")
13833 (const_string "*")))])
13835 (define_insn "*rotrhi3_1"
13836 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13837 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13838 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13839 (clobber (reg:CC FLAGS_REG))]
13840 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13842 ror{w}\t{%2, %0|%0, %2}
13843 ror{w}\t{%b2, %0|%0, %b2}"
13844 [(set_attr "type" "rotate")
13845 (set_attr "mode" "HI")])
13848 [(set (match_operand:HI 0 "register_operand" "")
13849 (rotatert:HI (match_dup 0) (const_int 8)))
13850 (clobber (reg:CC FLAGS_REG))]
13852 [(parallel [(set (strict_low_part (match_dup 0))
13853 (bswap:HI (match_dup 0)))
13854 (clobber (reg:CC FLAGS_REG))])]
13857 (define_expand "rotrqi3"
13858 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13859 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13860 (match_operand:QI 2 "nonmemory_operand" "")))]
13861 "TARGET_QIMODE_MATH"
13862 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13864 (define_insn "*rotrqi3_1_one_bit"
13865 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13866 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13867 (match_operand:QI 2 "const1_operand" "")))
13868 (clobber (reg:CC FLAGS_REG))]
13869 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13870 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13872 [(set_attr "type" "rotate")
13873 (set (attr "length")
13874 (if_then_else (match_operand 0 "register_operand" "")
13876 (const_string "*")))])
13878 (define_insn "*rotrqi3_1_one_bit_slp"
13879 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13880 (rotatert:QI (match_dup 0)
13881 (match_operand:QI 1 "const1_operand" "")))
13882 (clobber (reg:CC FLAGS_REG))]
13883 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13884 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13886 [(set_attr "type" "rotate1")
13887 (set (attr "length")
13888 (if_then_else (match_operand 0 "register_operand" "")
13890 (const_string "*")))])
13892 (define_insn "*rotrqi3_1"
13893 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13894 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13895 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13896 (clobber (reg:CC FLAGS_REG))]
13897 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13899 ror{b}\t{%2, %0|%0, %2}
13900 ror{b}\t{%b2, %0|%0, %b2}"
13901 [(set_attr "type" "rotate")
13902 (set_attr "mode" "QI")])
13904 (define_insn "*rotrqi3_1_slp"
13905 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13906 (rotatert:QI (match_dup 0)
13907 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13908 (clobber (reg:CC FLAGS_REG))]
13909 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13910 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13912 ror{b}\t{%1, %0|%0, %1}
13913 ror{b}\t{%b1, %0|%0, %b1}"
13914 [(set_attr "type" "rotate1")
13915 (set_attr "mode" "QI")])
13917 ;; Bit set / bit test instructions
13919 (define_expand "extv"
13920 [(set (match_operand:SI 0 "register_operand" "")
13921 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13922 (match_operand:SI 2 "const8_operand" "")
13923 (match_operand:SI 3 "const8_operand" "")))]
13926 /* Handle extractions from %ah et al. */
13927 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13930 /* From mips.md: extract_bit_field doesn't verify that our source
13931 matches the predicate, so check it again here. */
13932 if (! ext_register_operand (operands[1], VOIDmode))
13936 (define_expand "extzv"
13937 [(set (match_operand:SI 0 "register_operand" "")
13938 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13939 (match_operand:SI 2 "const8_operand" "")
13940 (match_operand:SI 3 "const8_operand" "")))]
13943 /* Handle extractions from %ah et al. */
13944 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13947 /* From mips.md: extract_bit_field doesn't verify that our source
13948 matches the predicate, so check it again here. */
13949 if (! ext_register_operand (operands[1], VOIDmode))
13953 (define_expand "insv"
13954 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13955 (match_operand 1 "const8_operand" "")
13956 (match_operand 2 "const8_operand" ""))
13957 (match_operand 3 "register_operand" ""))]
13960 /* Handle insertions to %ah et al. */
13961 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13964 /* From mips.md: insert_bit_field doesn't verify that our source
13965 matches the predicate, so check it again here. */
13966 if (! ext_register_operand (operands[0], VOIDmode))
13970 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13972 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13977 ;; %%% bts, btr, btc, bt.
13978 ;; In general these instructions are *slow* when applied to memory,
13979 ;; since they enforce atomic operation. When applied to registers,
13980 ;; it depends on the cpu implementation. They're never faster than
13981 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13982 ;; no point. But in 64-bit, we can't hold the relevant immediates
13983 ;; within the instruction itself, so operating on bits in the high
13984 ;; 32-bits of a register becomes easier.
13986 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13987 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13988 ;; negdf respectively, so they can never be disabled entirely.
13990 (define_insn "*btsq"
13991 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13993 (match_operand:DI 1 "const_0_to_63_operand" ""))
13995 (clobber (reg:CC FLAGS_REG))]
13996 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13997 "bts{q}\t{%1, %0|%0, %1}"
13998 [(set_attr "type" "alu1")])
14000 (define_insn "*btrq"
14001 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14003 (match_operand:DI 1 "const_0_to_63_operand" ""))
14005 (clobber (reg:CC FLAGS_REG))]
14006 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14007 "btr{q}\t{%1, %0|%0, %1}"
14008 [(set_attr "type" "alu1")])
14010 (define_insn "*btcq"
14011 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14013 (match_operand:DI 1 "const_0_to_63_operand" ""))
14014 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14015 (clobber (reg:CC FLAGS_REG))]
14016 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14017 "btc{q}\t{%1, %0|%0, %1}"
14018 [(set_attr "type" "alu1")])
14020 ;; Allow Nocona to avoid these instructions if a register is available.
14023 [(match_scratch:DI 2 "r")
14024 (parallel [(set (zero_extract:DI
14025 (match_operand:DI 0 "register_operand" "")
14027 (match_operand:DI 1 "const_0_to_63_operand" ""))
14029 (clobber (reg:CC FLAGS_REG))])]
14030 "TARGET_64BIT && !TARGET_USE_BT"
14033 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14036 if (HOST_BITS_PER_WIDE_INT >= 64)
14037 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14038 else if (i < HOST_BITS_PER_WIDE_INT)
14039 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14041 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14043 op1 = immed_double_const (lo, hi, DImode);
14046 emit_move_insn (operands[2], op1);
14050 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14055 [(match_scratch:DI 2 "r")
14056 (parallel [(set (zero_extract:DI
14057 (match_operand:DI 0 "register_operand" "")
14059 (match_operand:DI 1 "const_0_to_63_operand" ""))
14061 (clobber (reg:CC FLAGS_REG))])]
14062 "TARGET_64BIT && !TARGET_USE_BT"
14065 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14068 if (HOST_BITS_PER_WIDE_INT >= 64)
14069 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14070 else if (i < HOST_BITS_PER_WIDE_INT)
14071 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14073 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14075 op1 = immed_double_const (~lo, ~hi, DImode);
14078 emit_move_insn (operands[2], op1);
14082 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14087 [(match_scratch:DI 2 "r")
14088 (parallel [(set (zero_extract:DI
14089 (match_operand:DI 0 "register_operand" "")
14091 (match_operand:DI 1 "const_0_to_63_operand" ""))
14092 (not:DI (zero_extract:DI
14093 (match_dup 0) (const_int 1) (match_dup 1))))
14094 (clobber (reg:CC FLAGS_REG))])]
14095 "TARGET_64BIT && !TARGET_USE_BT"
14098 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14101 if (HOST_BITS_PER_WIDE_INT >= 64)
14102 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14103 else if (i < HOST_BITS_PER_WIDE_INT)
14104 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14106 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14108 op1 = immed_double_const (lo, hi, DImode);
14111 emit_move_insn (operands[2], op1);
14115 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14119 (define_insn "*btdi_rex64"
14120 [(set (reg:CCC FLAGS_REG)
14123 (match_operand:DI 0 "register_operand" "r")
14125 (match_operand:DI 1 "nonmemory_operand" "rN"))
14127 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14128 "bt{q}\t{%1, %0|%0, %1}"
14129 [(set_attr "type" "alu1")])
14131 (define_insn "*btsi"
14132 [(set (reg:CCC FLAGS_REG)
14135 (match_operand:SI 0 "register_operand" "r")
14137 (match_operand:SI 1 "nonmemory_operand" "rN"))
14139 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14140 "bt{l}\t{%1, %0|%0, %1}"
14141 [(set_attr "type" "alu1")])
14143 ;; Store-flag instructions.
14145 ;; For all sCOND expanders, also expand the compare or test insn that
14146 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14148 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14149 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14150 ;; way, which can later delete the movzx if only QImode is needed.
14152 (define_expand "s<code>"
14153 [(set (match_operand:QI 0 "register_operand" "")
14154 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14156 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14158 (define_expand "s<code>"
14159 [(set (match_operand:QI 0 "register_operand" "")
14160 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14161 "TARGET_80387 || TARGET_SSE"
14162 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14164 (define_insn "*setcc_1"
14165 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14166 (match_operator:QI 1 "ix86_comparison_operator"
14167 [(reg FLAGS_REG) (const_int 0)]))]
14170 [(set_attr "type" "setcc")
14171 (set_attr "mode" "QI")])
14173 (define_insn "*setcc_2"
14174 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14175 (match_operator:QI 1 "ix86_comparison_operator"
14176 [(reg FLAGS_REG) (const_int 0)]))]
14179 [(set_attr "type" "setcc")
14180 (set_attr "mode" "QI")])
14182 ;; In general it is not safe to assume too much about CCmode registers,
14183 ;; so simplify-rtx stops when it sees a second one. Under certain
14184 ;; conditions this is safe on x86, so help combine not create
14191 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14192 (ne:QI (match_operator 1 "ix86_comparison_operator"
14193 [(reg FLAGS_REG) (const_int 0)])
14196 [(set (match_dup 0) (match_dup 1))]
14198 PUT_MODE (operands[1], QImode);
14202 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14203 (ne:QI (match_operator 1 "ix86_comparison_operator"
14204 [(reg FLAGS_REG) (const_int 0)])
14207 [(set (match_dup 0) (match_dup 1))]
14209 PUT_MODE (operands[1], QImode);
14213 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14214 (eq:QI (match_operator 1 "ix86_comparison_operator"
14215 [(reg FLAGS_REG) (const_int 0)])
14218 [(set (match_dup 0) (match_dup 1))]
14220 rtx new_op1 = copy_rtx (operands[1]);
14221 operands[1] = new_op1;
14222 PUT_MODE (new_op1, QImode);
14223 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14224 GET_MODE (XEXP (new_op1, 0))));
14226 /* Make sure that (a) the CCmode we have for the flags is strong
14227 enough for the reversed compare or (b) we have a valid FP compare. */
14228 if (! ix86_comparison_operator (new_op1, VOIDmode))
14233 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14234 (eq:QI (match_operator 1 "ix86_comparison_operator"
14235 [(reg FLAGS_REG) (const_int 0)])
14238 [(set (match_dup 0) (match_dup 1))]
14240 rtx new_op1 = copy_rtx (operands[1]);
14241 operands[1] = new_op1;
14242 PUT_MODE (new_op1, QImode);
14243 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14244 GET_MODE (XEXP (new_op1, 0))));
14246 /* Make sure that (a) the CCmode we have for the flags is strong
14247 enough for the reversed compare or (b) we have a valid FP compare. */
14248 if (! ix86_comparison_operator (new_op1, VOIDmode))
14252 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14253 ;; subsequent logical operations are used to imitate conditional moves.
14254 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14257 (define_insn "*avx_setcc<mode>"
14258 [(set (match_operand:MODEF 0 "register_operand" "=x")
14259 (match_operator:MODEF 1 "avx_comparison_float_operator"
14260 [(match_operand:MODEF 2 "register_operand" "x")
14261 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14263 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14264 [(set_attr "type" "ssecmp")
14265 (set_attr "prefix" "vex")
14266 (set_attr "mode" "<MODE>")])
14268 (define_insn "*sse_setcc<mode>"
14269 [(set (match_operand:MODEF 0 "register_operand" "=x")
14270 (match_operator:MODEF 1 "sse_comparison_operator"
14271 [(match_operand:MODEF 2 "register_operand" "0")
14272 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14273 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14274 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14275 [(set_attr "type" "ssecmp")
14276 (set_attr "mode" "<MODE>")])
14278 (define_insn "*sse5_setcc<mode>"
14279 [(set (match_operand:MODEF 0 "register_operand" "=x")
14280 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14281 [(match_operand:MODEF 2 "register_operand" "x")
14282 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14284 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14285 [(set_attr "type" "sse4arg")
14286 (set_attr "mode" "<MODE>")])
14289 ;; Basic conditional jump instructions.
14290 ;; We ignore the overflow flag for signed branch instructions.
14292 ;; For all bCOND expanders, also expand the compare or test insn that
14293 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14295 (define_expand "b<code>"
14297 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14299 (label_ref (match_operand 0 ""))
14302 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14304 (define_expand "b<code>"
14306 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14308 (label_ref (match_operand 0 ""))
14310 "TARGET_80387 || TARGET_SSE_MATH"
14311 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14313 (define_insn "*jcc_1"
14315 (if_then_else (match_operator 1 "ix86_comparison_operator"
14316 [(reg FLAGS_REG) (const_int 0)])
14317 (label_ref (match_operand 0 "" ""))
14321 [(set_attr "type" "ibr")
14322 (set_attr "modrm" "0")
14323 (set (attr "length")
14324 (if_then_else (and (ge (minus (match_dup 0) (pc))
14326 (lt (minus (match_dup 0) (pc))
14331 (define_insn "*jcc_2"
14333 (if_then_else (match_operator 1 "ix86_comparison_operator"
14334 [(reg FLAGS_REG) (const_int 0)])
14336 (label_ref (match_operand 0 "" ""))))]
14339 [(set_attr "type" "ibr")
14340 (set_attr "modrm" "0")
14341 (set (attr "length")
14342 (if_then_else (and (ge (minus (match_dup 0) (pc))
14344 (lt (minus (match_dup 0) (pc))
14349 ;; In general it is not safe to assume too much about CCmode registers,
14350 ;; so simplify-rtx stops when it sees a second one. Under certain
14351 ;; conditions this is safe on x86, so help combine not create
14359 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14360 [(reg FLAGS_REG) (const_int 0)])
14362 (label_ref (match_operand 1 "" ""))
14366 (if_then_else (match_dup 0)
14367 (label_ref (match_dup 1))
14370 PUT_MODE (operands[0], VOIDmode);
14375 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14376 [(reg FLAGS_REG) (const_int 0)])
14378 (label_ref (match_operand 1 "" ""))
14382 (if_then_else (match_dup 0)
14383 (label_ref (match_dup 1))
14386 rtx new_op0 = copy_rtx (operands[0]);
14387 operands[0] = new_op0;
14388 PUT_MODE (new_op0, VOIDmode);
14389 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14390 GET_MODE (XEXP (new_op0, 0))));
14392 /* Make sure that (a) the CCmode we have for the flags is strong
14393 enough for the reversed compare or (b) we have a valid FP compare. */
14394 if (! ix86_comparison_operator (new_op0, VOIDmode))
14398 ;; zero_extend in SImode is correct, since this is what combine pass
14399 ;; generates from shift insn with QImode operand. Actually, the mode of
14400 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14401 ;; appropriate modulo of the bit offset value.
14403 (define_insn_and_split "*jcc_btdi_rex64"
14405 (if_then_else (match_operator 0 "bt_comparison_operator"
14407 (match_operand:DI 1 "register_operand" "r")
14410 (match_operand:QI 2 "register_operand" "r")))
14412 (label_ref (match_operand 3 "" ""))
14414 (clobber (reg:CC FLAGS_REG))]
14415 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14418 [(set (reg:CCC FLAGS_REG)
14426 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14427 (label_ref (match_dup 3))
14430 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14432 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14435 ;; avoid useless masking of bit offset operand
14436 (define_insn_and_split "*jcc_btdi_mask_rex64"
14438 (if_then_else (match_operator 0 "bt_comparison_operator"
14440 (match_operand:DI 1 "register_operand" "r")
14443 (match_operand:SI 2 "register_operand" "r")
14444 (match_operand:SI 3 "const_int_operand" "n")))])
14445 (label_ref (match_operand 4 "" ""))
14447 (clobber (reg:CC FLAGS_REG))]
14448 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14449 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14452 [(set (reg:CCC FLAGS_REG)
14460 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14461 (label_ref (match_dup 4))
14464 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14466 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14469 (define_insn_and_split "*jcc_btsi"
14471 (if_then_else (match_operator 0 "bt_comparison_operator"
14473 (match_operand:SI 1 "register_operand" "r")
14476 (match_operand:QI 2 "register_operand" "r")))
14478 (label_ref (match_operand 3 "" ""))
14480 (clobber (reg:CC FLAGS_REG))]
14481 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14484 [(set (reg:CCC FLAGS_REG)
14492 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14493 (label_ref (match_dup 3))
14496 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14498 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14501 ;; avoid useless masking of bit offset operand
14502 (define_insn_and_split "*jcc_btsi_mask"
14504 (if_then_else (match_operator 0 "bt_comparison_operator"
14506 (match_operand:SI 1 "register_operand" "r")
14509 (match_operand:SI 2 "register_operand" "r")
14510 (match_operand:SI 3 "const_int_operand" "n")))])
14511 (label_ref (match_operand 4 "" ""))
14513 (clobber (reg:CC FLAGS_REG))]
14514 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14515 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14518 [(set (reg:CCC FLAGS_REG)
14526 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14527 (label_ref (match_dup 4))
14529 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14531 (define_insn_and_split "*jcc_btsi_1"
14533 (if_then_else (match_operator 0 "bt_comparison_operator"
14536 (match_operand:SI 1 "register_operand" "r")
14537 (match_operand:QI 2 "register_operand" "r"))
14540 (label_ref (match_operand 3 "" ""))
14542 (clobber (reg:CC FLAGS_REG))]
14543 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14546 [(set (reg:CCC FLAGS_REG)
14554 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14555 (label_ref (match_dup 3))
14558 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14560 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14563 ;; avoid useless masking of bit offset operand
14564 (define_insn_and_split "*jcc_btsi_mask_1"
14567 (match_operator 0 "bt_comparison_operator"
14570 (match_operand:SI 1 "register_operand" "r")
14573 (match_operand:SI 2 "register_operand" "r")
14574 (match_operand:SI 3 "const_int_operand" "n")) 0))
14577 (label_ref (match_operand 4 "" ""))
14579 (clobber (reg:CC FLAGS_REG))]
14580 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14581 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14584 [(set (reg:CCC FLAGS_REG)
14592 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14593 (label_ref (match_dup 4))
14595 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14597 ;; Define combination compare-and-branch fp compare instructions to use
14598 ;; during early optimization. Splitting the operation apart early makes
14599 ;; for bad code when we want to reverse the operation.
14601 (define_insn "*fp_jcc_1_mixed"
14603 (if_then_else (match_operator 0 "comparison_operator"
14604 [(match_operand 1 "register_operand" "f,x")
14605 (match_operand 2 "nonimmediate_operand" "f,xm")])
14606 (label_ref (match_operand 3 "" ""))
14608 (clobber (reg:CCFP FPSR_REG))
14609 (clobber (reg:CCFP FLAGS_REG))]
14610 "TARGET_MIX_SSE_I387
14611 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14612 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14613 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14616 (define_insn "*fp_jcc_1_sse"
14618 (if_then_else (match_operator 0 "comparison_operator"
14619 [(match_operand 1 "register_operand" "x")
14620 (match_operand 2 "nonimmediate_operand" "xm")])
14621 (label_ref (match_operand 3 "" ""))
14623 (clobber (reg:CCFP FPSR_REG))
14624 (clobber (reg:CCFP FLAGS_REG))]
14626 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14627 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14628 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14631 (define_insn "*fp_jcc_1_387"
14633 (if_then_else (match_operator 0 "comparison_operator"
14634 [(match_operand 1 "register_operand" "f")
14635 (match_operand 2 "register_operand" "f")])
14636 (label_ref (match_operand 3 "" ""))
14638 (clobber (reg:CCFP FPSR_REG))
14639 (clobber (reg:CCFP FLAGS_REG))]
14640 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14642 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14643 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14646 (define_insn "*fp_jcc_2_mixed"
14648 (if_then_else (match_operator 0 "comparison_operator"
14649 [(match_operand 1 "register_operand" "f,x")
14650 (match_operand 2 "nonimmediate_operand" "f,xm")])
14652 (label_ref (match_operand 3 "" ""))))
14653 (clobber (reg:CCFP FPSR_REG))
14654 (clobber (reg:CCFP FLAGS_REG))]
14655 "TARGET_MIX_SSE_I387
14656 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14657 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14658 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14661 (define_insn "*fp_jcc_2_sse"
14663 (if_then_else (match_operator 0 "comparison_operator"
14664 [(match_operand 1 "register_operand" "x")
14665 (match_operand 2 "nonimmediate_operand" "xm")])
14667 (label_ref (match_operand 3 "" ""))))
14668 (clobber (reg:CCFP FPSR_REG))
14669 (clobber (reg:CCFP FLAGS_REG))]
14671 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14672 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14673 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14676 (define_insn "*fp_jcc_2_387"
14678 (if_then_else (match_operator 0 "comparison_operator"
14679 [(match_operand 1 "register_operand" "f")
14680 (match_operand 2 "register_operand" "f")])
14682 (label_ref (match_operand 3 "" ""))))
14683 (clobber (reg:CCFP FPSR_REG))
14684 (clobber (reg:CCFP FLAGS_REG))]
14685 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14687 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14688 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14691 (define_insn "*fp_jcc_3_387"
14693 (if_then_else (match_operator 0 "comparison_operator"
14694 [(match_operand 1 "register_operand" "f")
14695 (match_operand 2 "nonimmediate_operand" "fm")])
14696 (label_ref (match_operand 3 "" ""))
14698 (clobber (reg:CCFP FPSR_REG))
14699 (clobber (reg:CCFP FLAGS_REG))
14700 (clobber (match_scratch:HI 4 "=a"))]
14702 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14703 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14704 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14705 && SELECT_CC_MODE (GET_CODE (operands[0]),
14706 operands[1], operands[2]) == CCFPmode
14707 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14710 (define_insn "*fp_jcc_4_387"
14712 (if_then_else (match_operator 0 "comparison_operator"
14713 [(match_operand 1 "register_operand" "f")
14714 (match_operand 2 "nonimmediate_operand" "fm")])
14716 (label_ref (match_operand 3 "" ""))))
14717 (clobber (reg:CCFP FPSR_REG))
14718 (clobber (reg:CCFP FLAGS_REG))
14719 (clobber (match_scratch:HI 4 "=a"))]
14721 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14722 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14723 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14724 && SELECT_CC_MODE (GET_CODE (operands[0]),
14725 operands[1], operands[2]) == CCFPmode
14726 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14729 (define_insn "*fp_jcc_5_387"
14731 (if_then_else (match_operator 0 "comparison_operator"
14732 [(match_operand 1 "register_operand" "f")
14733 (match_operand 2 "register_operand" "f")])
14734 (label_ref (match_operand 3 "" ""))
14736 (clobber (reg:CCFP FPSR_REG))
14737 (clobber (reg:CCFP FLAGS_REG))
14738 (clobber (match_scratch:HI 4 "=a"))]
14739 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14740 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14741 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14744 (define_insn "*fp_jcc_6_387"
14746 (if_then_else (match_operator 0 "comparison_operator"
14747 [(match_operand 1 "register_operand" "f")
14748 (match_operand 2 "register_operand" "f")])
14750 (label_ref (match_operand 3 "" ""))))
14751 (clobber (reg:CCFP FPSR_REG))
14752 (clobber (reg:CCFP FLAGS_REG))
14753 (clobber (match_scratch:HI 4 "=a"))]
14754 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14755 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14756 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14759 (define_insn "*fp_jcc_7_387"
14761 (if_then_else (match_operator 0 "comparison_operator"
14762 [(match_operand 1 "register_operand" "f")
14763 (match_operand 2 "const0_operand" "")])
14764 (label_ref (match_operand 3 "" ""))
14766 (clobber (reg:CCFP FPSR_REG))
14767 (clobber (reg:CCFP FLAGS_REG))
14768 (clobber (match_scratch:HI 4 "=a"))]
14769 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14771 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14772 && SELECT_CC_MODE (GET_CODE (operands[0]),
14773 operands[1], operands[2]) == CCFPmode
14774 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14777 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14778 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14779 ;; with a precedence over other operators and is always put in the first
14780 ;; place. Swap condition and operands to match ficom instruction.
14782 (define_insn "*fp_jcc_8<mode>_387"
14784 (if_then_else (match_operator 0 "comparison_operator"
14785 [(match_operator 1 "float_operator"
14786 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14787 (match_operand 3 "register_operand" "f,f")])
14788 (label_ref (match_operand 4 "" ""))
14790 (clobber (reg:CCFP FPSR_REG))
14791 (clobber (reg:CCFP FLAGS_REG))
14792 (clobber (match_scratch:HI 5 "=a,a"))]
14793 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14794 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14795 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14796 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14797 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14798 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14803 (if_then_else (match_operator 0 "comparison_operator"
14804 [(match_operand 1 "register_operand" "")
14805 (match_operand 2 "nonimmediate_operand" "")])
14806 (match_operand 3 "" "")
14807 (match_operand 4 "" "")))
14808 (clobber (reg:CCFP FPSR_REG))
14809 (clobber (reg:CCFP FLAGS_REG))]
14813 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14814 operands[3], operands[4], NULL_RTX, NULL_RTX);
14820 (if_then_else (match_operator 0 "comparison_operator"
14821 [(match_operand 1 "register_operand" "")
14822 (match_operand 2 "general_operand" "")])
14823 (match_operand 3 "" "")
14824 (match_operand 4 "" "")))
14825 (clobber (reg:CCFP FPSR_REG))
14826 (clobber (reg:CCFP FLAGS_REG))
14827 (clobber (match_scratch:HI 5 "=a"))]
14831 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14832 operands[3], operands[4], operands[5], NULL_RTX);
14838 (if_then_else (match_operator 0 "comparison_operator"
14839 [(match_operator 1 "float_operator"
14840 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14841 (match_operand 3 "register_operand" "")])
14842 (match_operand 4 "" "")
14843 (match_operand 5 "" "")))
14844 (clobber (reg:CCFP FPSR_REG))
14845 (clobber (reg:CCFP FLAGS_REG))
14846 (clobber (match_scratch:HI 6 "=a"))]
14850 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14851 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14852 operands[3], operands[7],
14853 operands[4], operands[5], operands[6], NULL_RTX);
14857 ;; %%% Kill this when reload knows how to do it.
14860 (if_then_else (match_operator 0 "comparison_operator"
14861 [(match_operator 1 "float_operator"
14862 [(match_operand:X87MODEI12 2 "register_operand" "")])
14863 (match_operand 3 "register_operand" "")])
14864 (match_operand 4 "" "")
14865 (match_operand 5 "" "")))
14866 (clobber (reg:CCFP FPSR_REG))
14867 (clobber (reg:CCFP FLAGS_REG))
14868 (clobber (match_scratch:HI 6 "=a"))]
14872 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14873 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14874 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14875 operands[3], operands[7],
14876 operands[4], operands[5], operands[6], operands[2]);
14880 ;; Unconditional and other jump instructions
14882 (define_insn "jump"
14884 (label_ref (match_operand 0 "" "")))]
14887 [(set_attr "type" "ibr")
14888 (set (attr "length")
14889 (if_then_else (and (ge (minus (match_dup 0) (pc))
14891 (lt (minus (match_dup 0) (pc))
14895 (set_attr "modrm" "0")])
14897 (define_expand "indirect_jump"
14898 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14902 (define_insn "*indirect_jump"
14903 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14906 [(set_attr "type" "ibr")
14907 (set_attr "length_immediate" "0")])
14909 (define_expand "tablejump"
14910 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14911 (use (label_ref (match_operand 1 "" "")))])]
14914 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14915 relative. Convert the relative address to an absolute address. */
14919 enum rtx_code code;
14921 /* We can't use @GOTOFF for text labels on VxWorks;
14922 see gotoff_operand. */
14923 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14927 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14929 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14933 op1 = pic_offset_table_rtx;
14938 op0 = pic_offset_table_rtx;
14942 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14947 (define_insn "*tablejump_1"
14948 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14949 (use (label_ref (match_operand 1 "" "")))]
14952 [(set_attr "type" "ibr")
14953 (set_attr "length_immediate" "0")])
14955 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14958 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14959 (set (match_operand:QI 1 "register_operand" "")
14960 (match_operator:QI 2 "ix86_comparison_operator"
14961 [(reg FLAGS_REG) (const_int 0)]))
14962 (set (match_operand 3 "q_regs_operand" "")
14963 (zero_extend (match_dup 1)))]
14964 "(peep2_reg_dead_p (3, operands[1])
14965 || operands_match_p (operands[1], operands[3]))
14966 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14967 [(set (match_dup 4) (match_dup 0))
14968 (set (strict_low_part (match_dup 5))
14971 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14972 operands[5] = gen_lowpart (QImode, operands[3]);
14973 ix86_expand_clear (operands[3]);
14976 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14979 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14980 (set (match_operand:QI 1 "register_operand" "")
14981 (match_operator:QI 2 "ix86_comparison_operator"
14982 [(reg FLAGS_REG) (const_int 0)]))
14983 (parallel [(set (match_operand 3 "q_regs_operand" "")
14984 (zero_extend (match_dup 1)))
14985 (clobber (reg:CC FLAGS_REG))])]
14986 "(peep2_reg_dead_p (3, operands[1])
14987 || operands_match_p (operands[1], operands[3]))
14988 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14989 [(set (match_dup 4) (match_dup 0))
14990 (set (strict_low_part (match_dup 5))
14993 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14994 operands[5] = gen_lowpart (QImode, operands[3]);
14995 ix86_expand_clear (operands[3]);
14998 ;; Call instructions.
15000 ;; The predicates normally associated with named expanders are not properly
15001 ;; checked for calls. This is a bug in the generic code, but it isn't that
15002 ;; easy to fix. Ignore it for now and be prepared to fix things up.
15004 ;; Call subroutine returning no value.
15006 (define_expand "call_pop"
15007 [(parallel [(call (match_operand:QI 0 "" "")
15008 (match_operand:SI 1 "" ""))
15009 (set (reg:SI SP_REG)
15010 (plus:SI (reg:SI SP_REG)
15011 (match_operand:SI 3 "" "")))])]
15014 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15018 (define_insn "*call_pop_0"
15019 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15020 (match_operand:SI 1 "" ""))
15021 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15022 (match_operand:SI 2 "immediate_operand" "")))]
15025 if (SIBLING_CALL_P (insn))
15028 return "call\t%P0";
15030 [(set_attr "type" "call")])
15032 (define_insn "*call_pop_1"
15033 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15034 (match_operand:SI 1 "" ""))
15035 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15036 (match_operand:SI 2 "immediate_operand" "i")))]
15039 if (constant_call_address_operand (operands[0], Pmode))
15041 if (SIBLING_CALL_P (insn))
15044 return "call\t%P0";
15046 if (SIBLING_CALL_P (insn))
15049 return "call\t%A0";
15051 [(set_attr "type" "call")])
15053 (define_expand "call"
15054 [(call (match_operand:QI 0 "" "")
15055 (match_operand 1 "" ""))
15056 (use (match_operand 2 "" ""))]
15059 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15063 (define_expand "sibcall"
15064 [(call (match_operand:QI 0 "" "")
15065 (match_operand 1 "" ""))
15066 (use (match_operand 2 "" ""))]
15069 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15073 (define_insn "*call_0"
15074 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15075 (match_operand 1 "" ""))]
15078 if (SIBLING_CALL_P (insn))
15081 return "call\t%P0";
15083 [(set_attr "type" "call")])
15085 (define_insn "*call_1"
15086 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15087 (match_operand 1 "" ""))]
15088 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15090 if (constant_call_address_operand (operands[0], Pmode))
15091 return "call\t%P0";
15092 return "call\t%A0";
15094 [(set_attr "type" "call")])
15096 (define_insn "*sibcall_1"
15097 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15098 (match_operand 1 "" ""))]
15099 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15101 if (constant_call_address_operand (operands[0], Pmode))
15105 [(set_attr "type" "call")])
15107 (define_insn "*call_1_rex64"
15108 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15109 (match_operand 1 "" ""))]
15110 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15111 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15113 if (constant_call_address_operand (operands[0], Pmode))
15114 return "call\t%P0";
15115 return "call\t%A0";
15117 [(set_attr "type" "call")])
15119 (define_insn "*call_1_rex64_ms_sysv"
15120 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15121 (match_operand 1 "" ""))
15122 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15123 (clobber (reg:TI XMM6_REG))
15124 (clobber (reg:TI XMM7_REG))
15125 (clobber (reg:TI XMM8_REG))
15126 (clobber (reg:TI XMM9_REG))
15127 (clobber (reg:TI XMM10_REG))
15128 (clobber (reg:TI XMM11_REG))
15129 (clobber (reg:TI XMM12_REG))
15130 (clobber (reg:TI XMM13_REG))
15131 (clobber (reg:TI XMM14_REG))
15132 (clobber (reg:TI XMM15_REG))
15133 (clobber (reg:DI SI_REG))
15134 (clobber (reg:DI DI_REG))]
15135 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15137 if (constant_call_address_operand (operands[0], Pmode))
15138 return "call\t%P0";
15139 return "call\t%A0";
15141 [(set_attr "type" "call")])
15143 (define_insn "*call_1_rex64_large"
15144 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15145 (match_operand 1 "" ""))]
15146 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15148 [(set_attr "type" "call")])
15150 (define_insn "*sibcall_1_rex64"
15151 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15152 (match_operand 1 "" ""))]
15153 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15155 [(set_attr "type" "call")])
15157 (define_insn "*sibcall_1_rex64_v"
15158 [(call (mem:QI (reg:DI R11_REG))
15159 (match_operand 0 "" ""))]
15160 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15162 [(set_attr "type" "call")])
15165 ;; Call subroutine, returning value in operand 0
15167 (define_expand "call_value_pop"
15168 [(parallel [(set (match_operand 0 "" "")
15169 (call (match_operand:QI 1 "" "")
15170 (match_operand:SI 2 "" "")))
15171 (set (reg:SI SP_REG)
15172 (plus:SI (reg:SI SP_REG)
15173 (match_operand:SI 4 "" "")))])]
15176 ix86_expand_call (operands[0], operands[1], operands[2],
15177 operands[3], operands[4], 0);
15181 (define_expand "call_value"
15182 [(set (match_operand 0 "" "")
15183 (call (match_operand:QI 1 "" "")
15184 (match_operand:SI 2 "" "")))
15185 (use (match_operand:SI 3 "" ""))]
15186 ;; Operand 2 not used on the i386.
15189 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15193 (define_expand "sibcall_value"
15194 [(set (match_operand 0 "" "")
15195 (call (match_operand:QI 1 "" "")
15196 (match_operand:SI 2 "" "")))
15197 (use (match_operand:SI 3 "" ""))]
15198 ;; Operand 2 not used on the i386.
15201 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15205 ;; Call subroutine returning any type.
15207 (define_expand "untyped_call"
15208 [(parallel [(call (match_operand 0 "" "")
15210 (match_operand 1 "" "")
15211 (match_operand 2 "" "")])]
15216 /* In order to give reg-stack an easier job in validating two
15217 coprocessor registers as containing a possible return value,
15218 simply pretend the untyped call returns a complex long double
15221 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15222 and should have the default ABI. */
15224 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15225 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15226 operands[0], const0_rtx,
15227 GEN_INT ((TARGET_64BIT
15228 ? (ix86_abi == SYSV_ABI
15229 ? X86_64_SSE_REGPARM_MAX
15230 : X64_SSE_REGPARM_MAX)
15231 : X86_32_SSE_REGPARM_MAX)
15235 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15237 rtx set = XVECEXP (operands[2], 0, i);
15238 emit_move_insn (SET_DEST (set), SET_SRC (set));
15241 /* The optimizer does not know that the call sets the function value
15242 registers we stored in the result block. We avoid problems by
15243 claiming that all hard registers are used and clobbered at this
15245 emit_insn (gen_blockage ());
15250 ;; Prologue and epilogue instructions
15252 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15253 ;; all of memory. This blocks insns from being moved across this point.
15255 (define_insn "blockage"
15256 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15259 [(set_attr "length" "0")])
15261 ;; Do not schedule instructions accessing memory across this point.
15263 (define_expand "memory_blockage"
15264 [(set (match_dup 0)
15265 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15268 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15269 MEM_VOLATILE_P (operands[0]) = 1;
15272 (define_insn "*memory_blockage"
15273 [(set (match_operand:BLK 0 "" "")
15274 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15277 [(set_attr "length" "0")])
15279 ;; As USE insns aren't meaningful after reload, this is used instead
15280 ;; to prevent deleting instructions setting registers for PIC code
15281 (define_insn "prologue_use"
15282 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15285 [(set_attr "length" "0")])
15287 ;; Insn emitted into the body of a function to return from a function.
15288 ;; This is only done if the function's epilogue is known to be simple.
15289 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15291 (define_expand "return"
15293 "ix86_can_use_return_insn_p ()"
15295 if (crtl->args.pops_args)
15297 rtx popc = GEN_INT (crtl->args.pops_args);
15298 emit_jump_insn (gen_return_pop_internal (popc));
15303 (define_insn "return_internal"
15307 [(set_attr "length" "1")
15308 (set_attr "atom_unit" "jeu")
15309 (set_attr "length_immediate" "0")
15310 (set_attr "modrm" "0")])
15312 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15313 ;; instruction Athlon and K8 have.
15315 (define_insn "return_internal_long"
15317 (unspec [(const_int 0)] UNSPEC_REP)]
15320 [(set_attr "length" "1")
15321 (set_attr "atom_unit" "jeu")
15322 (set_attr "length_immediate" "0")
15323 (set_attr "prefix_rep" "1")
15324 (set_attr "modrm" "0")])
15326 (define_insn "return_pop_internal"
15328 (use (match_operand:SI 0 "const_int_operand" ""))]
15331 [(set_attr "length" "3")
15332 (set_attr "atom_unit" "jeu")
15333 (set_attr "length_immediate" "2")
15334 (set_attr "modrm" "0")])
15336 (define_insn "return_indirect_internal"
15338 (use (match_operand:SI 0 "register_operand" "r"))]
15341 [(set_attr "type" "ibr")
15342 (set_attr "length_immediate" "0")])
15348 [(set_attr "length" "1")
15349 (set_attr "length_immediate" "0")
15350 (set_attr "modrm" "0")])
15352 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15353 ;; branch prediction penalty for the third jump in a 16-byte
15356 (define_insn "align"
15357 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15360 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15361 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15363 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15364 The align insn is used to avoid 3 jump instructions in the row to improve
15365 branch prediction and the benefits hardly outweigh the cost of extra 8
15366 nops on the average inserted by full alignment pseudo operation. */
15370 [(set_attr "length" "16")])
15372 (define_expand "prologue"
15375 "ix86_expand_prologue (); DONE;")
15377 (define_insn "set_got"
15378 [(set (match_operand:SI 0 "register_operand" "=r")
15379 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15380 (clobber (reg:CC FLAGS_REG))]
15382 { return output_set_got (operands[0], NULL_RTX); }
15383 [(set_attr "type" "multi")
15384 (set_attr "length" "12")])
15386 (define_insn "set_got_labelled"
15387 [(set (match_operand:SI 0 "register_operand" "=r")
15388 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15390 (clobber (reg:CC FLAGS_REG))]
15392 { return output_set_got (operands[0], operands[1]); }
15393 [(set_attr "type" "multi")
15394 (set_attr "length" "12")])
15396 (define_insn "set_got_rex64"
15397 [(set (match_operand:DI 0 "register_operand" "=r")
15398 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15400 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15401 [(set_attr "type" "lea")
15402 (set_attr "length" "6")])
15404 (define_insn "set_rip_rex64"
15405 [(set (match_operand:DI 0 "register_operand" "=r")
15406 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15408 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15409 [(set_attr "type" "lea")
15410 (set_attr "length" "6")])
15412 (define_insn "set_got_offset_rex64"
15413 [(set (match_operand:DI 0 "register_operand" "=r")
15415 [(label_ref (match_operand 1 "" ""))]
15416 UNSPEC_SET_GOT_OFFSET))]
15418 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15419 [(set_attr "type" "imov")
15420 (set_attr "length" "11")])
15422 (define_expand "epilogue"
15425 "ix86_expand_epilogue (1); DONE;")
15427 (define_expand "sibcall_epilogue"
15430 "ix86_expand_epilogue (0); DONE;")
15432 (define_expand "eh_return"
15433 [(use (match_operand 0 "register_operand" ""))]
15436 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15438 /* Tricky bit: we write the address of the handler to which we will
15439 be returning into someone else's stack frame, one word below the
15440 stack address we wish to restore. */
15441 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15442 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15443 tmp = gen_rtx_MEM (Pmode, tmp);
15444 emit_move_insn (tmp, ra);
15446 if (Pmode == SImode)
15447 emit_jump_insn (gen_eh_return_si (sa));
15449 emit_jump_insn (gen_eh_return_di (sa));
15454 (define_insn_and_split "eh_return_<mode>"
15456 (unspec [(match_operand:P 0 "register_operand" "c")]
15457 UNSPEC_EH_RETURN))]
15462 "ix86_expand_epilogue (2); DONE;")
15464 (define_insn "leave"
15465 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15466 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15467 (clobber (mem:BLK (scratch)))]
15470 [(set_attr "type" "leave")])
15472 (define_insn "leave_rex64"
15473 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15474 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15475 (clobber (mem:BLK (scratch)))]
15478 [(set_attr "type" "leave")])
15480 (define_expand "ffssi2"
15482 [(set (match_operand:SI 0 "register_operand" "")
15483 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15484 (clobber (match_scratch:SI 2 ""))
15485 (clobber (reg:CC FLAGS_REG))])]
15490 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15495 (define_expand "ffs_cmove"
15496 [(set (match_dup 2) (const_int -1))
15497 (parallel [(set (reg:CCZ FLAGS_REG)
15498 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15500 (set (match_operand:SI 0 "register_operand" "")
15501 (ctz:SI (match_dup 1)))])
15502 (set (match_dup 0) (if_then_else:SI
15503 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15506 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15507 (clobber (reg:CC FLAGS_REG))])]
15509 "operands[2] = gen_reg_rtx (SImode);")
15511 (define_insn_and_split "*ffs_no_cmove"
15512 [(set (match_operand:SI 0 "register_operand" "=r")
15513 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15514 (clobber (match_scratch:SI 2 "=&q"))
15515 (clobber (reg:CC FLAGS_REG))]
15518 "&& reload_completed"
15519 [(parallel [(set (reg:CCZ FLAGS_REG)
15520 (compare:CCZ (match_dup 1) (const_int 0)))
15521 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15522 (set (strict_low_part (match_dup 3))
15523 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15524 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15525 (clobber (reg:CC FLAGS_REG))])
15526 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15527 (clobber (reg:CC FLAGS_REG))])
15528 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15529 (clobber (reg:CC FLAGS_REG))])]
15531 operands[3] = gen_lowpart (QImode, operands[2]);
15532 ix86_expand_clear (operands[2]);
15535 (define_insn "*ffssi_1"
15536 [(set (reg:CCZ FLAGS_REG)
15537 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15539 (set (match_operand:SI 0 "register_operand" "=r")
15540 (ctz:SI (match_dup 1)))]
15542 "bsf{l}\t{%1, %0|%0, %1}"
15543 [(set_attr "prefix_0f" "1")])
15545 (define_expand "ffsdi2"
15546 [(set (match_dup 2) (const_int -1))
15547 (parallel [(set (reg:CCZ FLAGS_REG)
15548 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15550 (set (match_operand:DI 0 "register_operand" "")
15551 (ctz:DI (match_dup 1)))])
15552 (set (match_dup 0) (if_then_else:DI
15553 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15556 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15557 (clobber (reg:CC FLAGS_REG))])]
15559 "operands[2] = gen_reg_rtx (DImode);")
15561 (define_insn "*ffsdi_1"
15562 [(set (reg:CCZ FLAGS_REG)
15563 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15565 (set (match_operand:DI 0 "register_operand" "=r")
15566 (ctz:DI (match_dup 1)))]
15568 "bsf{q}\t{%1, %0|%0, %1}"
15569 [(set_attr "prefix_0f" "1")])
15571 (define_insn "ctzsi2"
15572 [(set (match_operand:SI 0 "register_operand" "=r")
15573 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15574 (clobber (reg:CC FLAGS_REG))]
15576 "bsf{l}\t{%1, %0|%0, %1}"
15577 [(set_attr "prefix_0f" "1")])
15579 (define_insn "ctzdi2"
15580 [(set (match_operand:DI 0 "register_operand" "=r")
15581 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15582 (clobber (reg:CC FLAGS_REG))]
15584 "bsf{q}\t{%1, %0|%0, %1}"
15585 [(set_attr "prefix_0f" "1")])
15587 (define_expand "clzsi2"
15589 [(set (match_operand:SI 0 "register_operand" "")
15590 (minus:SI (const_int 31)
15591 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15592 (clobber (reg:CC FLAGS_REG))])
15594 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15595 (clobber (reg:CC FLAGS_REG))])]
15600 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15605 (define_insn "clzsi2_abm"
15606 [(set (match_operand:SI 0 "register_operand" "=r")
15607 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15608 (clobber (reg:CC FLAGS_REG))]
15610 "lzcnt{l}\t{%1, %0|%0, %1}"
15611 [(set_attr "prefix_rep" "1")
15612 (set_attr "type" "bitmanip")
15613 (set_attr "mode" "SI")])
15615 (define_insn "*bsr"
15616 [(set (match_operand:SI 0 "register_operand" "=r")
15617 (minus:SI (const_int 31)
15618 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15619 (clobber (reg:CC FLAGS_REG))]
15621 "bsr{l}\t{%1, %0|%0, %1}"
15622 [(set_attr "prefix_0f" "1")
15623 (set_attr "mode" "SI")])
15625 (define_insn "popcount<mode>2"
15626 [(set (match_operand:SWI248 0 "register_operand" "=r")
15628 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15629 (clobber (reg:CC FLAGS_REG))]
15633 return "popcnt\t{%1, %0|%0, %1}";
15635 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15638 [(set_attr "prefix_rep" "1")
15639 (set_attr "type" "bitmanip")
15640 (set_attr "mode" "<MODE>")])
15642 (define_insn "*popcount<mode>2_cmp"
15643 [(set (reg FLAGS_REG)
15646 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15648 (set (match_operand:SWI248 0 "register_operand" "=r")
15649 (popcount:SWI248 (match_dup 1)))]
15650 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15653 return "popcnt\t{%1, %0|%0, %1}";
15655 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15658 [(set_attr "prefix_rep" "1")
15659 (set_attr "type" "bitmanip")
15660 (set_attr "mode" "<MODE>")])
15662 (define_insn "*popcountsi2_cmp_zext"
15663 [(set (reg FLAGS_REG)
15665 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15667 (set (match_operand:DI 0 "register_operand" "=r")
15668 (zero_extend:DI(popcount:SI (match_dup 1))))]
15669 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15672 return "popcnt\t{%1, %0|%0, %1}";
15674 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15677 [(set_attr "prefix_rep" "1")
15678 (set_attr "type" "bitmanip")
15679 (set_attr "mode" "SI")])
15681 (define_expand "bswapsi2"
15682 [(set (match_operand:SI 0 "register_operand" "")
15683 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15688 rtx x = operands[0];
15690 emit_move_insn (x, operands[1]);
15691 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15692 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15693 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15698 (define_insn "*bswapsi_1"
15699 [(set (match_operand:SI 0 "register_operand" "=r")
15700 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15703 [(set_attr "prefix_0f" "1")
15704 (set_attr "length" "2")])
15706 (define_insn "*bswaphi_lowpart_1"
15707 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15708 (bswap:HI (match_dup 0)))
15709 (clobber (reg:CC FLAGS_REG))]
15710 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15712 xchg{b}\t{%h0, %b0|%b0, %h0}
15713 rol{w}\t{$8, %0|%0, 8}"
15714 [(set_attr "length" "2,4")
15715 (set_attr "mode" "QI,HI")])
15717 (define_insn "bswaphi_lowpart"
15718 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15719 (bswap:HI (match_dup 0)))
15720 (clobber (reg:CC FLAGS_REG))]
15722 "rol{w}\t{$8, %0|%0, 8}"
15723 [(set_attr "length" "4")
15724 (set_attr "mode" "HI")])
15726 (define_insn "bswapdi2"
15727 [(set (match_operand:DI 0 "register_operand" "=r")
15728 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15731 [(set_attr "prefix_0f" "1")
15732 (set_attr "length" "3")])
15734 (define_expand "clzdi2"
15736 [(set (match_operand:DI 0 "register_operand" "")
15737 (minus:DI (const_int 63)
15738 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15739 (clobber (reg:CC FLAGS_REG))])
15741 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15742 (clobber (reg:CC FLAGS_REG))])]
15747 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15752 (define_insn "clzdi2_abm"
15753 [(set (match_operand:DI 0 "register_operand" "=r")
15754 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15755 (clobber (reg:CC FLAGS_REG))]
15756 "TARGET_64BIT && TARGET_ABM"
15757 "lzcnt{q}\t{%1, %0|%0, %1}"
15758 [(set_attr "prefix_rep" "1")
15759 (set_attr "type" "bitmanip")
15760 (set_attr "mode" "DI")])
15762 (define_insn "*bsr_rex64"
15763 [(set (match_operand:DI 0 "register_operand" "=r")
15764 (minus:DI (const_int 63)
15765 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15766 (clobber (reg:CC FLAGS_REG))]
15768 "bsr{q}\t{%1, %0|%0, %1}"
15769 [(set_attr "prefix_0f" "1")
15770 (set_attr "mode" "DI")])
15772 (define_expand "clzhi2"
15774 [(set (match_operand:HI 0 "register_operand" "")
15775 (minus:HI (const_int 15)
15776 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15777 (clobber (reg:CC FLAGS_REG))])
15779 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15780 (clobber (reg:CC FLAGS_REG))])]
15785 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15790 (define_insn "clzhi2_abm"
15791 [(set (match_operand:HI 0 "register_operand" "=r")
15792 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15793 (clobber (reg:CC FLAGS_REG))]
15795 "lzcnt{w}\t{%1, %0|%0, %1}"
15796 [(set_attr "prefix_rep" "1")
15797 (set_attr "type" "bitmanip")
15798 (set_attr "mode" "HI")])
15800 (define_insn "*bsrhi"
15801 [(set (match_operand:HI 0 "register_operand" "=r")
15802 (minus:HI (const_int 15)
15803 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15804 (clobber (reg:CC FLAGS_REG))]
15806 "bsr{w}\t{%1, %0|%0, %1}"
15807 [(set_attr "prefix_0f" "1")
15808 (set_attr "mode" "HI")])
15810 (define_expand "paritydi2"
15811 [(set (match_operand:DI 0 "register_operand" "")
15812 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15815 rtx scratch = gen_reg_rtx (QImode);
15818 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15819 NULL_RTX, operands[1]));
15821 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15822 gen_rtx_REG (CCmode, FLAGS_REG),
15824 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15827 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15830 rtx tmp = gen_reg_rtx (SImode);
15832 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15833 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15838 (define_insn_and_split "paritydi2_cmp"
15839 [(set (reg:CC FLAGS_REG)
15840 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15841 (clobber (match_scratch:DI 0 "=r"))
15842 (clobber (match_scratch:SI 1 "=&r"))
15843 (clobber (match_scratch:HI 2 "=Q"))]
15846 "&& reload_completed"
15848 [(set (match_dup 1)
15849 (xor:SI (match_dup 1) (match_dup 4)))
15850 (clobber (reg:CC FLAGS_REG))])
15852 [(set (reg:CC FLAGS_REG)
15853 (parity:CC (match_dup 1)))
15854 (clobber (match_dup 1))
15855 (clobber (match_dup 2))])]
15857 operands[4] = gen_lowpart (SImode, operands[3]);
15861 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15862 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15865 operands[1] = gen_highpart (SImode, operands[3]);
15868 (define_expand "paritysi2"
15869 [(set (match_operand:SI 0 "register_operand" "")
15870 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15873 rtx scratch = gen_reg_rtx (QImode);
15876 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15878 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15879 gen_rtx_REG (CCmode, FLAGS_REG),
15881 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15883 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15887 (define_insn_and_split "paritysi2_cmp"
15888 [(set (reg:CC FLAGS_REG)
15889 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15890 (clobber (match_scratch:SI 0 "=r"))
15891 (clobber (match_scratch:HI 1 "=&Q"))]
15894 "&& reload_completed"
15896 [(set (match_dup 1)
15897 (xor:HI (match_dup 1) (match_dup 3)))
15898 (clobber (reg:CC FLAGS_REG))])
15900 [(set (reg:CC FLAGS_REG)
15901 (parity:CC (match_dup 1)))
15902 (clobber (match_dup 1))])]
15904 operands[3] = gen_lowpart (HImode, operands[2]);
15906 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15907 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15910 (define_insn "*parityhi2_cmp"
15911 [(set (reg:CC FLAGS_REG)
15912 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15913 (clobber (match_scratch:HI 0 "=Q"))]
15915 "xor{b}\t{%h0, %b0|%b0, %h0}"
15916 [(set_attr "length" "2")
15917 (set_attr "mode" "HI")])
15919 (define_insn "*parityqi2_cmp"
15920 [(set (reg:CC FLAGS_REG)
15921 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15924 [(set_attr "length" "2")
15925 (set_attr "mode" "QI")])
15927 ;; Thread-local storage patterns for ELF.
15929 ;; Note that these code sequences must appear exactly as shown
15930 ;; in order to allow linker relaxation.
15932 (define_insn "*tls_global_dynamic_32_gnu"
15933 [(set (match_operand:SI 0 "register_operand" "=a")
15934 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15935 (match_operand:SI 2 "tls_symbolic_operand" "")
15936 (match_operand:SI 3 "call_insn_operand" "")]
15938 (clobber (match_scratch:SI 4 "=d"))
15939 (clobber (match_scratch:SI 5 "=c"))
15940 (clobber (reg:CC FLAGS_REG))]
15941 "!TARGET_64BIT && TARGET_GNU_TLS"
15942 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15943 [(set_attr "type" "multi")
15944 (set_attr "length" "12")])
15946 (define_insn "*tls_global_dynamic_32_sun"
15947 [(set (match_operand:SI 0 "register_operand" "=a")
15948 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15949 (match_operand:SI 2 "tls_symbolic_operand" "")
15950 (match_operand:SI 3 "call_insn_operand" "")]
15952 (clobber (match_scratch:SI 4 "=d"))
15953 (clobber (match_scratch:SI 5 "=c"))
15954 (clobber (reg:CC FLAGS_REG))]
15955 "!TARGET_64BIT && TARGET_SUN_TLS"
15956 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15957 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15958 [(set_attr "type" "multi")
15959 (set_attr "length" "14")])
15961 (define_expand "tls_global_dynamic_32"
15962 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15965 (match_operand:SI 1 "tls_symbolic_operand" "")
15968 (clobber (match_scratch:SI 4 ""))
15969 (clobber (match_scratch:SI 5 ""))
15970 (clobber (reg:CC FLAGS_REG))])]
15974 operands[2] = pic_offset_table_rtx;
15977 operands[2] = gen_reg_rtx (Pmode);
15978 emit_insn (gen_set_got (operands[2]));
15980 if (TARGET_GNU2_TLS)
15982 emit_insn (gen_tls_dynamic_gnu2_32
15983 (operands[0], operands[1], operands[2]));
15986 operands[3] = ix86_tls_get_addr ();
15989 (define_insn "*tls_global_dynamic_64"
15990 [(set (match_operand:DI 0 "register_operand" "=a")
15991 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15992 (match_operand:DI 3 "" "")))
15993 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15996 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15997 [(set_attr "type" "multi")
15998 (set_attr "length" "16")])
16000 (define_expand "tls_global_dynamic_64"
16001 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16002 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16003 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16007 if (TARGET_GNU2_TLS)
16009 emit_insn (gen_tls_dynamic_gnu2_64
16010 (operands[0], operands[1]));
16013 operands[2] = ix86_tls_get_addr ();
16016 (define_insn "*tls_local_dynamic_base_32_gnu"
16017 [(set (match_operand:SI 0 "register_operand" "=a")
16018 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16019 (match_operand:SI 2 "call_insn_operand" "")]
16020 UNSPEC_TLS_LD_BASE))
16021 (clobber (match_scratch:SI 3 "=d"))
16022 (clobber (match_scratch:SI 4 "=c"))
16023 (clobber (reg:CC FLAGS_REG))]
16024 "!TARGET_64BIT && TARGET_GNU_TLS"
16025 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16026 [(set_attr "type" "multi")
16027 (set_attr "length" "11")])
16029 (define_insn "*tls_local_dynamic_base_32_sun"
16030 [(set (match_operand:SI 0 "register_operand" "=a")
16031 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16032 (match_operand:SI 2 "call_insn_operand" "")]
16033 UNSPEC_TLS_LD_BASE))
16034 (clobber (match_scratch:SI 3 "=d"))
16035 (clobber (match_scratch:SI 4 "=c"))
16036 (clobber (reg:CC FLAGS_REG))]
16037 "!TARGET_64BIT && TARGET_SUN_TLS"
16038 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16039 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16040 [(set_attr "type" "multi")
16041 (set_attr "length" "13")])
16043 (define_expand "tls_local_dynamic_base_32"
16044 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16045 (unspec:SI [(match_dup 1) (match_dup 2)]
16046 UNSPEC_TLS_LD_BASE))
16047 (clobber (match_scratch:SI 3 ""))
16048 (clobber (match_scratch:SI 4 ""))
16049 (clobber (reg:CC FLAGS_REG))])]
16053 operands[1] = pic_offset_table_rtx;
16056 operands[1] = gen_reg_rtx (Pmode);
16057 emit_insn (gen_set_got (operands[1]));
16059 if (TARGET_GNU2_TLS)
16061 emit_insn (gen_tls_dynamic_gnu2_32
16062 (operands[0], ix86_tls_module_base (), operands[1]));
16065 operands[2] = ix86_tls_get_addr ();
16068 (define_insn "*tls_local_dynamic_base_64"
16069 [(set (match_operand:DI 0 "register_operand" "=a")
16070 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16071 (match_operand:DI 2 "" "")))
16072 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16074 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16075 [(set_attr "type" "multi")
16076 (set_attr "length" "12")])
16078 (define_expand "tls_local_dynamic_base_64"
16079 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16080 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16081 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16084 if (TARGET_GNU2_TLS)
16086 emit_insn (gen_tls_dynamic_gnu2_64
16087 (operands[0], ix86_tls_module_base ()));
16090 operands[1] = ix86_tls_get_addr ();
16093 ;; Local dynamic of a single variable is a lose. Show combine how
16094 ;; to convert that back to global dynamic.
16096 (define_insn_and_split "*tls_local_dynamic_32_once"
16097 [(set (match_operand:SI 0 "register_operand" "=a")
16098 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16099 (match_operand:SI 2 "call_insn_operand" "")]
16100 UNSPEC_TLS_LD_BASE)
16101 (const:SI (unspec:SI
16102 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16104 (clobber (match_scratch:SI 4 "=d"))
16105 (clobber (match_scratch:SI 5 "=c"))
16106 (clobber (reg:CC FLAGS_REG))]
16110 [(parallel [(set (match_dup 0)
16111 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16113 (clobber (match_dup 4))
16114 (clobber (match_dup 5))
16115 (clobber (reg:CC FLAGS_REG))])]
16118 ;; Load and add the thread base pointer from %gs:0.
16120 (define_insn "*load_tp_si"
16121 [(set (match_operand:SI 0 "register_operand" "=r")
16122 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16124 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16125 [(set_attr "type" "imov")
16126 (set_attr "modrm" "0")
16127 (set_attr "length" "7")
16128 (set_attr "memory" "load")
16129 (set_attr "imm_disp" "false")])
16131 (define_insn "*add_tp_si"
16132 [(set (match_operand:SI 0 "register_operand" "=r")
16133 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16134 (match_operand:SI 1 "register_operand" "0")))
16135 (clobber (reg:CC FLAGS_REG))]
16137 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16138 [(set_attr "type" "alu")
16139 (set_attr "modrm" "0")
16140 (set_attr "length" "7")
16141 (set_attr "memory" "load")
16142 (set_attr "imm_disp" "false")])
16144 (define_insn "*load_tp_di"
16145 [(set (match_operand:DI 0 "register_operand" "=r")
16146 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16148 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16149 [(set_attr "type" "imov")
16150 (set_attr "modrm" "0")
16151 (set_attr "length" "7")
16152 (set_attr "memory" "load")
16153 (set_attr "imm_disp" "false")])
16155 (define_insn "*add_tp_di"
16156 [(set (match_operand:DI 0 "register_operand" "=r")
16157 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16158 (match_operand:DI 1 "register_operand" "0")))
16159 (clobber (reg:CC FLAGS_REG))]
16161 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16162 [(set_attr "type" "alu")
16163 (set_attr "modrm" "0")
16164 (set_attr "length" "7")
16165 (set_attr "memory" "load")
16166 (set_attr "imm_disp" "false")])
16168 ;; GNU2 TLS patterns can be split.
16170 (define_expand "tls_dynamic_gnu2_32"
16171 [(set (match_dup 3)
16172 (plus:SI (match_operand:SI 2 "register_operand" "")
16174 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16177 [(set (match_operand:SI 0 "register_operand" "")
16178 (unspec:SI [(match_dup 1) (match_dup 3)
16179 (match_dup 2) (reg:SI SP_REG)]
16181 (clobber (reg:CC FLAGS_REG))])]
16182 "!TARGET_64BIT && TARGET_GNU2_TLS"
16184 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16185 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16188 (define_insn "*tls_dynamic_lea_32"
16189 [(set (match_operand:SI 0 "register_operand" "=r")
16190 (plus:SI (match_operand:SI 1 "register_operand" "b")
16192 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16193 UNSPEC_TLSDESC))))]
16194 "!TARGET_64BIT && TARGET_GNU2_TLS"
16195 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16196 [(set_attr "type" "lea")
16197 (set_attr "mode" "SI")
16198 (set_attr "length" "6")
16199 (set_attr "length_address" "4")])
16201 (define_insn "*tls_dynamic_call_32"
16202 [(set (match_operand:SI 0 "register_operand" "=a")
16203 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16204 (match_operand:SI 2 "register_operand" "0")
16205 ;; we have to make sure %ebx still points to the GOT
16206 (match_operand:SI 3 "register_operand" "b")
16209 (clobber (reg:CC FLAGS_REG))]
16210 "!TARGET_64BIT && TARGET_GNU2_TLS"
16211 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16212 [(set_attr "type" "call")
16213 (set_attr "length" "2")
16214 (set_attr "length_address" "0")])
16216 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16217 [(set (match_operand:SI 0 "register_operand" "=&a")
16219 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16220 (match_operand:SI 4 "" "")
16221 (match_operand:SI 2 "register_operand" "b")
16224 (const:SI (unspec:SI
16225 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16227 (clobber (reg:CC FLAGS_REG))]
16228 "!TARGET_64BIT && TARGET_GNU2_TLS"
16231 [(set (match_dup 0) (match_dup 5))]
16233 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16234 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16237 (define_expand "tls_dynamic_gnu2_64"
16238 [(set (match_dup 2)
16239 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16242 [(set (match_operand:DI 0 "register_operand" "")
16243 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16245 (clobber (reg:CC FLAGS_REG))])]
16246 "TARGET_64BIT && TARGET_GNU2_TLS"
16248 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16249 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16252 (define_insn "*tls_dynamic_lea_64"
16253 [(set (match_operand:DI 0 "register_operand" "=r")
16254 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16256 "TARGET_64BIT && TARGET_GNU2_TLS"
16257 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16258 [(set_attr "type" "lea")
16259 (set_attr "mode" "DI")
16260 (set_attr "length" "7")
16261 (set_attr "length_address" "4")])
16263 (define_insn "*tls_dynamic_call_64"
16264 [(set (match_operand:DI 0 "register_operand" "=a")
16265 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16266 (match_operand:DI 2 "register_operand" "0")
16269 (clobber (reg:CC FLAGS_REG))]
16270 "TARGET_64BIT && TARGET_GNU2_TLS"
16271 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16272 [(set_attr "type" "call")
16273 (set_attr "length" "2")
16274 (set_attr "length_address" "0")])
16276 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16277 [(set (match_operand:DI 0 "register_operand" "=&a")
16279 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16280 (match_operand:DI 3 "" "")
16283 (const:DI (unspec:DI
16284 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16286 (clobber (reg:CC FLAGS_REG))]
16287 "TARGET_64BIT && TARGET_GNU2_TLS"
16290 [(set (match_dup 0) (match_dup 4))]
16292 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16293 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16298 ;; These patterns match the binary 387 instructions for addM3, subM3,
16299 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16300 ;; SFmode. The first is the normal insn, the second the same insn but
16301 ;; with one operand a conversion, and the third the same insn but with
16302 ;; the other operand a conversion. The conversion may be SFmode or
16303 ;; SImode if the target mode DFmode, but only SImode if the target mode
16306 ;; Gcc is slightly more smart about handling normal two address instructions
16307 ;; so use special patterns for add and mull.
16309 (define_insn "*fop_<mode>_comm_mixed_avx"
16310 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16311 (match_operator:MODEF 3 "binary_fp_operator"
16312 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16313 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16314 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16315 && COMMUTATIVE_ARITH_P (operands[3])
16316 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16317 "* return output_387_binary_op (insn, operands);"
16318 [(set (attr "type")
16319 (if_then_else (eq_attr "alternative" "1")
16320 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16321 (const_string "ssemul")
16322 (const_string "sseadd"))
16323 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16324 (const_string "fmul")
16325 (const_string "fop"))))
16326 (set_attr "prefix" "orig,maybe_vex")
16327 (set_attr "mode" "<MODE>")])
16329 (define_insn "*fop_<mode>_comm_mixed"
16330 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16331 (match_operator:MODEF 3 "binary_fp_operator"
16332 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16333 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16334 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16335 && COMMUTATIVE_ARITH_P (operands[3])
16336 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16337 "* return output_387_binary_op (insn, operands);"
16338 [(set (attr "type")
16339 (if_then_else (eq_attr "alternative" "1")
16340 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16341 (const_string "ssemul")
16342 (const_string "sseadd"))
16343 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16344 (const_string "fmul")
16345 (const_string "fop"))))
16346 (set_attr "mode" "<MODE>")])
16348 (define_insn "*fop_<mode>_comm_avx"
16349 [(set (match_operand:MODEF 0 "register_operand" "=x")
16350 (match_operator:MODEF 3 "binary_fp_operator"
16351 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16352 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16353 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16354 && COMMUTATIVE_ARITH_P (operands[3])
16355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16356 "* return output_387_binary_op (insn, operands);"
16357 [(set (attr "type")
16358 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16359 (const_string "ssemul")
16360 (const_string "sseadd")))
16361 (set_attr "prefix" "vex")
16362 (set_attr "mode" "<MODE>")])
16364 (define_insn "*fop_<mode>_comm_sse"
16365 [(set (match_operand:MODEF 0 "register_operand" "=x")
16366 (match_operator:MODEF 3 "binary_fp_operator"
16367 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16368 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16369 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16370 && COMMUTATIVE_ARITH_P (operands[3])
16371 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16372 "* return output_387_binary_op (insn, operands);"
16373 [(set (attr "type")
16374 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16375 (const_string "ssemul")
16376 (const_string "sseadd")))
16377 (set_attr "mode" "<MODE>")])
16379 (define_insn "*fop_<mode>_comm_i387"
16380 [(set (match_operand:MODEF 0 "register_operand" "=f")
16381 (match_operator:MODEF 3 "binary_fp_operator"
16382 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16383 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16384 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16385 && COMMUTATIVE_ARITH_P (operands[3])
16386 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16387 "* return output_387_binary_op (insn, operands);"
16388 [(set (attr "type")
16389 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16390 (const_string "fmul")
16391 (const_string "fop")))
16392 (set_attr "mode" "<MODE>")])
16394 (define_insn "*fop_<mode>_1_mixed_avx"
16395 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16396 (match_operator:MODEF 3 "binary_fp_operator"
16397 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16398 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16399 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16400 && !COMMUTATIVE_ARITH_P (operands[3])
16401 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16402 "* return output_387_binary_op (insn, operands);"
16403 [(set (attr "type")
16404 (cond [(and (eq_attr "alternative" "2")
16405 (match_operand:MODEF 3 "mult_operator" ""))
16406 (const_string "ssemul")
16407 (and (eq_attr "alternative" "2")
16408 (match_operand:MODEF 3 "div_operator" ""))
16409 (const_string "ssediv")
16410 (eq_attr "alternative" "2")
16411 (const_string "sseadd")
16412 (match_operand:MODEF 3 "mult_operator" "")
16413 (const_string "fmul")
16414 (match_operand:MODEF 3 "div_operator" "")
16415 (const_string "fdiv")
16417 (const_string "fop")))
16418 (set_attr "prefix" "orig,orig,maybe_vex")
16419 (set_attr "mode" "<MODE>")])
16421 (define_insn "*fop_<mode>_1_mixed"
16422 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16423 (match_operator:MODEF 3 "binary_fp_operator"
16424 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16425 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16427 && !COMMUTATIVE_ARITH_P (operands[3])
16428 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16429 "* return output_387_binary_op (insn, operands);"
16430 [(set (attr "type")
16431 (cond [(and (eq_attr "alternative" "2")
16432 (match_operand:MODEF 3 "mult_operator" ""))
16433 (const_string "ssemul")
16434 (and (eq_attr "alternative" "2")
16435 (match_operand:MODEF 3 "div_operator" ""))
16436 (const_string "ssediv")
16437 (eq_attr "alternative" "2")
16438 (const_string "sseadd")
16439 (match_operand:MODEF 3 "mult_operator" "")
16440 (const_string "fmul")
16441 (match_operand:MODEF 3 "div_operator" "")
16442 (const_string "fdiv")
16444 (const_string "fop")))
16445 (set_attr "mode" "<MODE>")])
16447 (define_insn "*rcpsf2_sse"
16448 [(set (match_operand:SF 0 "register_operand" "=x")
16449 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16452 "%vrcpss\t{%1, %d0|%d0, %1}"
16453 [(set_attr "type" "sse")
16454 (set_attr "atom_sse_attr" "rcp")
16455 (set_attr "prefix" "maybe_vex")
16456 (set_attr "mode" "SF")])
16458 (define_insn "*fop_<mode>_1_avx"
16459 [(set (match_operand:MODEF 0 "register_operand" "=x")
16460 (match_operator:MODEF 3 "binary_fp_operator"
16461 [(match_operand:MODEF 1 "register_operand" "x")
16462 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16463 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16464 && !COMMUTATIVE_ARITH_P (operands[3])"
16465 "* return output_387_binary_op (insn, operands);"
16466 [(set (attr "type")
16467 (cond [(match_operand:MODEF 3 "mult_operator" "")
16468 (const_string "ssemul")
16469 (match_operand:MODEF 3 "div_operator" "")
16470 (const_string "ssediv")
16472 (const_string "sseadd")))
16473 (set_attr "prefix" "vex")
16474 (set_attr "mode" "<MODE>")])
16476 (define_insn "*fop_<mode>_1_sse"
16477 [(set (match_operand:MODEF 0 "register_operand" "=x")
16478 (match_operator:MODEF 3 "binary_fp_operator"
16479 [(match_operand:MODEF 1 "register_operand" "0")
16480 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16481 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16482 && !COMMUTATIVE_ARITH_P (operands[3])"
16483 "* return output_387_binary_op (insn, operands);"
16484 [(set (attr "type")
16485 (cond [(match_operand:MODEF 3 "mult_operator" "")
16486 (const_string "ssemul")
16487 (match_operand:MODEF 3 "div_operator" "")
16488 (const_string "ssediv")
16490 (const_string "sseadd")))
16491 (set_attr "mode" "<MODE>")])
16493 ;; This pattern is not fully shadowed by the pattern above.
16494 (define_insn "*fop_<mode>_1_i387"
16495 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16496 (match_operator:MODEF 3 "binary_fp_operator"
16497 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16498 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16499 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16500 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16501 && !COMMUTATIVE_ARITH_P (operands[3])
16502 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16503 "* return output_387_binary_op (insn, operands);"
16504 [(set (attr "type")
16505 (cond [(match_operand:MODEF 3 "mult_operator" "")
16506 (const_string "fmul")
16507 (match_operand:MODEF 3 "div_operator" "")
16508 (const_string "fdiv")
16510 (const_string "fop")))
16511 (set_attr "mode" "<MODE>")])
16513 ;; ??? Add SSE splitters for these!
16514 (define_insn "*fop_<MODEF:mode>_2_i387"
16515 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16516 (match_operator:MODEF 3 "binary_fp_operator"
16518 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16519 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16520 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16521 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16522 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16523 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16524 [(set (attr "type")
16525 (cond [(match_operand:MODEF 3 "mult_operator" "")
16526 (const_string "fmul")
16527 (match_operand:MODEF 3 "div_operator" "")
16528 (const_string "fdiv")
16530 (const_string "fop")))
16531 (set_attr "fp_int_src" "true")
16532 (set_attr "mode" "<X87MODEI12:MODE>")])
16534 (define_insn "*fop_<MODEF:mode>_3_i387"
16535 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16536 (match_operator:MODEF 3 "binary_fp_operator"
16537 [(match_operand:MODEF 1 "register_operand" "0,0")
16539 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16540 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16541 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16542 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16543 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16544 [(set (attr "type")
16545 (cond [(match_operand:MODEF 3 "mult_operator" "")
16546 (const_string "fmul")
16547 (match_operand:MODEF 3 "div_operator" "")
16548 (const_string "fdiv")
16550 (const_string "fop")))
16551 (set_attr "fp_int_src" "true")
16552 (set_attr "mode" "<MODE>")])
16554 (define_insn "*fop_df_4_i387"
16555 [(set (match_operand:DF 0 "register_operand" "=f,f")
16556 (match_operator:DF 3 "binary_fp_operator"
16558 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16559 (match_operand:DF 2 "register_operand" "0,f")]))]
16560 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16561 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16562 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16563 "* return output_387_binary_op (insn, operands);"
16564 [(set (attr "type")
16565 (cond [(match_operand:DF 3 "mult_operator" "")
16566 (const_string "fmul")
16567 (match_operand:DF 3 "div_operator" "")
16568 (const_string "fdiv")
16570 (const_string "fop")))
16571 (set_attr "mode" "SF")])
16573 (define_insn "*fop_df_5_i387"
16574 [(set (match_operand:DF 0 "register_operand" "=f,f")
16575 (match_operator:DF 3 "binary_fp_operator"
16576 [(match_operand:DF 1 "register_operand" "0,f")
16578 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16579 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16580 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16581 "* return output_387_binary_op (insn, operands);"
16582 [(set (attr "type")
16583 (cond [(match_operand:DF 3 "mult_operator" "")
16584 (const_string "fmul")
16585 (match_operand:DF 3 "div_operator" "")
16586 (const_string "fdiv")
16588 (const_string "fop")))
16589 (set_attr "mode" "SF")])
16591 (define_insn "*fop_df_6_i387"
16592 [(set (match_operand:DF 0 "register_operand" "=f,f")
16593 (match_operator:DF 3 "binary_fp_operator"
16595 (match_operand:SF 1 "register_operand" "0,f"))
16597 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16598 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16599 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16600 "* return output_387_binary_op (insn, operands);"
16601 [(set (attr "type")
16602 (cond [(match_operand:DF 3 "mult_operator" "")
16603 (const_string "fmul")
16604 (match_operand:DF 3 "div_operator" "")
16605 (const_string "fdiv")
16607 (const_string "fop")))
16608 (set_attr "mode" "SF")])
16610 (define_insn "*fop_xf_comm_i387"
16611 [(set (match_operand:XF 0 "register_operand" "=f")
16612 (match_operator:XF 3 "binary_fp_operator"
16613 [(match_operand:XF 1 "register_operand" "%0")
16614 (match_operand:XF 2 "register_operand" "f")]))]
16616 && COMMUTATIVE_ARITH_P (operands[3])"
16617 "* return output_387_binary_op (insn, operands);"
16618 [(set (attr "type")
16619 (if_then_else (match_operand:XF 3 "mult_operator" "")
16620 (const_string "fmul")
16621 (const_string "fop")))
16622 (set_attr "mode" "XF")])
16624 (define_insn "*fop_xf_1_i387"
16625 [(set (match_operand:XF 0 "register_operand" "=f,f")
16626 (match_operator:XF 3 "binary_fp_operator"
16627 [(match_operand:XF 1 "register_operand" "0,f")
16628 (match_operand:XF 2 "register_operand" "f,0")]))]
16630 && !COMMUTATIVE_ARITH_P (operands[3])"
16631 "* return output_387_binary_op (insn, operands);"
16632 [(set (attr "type")
16633 (cond [(match_operand:XF 3 "mult_operator" "")
16634 (const_string "fmul")
16635 (match_operand:XF 3 "div_operator" "")
16636 (const_string "fdiv")
16638 (const_string "fop")))
16639 (set_attr "mode" "XF")])
16641 (define_insn "*fop_xf_2_i387"
16642 [(set (match_operand:XF 0 "register_operand" "=f,f")
16643 (match_operator:XF 3 "binary_fp_operator"
16645 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16646 (match_operand:XF 2 "register_operand" "0,0")]))]
16647 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16648 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16649 [(set (attr "type")
16650 (cond [(match_operand:XF 3 "mult_operator" "")
16651 (const_string "fmul")
16652 (match_operand:XF 3 "div_operator" "")
16653 (const_string "fdiv")
16655 (const_string "fop")))
16656 (set_attr "fp_int_src" "true")
16657 (set_attr "mode" "<MODE>")])
16659 (define_insn "*fop_xf_3_i387"
16660 [(set (match_operand:XF 0 "register_operand" "=f,f")
16661 (match_operator:XF 3 "binary_fp_operator"
16662 [(match_operand:XF 1 "register_operand" "0,0")
16664 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16665 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16666 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16667 [(set (attr "type")
16668 (cond [(match_operand:XF 3 "mult_operator" "")
16669 (const_string "fmul")
16670 (match_operand:XF 3 "div_operator" "")
16671 (const_string "fdiv")
16673 (const_string "fop")))
16674 (set_attr "fp_int_src" "true")
16675 (set_attr "mode" "<MODE>")])
16677 (define_insn "*fop_xf_4_i387"
16678 [(set (match_operand:XF 0 "register_operand" "=f,f")
16679 (match_operator:XF 3 "binary_fp_operator"
16681 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16682 (match_operand:XF 2 "register_operand" "0,f")]))]
16684 "* return output_387_binary_op (insn, operands);"
16685 [(set (attr "type")
16686 (cond [(match_operand:XF 3 "mult_operator" "")
16687 (const_string "fmul")
16688 (match_operand:XF 3 "div_operator" "")
16689 (const_string "fdiv")
16691 (const_string "fop")))
16692 (set_attr "mode" "<MODE>")])
16694 (define_insn "*fop_xf_5_i387"
16695 [(set (match_operand:XF 0 "register_operand" "=f,f")
16696 (match_operator:XF 3 "binary_fp_operator"
16697 [(match_operand:XF 1 "register_operand" "0,f")
16699 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16701 "* return output_387_binary_op (insn, operands);"
16702 [(set (attr "type")
16703 (cond [(match_operand:XF 3 "mult_operator" "")
16704 (const_string "fmul")
16705 (match_operand:XF 3 "div_operator" "")
16706 (const_string "fdiv")
16708 (const_string "fop")))
16709 (set_attr "mode" "<MODE>")])
16711 (define_insn "*fop_xf_6_i387"
16712 [(set (match_operand:XF 0 "register_operand" "=f,f")
16713 (match_operator:XF 3 "binary_fp_operator"
16715 (match_operand:MODEF 1 "register_operand" "0,f"))
16717 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16719 "* return output_387_binary_op (insn, operands);"
16720 [(set (attr "type")
16721 (cond [(match_operand:XF 3 "mult_operator" "")
16722 (const_string "fmul")
16723 (match_operand:XF 3 "div_operator" "")
16724 (const_string "fdiv")
16726 (const_string "fop")))
16727 (set_attr "mode" "<MODE>")])
16730 [(set (match_operand 0 "register_operand" "")
16731 (match_operator 3 "binary_fp_operator"
16732 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16733 (match_operand 2 "register_operand" "")]))]
16735 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16736 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16739 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16740 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16741 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16742 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16743 GET_MODE (operands[3]),
16746 ix86_free_from_memory (GET_MODE (operands[1]));
16751 [(set (match_operand 0 "register_operand" "")
16752 (match_operator 3 "binary_fp_operator"
16753 [(match_operand 1 "register_operand" "")
16754 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16756 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16757 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16760 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16761 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16762 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16763 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16764 GET_MODE (operands[3]),
16767 ix86_free_from_memory (GET_MODE (operands[2]));
16771 ;; FPU special functions.
16773 ;; This pattern implements a no-op XFmode truncation for
16774 ;; all fancy i386 XFmode math functions.
16776 (define_insn "truncxf<mode>2_i387_noop_unspec"
16777 [(set (match_operand:MODEF 0 "register_operand" "=f")
16778 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16779 UNSPEC_TRUNC_NOOP))]
16780 "TARGET_USE_FANCY_MATH_387"
16781 "* return output_387_reg_move (insn, operands);"
16782 [(set_attr "type" "fmov")
16783 (set_attr "mode" "<MODE>")])
16785 (define_insn "sqrtxf2"
16786 [(set (match_operand:XF 0 "register_operand" "=f")
16787 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16788 "TARGET_USE_FANCY_MATH_387"
16790 [(set_attr "type" "fpspc")
16791 (set_attr "mode" "XF")
16792 (set_attr "athlon_decode" "direct")
16793 (set_attr "amdfam10_decode" "direct")])
16795 (define_insn "sqrt_extend<mode>xf2_i387"
16796 [(set (match_operand:XF 0 "register_operand" "=f")
16799 (match_operand:MODEF 1 "register_operand" "0"))))]
16800 "TARGET_USE_FANCY_MATH_387"
16802 [(set_attr "type" "fpspc")
16803 (set_attr "mode" "XF")
16804 (set_attr "athlon_decode" "direct")
16805 (set_attr "amdfam10_decode" "direct")])
16807 (define_insn "*rsqrtsf2_sse"
16808 [(set (match_operand:SF 0 "register_operand" "=x")
16809 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16812 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16813 [(set_attr "type" "sse")
16814 (set_attr "atom_sse_attr" "rcp")
16815 (set_attr "prefix" "maybe_vex")
16816 (set_attr "mode" "SF")])
16818 (define_expand "rsqrtsf2"
16819 [(set (match_operand:SF 0 "register_operand" "")
16820 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16824 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16828 (define_insn "*sqrt<mode>2_sse"
16829 [(set (match_operand:MODEF 0 "register_operand" "=x")
16831 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16832 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16833 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16834 [(set_attr "type" "sse")
16835 (set_attr "atom_sse_attr" "sqrt")
16836 (set_attr "prefix" "maybe_vex")
16837 (set_attr "mode" "<MODE>")
16838 (set_attr "athlon_decode" "*")
16839 (set_attr "amdfam10_decode" "*")])
16841 (define_expand "sqrt<mode>2"
16842 [(set (match_operand:MODEF 0 "register_operand" "")
16844 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16845 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16846 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16848 if (<MODE>mode == SFmode
16849 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16850 && flag_finite_math_only && !flag_trapping_math
16851 && flag_unsafe_math_optimizations)
16853 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16857 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16859 rtx op0 = gen_reg_rtx (XFmode);
16860 rtx op1 = force_reg (<MODE>mode, operands[1]);
16862 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16863 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16868 (define_insn "fpremxf4_i387"
16869 [(set (match_operand:XF 0 "register_operand" "=f")
16870 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16871 (match_operand:XF 3 "register_operand" "1")]
16873 (set (match_operand:XF 1 "register_operand" "=u")
16874 (unspec:XF [(match_dup 2) (match_dup 3)]
16876 (set (reg:CCFP FPSR_REG)
16877 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16879 "TARGET_USE_FANCY_MATH_387"
16881 [(set_attr "type" "fpspc")
16882 (set_attr "mode" "XF")])
16884 (define_expand "fmodxf3"
16885 [(use (match_operand:XF 0 "register_operand" ""))
16886 (use (match_operand:XF 1 "general_operand" ""))
16887 (use (match_operand:XF 2 "general_operand" ""))]
16888 "TARGET_USE_FANCY_MATH_387"
16890 rtx label = gen_label_rtx ();
16892 rtx op1 = gen_reg_rtx (XFmode);
16893 rtx op2 = gen_reg_rtx (XFmode);
16895 emit_move_insn (op2, operands[2]);
16896 emit_move_insn (op1, operands[1]);
16898 emit_label (label);
16899 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16900 ix86_emit_fp_unordered_jump (label);
16901 LABEL_NUSES (label) = 1;
16903 emit_move_insn (operands[0], op1);
16907 (define_expand "fmod<mode>3"
16908 [(use (match_operand:MODEF 0 "register_operand" ""))
16909 (use (match_operand:MODEF 1 "general_operand" ""))
16910 (use (match_operand:MODEF 2 "general_operand" ""))]
16911 "TARGET_USE_FANCY_MATH_387"
16913 rtx label = gen_label_rtx ();
16915 rtx op1 = gen_reg_rtx (XFmode);
16916 rtx op2 = gen_reg_rtx (XFmode);
16918 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16921 emit_label (label);
16922 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16923 ix86_emit_fp_unordered_jump (label);
16924 LABEL_NUSES (label) = 1;
16926 /* Truncate the result properly for strict SSE math. */
16927 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16928 && !TARGET_MIX_SSE_I387)
16929 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16931 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16936 (define_insn "fprem1xf4_i387"
16937 [(set (match_operand:XF 0 "register_operand" "=f")
16938 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16939 (match_operand:XF 3 "register_operand" "1")]
16941 (set (match_operand:XF 1 "register_operand" "=u")
16942 (unspec:XF [(match_dup 2) (match_dup 3)]
16944 (set (reg:CCFP FPSR_REG)
16945 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16947 "TARGET_USE_FANCY_MATH_387"
16949 [(set_attr "type" "fpspc")
16950 (set_attr "mode" "XF")])
16952 (define_expand "remainderxf3"
16953 [(use (match_operand:XF 0 "register_operand" ""))
16954 (use (match_operand:XF 1 "general_operand" ""))
16955 (use (match_operand:XF 2 "general_operand" ""))]
16956 "TARGET_USE_FANCY_MATH_387"
16958 rtx label = gen_label_rtx ();
16960 rtx op1 = gen_reg_rtx (XFmode);
16961 rtx op2 = gen_reg_rtx (XFmode);
16963 emit_move_insn (op2, operands[2]);
16964 emit_move_insn (op1, operands[1]);
16966 emit_label (label);
16967 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16968 ix86_emit_fp_unordered_jump (label);
16969 LABEL_NUSES (label) = 1;
16971 emit_move_insn (operands[0], op1);
16975 (define_expand "remainder<mode>3"
16976 [(use (match_operand:MODEF 0 "register_operand" ""))
16977 (use (match_operand:MODEF 1 "general_operand" ""))
16978 (use (match_operand:MODEF 2 "general_operand" ""))]
16979 "TARGET_USE_FANCY_MATH_387"
16981 rtx label = gen_label_rtx ();
16983 rtx op1 = gen_reg_rtx (XFmode);
16984 rtx op2 = gen_reg_rtx (XFmode);
16986 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16987 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16989 emit_label (label);
16991 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16992 ix86_emit_fp_unordered_jump (label);
16993 LABEL_NUSES (label) = 1;
16995 /* Truncate the result properly for strict SSE math. */
16996 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16997 && !TARGET_MIX_SSE_I387)
16998 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17000 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17005 (define_insn "*sinxf2_i387"
17006 [(set (match_operand:XF 0 "register_operand" "=f")
17007 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17008 "TARGET_USE_FANCY_MATH_387
17009 && flag_unsafe_math_optimizations"
17011 [(set_attr "type" "fpspc")
17012 (set_attr "mode" "XF")])
17014 (define_insn "*sin_extend<mode>xf2_i387"
17015 [(set (match_operand:XF 0 "register_operand" "=f")
17016 (unspec:XF [(float_extend:XF
17017 (match_operand:MODEF 1 "register_operand" "0"))]
17019 "TARGET_USE_FANCY_MATH_387
17020 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17021 || TARGET_MIX_SSE_I387)
17022 && flag_unsafe_math_optimizations"
17024 [(set_attr "type" "fpspc")
17025 (set_attr "mode" "XF")])
17027 (define_insn "*cosxf2_i387"
17028 [(set (match_operand:XF 0 "register_operand" "=f")
17029 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17030 "TARGET_USE_FANCY_MATH_387
17031 && flag_unsafe_math_optimizations"
17033 [(set_attr "type" "fpspc")
17034 (set_attr "mode" "XF")])
17036 (define_insn "*cos_extend<mode>xf2_i387"
17037 [(set (match_operand:XF 0 "register_operand" "=f")
17038 (unspec:XF [(float_extend:XF
17039 (match_operand:MODEF 1 "register_operand" "0"))]
17041 "TARGET_USE_FANCY_MATH_387
17042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17043 || TARGET_MIX_SSE_I387)
17044 && flag_unsafe_math_optimizations"
17046 [(set_attr "type" "fpspc")
17047 (set_attr "mode" "XF")])
17049 ;; When sincos pattern is defined, sin and cos builtin functions will be
17050 ;; expanded to sincos pattern with one of its outputs left unused.
17051 ;; CSE pass will figure out if two sincos patterns can be combined,
17052 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17053 ;; depending on the unused output.
17055 (define_insn "sincosxf3"
17056 [(set (match_operand:XF 0 "register_operand" "=f")
17057 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17058 UNSPEC_SINCOS_COS))
17059 (set (match_operand:XF 1 "register_operand" "=u")
17060 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17061 "TARGET_USE_FANCY_MATH_387
17062 && flag_unsafe_math_optimizations"
17064 [(set_attr "type" "fpspc")
17065 (set_attr "mode" "XF")])
17068 [(set (match_operand:XF 0 "register_operand" "")
17069 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17070 UNSPEC_SINCOS_COS))
17071 (set (match_operand:XF 1 "register_operand" "")
17072 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17073 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17074 && !(reload_completed || reload_in_progress)"
17075 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17079 [(set (match_operand:XF 0 "register_operand" "")
17080 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17081 UNSPEC_SINCOS_COS))
17082 (set (match_operand:XF 1 "register_operand" "")
17083 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17084 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17085 && !(reload_completed || reload_in_progress)"
17086 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17089 (define_insn "sincos_extend<mode>xf3_i387"
17090 [(set (match_operand:XF 0 "register_operand" "=f")
17091 (unspec:XF [(float_extend:XF
17092 (match_operand:MODEF 2 "register_operand" "0"))]
17093 UNSPEC_SINCOS_COS))
17094 (set (match_operand:XF 1 "register_operand" "=u")
17095 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17096 "TARGET_USE_FANCY_MATH_387
17097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17098 || TARGET_MIX_SSE_I387)
17099 && flag_unsafe_math_optimizations"
17101 [(set_attr "type" "fpspc")
17102 (set_attr "mode" "XF")])
17105 [(set (match_operand:XF 0 "register_operand" "")
17106 (unspec:XF [(float_extend:XF
17107 (match_operand:MODEF 2 "register_operand" ""))]
17108 UNSPEC_SINCOS_COS))
17109 (set (match_operand:XF 1 "register_operand" "")
17110 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17111 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17112 && !(reload_completed || reload_in_progress)"
17113 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17117 [(set (match_operand:XF 0 "register_operand" "")
17118 (unspec:XF [(float_extend:XF
17119 (match_operand:MODEF 2 "register_operand" ""))]
17120 UNSPEC_SINCOS_COS))
17121 (set (match_operand:XF 1 "register_operand" "")
17122 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17123 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17124 && !(reload_completed || reload_in_progress)"
17125 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17128 (define_expand "sincos<mode>3"
17129 [(use (match_operand:MODEF 0 "register_operand" ""))
17130 (use (match_operand:MODEF 1 "register_operand" ""))
17131 (use (match_operand:MODEF 2 "register_operand" ""))]
17132 "TARGET_USE_FANCY_MATH_387
17133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17134 || TARGET_MIX_SSE_I387)
17135 && flag_unsafe_math_optimizations"
17137 rtx op0 = gen_reg_rtx (XFmode);
17138 rtx op1 = gen_reg_rtx (XFmode);
17140 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17141 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17146 (define_insn "fptanxf4_i387"
17147 [(set (match_operand:XF 0 "register_operand" "=f")
17148 (match_operand:XF 3 "const_double_operand" "F"))
17149 (set (match_operand:XF 1 "register_operand" "=u")
17150 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17152 "TARGET_USE_FANCY_MATH_387
17153 && flag_unsafe_math_optimizations
17154 && standard_80387_constant_p (operands[3]) == 2"
17156 [(set_attr "type" "fpspc")
17157 (set_attr "mode" "XF")])
17159 (define_insn "fptan_extend<mode>xf4_i387"
17160 [(set (match_operand:MODEF 0 "register_operand" "=f")
17161 (match_operand:MODEF 3 "const_double_operand" "F"))
17162 (set (match_operand:XF 1 "register_operand" "=u")
17163 (unspec:XF [(float_extend:XF
17164 (match_operand:MODEF 2 "register_operand" "0"))]
17166 "TARGET_USE_FANCY_MATH_387
17167 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17168 || TARGET_MIX_SSE_I387)
17169 && flag_unsafe_math_optimizations
17170 && standard_80387_constant_p (operands[3]) == 2"
17172 [(set_attr "type" "fpspc")
17173 (set_attr "mode" "XF")])
17175 (define_expand "tanxf2"
17176 [(use (match_operand:XF 0 "register_operand" ""))
17177 (use (match_operand:XF 1 "register_operand" ""))]
17178 "TARGET_USE_FANCY_MATH_387
17179 && flag_unsafe_math_optimizations"
17181 rtx one = gen_reg_rtx (XFmode);
17182 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17184 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17188 (define_expand "tan<mode>2"
17189 [(use (match_operand:MODEF 0 "register_operand" ""))
17190 (use (match_operand:MODEF 1 "register_operand" ""))]
17191 "TARGET_USE_FANCY_MATH_387
17192 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17193 || TARGET_MIX_SSE_I387)
17194 && flag_unsafe_math_optimizations"
17196 rtx op0 = gen_reg_rtx (XFmode);
17198 rtx one = gen_reg_rtx (<MODE>mode);
17199 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17201 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17202 operands[1], op2));
17203 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17207 (define_insn "*fpatanxf3_i387"
17208 [(set (match_operand:XF 0 "register_operand" "=f")
17209 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17210 (match_operand:XF 2 "register_operand" "u")]
17212 (clobber (match_scratch:XF 3 "=2"))]
17213 "TARGET_USE_FANCY_MATH_387
17214 && flag_unsafe_math_optimizations"
17216 [(set_attr "type" "fpspc")
17217 (set_attr "mode" "XF")])
17219 (define_insn "fpatan_extend<mode>xf3_i387"
17220 [(set (match_operand:XF 0 "register_operand" "=f")
17221 (unspec:XF [(float_extend:XF
17222 (match_operand:MODEF 1 "register_operand" "0"))
17224 (match_operand:MODEF 2 "register_operand" "u"))]
17226 (clobber (match_scratch:XF 3 "=2"))]
17227 "TARGET_USE_FANCY_MATH_387
17228 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17229 || TARGET_MIX_SSE_I387)
17230 && flag_unsafe_math_optimizations"
17232 [(set_attr "type" "fpspc")
17233 (set_attr "mode" "XF")])
17235 (define_expand "atan2xf3"
17236 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17237 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17238 (match_operand:XF 1 "register_operand" "")]
17240 (clobber (match_scratch:XF 3 ""))])]
17241 "TARGET_USE_FANCY_MATH_387
17242 && flag_unsafe_math_optimizations"
17245 (define_expand "atan2<mode>3"
17246 [(use (match_operand:MODEF 0 "register_operand" ""))
17247 (use (match_operand:MODEF 1 "register_operand" ""))
17248 (use (match_operand:MODEF 2 "register_operand" ""))]
17249 "TARGET_USE_FANCY_MATH_387
17250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17251 || TARGET_MIX_SSE_I387)
17252 && flag_unsafe_math_optimizations"
17254 rtx op0 = gen_reg_rtx (XFmode);
17256 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17257 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17261 (define_expand "atanxf2"
17262 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17263 (unspec:XF [(match_dup 2)
17264 (match_operand:XF 1 "register_operand" "")]
17266 (clobber (match_scratch:XF 3 ""))])]
17267 "TARGET_USE_FANCY_MATH_387
17268 && flag_unsafe_math_optimizations"
17270 operands[2] = gen_reg_rtx (XFmode);
17271 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17274 (define_expand "atan<mode>2"
17275 [(use (match_operand:MODEF 0 "register_operand" ""))
17276 (use (match_operand:MODEF 1 "register_operand" ""))]
17277 "TARGET_USE_FANCY_MATH_387
17278 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17279 || TARGET_MIX_SSE_I387)
17280 && flag_unsafe_math_optimizations"
17282 rtx op0 = gen_reg_rtx (XFmode);
17284 rtx op2 = gen_reg_rtx (<MODE>mode);
17285 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17287 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17288 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17292 (define_expand "asinxf2"
17293 [(set (match_dup 2)
17294 (mult:XF (match_operand:XF 1 "register_operand" "")
17296 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17297 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17298 (parallel [(set (match_operand:XF 0 "register_operand" "")
17299 (unspec:XF [(match_dup 5) (match_dup 1)]
17301 (clobber (match_scratch:XF 6 ""))])]
17302 "TARGET_USE_FANCY_MATH_387
17303 && flag_unsafe_math_optimizations"
17307 if (optimize_insn_for_size_p ())
17310 for (i = 2; i < 6; i++)
17311 operands[i] = gen_reg_rtx (XFmode);
17313 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17316 (define_expand "asin<mode>2"
17317 [(use (match_operand:MODEF 0 "register_operand" ""))
17318 (use (match_operand:MODEF 1 "general_operand" ""))]
17319 "TARGET_USE_FANCY_MATH_387
17320 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17321 || TARGET_MIX_SSE_I387)
17322 && flag_unsafe_math_optimizations"
17324 rtx op0 = gen_reg_rtx (XFmode);
17325 rtx op1 = gen_reg_rtx (XFmode);
17327 if (optimize_insn_for_size_p ())
17330 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17331 emit_insn (gen_asinxf2 (op0, op1));
17332 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17336 (define_expand "acosxf2"
17337 [(set (match_dup 2)
17338 (mult:XF (match_operand:XF 1 "register_operand" "")
17340 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17341 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17342 (parallel [(set (match_operand:XF 0 "register_operand" "")
17343 (unspec:XF [(match_dup 1) (match_dup 5)]
17345 (clobber (match_scratch:XF 6 ""))])]
17346 "TARGET_USE_FANCY_MATH_387
17347 && flag_unsafe_math_optimizations"
17351 if (optimize_insn_for_size_p ())
17354 for (i = 2; i < 6; i++)
17355 operands[i] = gen_reg_rtx (XFmode);
17357 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17360 (define_expand "acos<mode>2"
17361 [(use (match_operand:MODEF 0 "register_operand" ""))
17362 (use (match_operand:MODEF 1 "general_operand" ""))]
17363 "TARGET_USE_FANCY_MATH_387
17364 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17365 || TARGET_MIX_SSE_I387)
17366 && flag_unsafe_math_optimizations"
17368 rtx op0 = gen_reg_rtx (XFmode);
17369 rtx op1 = gen_reg_rtx (XFmode);
17371 if (optimize_insn_for_size_p ())
17374 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17375 emit_insn (gen_acosxf2 (op0, op1));
17376 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17380 (define_insn "fyl2xxf3_i387"
17381 [(set (match_operand:XF 0 "register_operand" "=f")
17382 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17383 (match_operand:XF 2 "register_operand" "u")]
17385 (clobber (match_scratch:XF 3 "=2"))]
17386 "TARGET_USE_FANCY_MATH_387
17387 && flag_unsafe_math_optimizations"
17389 [(set_attr "type" "fpspc")
17390 (set_attr "mode" "XF")])
17392 (define_insn "fyl2x_extend<mode>xf3_i387"
17393 [(set (match_operand:XF 0 "register_operand" "=f")
17394 (unspec:XF [(float_extend:XF
17395 (match_operand:MODEF 1 "register_operand" "0"))
17396 (match_operand:XF 2 "register_operand" "u")]
17398 (clobber (match_scratch:XF 3 "=2"))]
17399 "TARGET_USE_FANCY_MATH_387
17400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17401 || TARGET_MIX_SSE_I387)
17402 && flag_unsafe_math_optimizations"
17404 [(set_attr "type" "fpspc")
17405 (set_attr "mode" "XF")])
17407 (define_expand "logxf2"
17408 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17409 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17410 (match_dup 2)] UNSPEC_FYL2X))
17411 (clobber (match_scratch:XF 3 ""))])]
17412 "TARGET_USE_FANCY_MATH_387
17413 && flag_unsafe_math_optimizations"
17415 operands[2] = gen_reg_rtx (XFmode);
17416 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17419 (define_expand "log<mode>2"
17420 [(use (match_operand:MODEF 0 "register_operand" ""))
17421 (use (match_operand:MODEF 1 "register_operand" ""))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17424 || TARGET_MIX_SSE_I387)
17425 && flag_unsafe_math_optimizations"
17427 rtx op0 = gen_reg_rtx (XFmode);
17429 rtx op2 = gen_reg_rtx (XFmode);
17430 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17432 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17433 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17437 (define_expand "log10xf2"
17438 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17439 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17440 (match_dup 2)] UNSPEC_FYL2X))
17441 (clobber (match_scratch:XF 3 ""))])]
17442 "TARGET_USE_FANCY_MATH_387
17443 && flag_unsafe_math_optimizations"
17445 operands[2] = gen_reg_rtx (XFmode);
17446 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17449 (define_expand "log10<mode>2"
17450 [(use (match_operand:MODEF 0 "register_operand" ""))
17451 (use (match_operand:MODEF 1 "register_operand" ""))]
17452 "TARGET_USE_FANCY_MATH_387
17453 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17454 || TARGET_MIX_SSE_I387)
17455 && flag_unsafe_math_optimizations"
17457 rtx op0 = gen_reg_rtx (XFmode);
17459 rtx op2 = gen_reg_rtx (XFmode);
17460 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17462 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17463 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17467 (define_expand "log2xf2"
17468 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17469 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17470 (match_dup 2)] UNSPEC_FYL2X))
17471 (clobber (match_scratch:XF 3 ""))])]
17472 "TARGET_USE_FANCY_MATH_387
17473 && flag_unsafe_math_optimizations"
17475 operands[2] = gen_reg_rtx (XFmode);
17476 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17479 (define_expand "log2<mode>2"
17480 [(use (match_operand:MODEF 0 "register_operand" ""))
17481 (use (match_operand:MODEF 1 "register_operand" ""))]
17482 "TARGET_USE_FANCY_MATH_387
17483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17484 || TARGET_MIX_SSE_I387)
17485 && flag_unsafe_math_optimizations"
17487 rtx op0 = gen_reg_rtx (XFmode);
17489 rtx op2 = gen_reg_rtx (XFmode);
17490 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17492 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17493 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17497 (define_insn "fyl2xp1xf3_i387"
17498 [(set (match_operand:XF 0 "register_operand" "=f")
17499 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17500 (match_operand:XF 2 "register_operand" "u")]
17502 (clobber (match_scratch:XF 3 "=2"))]
17503 "TARGET_USE_FANCY_MATH_387
17504 && flag_unsafe_math_optimizations"
17506 [(set_attr "type" "fpspc")
17507 (set_attr "mode" "XF")])
17509 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17510 [(set (match_operand:XF 0 "register_operand" "=f")
17511 (unspec:XF [(float_extend:XF
17512 (match_operand:MODEF 1 "register_operand" "0"))
17513 (match_operand:XF 2 "register_operand" "u")]
17515 (clobber (match_scratch:XF 3 "=2"))]
17516 "TARGET_USE_FANCY_MATH_387
17517 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17518 || TARGET_MIX_SSE_I387)
17519 && flag_unsafe_math_optimizations"
17521 [(set_attr "type" "fpspc")
17522 (set_attr "mode" "XF")])
17524 (define_expand "log1pxf2"
17525 [(use (match_operand:XF 0 "register_operand" ""))
17526 (use (match_operand:XF 1 "register_operand" ""))]
17527 "TARGET_USE_FANCY_MATH_387
17528 && flag_unsafe_math_optimizations"
17530 if (optimize_insn_for_size_p ())
17533 ix86_emit_i387_log1p (operands[0], operands[1]);
17537 (define_expand "log1p<mode>2"
17538 [(use (match_operand:MODEF 0 "register_operand" ""))
17539 (use (match_operand:MODEF 1 "register_operand" ""))]
17540 "TARGET_USE_FANCY_MATH_387
17541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17542 || TARGET_MIX_SSE_I387)
17543 && flag_unsafe_math_optimizations"
17547 if (optimize_insn_for_size_p ())
17550 op0 = gen_reg_rtx (XFmode);
17552 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17554 ix86_emit_i387_log1p (op0, operands[1]);
17555 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17559 (define_insn "fxtractxf3_i387"
17560 [(set (match_operand:XF 0 "register_operand" "=f")
17561 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17562 UNSPEC_XTRACT_FRACT))
17563 (set (match_operand:XF 1 "register_operand" "=u")
17564 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17565 "TARGET_USE_FANCY_MATH_387
17566 && flag_unsafe_math_optimizations"
17568 [(set_attr "type" "fpspc")
17569 (set_attr "mode" "XF")])
17571 (define_insn "fxtract_extend<mode>xf3_i387"
17572 [(set (match_operand:XF 0 "register_operand" "=f")
17573 (unspec:XF [(float_extend:XF
17574 (match_operand:MODEF 2 "register_operand" "0"))]
17575 UNSPEC_XTRACT_FRACT))
17576 (set (match_operand:XF 1 "register_operand" "=u")
17577 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17578 "TARGET_USE_FANCY_MATH_387
17579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17580 || TARGET_MIX_SSE_I387)
17581 && flag_unsafe_math_optimizations"
17583 [(set_attr "type" "fpspc")
17584 (set_attr "mode" "XF")])
17586 (define_expand "logbxf2"
17587 [(parallel [(set (match_dup 2)
17588 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17589 UNSPEC_XTRACT_FRACT))
17590 (set (match_operand:XF 0 "register_operand" "")
17591 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17592 "TARGET_USE_FANCY_MATH_387
17593 && flag_unsafe_math_optimizations"
17595 operands[2] = gen_reg_rtx (XFmode);
17598 (define_expand "logb<mode>2"
17599 [(use (match_operand:MODEF 0 "register_operand" ""))
17600 (use (match_operand:MODEF 1 "register_operand" ""))]
17601 "TARGET_USE_FANCY_MATH_387
17602 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17603 || TARGET_MIX_SSE_I387)
17604 && flag_unsafe_math_optimizations"
17606 rtx op0 = gen_reg_rtx (XFmode);
17607 rtx op1 = gen_reg_rtx (XFmode);
17609 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17610 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17614 (define_expand "ilogbxf2"
17615 [(use (match_operand:SI 0 "register_operand" ""))
17616 (use (match_operand:XF 1 "register_operand" ""))]
17617 "TARGET_USE_FANCY_MATH_387
17618 && flag_unsafe_math_optimizations"
17622 if (optimize_insn_for_size_p ())
17625 op0 = gen_reg_rtx (XFmode);
17626 op1 = gen_reg_rtx (XFmode);
17628 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17629 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17633 (define_expand "ilogb<mode>2"
17634 [(use (match_operand:SI 0 "register_operand" ""))
17635 (use (match_operand:MODEF 1 "register_operand" ""))]
17636 "TARGET_USE_FANCY_MATH_387
17637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17638 || TARGET_MIX_SSE_I387)
17639 && flag_unsafe_math_optimizations"
17643 if (optimize_insn_for_size_p ())
17646 op0 = gen_reg_rtx (XFmode);
17647 op1 = gen_reg_rtx (XFmode);
17649 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17650 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17654 (define_insn "*f2xm1xf2_i387"
17655 [(set (match_operand:XF 0 "register_operand" "=f")
17656 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17658 "TARGET_USE_FANCY_MATH_387
17659 && flag_unsafe_math_optimizations"
17661 [(set_attr "type" "fpspc")
17662 (set_attr "mode" "XF")])
17664 (define_insn "*fscalexf4_i387"
17665 [(set (match_operand:XF 0 "register_operand" "=f")
17666 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17667 (match_operand:XF 3 "register_operand" "1")]
17668 UNSPEC_FSCALE_FRACT))
17669 (set (match_operand:XF 1 "register_operand" "=u")
17670 (unspec:XF [(match_dup 2) (match_dup 3)]
17671 UNSPEC_FSCALE_EXP))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && flag_unsafe_math_optimizations"
17675 [(set_attr "type" "fpspc")
17676 (set_attr "mode" "XF")])
17678 (define_expand "expNcorexf3"
17679 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17680 (match_operand:XF 2 "register_operand" "")))
17681 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17682 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17683 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17684 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17685 (parallel [(set (match_operand:XF 0 "register_operand" "")
17686 (unspec:XF [(match_dup 8) (match_dup 4)]
17687 UNSPEC_FSCALE_FRACT))
17689 (unspec:XF [(match_dup 8) (match_dup 4)]
17690 UNSPEC_FSCALE_EXP))])]
17691 "TARGET_USE_FANCY_MATH_387
17692 && flag_unsafe_math_optimizations"
17696 if (optimize_insn_for_size_p ())
17699 for (i = 3; i < 10; i++)
17700 operands[i] = gen_reg_rtx (XFmode);
17702 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17705 (define_expand "expxf2"
17706 [(use (match_operand:XF 0 "register_operand" ""))
17707 (use (match_operand:XF 1 "register_operand" ""))]
17708 "TARGET_USE_FANCY_MATH_387
17709 && flag_unsafe_math_optimizations"
17713 if (optimize_insn_for_size_p ())
17716 op2 = gen_reg_rtx (XFmode);
17717 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17719 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17723 (define_expand "exp<mode>2"
17724 [(use (match_operand:MODEF 0 "register_operand" ""))
17725 (use (match_operand:MODEF 1 "general_operand" ""))]
17726 "TARGET_USE_FANCY_MATH_387
17727 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17728 || TARGET_MIX_SSE_I387)
17729 && flag_unsafe_math_optimizations"
17733 if (optimize_insn_for_size_p ())
17736 op0 = gen_reg_rtx (XFmode);
17737 op1 = gen_reg_rtx (XFmode);
17739 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17740 emit_insn (gen_expxf2 (op0, op1));
17741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17745 (define_expand "exp10xf2"
17746 [(use (match_operand:XF 0 "register_operand" ""))
17747 (use (match_operand:XF 1 "register_operand" ""))]
17748 "TARGET_USE_FANCY_MATH_387
17749 && flag_unsafe_math_optimizations"
17753 if (optimize_insn_for_size_p ())
17756 op2 = gen_reg_rtx (XFmode);
17757 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17759 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17763 (define_expand "exp10<mode>2"
17764 [(use (match_operand:MODEF 0 "register_operand" ""))
17765 (use (match_operand:MODEF 1 "general_operand" ""))]
17766 "TARGET_USE_FANCY_MATH_387
17767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17768 || TARGET_MIX_SSE_I387)
17769 && flag_unsafe_math_optimizations"
17773 if (optimize_insn_for_size_p ())
17776 op0 = gen_reg_rtx (XFmode);
17777 op1 = gen_reg_rtx (XFmode);
17779 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17780 emit_insn (gen_exp10xf2 (op0, op1));
17781 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17785 (define_expand "exp2xf2"
17786 [(use (match_operand:XF 0 "register_operand" ""))
17787 (use (match_operand:XF 1 "register_operand" ""))]
17788 "TARGET_USE_FANCY_MATH_387
17789 && flag_unsafe_math_optimizations"
17793 if (optimize_insn_for_size_p ())
17796 op2 = gen_reg_rtx (XFmode);
17797 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17799 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17803 (define_expand "exp2<mode>2"
17804 [(use (match_operand:MODEF 0 "register_operand" ""))
17805 (use (match_operand:MODEF 1 "general_operand" ""))]
17806 "TARGET_USE_FANCY_MATH_387
17807 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17808 || TARGET_MIX_SSE_I387)
17809 && flag_unsafe_math_optimizations"
17813 if (optimize_insn_for_size_p ())
17816 op0 = gen_reg_rtx (XFmode);
17817 op1 = gen_reg_rtx (XFmode);
17819 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17820 emit_insn (gen_exp2xf2 (op0, op1));
17821 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17825 (define_expand "expm1xf2"
17826 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17828 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17829 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17830 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17831 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17832 (parallel [(set (match_dup 7)
17833 (unspec:XF [(match_dup 6) (match_dup 4)]
17834 UNSPEC_FSCALE_FRACT))
17836 (unspec:XF [(match_dup 6) (match_dup 4)]
17837 UNSPEC_FSCALE_EXP))])
17838 (parallel [(set (match_dup 10)
17839 (unspec:XF [(match_dup 9) (match_dup 8)]
17840 UNSPEC_FSCALE_FRACT))
17841 (set (match_dup 11)
17842 (unspec:XF [(match_dup 9) (match_dup 8)]
17843 UNSPEC_FSCALE_EXP))])
17844 (set (match_dup 12) (minus:XF (match_dup 10)
17845 (float_extend:XF (match_dup 13))))
17846 (set (match_operand:XF 0 "register_operand" "")
17847 (plus:XF (match_dup 12) (match_dup 7)))]
17848 "TARGET_USE_FANCY_MATH_387
17849 && flag_unsafe_math_optimizations"
17853 if (optimize_insn_for_size_p ())
17856 for (i = 2; i < 13; i++)
17857 operands[i] = gen_reg_rtx (XFmode);
17860 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17862 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17865 (define_expand "expm1<mode>2"
17866 [(use (match_operand:MODEF 0 "register_operand" ""))
17867 (use (match_operand:MODEF 1 "general_operand" ""))]
17868 "TARGET_USE_FANCY_MATH_387
17869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17870 || TARGET_MIX_SSE_I387)
17871 && flag_unsafe_math_optimizations"
17875 if (optimize_insn_for_size_p ())
17878 op0 = gen_reg_rtx (XFmode);
17879 op1 = gen_reg_rtx (XFmode);
17881 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17882 emit_insn (gen_expm1xf2 (op0, op1));
17883 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17887 (define_expand "ldexpxf3"
17888 [(set (match_dup 3)
17889 (float:XF (match_operand:SI 2 "register_operand" "")))
17890 (parallel [(set (match_operand:XF 0 " register_operand" "")
17891 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17893 UNSPEC_FSCALE_FRACT))
17895 (unspec:XF [(match_dup 1) (match_dup 3)]
17896 UNSPEC_FSCALE_EXP))])]
17897 "TARGET_USE_FANCY_MATH_387
17898 && flag_unsafe_math_optimizations"
17900 if (optimize_insn_for_size_p ())
17903 operands[3] = gen_reg_rtx (XFmode);
17904 operands[4] = gen_reg_rtx (XFmode);
17907 (define_expand "ldexp<mode>3"
17908 [(use (match_operand:MODEF 0 "register_operand" ""))
17909 (use (match_operand:MODEF 1 "general_operand" ""))
17910 (use (match_operand:SI 2 "register_operand" ""))]
17911 "TARGET_USE_FANCY_MATH_387
17912 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17913 || TARGET_MIX_SSE_I387)
17914 && flag_unsafe_math_optimizations"
17918 if (optimize_insn_for_size_p ())
17921 op0 = gen_reg_rtx (XFmode);
17922 op1 = gen_reg_rtx (XFmode);
17924 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17925 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17926 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17930 (define_expand "scalbxf3"
17931 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17932 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17933 (match_operand:XF 2 "register_operand" "")]
17934 UNSPEC_FSCALE_FRACT))
17936 (unspec:XF [(match_dup 1) (match_dup 2)]
17937 UNSPEC_FSCALE_EXP))])]
17938 "TARGET_USE_FANCY_MATH_387
17939 && flag_unsafe_math_optimizations"
17941 if (optimize_insn_for_size_p ())
17944 operands[3] = gen_reg_rtx (XFmode);
17947 (define_expand "scalb<mode>3"
17948 [(use (match_operand:MODEF 0 "register_operand" ""))
17949 (use (match_operand:MODEF 1 "general_operand" ""))
17950 (use (match_operand:MODEF 2 "register_operand" ""))]
17951 "TARGET_USE_FANCY_MATH_387
17952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17953 || TARGET_MIX_SSE_I387)
17954 && flag_unsafe_math_optimizations"
17958 if (optimize_insn_for_size_p ())
17961 op0 = gen_reg_rtx (XFmode);
17962 op1 = gen_reg_rtx (XFmode);
17963 op2 = gen_reg_rtx (XFmode);
17965 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17966 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17967 emit_insn (gen_scalbxf3 (op0, op1, op2));
17968 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17973 (define_insn "sse4_1_round<mode>2"
17974 [(set (match_operand:MODEF 0 "register_operand" "=x")
17975 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17976 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17979 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17980 [(set_attr "type" "ssecvt")
17981 (set_attr "prefix_extra" "1")
17982 (set_attr "prefix" "maybe_vex")
17983 (set_attr "mode" "<MODE>")])
17985 (define_insn "rintxf2"
17986 [(set (match_operand:XF 0 "register_operand" "=f")
17987 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17989 "TARGET_USE_FANCY_MATH_387
17990 && flag_unsafe_math_optimizations"
17992 [(set_attr "type" "fpspc")
17993 (set_attr "mode" "XF")])
17995 (define_expand "rint<mode>2"
17996 [(use (match_operand:MODEF 0 "register_operand" ""))
17997 (use (match_operand:MODEF 1 "register_operand" ""))]
17998 "(TARGET_USE_FANCY_MATH_387
17999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18000 || TARGET_MIX_SSE_I387)
18001 && flag_unsafe_math_optimizations)
18002 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18003 && !flag_trapping_math)"
18005 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18006 && !flag_trapping_math)
18008 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18011 emit_insn (gen_sse4_1_round<mode>2
18012 (operands[0], operands[1], GEN_INT (0x04)));
18014 ix86_expand_rint (operand0, operand1);
18018 rtx op0 = gen_reg_rtx (XFmode);
18019 rtx op1 = gen_reg_rtx (XFmode);
18021 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18022 emit_insn (gen_rintxf2 (op0, op1));
18024 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18029 (define_expand "round<mode>2"
18030 [(match_operand:MODEF 0 "register_operand" "")
18031 (match_operand:MODEF 1 "nonimmediate_operand" "")]
18032 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18033 && !flag_trapping_math && !flag_rounding_math"
18035 if (optimize_insn_for_size_p ())
18037 if (TARGET_64BIT || (<MODE>mode != DFmode))
18038 ix86_expand_round (operand0, operand1);
18040 ix86_expand_rounddf_32 (operand0, operand1);
18044 (define_insn_and_split "*fistdi2_1"
18045 [(set (match_operand:DI 0 "nonimmediate_operand" "")
18046 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18048 "TARGET_USE_FANCY_MATH_387
18049 && !(reload_completed || reload_in_progress)"
18054 if (memory_operand (operands[0], VOIDmode))
18055 emit_insn (gen_fistdi2 (operands[0], operands[1]));
18058 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18059 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18064 [(set_attr "type" "fpspc")
18065 (set_attr "mode" "DI")])
18067 (define_insn "fistdi2"
18068 [(set (match_operand:DI 0 "memory_operand" "=m")
18069 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18071 (clobber (match_scratch:XF 2 "=&1f"))]
18072 "TARGET_USE_FANCY_MATH_387"
18073 "* return output_fix_trunc (insn, operands, 0);"
18074 [(set_attr "type" "fpspc")
18075 (set_attr "mode" "DI")])
18077 (define_insn "fistdi2_with_temp"
18078 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18079 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18081 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18082 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18083 "TARGET_USE_FANCY_MATH_387"
18085 [(set_attr "type" "fpspc")
18086 (set_attr "mode" "DI")])
18089 [(set (match_operand:DI 0 "register_operand" "")
18090 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18092 (clobber (match_operand:DI 2 "memory_operand" ""))
18093 (clobber (match_scratch 3 ""))]
18095 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18096 (clobber (match_dup 3))])
18097 (set (match_dup 0) (match_dup 2))]
18101 [(set (match_operand:DI 0 "memory_operand" "")
18102 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18104 (clobber (match_operand:DI 2 "memory_operand" ""))
18105 (clobber (match_scratch 3 ""))]
18107 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18108 (clobber (match_dup 3))])]
18111 (define_insn_and_split "*fist<mode>2_1"
18112 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18113 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18115 "TARGET_USE_FANCY_MATH_387
18116 && !(reload_completed || reload_in_progress)"
18121 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18122 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18126 [(set_attr "type" "fpspc")
18127 (set_attr "mode" "<MODE>")])
18129 (define_insn "fist<mode>2"
18130 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18131 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18133 "TARGET_USE_FANCY_MATH_387"
18134 "* return output_fix_trunc (insn, operands, 0);"
18135 [(set_attr "type" "fpspc")
18136 (set_attr "mode" "<MODE>")])
18138 (define_insn "fist<mode>2_with_temp"
18139 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18140 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18142 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18143 "TARGET_USE_FANCY_MATH_387"
18145 [(set_attr "type" "fpspc")
18146 (set_attr "mode" "<MODE>")])
18149 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18150 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18152 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18154 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18155 (set (match_dup 0) (match_dup 2))]
18159 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18160 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18162 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18164 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18167 (define_expand "lrintxf<mode>2"
18168 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18169 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18171 "TARGET_USE_FANCY_MATH_387"
18174 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18175 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18176 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18177 UNSPEC_FIX_NOTRUNC))]
18178 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18179 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18182 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18183 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18184 (match_operand:MODEF 1 "register_operand" "")]
18185 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18186 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18187 && !flag_trapping_math && !flag_rounding_math"
18189 if (optimize_insn_for_size_p ())
18191 ix86_expand_lround (operand0, operand1);
18195 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18196 (define_insn_and_split "frndintxf2_floor"
18197 [(set (match_operand:XF 0 "register_operand" "")
18198 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18199 UNSPEC_FRNDINT_FLOOR))
18200 (clobber (reg:CC FLAGS_REG))]
18201 "TARGET_USE_FANCY_MATH_387
18202 && flag_unsafe_math_optimizations
18203 && !(reload_completed || reload_in_progress)"
18208 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18210 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18211 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18213 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18214 operands[2], operands[3]));
18217 [(set_attr "type" "frndint")
18218 (set_attr "i387_cw" "floor")
18219 (set_attr "mode" "XF")])
18221 (define_insn "frndintxf2_floor_i387"
18222 [(set (match_operand:XF 0 "register_operand" "=f")
18223 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18224 UNSPEC_FRNDINT_FLOOR))
18225 (use (match_operand:HI 2 "memory_operand" "m"))
18226 (use (match_operand:HI 3 "memory_operand" "m"))]
18227 "TARGET_USE_FANCY_MATH_387
18228 && flag_unsafe_math_optimizations"
18229 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18230 [(set_attr "type" "frndint")
18231 (set_attr "i387_cw" "floor")
18232 (set_attr "mode" "XF")])
18234 (define_expand "floorxf2"
18235 [(use (match_operand:XF 0 "register_operand" ""))
18236 (use (match_operand:XF 1 "register_operand" ""))]
18237 "TARGET_USE_FANCY_MATH_387
18238 && flag_unsafe_math_optimizations"
18240 if (optimize_insn_for_size_p ())
18242 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18246 (define_expand "floor<mode>2"
18247 [(use (match_operand:MODEF 0 "register_operand" ""))
18248 (use (match_operand:MODEF 1 "register_operand" ""))]
18249 "(TARGET_USE_FANCY_MATH_387
18250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18251 || TARGET_MIX_SSE_I387)
18252 && flag_unsafe_math_optimizations)
18253 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18254 && !flag_trapping_math)"
18256 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18257 && !flag_trapping_math
18258 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18260 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18263 emit_insn (gen_sse4_1_round<mode>2
18264 (operands[0], operands[1], GEN_INT (0x01)));
18265 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18266 ix86_expand_floorceil (operand0, operand1, true);
18268 ix86_expand_floorceildf_32 (operand0, operand1, true);
18274 if (optimize_insn_for_size_p ())
18277 op0 = gen_reg_rtx (XFmode);
18278 op1 = gen_reg_rtx (XFmode);
18279 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18280 emit_insn (gen_frndintxf2_floor (op0, op1));
18282 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18287 (define_insn_and_split "*fist<mode>2_floor_1"
18288 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18289 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18290 UNSPEC_FIST_FLOOR))
18291 (clobber (reg:CC FLAGS_REG))]
18292 "TARGET_USE_FANCY_MATH_387
18293 && flag_unsafe_math_optimizations
18294 && !(reload_completed || reload_in_progress)"
18299 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18301 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18302 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18303 if (memory_operand (operands[0], VOIDmode))
18304 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18305 operands[2], operands[3]));
18308 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18309 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18310 operands[2], operands[3],
18315 [(set_attr "type" "fistp")
18316 (set_attr "i387_cw" "floor")
18317 (set_attr "mode" "<MODE>")])
18319 (define_insn "fistdi2_floor"
18320 [(set (match_operand:DI 0 "memory_operand" "=m")
18321 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18322 UNSPEC_FIST_FLOOR))
18323 (use (match_operand:HI 2 "memory_operand" "m"))
18324 (use (match_operand:HI 3 "memory_operand" "m"))
18325 (clobber (match_scratch:XF 4 "=&1f"))]
18326 "TARGET_USE_FANCY_MATH_387
18327 && flag_unsafe_math_optimizations"
18328 "* return output_fix_trunc (insn, operands, 0);"
18329 [(set_attr "type" "fistp")
18330 (set_attr "i387_cw" "floor")
18331 (set_attr "mode" "DI")])
18333 (define_insn "fistdi2_floor_with_temp"
18334 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18335 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18336 UNSPEC_FIST_FLOOR))
18337 (use (match_operand:HI 2 "memory_operand" "m,m"))
18338 (use (match_operand:HI 3 "memory_operand" "m,m"))
18339 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18340 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18341 "TARGET_USE_FANCY_MATH_387
18342 && flag_unsafe_math_optimizations"
18344 [(set_attr "type" "fistp")
18345 (set_attr "i387_cw" "floor")
18346 (set_attr "mode" "DI")])
18349 [(set (match_operand:DI 0 "register_operand" "")
18350 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18351 UNSPEC_FIST_FLOOR))
18352 (use (match_operand:HI 2 "memory_operand" ""))
18353 (use (match_operand:HI 3 "memory_operand" ""))
18354 (clobber (match_operand:DI 4 "memory_operand" ""))
18355 (clobber (match_scratch 5 ""))]
18357 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18358 (use (match_dup 2))
18359 (use (match_dup 3))
18360 (clobber (match_dup 5))])
18361 (set (match_dup 0) (match_dup 4))]
18365 [(set (match_operand:DI 0 "memory_operand" "")
18366 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18367 UNSPEC_FIST_FLOOR))
18368 (use (match_operand:HI 2 "memory_operand" ""))
18369 (use (match_operand:HI 3 "memory_operand" ""))
18370 (clobber (match_operand:DI 4 "memory_operand" ""))
18371 (clobber (match_scratch 5 ""))]
18373 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18374 (use (match_dup 2))
18375 (use (match_dup 3))
18376 (clobber (match_dup 5))])]
18379 (define_insn "fist<mode>2_floor"
18380 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18381 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18382 UNSPEC_FIST_FLOOR))
18383 (use (match_operand:HI 2 "memory_operand" "m"))
18384 (use (match_operand:HI 3 "memory_operand" "m"))]
18385 "TARGET_USE_FANCY_MATH_387
18386 && flag_unsafe_math_optimizations"
18387 "* return output_fix_trunc (insn, operands, 0);"
18388 [(set_attr "type" "fistp")
18389 (set_attr "i387_cw" "floor")
18390 (set_attr "mode" "<MODE>")])
18392 (define_insn "fist<mode>2_floor_with_temp"
18393 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18394 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18395 UNSPEC_FIST_FLOOR))
18396 (use (match_operand:HI 2 "memory_operand" "m,m"))
18397 (use (match_operand:HI 3 "memory_operand" "m,m"))
18398 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18399 "TARGET_USE_FANCY_MATH_387
18400 && flag_unsafe_math_optimizations"
18402 [(set_attr "type" "fistp")
18403 (set_attr "i387_cw" "floor")
18404 (set_attr "mode" "<MODE>")])
18407 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18408 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18409 UNSPEC_FIST_FLOOR))
18410 (use (match_operand:HI 2 "memory_operand" ""))
18411 (use (match_operand:HI 3 "memory_operand" ""))
18412 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18414 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18415 UNSPEC_FIST_FLOOR))
18416 (use (match_dup 2))
18417 (use (match_dup 3))])
18418 (set (match_dup 0) (match_dup 4))]
18422 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18423 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18424 UNSPEC_FIST_FLOOR))
18425 (use (match_operand:HI 2 "memory_operand" ""))
18426 (use (match_operand:HI 3 "memory_operand" ""))
18427 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18429 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18430 UNSPEC_FIST_FLOOR))
18431 (use (match_dup 2))
18432 (use (match_dup 3))])]
18435 (define_expand "lfloorxf<mode>2"
18436 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18437 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18438 UNSPEC_FIST_FLOOR))
18439 (clobber (reg:CC FLAGS_REG))])]
18440 "TARGET_USE_FANCY_MATH_387
18441 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18442 && flag_unsafe_math_optimizations"
18445 (define_expand "lfloor<mode>di2"
18446 [(match_operand:DI 0 "nonimmediate_operand" "")
18447 (match_operand:MODEF 1 "register_operand" "")]
18448 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18449 && !flag_trapping_math"
18451 if (optimize_insn_for_size_p ())
18453 ix86_expand_lfloorceil (operand0, operand1, true);
18457 (define_expand "lfloor<mode>si2"
18458 [(match_operand:SI 0 "nonimmediate_operand" "")
18459 (match_operand:MODEF 1 "register_operand" "")]
18460 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18461 && !flag_trapping_math"
18463 if (optimize_insn_for_size_p () && TARGET_64BIT)
18465 ix86_expand_lfloorceil (operand0, operand1, true);
18469 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18470 (define_insn_and_split "frndintxf2_ceil"
18471 [(set (match_operand:XF 0 "register_operand" "")
18472 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18473 UNSPEC_FRNDINT_CEIL))
18474 (clobber (reg:CC FLAGS_REG))]
18475 "TARGET_USE_FANCY_MATH_387
18476 && flag_unsafe_math_optimizations
18477 && !(reload_completed || reload_in_progress)"
18482 ix86_optimize_mode_switching[I387_CEIL] = 1;
18484 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18485 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18487 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18488 operands[2], operands[3]));
18491 [(set_attr "type" "frndint")
18492 (set_attr "i387_cw" "ceil")
18493 (set_attr "mode" "XF")])
18495 (define_insn "frndintxf2_ceil_i387"
18496 [(set (match_operand:XF 0 "register_operand" "=f")
18497 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18498 UNSPEC_FRNDINT_CEIL))
18499 (use (match_operand:HI 2 "memory_operand" "m"))
18500 (use (match_operand:HI 3 "memory_operand" "m"))]
18501 "TARGET_USE_FANCY_MATH_387
18502 && flag_unsafe_math_optimizations"
18503 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18504 [(set_attr "type" "frndint")
18505 (set_attr "i387_cw" "ceil")
18506 (set_attr "mode" "XF")])
18508 (define_expand "ceilxf2"
18509 [(use (match_operand:XF 0 "register_operand" ""))
18510 (use (match_operand:XF 1 "register_operand" ""))]
18511 "TARGET_USE_FANCY_MATH_387
18512 && flag_unsafe_math_optimizations"
18514 if (optimize_insn_for_size_p ())
18516 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18520 (define_expand "ceil<mode>2"
18521 [(use (match_operand:MODEF 0 "register_operand" ""))
18522 (use (match_operand:MODEF 1 "register_operand" ""))]
18523 "(TARGET_USE_FANCY_MATH_387
18524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18525 || TARGET_MIX_SSE_I387)
18526 && flag_unsafe_math_optimizations)
18527 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18528 && !flag_trapping_math)"
18530 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18531 && !flag_trapping_math
18532 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18535 emit_insn (gen_sse4_1_round<mode>2
18536 (operands[0], operands[1], GEN_INT (0x02)));
18537 else if (optimize_insn_for_size_p ())
18539 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18540 ix86_expand_floorceil (operand0, operand1, false);
18542 ix86_expand_floorceildf_32 (operand0, operand1, false);
18548 if (optimize_insn_for_size_p ())
18551 op0 = gen_reg_rtx (XFmode);
18552 op1 = gen_reg_rtx (XFmode);
18553 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18554 emit_insn (gen_frndintxf2_ceil (op0, op1));
18556 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18561 (define_insn_and_split "*fist<mode>2_ceil_1"
18562 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18563 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18565 (clobber (reg:CC FLAGS_REG))]
18566 "TARGET_USE_FANCY_MATH_387
18567 && flag_unsafe_math_optimizations
18568 && !(reload_completed || reload_in_progress)"
18573 ix86_optimize_mode_switching[I387_CEIL] = 1;
18575 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18576 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18577 if (memory_operand (operands[0], VOIDmode))
18578 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18579 operands[2], operands[3]));
18582 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18583 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18584 operands[2], operands[3],
18589 [(set_attr "type" "fistp")
18590 (set_attr "i387_cw" "ceil")
18591 (set_attr "mode" "<MODE>")])
18593 (define_insn "fistdi2_ceil"
18594 [(set (match_operand:DI 0 "memory_operand" "=m")
18595 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18597 (use (match_operand:HI 2 "memory_operand" "m"))
18598 (use (match_operand:HI 3 "memory_operand" "m"))
18599 (clobber (match_scratch:XF 4 "=&1f"))]
18600 "TARGET_USE_FANCY_MATH_387
18601 && flag_unsafe_math_optimizations"
18602 "* return output_fix_trunc (insn, operands, 0);"
18603 [(set_attr "type" "fistp")
18604 (set_attr "i387_cw" "ceil")
18605 (set_attr "mode" "DI")])
18607 (define_insn "fistdi2_ceil_with_temp"
18608 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18609 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18611 (use (match_operand:HI 2 "memory_operand" "m,m"))
18612 (use (match_operand:HI 3 "memory_operand" "m,m"))
18613 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18614 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18615 "TARGET_USE_FANCY_MATH_387
18616 && flag_unsafe_math_optimizations"
18618 [(set_attr "type" "fistp")
18619 (set_attr "i387_cw" "ceil")
18620 (set_attr "mode" "DI")])
18623 [(set (match_operand:DI 0 "register_operand" "")
18624 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18626 (use (match_operand:HI 2 "memory_operand" ""))
18627 (use (match_operand:HI 3 "memory_operand" ""))
18628 (clobber (match_operand:DI 4 "memory_operand" ""))
18629 (clobber (match_scratch 5 ""))]
18631 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18632 (use (match_dup 2))
18633 (use (match_dup 3))
18634 (clobber (match_dup 5))])
18635 (set (match_dup 0) (match_dup 4))]
18639 [(set (match_operand:DI 0 "memory_operand" "")
18640 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18642 (use (match_operand:HI 2 "memory_operand" ""))
18643 (use (match_operand:HI 3 "memory_operand" ""))
18644 (clobber (match_operand:DI 4 "memory_operand" ""))
18645 (clobber (match_scratch 5 ""))]
18647 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18648 (use (match_dup 2))
18649 (use (match_dup 3))
18650 (clobber (match_dup 5))])]
18653 (define_insn "fist<mode>2_ceil"
18654 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18655 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18657 (use (match_operand:HI 2 "memory_operand" "m"))
18658 (use (match_operand:HI 3 "memory_operand" "m"))]
18659 "TARGET_USE_FANCY_MATH_387
18660 && flag_unsafe_math_optimizations"
18661 "* return output_fix_trunc (insn, operands, 0);"
18662 [(set_attr "type" "fistp")
18663 (set_attr "i387_cw" "ceil")
18664 (set_attr "mode" "<MODE>")])
18666 (define_insn "fist<mode>2_ceil_with_temp"
18667 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18668 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18670 (use (match_operand:HI 2 "memory_operand" "m,m"))
18671 (use (match_operand:HI 3 "memory_operand" "m,m"))
18672 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18673 "TARGET_USE_FANCY_MATH_387
18674 && flag_unsafe_math_optimizations"
18676 [(set_attr "type" "fistp")
18677 (set_attr "i387_cw" "ceil")
18678 (set_attr "mode" "<MODE>")])
18681 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18682 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18684 (use (match_operand:HI 2 "memory_operand" ""))
18685 (use (match_operand:HI 3 "memory_operand" ""))
18686 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18688 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18690 (use (match_dup 2))
18691 (use (match_dup 3))])
18692 (set (match_dup 0) (match_dup 4))]
18696 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18697 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18699 (use (match_operand:HI 2 "memory_operand" ""))
18700 (use (match_operand:HI 3 "memory_operand" ""))
18701 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18703 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18705 (use (match_dup 2))
18706 (use (match_dup 3))])]
18709 (define_expand "lceilxf<mode>2"
18710 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18711 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18713 (clobber (reg:CC FLAGS_REG))])]
18714 "TARGET_USE_FANCY_MATH_387
18715 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18716 && flag_unsafe_math_optimizations"
18719 (define_expand "lceil<mode>di2"
18720 [(match_operand:DI 0 "nonimmediate_operand" "")
18721 (match_operand:MODEF 1 "register_operand" "")]
18722 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18723 && !flag_trapping_math"
18725 ix86_expand_lfloorceil (operand0, operand1, false);
18729 (define_expand "lceil<mode>si2"
18730 [(match_operand:SI 0 "nonimmediate_operand" "")
18731 (match_operand:MODEF 1 "register_operand" "")]
18732 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18733 && !flag_trapping_math"
18735 ix86_expand_lfloorceil (operand0, operand1, false);
18739 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18740 (define_insn_and_split "frndintxf2_trunc"
18741 [(set (match_operand:XF 0 "register_operand" "")
18742 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18743 UNSPEC_FRNDINT_TRUNC))
18744 (clobber (reg:CC FLAGS_REG))]
18745 "TARGET_USE_FANCY_MATH_387
18746 && flag_unsafe_math_optimizations
18747 && !(reload_completed || reload_in_progress)"
18752 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18754 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18755 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18757 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18758 operands[2], operands[3]));
18761 [(set_attr "type" "frndint")
18762 (set_attr "i387_cw" "trunc")
18763 (set_attr "mode" "XF")])
18765 (define_insn "frndintxf2_trunc_i387"
18766 [(set (match_operand:XF 0 "register_operand" "=f")
18767 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18768 UNSPEC_FRNDINT_TRUNC))
18769 (use (match_operand:HI 2 "memory_operand" "m"))
18770 (use (match_operand:HI 3 "memory_operand" "m"))]
18771 "TARGET_USE_FANCY_MATH_387
18772 && flag_unsafe_math_optimizations"
18773 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18774 [(set_attr "type" "frndint")
18775 (set_attr "i387_cw" "trunc")
18776 (set_attr "mode" "XF")])
18778 (define_expand "btruncxf2"
18779 [(use (match_operand:XF 0 "register_operand" ""))
18780 (use (match_operand:XF 1 "register_operand" ""))]
18781 "TARGET_USE_FANCY_MATH_387
18782 && flag_unsafe_math_optimizations"
18784 if (optimize_insn_for_size_p ())
18786 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18790 (define_expand "btrunc<mode>2"
18791 [(use (match_operand:MODEF 0 "register_operand" ""))
18792 (use (match_operand:MODEF 1 "register_operand" ""))]
18793 "(TARGET_USE_FANCY_MATH_387
18794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18795 || TARGET_MIX_SSE_I387)
18796 && flag_unsafe_math_optimizations)
18797 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18798 && !flag_trapping_math)"
18800 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18801 && !flag_trapping_math
18802 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18805 emit_insn (gen_sse4_1_round<mode>2
18806 (operands[0], operands[1], GEN_INT (0x03)));
18807 else if (optimize_insn_for_size_p ())
18809 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18810 ix86_expand_trunc (operand0, operand1);
18812 ix86_expand_truncdf_32 (operand0, operand1);
18818 if (optimize_insn_for_size_p ())
18821 op0 = gen_reg_rtx (XFmode);
18822 op1 = gen_reg_rtx (XFmode);
18823 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18824 emit_insn (gen_frndintxf2_trunc (op0, op1));
18826 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18831 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18832 (define_insn_and_split "frndintxf2_mask_pm"
18833 [(set (match_operand:XF 0 "register_operand" "")
18834 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18835 UNSPEC_FRNDINT_MASK_PM))
18836 (clobber (reg:CC FLAGS_REG))]
18837 "TARGET_USE_FANCY_MATH_387
18838 && flag_unsafe_math_optimizations
18839 && !(reload_completed || reload_in_progress)"
18844 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18846 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18847 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18849 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18850 operands[2], operands[3]));
18853 [(set_attr "type" "frndint")
18854 (set_attr "i387_cw" "mask_pm")
18855 (set_attr "mode" "XF")])
18857 (define_insn "frndintxf2_mask_pm_i387"
18858 [(set (match_operand:XF 0 "register_operand" "=f")
18859 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18860 UNSPEC_FRNDINT_MASK_PM))
18861 (use (match_operand:HI 2 "memory_operand" "m"))
18862 (use (match_operand:HI 3 "memory_operand" "m"))]
18863 "TARGET_USE_FANCY_MATH_387
18864 && flag_unsafe_math_optimizations"
18865 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18866 [(set_attr "type" "frndint")
18867 (set_attr "i387_cw" "mask_pm")
18868 (set_attr "mode" "XF")])
18870 (define_expand "nearbyintxf2"
18871 [(use (match_operand:XF 0 "register_operand" ""))
18872 (use (match_operand:XF 1 "register_operand" ""))]
18873 "TARGET_USE_FANCY_MATH_387
18874 && flag_unsafe_math_optimizations"
18876 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18881 (define_expand "nearbyint<mode>2"
18882 [(use (match_operand:MODEF 0 "register_operand" ""))
18883 (use (match_operand:MODEF 1 "register_operand" ""))]
18884 "TARGET_USE_FANCY_MATH_387
18885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18886 || TARGET_MIX_SSE_I387)
18887 && flag_unsafe_math_optimizations"
18889 rtx op0 = gen_reg_rtx (XFmode);
18890 rtx op1 = gen_reg_rtx (XFmode);
18892 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18893 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18895 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18899 (define_insn "fxam<mode>2_i387"
18900 [(set (match_operand:HI 0 "register_operand" "=a")
18902 [(match_operand:X87MODEF 1 "register_operand" "f")]
18904 "TARGET_USE_FANCY_MATH_387"
18905 "fxam\n\tfnstsw\t%0"
18906 [(set_attr "type" "multi")
18907 (set_attr "unit" "i387")
18908 (set_attr "mode" "<MODE>")])
18910 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18911 [(set (match_operand:HI 0 "register_operand" "")
18913 [(match_operand:MODEF 1 "memory_operand" "")]
18915 "TARGET_USE_FANCY_MATH_387
18916 && !(reload_completed || reload_in_progress)"
18919 [(set (match_dup 2)(match_dup 1))
18921 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18923 operands[2] = gen_reg_rtx (<MODE>mode);
18925 MEM_VOLATILE_P (operands[1]) = 1;
18927 [(set_attr "type" "multi")
18928 (set_attr "unit" "i387")
18929 (set_attr "mode" "<MODE>")])
18931 (define_expand "isinfxf2"
18932 [(use (match_operand:SI 0 "register_operand" ""))
18933 (use (match_operand:XF 1 "register_operand" ""))]
18934 "TARGET_USE_FANCY_MATH_387
18935 && TARGET_C99_FUNCTIONS"
18937 rtx mask = GEN_INT (0x45);
18938 rtx val = GEN_INT (0x05);
18942 rtx scratch = gen_reg_rtx (HImode);
18943 rtx res = gen_reg_rtx (QImode);
18945 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18947 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18948 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18949 cond = gen_rtx_fmt_ee (EQ, QImode,
18950 gen_rtx_REG (CCmode, FLAGS_REG),
18952 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18953 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18957 (define_expand "isinf<mode>2"
18958 [(use (match_operand:SI 0 "register_operand" ""))
18959 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18960 "TARGET_USE_FANCY_MATH_387
18961 && TARGET_C99_FUNCTIONS
18962 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18964 rtx mask = GEN_INT (0x45);
18965 rtx val = GEN_INT (0x05);
18969 rtx scratch = gen_reg_rtx (HImode);
18970 rtx res = gen_reg_rtx (QImode);
18972 /* Remove excess precision by forcing value through memory. */
18973 if (memory_operand (operands[1], VOIDmode))
18974 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18977 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18978 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18980 emit_move_insn (temp, operands[1]);
18981 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18984 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18985 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18986 cond = gen_rtx_fmt_ee (EQ, QImode,
18987 gen_rtx_REG (CCmode, FLAGS_REG),
18989 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18990 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18994 (define_expand "signbit<mode>2"
18995 [(use (match_operand:SI 0 "register_operand" ""))
18996 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18997 "TARGET_USE_FANCY_MATH_387
18998 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19000 rtx mask = GEN_INT (0x0200);
19002 rtx scratch = gen_reg_rtx (HImode);
19004 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19005 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19009 ;; Block operation instructions
19012 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19015 [(set_attr "length" "1")
19016 (set_attr "length_immediate" "0")
19017 (set_attr "modrm" "0")])
19019 (define_expand "movmemsi"
19020 [(use (match_operand:BLK 0 "memory_operand" ""))
19021 (use (match_operand:BLK 1 "memory_operand" ""))
19022 (use (match_operand:SI 2 "nonmemory_operand" ""))
19023 (use (match_operand:SI 3 "const_int_operand" ""))
19024 (use (match_operand:SI 4 "const_int_operand" ""))
19025 (use (match_operand:SI 5 "const_int_operand" ""))]
19028 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19029 operands[4], operands[5]))
19035 (define_expand "movmemdi"
19036 [(use (match_operand:BLK 0 "memory_operand" ""))
19037 (use (match_operand:BLK 1 "memory_operand" ""))
19038 (use (match_operand:DI 2 "nonmemory_operand" ""))
19039 (use (match_operand:DI 3 "const_int_operand" ""))
19040 (use (match_operand:SI 4 "const_int_operand" ""))
19041 (use (match_operand:SI 5 "const_int_operand" ""))]
19044 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19045 operands[4], operands[5]))
19051 ;; Most CPUs don't like single string operations
19052 ;; Handle this case here to simplify previous expander.
19054 (define_expand "strmov"
19055 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19056 (set (match_operand 1 "memory_operand" "") (match_dup 4))
19057 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19058 (clobber (reg:CC FLAGS_REG))])
19059 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19060 (clobber (reg:CC FLAGS_REG))])]
19063 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19065 /* If .md ever supports :P for Pmode, these can be directly
19066 in the pattern above. */
19067 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19068 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19070 /* Can't use this if the user has appropriated esi or edi. */
19071 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19072 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19074 emit_insn (gen_strmov_singleop (operands[0], operands[1],
19075 operands[2], operands[3],
19076 operands[5], operands[6]));
19080 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19083 (define_expand "strmov_singleop"
19084 [(parallel [(set (match_operand 1 "memory_operand" "")
19085 (match_operand 3 "memory_operand" ""))
19086 (set (match_operand 0 "register_operand" "")
19087 (match_operand 4 "" ""))
19088 (set (match_operand 2 "register_operand" "")
19089 (match_operand 5 "" ""))])]
19091 "ix86_current_function_needs_cld = 1;")
19093 (define_insn "*strmovdi_rex_1"
19094 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19095 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19096 (set (match_operand:DI 0 "register_operand" "=D")
19097 (plus:DI (match_dup 2)
19099 (set (match_operand:DI 1 "register_operand" "=S")
19100 (plus:DI (match_dup 3)
19104 [(set_attr "type" "str")
19105 (set_attr "mode" "DI")
19106 (set_attr "memory" "both")])
19108 (define_insn "*strmovsi_1"
19109 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19110 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19111 (set (match_operand:SI 0 "register_operand" "=D")
19112 (plus:SI (match_dup 2)
19114 (set (match_operand:SI 1 "register_operand" "=S")
19115 (plus:SI (match_dup 3)
19119 [(set_attr "type" "str")
19120 (set_attr "mode" "SI")
19121 (set_attr "memory" "both")])
19123 (define_insn "*strmovsi_rex_1"
19124 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19125 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19126 (set (match_operand:DI 0 "register_operand" "=D")
19127 (plus:DI (match_dup 2)
19129 (set (match_operand:DI 1 "register_operand" "=S")
19130 (plus:DI (match_dup 3)
19134 [(set_attr "type" "str")
19135 (set_attr "mode" "SI")
19136 (set_attr "memory" "both")])
19138 (define_insn "*strmovhi_1"
19139 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19140 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19141 (set (match_operand:SI 0 "register_operand" "=D")
19142 (plus:SI (match_dup 2)
19144 (set (match_operand:SI 1 "register_operand" "=S")
19145 (plus:SI (match_dup 3)
19149 [(set_attr "type" "str")
19150 (set_attr "memory" "both")
19151 (set_attr "mode" "HI")])
19153 (define_insn "*strmovhi_rex_1"
19154 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19155 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19156 (set (match_operand:DI 0 "register_operand" "=D")
19157 (plus:DI (match_dup 2)
19159 (set (match_operand:DI 1 "register_operand" "=S")
19160 (plus:DI (match_dup 3)
19164 [(set_attr "type" "str")
19165 (set_attr "memory" "both")
19166 (set_attr "mode" "HI")])
19168 (define_insn "*strmovqi_1"
19169 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19170 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19171 (set (match_operand:SI 0 "register_operand" "=D")
19172 (plus:SI (match_dup 2)
19174 (set (match_operand:SI 1 "register_operand" "=S")
19175 (plus:SI (match_dup 3)
19179 [(set_attr "type" "str")
19180 (set_attr "memory" "both")
19181 (set_attr "mode" "QI")])
19183 (define_insn "*strmovqi_rex_1"
19184 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19185 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19186 (set (match_operand:DI 0 "register_operand" "=D")
19187 (plus:DI (match_dup 2)
19189 (set (match_operand:DI 1 "register_operand" "=S")
19190 (plus:DI (match_dup 3)
19194 [(set_attr "type" "str")
19195 (set_attr "memory" "both")
19196 (set_attr "mode" "QI")])
19198 (define_expand "rep_mov"
19199 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19200 (set (match_operand 0 "register_operand" "")
19201 (match_operand 5 "" ""))
19202 (set (match_operand 2 "register_operand" "")
19203 (match_operand 6 "" ""))
19204 (set (match_operand 1 "memory_operand" "")
19205 (match_operand 3 "memory_operand" ""))
19206 (use (match_dup 4))])]
19208 "ix86_current_function_needs_cld = 1;")
19210 (define_insn "*rep_movdi_rex64"
19211 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19212 (set (match_operand:DI 0 "register_operand" "=D")
19213 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19215 (match_operand:DI 3 "register_operand" "0")))
19216 (set (match_operand:DI 1 "register_operand" "=S")
19217 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19218 (match_operand:DI 4 "register_operand" "1")))
19219 (set (mem:BLK (match_dup 3))
19220 (mem:BLK (match_dup 4)))
19221 (use (match_dup 5))]
19224 [(set_attr "type" "str")
19225 (set_attr "prefix_rep" "1")
19226 (set_attr "memory" "both")
19227 (set_attr "mode" "DI")])
19229 (define_insn "*rep_movsi"
19230 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19231 (set (match_operand:SI 0 "register_operand" "=D")
19232 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19234 (match_operand:SI 3 "register_operand" "0")))
19235 (set (match_operand:SI 1 "register_operand" "=S")
19236 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19237 (match_operand:SI 4 "register_operand" "1")))
19238 (set (mem:BLK (match_dup 3))
19239 (mem:BLK (match_dup 4)))
19240 (use (match_dup 5))]
19243 [(set_attr "type" "str")
19244 (set_attr "prefix_rep" "1")
19245 (set_attr "memory" "both")
19246 (set_attr "mode" "SI")])
19248 (define_insn "*rep_movsi_rex64"
19249 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19250 (set (match_operand:DI 0 "register_operand" "=D")
19251 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19253 (match_operand:DI 3 "register_operand" "0")))
19254 (set (match_operand:DI 1 "register_operand" "=S")
19255 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19256 (match_operand:DI 4 "register_operand" "1")))
19257 (set (mem:BLK (match_dup 3))
19258 (mem:BLK (match_dup 4)))
19259 (use (match_dup 5))]
19262 [(set_attr "type" "str")
19263 (set_attr "prefix_rep" "1")
19264 (set_attr "memory" "both")
19265 (set_attr "mode" "SI")])
19267 (define_insn "*rep_movqi"
19268 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19269 (set (match_operand:SI 0 "register_operand" "=D")
19270 (plus:SI (match_operand:SI 3 "register_operand" "0")
19271 (match_operand:SI 5 "register_operand" "2")))
19272 (set (match_operand:SI 1 "register_operand" "=S")
19273 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19274 (set (mem:BLK (match_dup 3))
19275 (mem:BLK (match_dup 4)))
19276 (use (match_dup 5))]
19279 [(set_attr "type" "str")
19280 (set_attr "prefix_rep" "1")
19281 (set_attr "memory" "both")
19282 (set_attr "mode" "SI")])
19284 (define_insn "*rep_movqi_rex64"
19285 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19286 (set (match_operand:DI 0 "register_operand" "=D")
19287 (plus:DI (match_operand:DI 3 "register_operand" "0")
19288 (match_operand:DI 5 "register_operand" "2")))
19289 (set (match_operand:DI 1 "register_operand" "=S")
19290 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19291 (set (mem:BLK (match_dup 3))
19292 (mem:BLK (match_dup 4)))
19293 (use (match_dup 5))]
19296 [(set_attr "type" "str")
19297 (set_attr "prefix_rep" "1")
19298 (set_attr "memory" "both")
19299 (set_attr "mode" "SI")])
19301 (define_expand "setmemsi"
19302 [(use (match_operand:BLK 0 "memory_operand" ""))
19303 (use (match_operand:SI 1 "nonmemory_operand" ""))
19304 (use (match_operand 2 "const_int_operand" ""))
19305 (use (match_operand 3 "const_int_operand" ""))
19306 (use (match_operand:SI 4 "const_int_operand" ""))
19307 (use (match_operand:SI 5 "const_int_operand" ""))]
19310 if (ix86_expand_setmem (operands[0], operands[1],
19311 operands[2], operands[3],
19312 operands[4], operands[5]))
19318 (define_expand "setmemdi"
19319 [(use (match_operand:BLK 0 "memory_operand" ""))
19320 (use (match_operand:DI 1 "nonmemory_operand" ""))
19321 (use (match_operand 2 "const_int_operand" ""))
19322 (use (match_operand 3 "const_int_operand" ""))
19323 (use (match_operand 4 "const_int_operand" ""))
19324 (use (match_operand 5 "const_int_operand" ""))]
19327 if (ix86_expand_setmem (operands[0], operands[1],
19328 operands[2], operands[3],
19329 operands[4], operands[5]))
19335 ;; Most CPUs don't like single string operations
19336 ;; Handle this case here to simplify previous expander.
19338 (define_expand "strset"
19339 [(set (match_operand 1 "memory_operand" "")
19340 (match_operand 2 "register_operand" ""))
19341 (parallel [(set (match_operand 0 "register_operand" "")
19343 (clobber (reg:CC FLAGS_REG))])]
19346 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19347 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19349 /* If .md ever supports :P for Pmode, this can be directly
19350 in the pattern above. */
19351 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19352 GEN_INT (GET_MODE_SIZE (GET_MODE
19354 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19356 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19362 (define_expand "strset_singleop"
19363 [(parallel [(set (match_operand 1 "memory_operand" "")
19364 (match_operand 2 "register_operand" ""))
19365 (set (match_operand 0 "register_operand" "")
19366 (match_operand 3 "" ""))])]
19368 "ix86_current_function_needs_cld = 1;")
19370 (define_insn "*strsetdi_rex_1"
19371 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19372 (match_operand:DI 2 "register_operand" "a"))
19373 (set (match_operand:DI 0 "register_operand" "=D")
19374 (plus:DI (match_dup 1)
19378 [(set_attr "type" "str")
19379 (set_attr "memory" "store")
19380 (set_attr "mode" "DI")])
19382 (define_insn "*strsetsi_1"
19383 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19384 (match_operand:SI 2 "register_operand" "a"))
19385 (set (match_operand:SI 0 "register_operand" "=D")
19386 (plus:SI (match_dup 1)
19390 [(set_attr "type" "str")
19391 (set_attr "memory" "store")
19392 (set_attr "mode" "SI")])
19394 (define_insn "*strsetsi_rex_1"
19395 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19396 (match_operand:SI 2 "register_operand" "a"))
19397 (set (match_operand:DI 0 "register_operand" "=D")
19398 (plus:DI (match_dup 1)
19402 [(set_attr "type" "str")
19403 (set_attr "memory" "store")
19404 (set_attr "mode" "SI")])
19406 (define_insn "*strsethi_1"
19407 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19408 (match_operand:HI 2 "register_operand" "a"))
19409 (set (match_operand:SI 0 "register_operand" "=D")
19410 (plus:SI (match_dup 1)
19414 [(set_attr "type" "str")
19415 (set_attr "memory" "store")
19416 (set_attr "mode" "HI")])
19418 (define_insn "*strsethi_rex_1"
19419 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19420 (match_operand:HI 2 "register_operand" "a"))
19421 (set (match_operand:DI 0 "register_operand" "=D")
19422 (plus:DI (match_dup 1)
19426 [(set_attr "type" "str")
19427 (set_attr "memory" "store")
19428 (set_attr "mode" "HI")])
19430 (define_insn "*strsetqi_1"
19431 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19432 (match_operand:QI 2 "register_operand" "a"))
19433 (set (match_operand:SI 0 "register_operand" "=D")
19434 (plus:SI (match_dup 1)
19438 [(set_attr "type" "str")
19439 (set_attr "memory" "store")
19440 (set_attr "mode" "QI")])
19442 (define_insn "*strsetqi_rex_1"
19443 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19444 (match_operand:QI 2 "register_operand" "a"))
19445 (set (match_operand:DI 0 "register_operand" "=D")
19446 (plus:DI (match_dup 1)
19450 [(set_attr "type" "str")
19451 (set_attr "memory" "store")
19452 (set_attr "mode" "QI")])
19454 (define_expand "rep_stos"
19455 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19456 (set (match_operand 0 "register_operand" "")
19457 (match_operand 4 "" ""))
19458 (set (match_operand 2 "memory_operand" "") (const_int 0))
19459 (use (match_operand 3 "register_operand" ""))
19460 (use (match_dup 1))])]
19462 "ix86_current_function_needs_cld = 1;")
19464 (define_insn "*rep_stosdi_rex64"
19465 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19466 (set (match_operand:DI 0 "register_operand" "=D")
19467 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19469 (match_operand:DI 3 "register_operand" "0")))
19470 (set (mem:BLK (match_dup 3))
19472 (use (match_operand:DI 2 "register_operand" "a"))
19473 (use (match_dup 4))]
19476 [(set_attr "type" "str")
19477 (set_attr "prefix_rep" "1")
19478 (set_attr "memory" "store")
19479 (set_attr "mode" "DI")])
19481 (define_insn "*rep_stossi"
19482 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19483 (set (match_operand:SI 0 "register_operand" "=D")
19484 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19486 (match_operand:SI 3 "register_operand" "0")))
19487 (set (mem:BLK (match_dup 3))
19489 (use (match_operand:SI 2 "register_operand" "a"))
19490 (use (match_dup 4))]
19493 [(set_attr "type" "str")
19494 (set_attr "prefix_rep" "1")
19495 (set_attr "memory" "store")
19496 (set_attr "mode" "SI")])
19498 (define_insn "*rep_stossi_rex64"
19499 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19500 (set (match_operand:DI 0 "register_operand" "=D")
19501 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19503 (match_operand:DI 3 "register_operand" "0")))
19504 (set (mem:BLK (match_dup 3))
19506 (use (match_operand:SI 2 "register_operand" "a"))
19507 (use (match_dup 4))]
19510 [(set_attr "type" "str")
19511 (set_attr "prefix_rep" "1")
19512 (set_attr "memory" "store")
19513 (set_attr "mode" "SI")])
19515 (define_insn "*rep_stosqi"
19516 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19517 (set (match_operand:SI 0 "register_operand" "=D")
19518 (plus:SI (match_operand:SI 3 "register_operand" "0")
19519 (match_operand:SI 4 "register_operand" "1")))
19520 (set (mem:BLK (match_dup 3))
19522 (use (match_operand:QI 2 "register_operand" "a"))
19523 (use (match_dup 4))]
19526 [(set_attr "type" "str")
19527 (set_attr "prefix_rep" "1")
19528 (set_attr "memory" "store")
19529 (set_attr "mode" "QI")])
19531 (define_insn "*rep_stosqi_rex64"
19532 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19533 (set (match_operand:DI 0 "register_operand" "=D")
19534 (plus:DI (match_operand:DI 3 "register_operand" "0")
19535 (match_operand:DI 4 "register_operand" "1")))
19536 (set (mem:BLK (match_dup 3))
19538 (use (match_operand:QI 2 "register_operand" "a"))
19539 (use (match_dup 4))]
19542 [(set_attr "type" "str")
19543 (set_attr "prefix_rep" "1")
19544 (set_attr "memory" "store")
19545 (set_attr "mode" "QI")])
19547 (define_expand "cmpstrnsi"
19548 [(set (match_operand:SI 0 "register_operand" "")
19549 (compare:SI (match_operand:BLK 1 "general_operand" "")
19550 (match_operand:BLK 2 "general_operand" "")))
19551 (use (match_operand 3 "general_operand" ""))
19552 (use (match_operand 4 "immediate_operand" ""))]
19555 rtx addr1, addr2, out, outlow, count, countreg, align;
19557 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19560 /* Can't use this if the user has appropriated esi or edi. */
19561 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19566 out = gen_reg_rtx (SImode);
19568 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19569 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19570 if (addr1 != XEXP (operands[1], 0))
19571 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19572 if (addr2 != XEXP (operands[2], 0))
19573 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19575 count = operands[3];
19576 countreg = ix86_zero_extend_to_Pmode (count);
19578 /* %%% Iff we are testing strict equality, we can use known alignment
19579 to good advantage. This may be possible with combine, particularly
19580 once cc0 is dead. */
19581 align = operands[4];
19583 if (CONST_INT_P (count))
19585 if (INTVAL (count) == 0)
19587 emit_move_insn (operands[0], const0_rtx);
19590 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19591 operands[1], operands[2]));
19596 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19598 emit_insn (gen_cmpsi_1 (countreg, countreg));
19599 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19600 operands[1], operands[2]));
19603 outlow = gen_lowpart (QImode, out);
19604 emit_insn (gen_cmpintqi (outlow));
19605 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19607 if (operands[0] != out)
19608 emit_move_insn (operands[0], out);
19613 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19615 (define_expand "cmpintqi"
19616 [(set (match_dup 1)
19617 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19619 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19620 (parallel [(set (match_operand:QI 0 "register_operand" "")
19621 (minus:QI (match_dup 1)
19623 (clobber (reg:CC FLAGS_REG))])]
19625 "operands[1] = gen_reg_rtx (QImode);
19626 operands[2] = gen_reg_rtx (QImode);")
19628 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19629 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19631 (define_expand "cmpstrnqi_nz_1"
19632 [(parallel [(set (reg:CC FLAGS_REG)
19633 (compare:CC (match_operand 4 "memory_operand" "")
19634 (match_operand 5 "memory_operand" "")))
19635 (use (match_operand 2 "register_operand" ""))
19636 (use (match_operand:SI 3 "immediate_operand" ""))
19637 (clobber (match_operand 0 "register_operand" ""))
19638 (clobber (match_operand 1 "register_operand" ""))
19639 (clobber (match_dup 2))])]
19641 "ix86_current_function_needs_cld = 1;")
19643 (define_insn "*cmpstrnqi_nz_1"
19644 [(set (reg:CC FLAGS_REG)
19645 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19646 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19647 (use (match_operand:SI 6 "register_operand" "2"))
19648 (use (match_operand:SI 3 "immediate_operand" "i"))
19649 (clobber (match_operand:SI 0 "register_operand" "=S"))
19650 (clobber (match_operand:SI 1 "register_operand" "=D"))
19651 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19654 [(set_attr "type" "str")
19655 (set_attr "mode" "QI")
19656 (set_attr "prefix_rep" "1")])
19658 (define_insn "*cmpstrnqi_nz_rex_1"
19659 [(set (reg:CC FLAGS_REG)
19660 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19661 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19662 (use (match_operand:DI 6 "register_operand" "2"))
19663 (use (match_operand:SI 3 "immediate_operand" "i"))
19664 (clobber (match_operand:DI 0 "register_operand" "=S"))
19665 (clobber (match_operand:DI 1 "register_operand" "=D"))
19666 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19669 [(set_attr "type" "str")
19670 (set_attr "mode" "QI")
19671 (set_attr "prefix_rep" "1")])
19673 ;; The same, but the count is not known to not be zero.
19675 (define_expand "cmpstrnqi_1"
19676 [(parallel [(set (reg:CC FLAGS_REG)
19677 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19679 (compare:CC (match_operand 4 "memory_operand" "")
19680 (match_operand 5 "memory_operand" ""))
19682 (use (match_operand:SI 3 "immediate_operand" ""))
19683 (use (reg:CC FLAGS_REG))
19684 (clobber (match_operand 0 "register_operand" ""))
19685 (clobber (match_operand 1 "register_operand" ""))
19686 (clobber (match_dup 2))])]
19688 "ix86_current_function_needs_cld = 1;")
19690 (define_insn "*cmpstrnqi_1"
19691 [(set (reg:CC FLAGS_REG)
19692 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19694 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19695 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19697 (use (match_operand:SI 3 "immediate_operand" "i"))
19698 (use (reg:CC FLAGS_REG))
19699 (clobber (match_operand:SI 0 "register_operand" "=S"))
19700 (clobber (match_operand:SI 1 "register_operand" "=D"))
19701 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19704 [(set_attr "type" "str")
19705 (set_attr "mode" "QI")
19706 (set_attr "prefix_rep" "1")])
19708 (define_insn "*cmpstrnqi_rex_1"
19709 [(set (reg:CC FLAGS_REG)
19710 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19712 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19713 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19715 (use (match_operand:SI 3 "immediate_operand" "i"))
19716 (use (reg:CC FLAGS_REG))
19717 (clobber (match_operand:DI 0 "register_operand" "=S"))
19718 (clobber (match_operand:DI 1 "register_operand" "=D"))
19719 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19722 [(set_attr "type" "str")
19723 (set_attr "mode" "QI")
19724 (set_attr "prefix_rep" "1")])
19726 (define_expand "strlensi"
19727 [(set (match_operand:SI 0 "register_operand" "")
19728 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19729 (match_operand:QI 2 "immediate_operand" "")
19730 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19733 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19739 (define_expand "strlendi"
19740 [(set (match_operand:DI 0 "register_operand" "")
19741 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19742 (match_operand:QI 2 "immediate_operand" "")
19743 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19746 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19752 (define_expand "strlenqi_1"
19753 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19754 (clobber (match_operand 1 "register_operand" ""))
19755 (clobber (reg:CC FLAGS_REG))])]
19757 "ix86_current_function_needs_cld = 1;")
19759 (define_insn "*strlenqi_1"
19760 [(set (match_operand:SI 0 "register_operand" "=&c")
19761 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19762 (match_operand:QI 2 "register_operand" "a")
19763 (match_operand:SI 3 "immediate_operand" "i")
19764 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19765 (clobber (match_operand:SI 1 "register_operand" "=D"))
19766 (clobber (reg:CC FLAGS_REG))]
19769 [(set_attr "type" "str")
19770 (set_attr "mode" "QI")
19771 (set_attr "prefix_rep" "1")])
19773 (define_insn "*strlenqi_rex_1"
19774 [(set (match_operand:DI 0 "register_operand" "=&c")
19775 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19776 (match_operand:QI 2 "register_operand" "a")
19777 (match_operand:DI 3 "immediate_operand" "i")
19778 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19779 (clobber (match_operand:DI 1 "register_operand" "=D"))
19780 (clobber (reg:CC FLAGS_REG))]
19783 [(set_attr "type" "str")
19784 (set_attr "mode" "QI")
19785 (set_attr "prefix_rep" "1")])
19787 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19788 ;; handled in combine, but it is not currently up to the task.
19789 ;; When used for their truth value, the cmpstrn* expanders generate
19798 ;; The intermediate three instructions are unnecessary.
19800 ;; This one handles cmpstrn*_nz_1...
19803 (set (reg:CC FLAGS_REG)
19804 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19805 (mem:BLK (match_operand 5 "register_operand" ""))))
19806 (use (match_operand 6 "register_operand" ""))
19807 (use (match_operand:SI 3 "immediate_operand" ""))
19808 (clobber (match_operand 0 "register_operand" ""))
19809 (clobber (match_operand 1 "register_operand" ""))
19810 (clobber (match_operand 2 "register_operand" ""))])
19811 (set (match_operand:QI 7 "register_operand" "")
19812 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19813 (set (match_operand:QI 8 "register_operand" "")
19814 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19815 (set (reg FLAGS_REG)
19816 (compare (match_dup 7) (match_dup 8)))
19818 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19820 (set (reg:CC FLAGS_REG)
19821 (compare:CC (mem:BLK (match_dup 4))
19822 (mem:BLK (match_dup 5))))
19823 (use (match_dup 6))
19824 (use (match_dup 3))
19825 (clobber (match_dup 0))
19826 (clobber (match_dup 1))
19827 (clobber (match_dup 2))])]
19830 ;; ...and this one handles cmpstrn*_1.
19833 (set (reg:CC FLAGS_REG)
19834 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19836 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19837 (mem:BLK (match_operand 5 "register_operand" "")))
19839 (use (match_operand:SI 3 "immediate_operand" ""))
19840 (use (reg:CC FLAGS_REG))
19841 (clobber (match_operand 0 "register_operand" ""))
19842 (clobber (match_operand 1 "register_operand" ""))
19843 (clobber (match_operand 2 "register_operand" ""))])
19844 (set (match_operand:QI 7 "register_operand" "")
19845 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19846 (set (match_operand:QI 8 "register_operand" "")
19847 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19848 (set (reg FLAGS_REG)
19849 (compare (match_dup 7) (match_dup 8)))
19851 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19853 (set (reg:CC FLAGS_REG)
19854 (if_then_else:CC (ne (match_dup 6)
19856 (compare:CC (mem:BLK (match_dup 4))
19857 (mem:BLK (match_dup 5)))
19859 (use (match_dup 3))
19860 (use (reg:CC FLAGS_REG))
19861 (clobber (match_dup 0))
19862 (clobber (match_dup 1))
19863 (clobber (match_dup 2))])]
19868 ;; Conditional move instructions.
19870 (define_expand "movdicc"
19871 [(set (match_operand:DI 0 "register_operand" "")
19872 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19873 (match_operand:DI 2 "general_operand" "")
19874 (match_operand:DI 3 "general_operand" "")))]
19876 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19878 (define_insn "x86_movdicc_0_m1_rex64"
19879 [(set (match_operand:DI 0 "register_operand" "=r")
19880 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19883 (clobber (reg:CC FLAGS_REG))]
19886 ; Since we don't have the proper number of operands for an alu insn,
19887 ; fill in all the blanks.
19888 [(set_attr "type" "alu")
19889 (set_attr "use_carry" "1")
19890 (set_attr "pent_pair" "pu")
19891 (set_attr "memory" "none")
19892 (set_attr "imm_disp" "false")
19893 (set_attr "mode" "DI")
19894 (set_attr "length_immediate" "0")])
19896 (define_insn "*x86_movdicc_0_m1_se"
19897 [(set (match_operand:DI 0 "register_operand" "=r")
19898 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19901 (clobber (reg:CC FLAGS_REG))]
19904 [(set_attr "type" "alu")
19905 (set_attr "use_carry" "1")
19906 (set_attr "pent_pair" "pu")
19907 (set_attr "memory" "none")
19908 (set_attr "imm_disp" "false")
19909 (set_attr "mode" "DI")
19910 (set_attr "length_immediate" "0")])
19912 (define_insn "*movdicc_c_rex64"
19913 [(set (match_operand:DI 0 "register_operand" "=r,r")
19914 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19915 [(reg FLAGS_REG) (const_int 0)])
19916 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19917 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19918 "TARGET_64BIT && TARGET_CMOVE
19919 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19921 cmov%O2%C1\t{%2, %0|%0, %2}
19922 cmov%O2%c1\t{%3, %0|%0, %3}"
19923 [(set_attr "type" "icmov")
19924 (set_attr "mode" "DI")])
19926 (define_expand "movsicc"
19927 [(set (match_operand:SI 0 "register_operand" "")
19928 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19929 (match_operand:SI 2 "general_operand" "")
19930 (match_operand:SI 3 "general_operand" "")))]
19932 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19934 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19935 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19936 ;; So just document what we're doing explicitly.
19938 (define_insn "x86_movsicc_0_m1"
19939 [(set (match_operand:SI 0 "register_operand" "=r")
19940 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19943 (clobber (reg:CC FLAGS_REG))]
19946 ; Since we don't have the proper number of operands for an alu insn,
19947 ; fill in all the blanks.
19948 [(set_attr "type" "alu")
19949 (set_attr "use_carry" "1")
19950 (set_attr "pent_pair" "pu")
19951 (set_attr "memory" "none")
19952 (set_attr "imm_disp" "false")
19953 (set_attr "mode" "SI")
19954 (set_attr "length_immediate" "0")])
19956 (define_insn "*x86_movsicc_0_m1_se"
19957 [(set (match_operand:SI 0 "register_operand" "=r")
19958 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19961 (clobber (reg:CC FLAGS_REG))]
19964 [(set_attr "type" "alu")
19965 (set_attr "use_carry" "1")
19966 (set_attr "pent_pair" "pu")
19967 (set_attr "memory" "none")
19968 (set_attr "imm_disp" "false")
19969 (set_attr "mode" "SI")
19970 (set_attr "length_immediate" "0")])
19972 (define_insn "*movsicc_noc"
19973 [(set (match_operand:SI 0 "register_operand" "=r,r")
19974 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19975 [(reg FLAGS_REG) (const_int 0)])
19976 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19977 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19979 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19981 cmov%O2%C1\t{%2, %0|%0, %2}
19982 cmov%O2%c1\t{%3, %0|%0, %3}"
19983 [(set_attr "type" "icmov")
19984 (set_attr "mode" "SI")])
19986 (define_expand "movhicc"
19987 [(set (match_operand:HI 0 "register_operand" "")
19988 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19989 (match_operand:HI 2 "general_operand" "")
19990 (match_operand:HI 3 "general_operand" "")))]
19991 "TARGET_HIMODE_MATH"
19992 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19994 (define_insn "*movhicc_noc"
19995 [(set (match_operand:HI 0 "register_operand" "=r,r")
19996 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19997 [(reg FLAGS_REG) (const_int 0)])
19998 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19999 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20001 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20003 cmov%O2%C1\t{%2, %0|%0, %2}
20004 cmov%O2%c1\t{%3, %0|%0, %3}"
20005 [(set_attr "type" "icmov")
20006 (set_attr "mode" "HI")])
20008 (define_expand "movqicc"
20009 [(set (match_operand:QI 0 "register_operand" "")
20010 (if_then_else:QI (match_operand 1 "comparison_operator" "")
20011 (match_operand:QI 2 "general_operand" "")
20012 (match_operand:QI 3 "general_operand" "")))]
20013 "TARGET_QIMODE_MATH"
20014 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20016 (define_insn_and_split "*movqicc_noc"
20017 [(set (match_operand:QI 0 "register_operand" "=r,r")
20018 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20019 [(match_operand 4 "flags_reg_operand" "")
20021 (match_operand:QI 2 "register_operand" "r,0")
20022 (match_operand:QI 3 "register_operand" "0,r")))]
20023 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20025 "&& reload_completed"
20026 [(set (match_dup 0)
20027 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20030 "operands[0] = gen_lowpart (SImode, operands[0]);
20031 operands[2] = gen_lowpart (SImode, operands[2]);
20032 operands[3] = gen_lowpart (SImode, operands[3]);"
20033 [(set_attr "type" "icmov")
20034 (set_attr "mode" "SI")])
20036 (define_expand "mov<mode>cc"
20037 [(set (match_operand:X87MODEF 0 "register_operand" "")
20038 (if_then_else:X87MODEF
20039 (match_operand 1 "comparison_operator" "")
20040 (match_operand:X87MODEF 2 "register_operand" "")
20041 (match_operand:X87MODEF 3 "register_operand" "")))]
20042 "(TARGET_80387 && TARGET_CMOVE)
20043 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20044 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20046 (define_insn "*movsfcc_1_387"
20047 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20048 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20049 [(reg FLAGS_REG) (const_int 0)])
20050 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20051 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20052 "TARGET_80387 && TARGET_CMOVE
20053 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20055 fcmov%F1\t{%2, %0|%0, %2}
20056 fcmov%f1\t{%3, %0|%0, %3}
20057 cmov%O2%C1\t{%2, %0|%0, %2}
20058 cmov%O2%c1\t{%3, %0|%0, %3}"
20059 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20060 (set_attr "mode" "SF,SF,SI,SI")])
20062 (define_insn "*movdfcc_1"
20063 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20064 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20065 [(reg FLAGS_REG) (const_int 0)])
20066 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20067 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20068 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20069 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20071 fcmov%F1\t{%2, %0|%0, %2}
20072 fcmov%f1\t{%3, %0|%0, %3}
20075 [(set_attr "type" "fcmov,fcmov,multi,multi")
20076 (set_attr "mode" "DF")])
20078 (define_insn "*movdfcc_1_rex64"
20079 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20080 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20081 [(reg FLAGS_REG) (const_int 0)])
20082 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20083 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20084 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20085 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20087 fcmov%F1\t{%2, %0|%0, %2}
20088 fcmov%f1\t{%3, %0|%0, %3}
20089 cmov%O2%C1\t{%2, %0|%0, %2}
20090 cmov%O2%c1\t{%3, %0|%0, %3}"
20091 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20092 (set_attr "mode" "DF")])
20095 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20096 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20097 [(match_operand 4 "flags_reg_operand" "")
20099 (match_operand:DF 2 "nonimmediate_operand" "")
20100 (match_operand:DF 3 "nonimmediate_operand" "")))]
20101 "!TARGET_64BIT && reload_completed"
20102 [(set (match_dup 2)
20103 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20107 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20110 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20111 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20113 (define_insn "*movxfcc_1"
20114 [(set (match_operand:XF 0 "register_operand" "=f,f")
20115 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20116 [(reg FLAGS_REG) (const_int 0)])
20117 (match_operand:XF 2 "register_operand" "f,0")
20118 (match_operand:XF 3 "register_operand" "0,f")))]
20119 "TARGET_80387 && TARGET_CMOVE"
20121 fcmov%F1\t{%2, %0|%0, %2}
20122 fcmov%f1\t{%3, %0|%0, %3}"
20123 [(set_attr "type" "fcmov")
20124 (set_attr "mode" "XF")])
20126 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20127 ;; the scalar versions to have only XMM registers as operands.
20129 ;; SSE5 conditional move
20130 (define_insn "*sse5_pcmov_<mode>"
20131 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20132 (if_then_else:MODEF
20133 (match_operand:MODEF 1 "register_operand" "x,0")
20134 (match_operand:MODEF 2 "register_operand" "0,x")
20135 (match_operand:MODEF 3 "register_operand" "x,x")))]
20136 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20137 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20138 [(set_attr "type" "sse4arg")])
20140 ;; These versions of the min/max patterns are intentionally ignorant of
20141 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20142 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20143 ;; are undefined in this condition, we're certain this is correct.
20145 (define_insn "*avx_<code><mode>3"
20146 [(set (match_operand:MODEF 0 "register_operand" "=x")
20148 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20149 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20150 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20151 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20152 [(set_attr "type" "sseadd")
20153 (set_attr "prefix" "vex")
20154 (set_attr "mode" "<MODE>")])
20156 (define_insn "<code><mode>3"
20157 [(set (match_operand:MODEF 0 "register_operand" "=x")
20159 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20160 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20161 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20162 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20163 [(set_attr "type" "sseadd")
20164 (set_attr "mode" "<MODE>")])
20166 ;; These versions of the min/max patterns implement exactly the operations
20167 ;; min = (op1 < op2 ? op1 : op2)
20168 ;; max = (!(op1 < op2) ? op1 : op2)
20169 ;; Their operands are not commutative, and thus they may be used in the
20170 ;; presence of -0.0 and NaN.
20172 (define_insn "*avx_ieee_smin<mode>3"
20173 [(set (match_operand:MODEF 0 "register_operand" "=x")
20175 [(match_operand:MODEF 1 "register_operand" "x")
20176 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20178 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20179 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20180 [(set_attr "type" "sseadd")
20181 (set_attr "prefix" "vex")
20182 (set_attr "mode" "<MODE>")])
20184 (define_insn "*ieee_smin<mode>3"
20185 [(set (match_operand:MODEF 0 "register_operand" "=x")
20187 [(match_operand:MODEF 1 "register_operand" "0")
20188 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20190 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20191 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20192 [(set_attr "type" "sseadd")
20193 (set_attr "mode" "<MODE>")])
20195 (define_insn "*avx_ieee_smax<mode>3"
20196 [(set (match_operand:MODEF 0 "register_operand" "=x")
20198 [(match_operand:MODEF 1 "register_operand" "0")
20199 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20201 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20202 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20203 [(set_attr "type" "sseadd")
20204 (set_attr "prefix" "vex")
20205 (set_attr "mode" "<MODE>")])
20207 (define_insn "*ieee_smax<mode>3"
20208 [(set (match_operand:MODEF 0 "register_operand" "=x")
20210 [(match_operand:MODEF 1 "register_operand" "0")
20211 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20213 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20214 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20215 [(set_attr "type" "sseadd")
20216 (set_attr "mode" "<MODE>")])
20218 ;; Make two stack loads independent:
20220 ;; fld %st(0) -> fld bb
20221 ;; fmul bb fmul %st(1), %st
20223 ;; Actually we only match the last two instructions for simplicity.
20225 [(set (match_operand 0 "fp_register_operand" "")
20226 (match_operand 1 "fp_register_operand" ""))
20228 (match_operator 2 "binary_fp_operator"
20230 (match_operand 3 "memory_operand" "")]))]
20231 "REGNO (operands[0]) != REGNO (operands[1])"
20232 [(set (match_dup 0) (match_dup 3))
20233 (set (match_dup 0) (match_dup 4))]
20235 ;; The % modifier is not operational anymore in peephole2's, so we have to
20236 ;; swap the operands manually in the case of addition and multiplication.
20237 "if (COMMUTATIVE_ARITH_P (operands[2]))
20238 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20239 operands[0], operands[1]);
20241 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20242 operands[1], operands[0]);")
20244 ;; Conditional addition patterns
20245 (define_expand "add<mode>cc"
20246 [(match_operand:SWI 0 "register_operand" "")
20247 (match_operand 1 "comparison_operator" "")
20248 (match_operand:SWI 2 "register_operand" "")
20249 (match_operand:SWI 3 "const_int_operand" "")]
20251 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20254 ;; Misc patterns (?)
20256 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20257 ;; Otherwise there will be nothing to keep
20259 ;; [(set (reg ebp) (reg esp))]
20260 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20261 ;; (clobber (eflags)]
20262 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20264 ;; in proper program order.
20265 (define_insn "pro_epilogue_adjust_stack_1"
20266 [(set (match_operand:SI 0 "register_operand" "=r,r")
20267 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20268 (match_operand:SI 2 "immediate_operand" "i,i")))
20269 (clobber (reg:CC FLAGS_REG))
20270 (clobber (mem:BLK (scratch)))]
20273 switch (get_attr_type (insn))
20276 return "mov{l}\t{%1, %0|%0, %1}";
20279 if (CONST_INT_P (operands[2])
20280 && (INTVAL (operands[2]) == 128
20281 || (INTVAL (operands[2]) < 0
20282 && INTVAL (operands[2]) != -128)))
20284 operands[2] = GEN_INT (-INTVAL (operands[2]));
20285 return "sub{l}\t{%2, %0|%0, %2}";
20287 return "add{l}\t{%2, %0|%0, %2}";
20290 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20291 return "lea{l}\t{%a2, %0|%0, %a2}";
20294 gcc_unreachable ();
20297 [(set (attr "type")
20298 (cond [(and (eq_attr "alternative" "0")
20299 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20300 (const_string "alu")
20301 (match_operand:SI 2 "const0_operand" "")
20302 (const_string "imov")
20304 (const_string "lea")))
20305 (set_attr "mode" "SI")])
20307 (define_insn "pro_epilogue_adjust_stack_rex64"
20308 [(set (match_operand:DI 0 "register_operand" "=r,r")
20309 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20310 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20311 (clobber (reg:CC FLAGS_REG))
20312 (clobber (mem:BLK (scratch)))]
20315 switch (get_attr_type (insn))
20318 return "mov{q}\t{%1, %0|%0, %1}";
20321 if (CONST_INT_P (operands[2])
20322 /* Avoid overflows. */
20323 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20324 && (INTVAL (operands[2]) == 128
20325 || (INTVAL (operands[2]) < 0
20326 && INTVAL (operands[2]) != -128)))
20328 operands[2] = GEN_INT (-INTVAL (operands[2]));
20329 return "sub{q}\t{%2, %0|%0, %2}";
20331 return "add{q}\t{%2, %0|%0, %2}";
20334 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20335 return "lea{q}\t{%a2, %0|%0, %a2}";
20338 gcc_unreachable ();
20341 [(set (attr "type")
20342 (cond [(and (eq_attr "alternative" "0")
20343 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20344 (const_string "alu")
20345 (match_operand:DI 2 "const0_operand" "")
20346 (const_string "imov")
20348 (const_string "lea")))
20349 (set_attr "mode" "DI")])
20351 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20352 [(set (match_operand:DI 0 "register_operand" "=r,r")
20353 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20354 (match_operand:DI 3 "immediate_operand" "i,i")))
20355 (use (match_operand:DI 2 "register_operand" "r,r"))
20356 (clobber (reg:CC FLAGS_REG))
20357 (clobber (mem:BLK (scratch)))]
20360 switch (get_attr_type (insn))
20363 return "add{q}\t{%2, %0|%0, %2}";
20366 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20367 return "lea{q}\t{%a2, %0|%0, %a2}";
20370 gcc_unreachable ();
20373 [(set_attr "type" "alu,lea")
20374 (set_attr "mode" "DI")])
20376 (define_insn "allocate_stack_worker_32"
20377 [(set (match_operand:SI 0 "register_operand" "=a")
20378 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20379 UNSPECV_STACK_PROBE))
20380 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20381 (clobber (reg:CC FLAGS_REG))]
20382 "!TARGET_64BIT && TARGET_STACK_PROBE"
20384 [(set_attr "type" "multi")
20385 (set_attr "length" "5")])
20387 (define_insn "allocate_stack_worker_64"
20388 [(set (match_operand:DI 0 "register_operand" "=a")
20389 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20390 UNSPECV_STACK_PROBE))
20391 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20392 (clobber (reg:DI R10_REG))
20393 (clobber (reg:DI R11_REG))
20394 (clobber (reg:CC FLAGS_REG))]
20395 "TARGET_64BIT && TARGET_STACK_PROBE"
20397 [(set_attr "type" "multi")
20398 (set_attr "length" "5")])
20400 (define_expand "allocate_stack"
20401 [(match_operand 0 "register_operand" "")
20402 (match_operand 1 "general_operand" "")]
20403 "TARGET_STACK_PROBE"
20407 #ifndef CHECK_STACK_LIMIT
20408 #define CHECK_STACK_LIMIT 0
20411 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20412 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20414 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20415 stack_pointer_rtx, 0, OPTAB_DIRECT);
20416 if (x != stack_pointer_rtx)
20417 emit_move_insn (stack_pointer_rtx, x);
20421 x = copy_to_mode_reg (Pmode, operands[1]);
20423 x = gen_allocate_stack_worker_64 (x, x);
20425 x = gen_allocate_stack_worker_32 (x, x);
20429 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20433 (define_expand "builtin_setjmp_receiver"
20434 [(label_ref (match_operand 0 "" ""))]
20435 "!TARGET_64BIT && flag_pic"
20441 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20442 rtx label_rtx = gen_label_rtx ();
20443 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20444 xops[0] = xops[1] = picreg;
20445 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20446 ix86_expand_binary_operator (MINUS, SImode, xops);
20450 emit_insn (gen_set_got (pic_offset_table_rtx));
20454 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20457 [(set (match_operand 0 "register_operand" "")
20458 (match_operator 3 "promotable_binary_operator"
20459 [(match_operand 1 "register_operand" "")
20460 (match_operand 2 "aligned_operand" "")]))
20461 (clobber (reg:CC FLAGS_REG))]
20462 "! TARGET_PARTIAL_REG_STALL && reload_completed
20463 && ((GET_MODE (operands[0]) == HImode
20464 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20465 /* ??? next two lines just !satisfies_constraint_K (...) */
20466 || !CONST_INT_P (operands[2])
20467 || satisfies_constraint_K (operands[2])))
20468 || (GET_MODE (operands[0]) == QImode
20469 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20470 [(parallel [(set (match_dup 0)
20471 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20472 (clobber (reg:CC FLAGS_REG))])]
20473 "operands[0] = gen_lowpart (SImode, operands[0]);
20474 operands[1] = gen_lowpart (SImode, operands[1]);
20475 if (GET_CODE (operands[3]) != ASHIFT)
20476 operands[2] = gen_lowpart (SImode, operands[2]);
20477 PUT_MODE (operands[3], SImode);")
20479 ; Promote the QImode tests, as i386 has encoding of the AND
20480 ; instruction with 32-bit sign-extended immediate and thus the
20481 ; instruction size is unchanged, except in the %eax case for
20482 ; which it is increased by one byte, hence the ! optimize_size.
20484 [(set (match_operand 0 "flags_reg_operand" "")
20485 (match_operator 2 "compare_operator"
20486 [(and (match_operand 3 "aligned_operand" "")
20487 (match_operand 4 "const_int_operand" ""))
20489 (set (match_operand 1 "register_operand" "")
20490 (and (match_dup 3) (match_dup 4)))]
20491 "! TARGET_PARTIAL_REG_STALL && reload_completed
20492 && optimize_insn_for_speed_p ()
20493 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20494 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20495 /* Ensure that the operand will remain sign-extended immediate. */
20496 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20497 [(parallel [(set (match_dup 0)
20498 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20501 (and:SI (match_dup 3) (match_dup 4)))])]
20504 = gen_int_mode (INTVAL (operands[4])
20505 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20506 operands[1] = gen_lowpart (SImode, operands[1]);
20507 operands[3] = gen_lowpart (SImode, operands[3]);
20510 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20511 ; the TEST instruction with 32-bit sign-extended immediate and thus
20512 ; the instruction size would at least double, which is not what we
20513 ; want even with ! optimize_size.
20515 [(set (match_operand 0 "flags_reg_operand" "")
20516 (match_operator 1 "compare_operator"
20517 [(and (match_operand:HI 2 "aligned_operand" "")
20518 (match_operand:HI 3 "const_int_operand" ""))
20520 "! TARGET_PARTIAL_REG_STALL && reload_completed
20521 && ! TARGET_FAST_PREFIX
20522 && optimize_insn_for_speed_p ()
20523 /* Ensure that the operand will remain sign-extended immediate. */
20524 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20525 [(set (match_dup 0)
20526 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20530 = gen_int_mode (INTVAL (operands[3])
20531 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20532 operands[2] = gen_lowpart (SImode, operands[2]);
20536 [(set (match_operand 0 "register_operand" "")
20537 (neg (match_operand 1 "register_operand" "")))
20538 (clobber (reg:CC FLAGS_REG))]
20539 "! TARGET_PARTIAL_REG_STALL && reload_completed
20540 && (GET_MODE (operands[0]) == HImode
20541 || (GET_MODE (operands[0]) == QImode
20542 && (TARGET_PROMOTE_QImode
20543 || optimize_insn_for_size_p ())))"
20544 [(parallel [(set (match_dup 0)
20545 (neg:SI (match_dup 1)))
20546 (clobber (reg:CC FLAGS_REG))])]
20547 "operands[0] = gen_lowpart (SImode, operands[0]);
20548 operands[1] = gen_lowpart (SImode, operands[1]);")
20551 [(set (match_operand 0 "register_operand" "")
20552 (not (match_operand 1 "register_operand" "")))]
20553 "! TARGET_PARTIAL_REG_STALL && reload_completed
20554 && (GET_MODE (operands[0]) == HImode
20555 || (GET_MODE (operands[0]) == QImode
20556 && (TARGET_PROMOTE_QImode
20557 || optimize_insn_for_size_p ())))"
20558 [(set (match_dup 0)
20559 (not:SI (match_dup 1)))]
20560 "operands[0] = gen_lowpart (SImode, operands[0]);
20561 operands[1] = gen_lowpart (SImode, operands[1]);")
20564 [(set (match_operand 0 "register_operand" "")
20565 (if_then_else (match_operator 1 "comparison_operator"
20566 [(reg FLAGS_REG) (const_int 0)])
20567 (match_operand 2 "register_operand" "")
20568 (match_operand 3 "register_operand" "")))]
20569 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20570 && (GET_MODE (operands[0]) == HImode
20571 || (GET_MODE (operands[0]) == QImode
20572 && (TARGET_PROMOTE_QImode
20573 || optimize_insn_for_size_p ())))"
20574 [(set (match_dup 0)
20575 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20576 "operands[0] = gen_lowpart (SImode, operands[0]);
20577 operands[2] = gen_lowpart (SImode, operands[2]);
20578 operands[3] = gen_lowpart (SImode, operands[3]);")
20581 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20582 ;; transform a complex memory operation into two memory to register operations.
20584 ;; Don't push memory operands
20586 [(set (match_operand:SI 0 "push_operand" "")
20587 (match_operand:SI 1 "memory_operand" ""))
20588 (match_scratch:SI 2 "r")]
20589 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20590 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20591 [(set (match_dup 2) (match_dup 1))
20592 (set (match_dup 0) (match_dup 2))]
20596 [(set (match_operand:DI 0 "push_operand" "")
20597 (match_operand:DI 1 "memory_operand" ""))
20598 (match_scratch:DI 2 "r")]
20599 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20600 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20601 [(set (match_dup 2) (match_dup 1))
20602 (set (match_dup 0) (match_dup 2))]
20605 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20608 [(set (match_operand:SF 0 "push_operand" "")
20609 (match_operand:SF 1 "memory_operand" ""))
20610 (match_scratch:SF 2 "r")]
20611 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20612 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20613 [(set (match_dup 2) (match_dup 1))
20614 (set (match_dup 0) (match_dup 2))]
20618 [(set (match_operand:HI 0 "push_operand" "")
20619 (match_operand:HI 1 "memory_operand" ""))
20620 (match_scratch:HI 2 "r")]
20621 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20622 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20623 [(set (match_dup 2) (match_dup 1))
20624 (set (match_dup 0) (match_dup 2))]
20628 [(set (match_operand:QI 0 "push_operand" "")
20629 (match_operand:QI 1 "memory_operand" ""))
20630 (match_scratch:QI 2 "q")]
20631 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20632 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20633 [(set (match_dup 2) (match_dup 1))
20634 (set (match_dup 0) (match_dup 2))]
20637 ;; Don't move an immediate directly to memory when the instruction
20640 [(match_scratch:SI 1 "r")
20641 (set (match_operand:SI 0 "memory_operand" "")
20643 "optimize_insn_for_speed_p ()
20644 && ! TARGET_USE_MOV0
20645 && TARGET_SPLIT_LONG_MOVES
20646 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20647 && peep2_regno_dead_p (0, FLAGS_REG)"
20648 [(parallel [(set (match_dup 1) (const_int 0))
20649 (clobber (reg:CC FLAGS_REG))])
20650 (set (match_dup 0) (match_dup 1))]
20654 [(match_scratch:HI 1 "r")
20655 (set (match_operand:HI 0 "memory_operand" "")
20657 "optimize_insn_for_speed_p ()
20658 && ! TARGET_USE_MOV0
20659 && TARGET_SPLIT_LONG_MOVES
20660 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20661 && peep2_regno_dead_p (0, FLAGS_REG)"
20662 [(parallel [(set (match_dup 2) (const_int 0))
20663 (clobber (reg:CC FLAGS_REG))])
20664 (set (match_dup 0) (match_dup 1))]
20665 "operands[2] = gen_lowpart (SImode, operands[1]);")
20668 [(match_scratch:QI 1 "q")
20669 (set (match_operand:QI 0 "memory_operand" "")
20671 "optimize_insn_for_speed_p ()
20672 && ! TARGET_USE_MOV0
20673 && TARGET_SPLIT_LONG_MOVES
20674 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20675 && peep2_regno_dead_p (0, FLAGS_REG)"
20676 [(parallel [(set (match_dup 2) (const_int 0))
20677 (clobber (reg:CC FLAGS_REG))])
20678 (set (match_dup 0) (match_dup 1))]
20679 "operands[2] = gen_lowpart (SImode, operands[1]);")
20682 [(match_scratch:SI 2 "r")
20683 (set (match_operand:SI 0 "memory_operand" "")
20684 (match_operand:SI 1 "immediate_operand" ""))]
20685 "optimize_insn_for_speed_p ()
20686 && TARGET_SPLIT_LONG_MOVES
20687 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20688 [(set (match_dup 2) (match_dup 1))
20689 (set (match_dup 0) (match_dup 2))]
20693 [(match_scratch:HI 2 "r")
20694 (set (match_operand:HI 0 "memory_operand" "")
20695 (match_operand:HI 1 "immediate_operand" ""))]
20696 "optimize_insn_for_speed_p ()
20697 && TARGET_SPLIT_LONG_MOVES
20698 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20699 [(set (match_dup 2) (match_dup 1))
20700 (set (match_dup 0) (match_dup 2))]
20704 [(match_scratch:QI 2 "q")
20705 (set (match_operand:QI 0 "memory_operand" "")
20706 (match_operand:QI 1 "immediate_operand" ""))]
20707 "optimize_insn_for_speed_p ()
20708 && TARGET_SPLIT_LONG_MOVES
20709 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20710 [(set (match_dup 2) (match_dup 1))
20711 (set (match_dup 0) (match_dup 2))]
20714 ;; Don't compare memory with zero, load and use a test instead.
20716 [(set (match_operand 0 "flags_reg_operand" "")
20717 (match_operator 1 "compare_operator"
20718 [(match_operand:SI 2 "memory_operand" "")
20720 (match_scratch:SI 3 "r")]
20721 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20722 [(set (match_dup 3) (match_dup 2))
20723 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20726 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20727 ;; Don't split NOTs with a displacement operand, because resulting XOR
20728 ;; will not be pairable anyway.
20730 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20731 ;; represented using a modRM byte. The XOR replacement is long decoded,
20732 ;; so this split helps here as well.
20734 ;; Note: Can't do this as a regular split because we can't get proper
20735 ;; lifetime information then.
20738 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20739 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20740 "optimize_insn_for_speed_p ()
20741 && ((TARGET_NOT_UNPAIRABLE
20742 && (!MEM_P (operands[0])
20743 || !memory_displacement_operand (operands[0], SImode)))
20744 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20745 && peep2_regno_dead_p (0, FLAGS_REG)"
20746 [(parallel [(set (match_dup 0)
20747 (xor:SI (match_dup 1) (const_int -1)))
20748 (clobber (reg:CC FLAGS_REG))])]
20752 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20753 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20754 "optimize_insn_for_speed_p ()
20755 && ((TARGET_NOT_UNPAIRABLE
20756 && (!MEM_P (operands[0])
20757 || !memory_displacement_operand (operands[0], HImode)))
20758 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20759 && peep2_regno_dead_p (0, FLAGS_REG)"
20760 [(parallel [(set (match_dup 0)
20761 (xor:HI (match_dup 1) (const_int -1)))
20762 (clobber (reg:CC FLAGS_REG))])]
20766 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20767 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20768 "optimize_insn_for_speed_p ()
20769 && ((TARGET_NOT_UNPAIRABLE
20770 && (!MEM_P (operands[0])
20771 || !memory_displacement_operand (operands[0], QImode)))
20772 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20773 && peep2_regno_dead_p (0, FLAGS_REG)"
20774 [(parallel [(set (match_dup 0)
20775 (xor:QI (match_dup 1) (const_int -1)))
20776 (clobber (reg:CC FLAGS_REG))])]
20779 ;; Non pairable "test imm, reg" instructions can be translated to
20780 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20781 ;; byte opcode instead of two, have a short form for byte operands),
20782 ;; so do it for other CPUs as well. Given that the value was dead,
20783 ;; this should not create any new dependencies. Pass on the sub-word
20784 ;; versions if we're concerned about partial register stalls.
20787 [(set (match_operand 0 "flags_reg_operand" "")
20788 (match_operator 1 "compare_operator"
20789 [(and:SI (match_operand:SI 2 "register_operand" "")
20790 (match_operand:SI 3 "immediate_operand" ""))
20792 "ix86_match_ccmode (insn, CCNOmode)
20793 && (true_regnum (operands[2]) != AX_REG
20794 || satisfies_constraint_K (operands[3]))
20795 && peep2_reg_dead_p (1, operands[2])"
20797 [(set (match_dup 0)
20798 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20801 (and:SI (match_dup 2) (match_dup 3)))])]
20804 ;; We don't need to handle HImode case, because it will be promoted to SImode
20805 ;; on ! TARGET_PARTIAL_REG_STALL
20808 [(set (match_operand 0 "flags_reg_operand" "")
20809 (match_operator 1 "compare_operator"
20810 [(and:QI (match_operand:QI 2 "register_operand" "")
20811 (match_operand:QI 3 "immediate_operand" ""))
20813 "! TARGET_PARTIAL_REG_STALL
20814 && ix86_match_ccmode (insn, CCNOmode)
20815 && true_regnum (operands[2]) != AX_REG
20816 && peep2_reg_dead_p (1, operands[2])"
20818 [(set (match_dup 0)
20819 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20822 (and:QI (match_dup 2) (match_dup 3)))])]
20826 [(set (match_operand 0 "flags_reg_operand" "")
20827 (match_operator 1 "compare_operator"
20830 (match_operand 2 "ext_register_operand" "")
20833 (match_operand 3 "const_int_operand" ""))
20835 "! TARGET_PARTIAL_REG_STALL
20836 && ix86_match_ccmode (insn, CCNOmode)
20837 && true_regnum (operands[2]) != AX_REG
20838 && peep2_reg_dead_p (1, operands[2])"
20839 [(parallel [(set (match_dup 0)
20848 (set (zero_extract:SI (match_dup 2)
20859 ;; Don't do logical operations with memory inputs.
20861 [(match_scratch:SI 2 "r")
20862 (parallel [(set (match_operand:SI 0 "register_operand" "")
20863 (match_operator:SI 3 "arith_or_logical_operator"
20865 (match_operand:SI 1 "memory_operand" "")]))
20866 (clobber (reg:CC FLAGS_REG))])]
20867 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20868 [(set (match_dup 2) (match_dup 1))
20869 (parallel [(set (match_dup 0)
20870 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20871 (clobber (reg:CC FLAGS_REG))])]
20875 [(match_scratch:SI 2 "r")
20876 (parallel [(set (match_operand:SI 0 "register_operand" "")
20877 (match_operator:SI 3 "arith_or_logical_operator"
20878 [(match_operand:SI 1 "memory_operand" "")
20880 (clobber (reg:CC FLAGS_REG))])]
20881 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20882 [(set (match_dup 2) (match_dup 1))
20883 (parallel [(set (match_dup 0)
20884 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20885 (clobber (reg:CC FLAGS_REG))])]
20888 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20889 ;; refers to the destination of the load!
20892 [(set (match_operand:SI 0 "register_operand" "")
20893 (match_operand:SI 1 "register_operand" ""))
20894 (parallel [(set (match_dup 0)
20895 (match_operator:SI 3 "commutative_operator"
20897 (match_operand:SI 2 "memory_operand" "")]))
20898 (clobber (reg:CC FLAGS_REG))])]
20899 "REGNO (operands[0]) != REGNO (operands[1])
20900 && GENERAL_REGNO_P (REGNO (operands[0]))
20901 && GENERAL_REGNO_P (REGNO (operands[1]))"
20902 [(set (match_dup 0) (match_dup 4))
20903 (parallel [(set (match_dup 0)
20904 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20905 (clobber (reg:CC FLAGS_REG))])]
20906 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20909 [(set (match_operand 0 "register_operand" "")
20910 (match_operand 1 "register_operand" ""))
20912 (match_operator 3 "commutative_operator"
20914 (match_operand 2 "memory_operand" "")]))]
20915 "REGNO (operands[0]) != REGNO (operands[1])
20916 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20917 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20918 [(set (match_dup 0) (match_dup 2))
20920 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20923 ; Don't do logical operations with memory outputs
20925 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20926 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20927 ; the same decoder scheduling characteristics as the original.
20930 [(match_scratch:SI 2 "r")
20931 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20932 (match_operator:SI 3 "arith_or_logical_operator"
20934 (match_operand:SI 1 "nonmemory_operand" "")]))
20935 (clobber (reg:CC FLAGS_REG))])]
20936 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20937 [(set (match_dup 2) (match_dup 0))
20938 (parallel [(set (match_dup 2)
20939 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20940 (clobber (reg:CC FLAGS_REG))])
20941 (set (match_dup 0) (match_dup 2))]
20945 [(match_scratch:SI 2 "r")
20946 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20947 (match_operator:SI 3 "arith_or_logical_operator"
20948 [(match_operand:SI 1 "nonmemory_operand" "")
20950 (clobber (reg:CC FLAGS_REG))])]
20951 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20952 [(set (match_dup 2) (match_dup 0))
20953 (parallel [(set (match_dup 2)
20954 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20955 (clobber (reg:CC FLAGS_REG))])
20956 (set (match_dup 0) (match_dup 2))]
20959 ;; Attempt to always use XOR for zeroing registers.
20961 [(set (match_operand 0 "register_operand" "")
20962 (match_operand 1 "const0_operand" ""))]
20963 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20964 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20965 && GENERAL_REG_P (operands[0])
20966 && peep2_regno_dead_p (0, FLAGS_REG)"
20967 [(parallel [(set (match_dup 0) (const_int 0))
20968 (clobber (reg:CC FLAGS_REG))])]
20970 operands[0] = gen_lowpart (word_mode, operands[0]);
20974 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20976 "(GET_MODE (operands[0]) == QImode
20977 || GET_MODE (operands[0]) == HImode)
20978 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20979 && peep2_regno_dead_p (0, FLAGS_REG)"
20980 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20981 (clobber (reg:CC FLAGS_REG))])])
20983 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20985 [(set (match_operand 0 "register_operand" "")
20987 "(GET_MODE (operands[0]) == HImode
20988 || GET_MODE (operands[0]) == SImode
20989 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20990 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20991 && peep2_regno_dead_p (0, FLAGS_REG)"
20992 [(parallel [(set (match_dup 0) (const_int -1))
20993 (clobber (reg:CC FLAGS_REG))])]
20994 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20997 ;; Attempt to convert simple leas to adds. These can be created by
21000 [(set (match_operand:SI 0 "register_operand" "")
21001 (plus:SI (match_dup 0)
21002 (match_operand:SI 1 "nonmemory_operand" "")))]
21003 "peep2_regno_dead_p (0, FLAGS_REG)"
21004 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21005 (clobber (reg:CC FLAGS_REG))])]
21009 [(set (match_operand:SI 0 "register_operand" "")
21010 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21011 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21012 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21013 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21014 (clobber (reg:CC FLAGS_REG))])]
21015 "operands[2] = gen_lowpart (SImode, operands[2]);")
21018 [(set (match_operand:DI 0 "register_operand" "")
21019 (plus:DI (match_dup 0)
21020 (match_operand:DI 1 "x86_64_general_operand" "")))]
21021 "peep2_regno_dead_p (0, FLAGS_REG)"
21022 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21023 (clobber (reg:CC FLAGS_REG))])]
21027 [(set (match_operand:SI 0 "register_operand" "")
21028 (mult:SI (match_dup 0)
21029 (match_operand:SI 1 "const_int_operand" "")))]
21030 "exact_log2 (INTVAL (operands[1])) >= 0
21031 && peep2_regno_dead_p (0, FLAGS_REG)"
21032 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21033 (clobber (reg:CC FLAGS_REG))])]
21034 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21037 [(set (match_operand:DI 0 "register_operand" "")
21038 (mult:DI (match_dup 0)
21039 (match_operand:DI 1 "const_int_operand" "")))]
21040 "exact_log2 (INTVAL (operands[1])) >= 0
21041 && peep2_regno_dead_p (0, FLAGS_REG)"
21042 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21043 (clobber (reg:CC FLAGS_REG))])]
21044 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21047 [(set (match_operand:SI 0 "register_operand" "")
21048 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21049 (match_operand:DI 2 "const_int_operand" "")) 0))]
21050 "exact_log2 (INTVAL (operands[2])) >= 0
21051 && REGNO (operands[0]) == REGNO (operands[1])
21052 && peep2_regno_dead_p (0, FLAGS_REG)"
21053 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21054 (clobber (reg:CC FLAGS_REG))])]
21055 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21057 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
21058 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
21059 ;; many CPUs it is also faster, since special hardware to avoid esp
21060 ;; dependencies is present.
21062 ;; While some of these conversions may be done using splitters, we use peepholes
21063 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21065 ;; Convert prologue esp subtractions to push.
21066 ;; We need register to push. In order to keep verify_flow_info happy we have
21068 ;; - use scratch and clobber it in order to avoid dependencies
21069 ;; - use already live register
21070 ;; We can't use the second way right now, since there is no reliable way how to
21071 ;; verify that given register is live. First choice will also most likely in
21072 ;; fewer dependencies. On the place of esp adjustments it is very likely that
21073 ;; call clobbered registers are dead. We may want to use base pointer as an
21074 ;; alternative when no register is available later.
21077 [(match_scratch:SI 0 "r")
21078 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21079 (clobber (reg:CC FLAGS_REG))
21080 (clobber (mem:BLK (scratch)))])]
21081 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21082 [(clobber (match_dup 0))
21083 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21084 (clobber (mem:BLK (scratch)))])])
21087 [(match_scratch:SI 0 "r")
21088 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21089 (clobber (reg:CC FLAGS_REG))
21090 (clobber (mem:BLK (scratch)))])]
21091 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21092 [(clobber (match_dup 0))
21093 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21094 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21095 (clobber (mem:BLK (scratch)))])])
21097 ;; Convert esp subtractions to push.
21099 [(match_scratch:SI 0 "r")
21100 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21101 (clobber (reg:CC FLAGS_REG))])]
21102 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21103 [(clobber (match_dup 0))
21104 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21107 [(match_scratch:SI 0 "r")
21108 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21109 (clobber (reg:CC FLAGS_REG))])]
21110 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21111 [(clobber (match_dup 0))
21112 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21113 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21115 ;; Convert epilogue deallocator to pop.
21117 [(match_scratch:SI 0 "r")
21118 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21119 (clobber (reg:CC FLAGS_REG))
21120 (clobber (mem:BLK (scratch)))])]
21121 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21122 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21123 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21124 (clobber (mem:BLK (scratch)))])]
21127 ;; Two pops case is tricky, since pop causes dependency on destination register.
21128 ;; We use two registers if available.
21130 [(match_scratch:SI 0 "r")
21131 (match_scratch:SI 1 "r")
21132 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21133 (clobber (reg:CC FLAGS_REG))
21134 (clobber (mem:BLK (scratch)))])]
21135 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21136 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21137 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21138 (clobber (mem:BLK (scratch)))])
21139 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21140 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21144 [(match_scratch:SI 0 "r")
21145 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21146 (clobber (reg:CC FLAGS_REG))
21147 (clobber (mem:BLK (scratch)))])]
21148 "optimize_insn_for_size_p ()"
21149 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21150 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21151 (clobber (mem:BLK (scratch)))])
21152 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21153 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21156 ;; Convert esp additions to pop.
21158 [(match_scratch:SI 0 "r")
21159 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21160 (clobber (reg:CC FLAGS_REG))])]
21162 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21163 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21166 ;; Two pops case is tricky, since pop causes dependency on destination register.
21167 ;; We use two registers if available.
21169 [(match_scratch:SI 0 "r")
21170 (match_scratch:SI 1 "r")
21171 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21172 (clobber (reg:CC FLAGS_REG))])]
21174 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21175 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21176 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21177 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21181 [(match_scratch:SI 0 "r")
21182 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21183 (clobber (reg:CC FLAGS_REG))])]
21184 "optimize_insn_for_size_p ()"
21185 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21186 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21187 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21188 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21191 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21192 ;; required and register dies. Similarly for 128 to -128.
21194 [(set (match_operand 0 "flags_reg_operand" "")
21195 (match_operator 1 "compare_operator"
21196 [(match_operand 2 "register_operand" "")
21197 (match_operand 3 "const_int_operand" "")]))]
21198 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21199 && incdec_operand (operands[3], GET_MODE (operands[3])))
21200 || (!TARGET_FUSE_CMP_AND_BRANCH
21201 && INTVAL (operands[3]) == 128))
21202 && ix86_match_ccmode (insn, CCGCmode)
21203 && peep2_reg_dead_p (1, operands[2])"
21204 [(parallel [(set (match_dup 0)
21205 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21206 (clobber (match_dup 2))])]
21210 [(match_scratch:DI 0 "r")
21211 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21212 (clobber (reg:CC FLAGS_REG))
21213 (clobber (mem:BLK (scratch)))])]
21214 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21215 [(clobber (match_dup 0))
21216 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21217 (clobber (mem:BLK (scratch)))])])
21220 [(match_scratch:DI 0 "r")
21221 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21222 (clobber (reg:CC FLAGS_REG))
21223 (clobber (mem:BLK (scratch)))])]
21224 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21225 [(clobber (match_dup 0))
21226 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21227 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21228 (clobber (mem:BLK (scratch)))])])
21230 ;; Convert esp subtractions to push.
21232 [(match_scratch:DI 0 "r")
21233 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21234 (clobber (reg:CC FLAGS_REG))])]
21235 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21236 [(clobber (match_dup 0))
21237 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21240 [(match_scratch:DI 0 "r")
21241 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21242 (clobber (reg:CC FLAGS_REG))])]
21243 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21244 [(clobber (match_dup 0))
21245 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21246 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21248 ;; Convert epilogue deallocator to pop.
21250 [(match_scratch:DI 0 "r")
21251 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21252 (clobber (reg:CC FLAGS_REG))
21253 (clobber (mem:BLK (scratch)))])]
21254 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21255 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21256 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21257 (clobber (mem:BLK (scratch)))])]
21260 ;; Two pops case is tricky, since pop causes dependency on destination register.
21261 ;; We use two registers if available.
21263 [(match_scratch:DI 0 "r")
21264 (match_scratch:DI 1 "r")
21265 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21266 (clobber (reg:CC FLAGS_REG))
21267 (clobber (mem:BLK (scratch)))])]
21268 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21269 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21270 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21271 (clobber (mem:BLK (scratch)))])
21272 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21273 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21277 [(match_scratch:DI 0 "r")
21278 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21279 (clobber (reg:CC FLAGS_REG))
21280 (clobber (mem:BLK (scratch)))])]
21281 "optimize_insn_for_size_p ()"
21282 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21283 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21284 (clobber (mem:BLK (scratch)))])
21285 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21286 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21289 ;; Convert esp additions to pop.
21291 [(match_scratch:DI 0 "r")
21292 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21293 (clobber (reg:CC FLAGS_REG))])]
21295 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21296 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21299 ;; Two pops case is tricky, since pop causes dependency on destination register.
21300 ;; We use two registers if available.
21302 [(match_scratch:DI 0 "r")
21303 (match_scratch:DI 1 "r")
21304 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21305 (clobber (reg:CC FLAGS_REG))])]
21307 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21308 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21309 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21310 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21314 [(match_scratch:DI 0 "r")
21315 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21316 (clobber (reg:CC FLAGS_REG))])]
21317 "optimize_insn_for_size_p ()"
21318 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21319 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21320 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21321 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21324 ;; Convert imul by three, five and nine into lea
21327 [(set (match_operand:SI 0 "register_operand" "")
21328 (mult:SI (match_operand:SI 1 "register_operand" "")
21329 (match_operand:SI 2 "const_int_operand" "")))
21330 (clobber (reg:CC FLAGS_REG))])]
21331 "INTVAL (operands[2]) == 3
21332 || INTVAL (operands[2]) == 5
21333 || INTVAL (operands[2]) == 9"
21334 [(set (match_dup 0)
21335 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21337 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21341 [(set (match_operand:SI 0 "register_operand" "")
21342 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21343 (match_operand:SI 2 "const_int_operand" "")))
21344 (clobber (reg:CC FLAGS_REG))])]
21345 "optimize_insn_for_speed_p ()
21346 && (INTVAL (operands[2]) == 3
21347 || INTVAL (operands[2]) == 5
21348 || INTVAL (operands[2]) == 9)"
21349 [(set (match_dup 0) (match_dup 1))
21351 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21353 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21357 [(set (match_operand:DI 0 "register_operand" "")
21358 (mult:DI (match_operand:DI 1 "register_operand" "")
21359 (match_operand:DI 2 "const_int_operand" "")))
21360 (clobber (reg:CC FLAGS_REG))])]
21362 && (INTVAL (operands[2]) == 3
21363 || INTVAL (operands[2]) == 5
21364 || INTVAL (operands[2]) == 9)"
21365 [(set (match_dup 0)
21366 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21368 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21372 [(set (match_operand:DI 0 "register_operand" "")
21373 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21374 (match_operand:DI 2 "const_int_operand" "")))
21375 (clobber (reg:CC FLAGS_REG))])]
21377 && optimize_insn_for_speed_p ()
21378 && (INTVAL (operands[2]) == 3
21379 || INTVAL (operands[2]) == 5
21380 || INTVAL (operands[2]) == 9)"
21381 [(set (match_dup 0) (match_dup 1))
21383 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21385 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21387 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21388 ;; imul $32bit_imm, reg, reg is direct decoded.
21390 [(match_scratch:DI 3 "r")
21391 (parallel [(set (match_operand:DI 0 "register_operand" "")
21392 (mult:DI (match_operand:DI 1 "memory_operand" "")
21393 (match_operand:DI 2 "immediate_operand" "")))
21394 (clobber (reg:CC FLAGS_REG))])]
21395 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21396 && !satisfies_constraint_K (operands[2])"
21397 [(set (match_dup 3) (match_dup 1))
21398 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21399 (clobber (reg:CC FLAGS_REG))])]
21403 [(match_scratch:SI 3 "r")
21404 (parallel [(set (match_operand:SI 0 "register_operand" "")
21405 (mult:SI (match_operand:SI 1 "memory_operand" "")
21406 (match_operand:SI 2 "immediate_operand" "")))
21407 (clobber (reg:CC FLAGS_REG))])]
21408 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21409 && !satisfies_constraint_K (operands[2])"
21410 [(set (match_dup 3) (match_dup 1))
21411 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21412 (clobber (reg:CC FLAGS_REG))])]
21416 [(match_scratch:SI 3 "r")
21417 (parallel [(set (match_operand:DI 0 "register_operand" "")
21419 (mult:SI (match_operand:SI 1 "memory_operand" "")
21420 (match_operand:SI 2 "immediate_operand" ""))))
21421 (clobber (reg:CC FLAGS_REG))])]
21422 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21423 && !satisfies_constraint_K (operands[2])"
21424 [(set (match_dup 3) (match_dup 1))
21425 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21426 (clobber (reg:CC FLAGS_REG))])]
21429 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21430 ;; Convert it into imul reg, reg
21431 ;; It would be better to force assembler to encode instruction using long
21432 ;; immediate, but there is apparently no way to do so.
21434 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21435 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21436 (match_operand:DI 2 "const_int_operand" "")))
21437 (clobber (reg:CC FLAGS_REG))])
21438 (match_scratch:DI 3 "r")]
21439 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21440 && satisfies_constraint_K (operands[2])"
21441 [(set (match_dup 3) (match_dup 2))
21442 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21443 (clobber (reg:CC FLAGS_REG))])]
21445 if (!rtx_equal_p (operands[0], operands[1]))
21446 emit_move_insn (operands[0], operands[1]);
21450 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21451 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21452 (match_operand:SI 2 "const_int_operand" "")))
21453 (clobber (reg:CC FLAGS_REG))])
21454 (match_scratch:SI 3 "r")]
21455 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21456 && satisfies_constraint_K (operands[2])"
21457 [(set (match_dup 3) (match_dup 2))
21458 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21459 (clobber (reg:CC FLAGS_REG))])]
21461 if (!rtx_equal_p (operands[0], operands[1]))
21462 emit_move_insn (operands[0], operands[1]);
21466 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21467 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21468 (match_operand:HI 2 "immediate_operand" "")))
21469 (clobber (reg:CC FLAGS_REG))])
21470 (match_scratch:HI 3 "r")]
21471 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21472 [(set (match_dup 3) (match_dup 2))
21473 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21474 (clobber (reg:CC FLAGS_REG))])]
21476 if (!rtx_equal_p (operands[0], operands[1]))
21477 emit_move_insn (operands[0], operands[1]);
21480 ;; After splitting up read-modify operations, array accesses with memory
21481 ;; operands might end up in form:
21483 ;; movl 4(%esp), %edx
21485 ;; instead of pre-splitting:
21487 ;; addl 4(%esp), %eax
21489 ;; movl 4(%esp), %edx
21490 ;; leal (%edx,%eax,4), %eax
21493 [(parallel [(set (match_operand 0 "register_operand" "")
21494 (ashift (match_operand 1 "register_operand" "")
21495 (match_operand 2 "const_int_operand" "")))
21496 (clobber (reg:CC FLAGS_REG))])
21497 (set (match_operand 3 "register_operand")
21498 (match_operand 4 "x86_64_general_operand" ""))
21499 (parallel [(set (match_operand 5 "register_operand" "")
21500 (plus (match_operand 6 "register_operand" "")
21501 (match_operand 7 "register_operand" "")))
21502 (clobber (reg:CC FLAGS_REG))])]
21503 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21504 /* Validate MODE for lea. */
21505 && ((!TARGET_PARTIAL_REG_STALL
21506 && (GET_MODE (operands[0]) == QImode
21507 || GET_MODE (operands[0]) == HImode))
21508 || GET_MODE (operands[0]) == SImode
21509 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21510 /* We reorder load and the shift. */
21511 && !rtx_equal_p (operands[1], operands[3])
21512 && !reg_overlap_mentioned_p (operands[0], operands[4])
21513 /* Last PLUS must consist of operand 0 and 3. */
21514 && !rtx_equal_p (operands[0], operands[3])
21515 && (rtx_equal_p (operands[3], operands[6])
21516 || rtx_equal_p (operands[3], operands[7]))
21517 && (rtx_equal_p (operands[0], operands[6])
21518 || rtx_equal_p (operands[0], operands[7]))
21519 /* The intermediate operand 0 must die or be same as output. */
21520 && (rtx_equal_p (operands[0], operands[5])
21521 || peep2_reg_dead_p (3, operands[0]))"
21522 [(set (match_dup 3) (match_dup 4))
21523 (set (match_dup 0) (match_dup 1))]
21525 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21526 int scale = 1 << INTVAL (operands[2]);
21527 rtx index = gen_lowpart (Pmode, operands[1]);
21528 rtx base = gen_lowpart (Pmode, operands[3]);
21529 rtx dest = gen_lowpart (mode, operands[5]);
21531 operands[1] = gen_rtx_PLUS (Pmode, base,
21532 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21534 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21535 operands[0] = dest;
21538 ;; Call-value patterns last so that the wildcard operand does not
21539 ;; disrupt insn-recog's switch tables.
21541 (define_insn "*call_value_pop_0"
21542 [(set (match_operand 0 "" "")
21543 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21544 (match_operand:SI 2 "" "")))
21545 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21546 (match_operand:SI 3 "immediate_operand" "")))]
21549 if (SIBLING_CALL_P (insn))
21552 return "call\t%P1";
21554 [(set_attr "type" "callv")])
21556 (define_insn "*call_value_pop_1"
21557 [(set (match_operand 0 "" "")
21558 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21559 (match_operand:SI 2 "" "")))
21560 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21561 (match_operand:SI 3 "immediate_operand" "i")))]
21564 if (constant_call_address_operand (operands[1], Pmode))
21566 if (SIBLING_CALL_P (insn))
21569 return "call\t%P1";
21571 if (SIBLING_CALL_P (insn))
21574 return "call\t%A1";
21576 [(set_attr "type" "callv")])
21578 (define_insn "*call_value_0"
21579 [(set (match_operand 0 "" "")
21580 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21581 (match_operand:SI 2 "" "")))]
21584 if (SIBLING_CALL_P (insn))
21587 return "call\t%P1";
21589 [(set_attr "type" "callv")])
21591 (define_insn "*call_value_0_rex64"
21592 [(set (match_operand 0 "" "")
21593 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21594 (match_operand:DI 2 "const_int_operand" "")))]
21597 if (SIBLING_CALL_P (insn))
21600 return "call\t%P1";
21602 [(set_attr "type" "callv")])
21604 (define_insn "*call_value_0_rex64_ms_sysv"
21605 [(set (match_operand 0 "" "")
21606 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21607 (match_operand:DI 2 "const_int_operand" "")))
21608 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21609 (clobber (reg:TI XMM6_REG))
21610 (clobber (reg:TI XMM7_REG))
21611 (clobber (reg:TI XMM8_REG))
21612 (clobber (reg:TI XMM9_REG))
21613 (clobber (reg:TI XMM10_REG))
21614 (clobber (reg:TI XMM11_REG))
21615 (clobber (reg:TI XMM12_REG))
21616 (clobber (reg:TI XMM13_REG))
21617 (clobber (reg:TI XMM14_REG))
21618 (clobber (reg:TI XMM15_REG))
21619 (clobber (reg:DI SI_REG))
21620 (clobber (reg:DI DI_REG))]
21621 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21623 if (SIBLING_CALL_P (insn))
21626 return "call\t%P1";
21628 [(set_attr "type" "callv")])
21630 (define_insn "*call_value_1"
21631 [(set (match_operand 0 "" "")
21632 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21633 (match_operand:SI 2 "" "")))]
21634 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21636 if (constant_call_address_operand (operands[1], Pmode))
21637 return "call\t%P1";
21638 return "call\t%A1";
21640 [(set_attr "type" "callv")])
21642 (define_insn "*sibcall_value_1"
21643 [(set (match_operand 0 "" "")
21644 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21645 (match_operand:SI 2 "" "")))]
21646 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21648 if (constant_call_address_operand (operands[1], Pmode))
21652 [(set_attr "type" "callv")])
21654 (define_insn "*call_value_1_rex64"
21655 [(set (match_operand 0 "" "")
21656 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21657 (match_operand:DI 2 "" "")))]
21658 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21659 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21661 if (constant_call_address_operand (operands[1], Pmode))
21662 return "call\t%P1";
21663 return "call\t%A1";
21665 [(set_attr "type" "callv")])
21667 (define_insn "*call_value_1_rex64_ms_sysv"
21668 [(set (match_operand 0 "" "")
21669 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21670 (match_operand:DI 2 "" "")))
21671 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21672 (clobber (reg:TI 27))
21673 (clobber (reg:TI 28))
21674 (clobber (reg:TI 45))
21675 (clobber (reg:TI 46))
21676 (clobber (reg:TI 47))
21677 (clobber (reg:TI 48))
21678 (clobber (reg:TI 49))
21679 (clobber (reg:TI 50))
21680 (clobber (reg:TI 51))
21681 (clobber (reg:TI 52))
21682 (clobber (reg:DI SI_REG))
21683 (clobber (reg:DI DI_REG))]
21684 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21686 if (constant_call_address_operand (operands[1], Pmode))
21687 return "call\t%P1";
21688 return "call\t%A1";
21690 [(set_attr "type" "callv")])
21692 (define_insn "*call_value_1_rex64_large"
21693 [(set (match_operand 0 "" "")
21694 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21695 (match_operand:DI 2 "" "")))]
21696 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21698 [(set_attr "type" "callv")])
21700 (define_insn "*sibcall_value_1_rex64"
21701 [(set (match_operand 0 "" "")
21702 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21703 (match_operand:DI 2 "" "")))]
21704 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21706 [(set_attr "type" "callv")])
21708 (define_insn "*sibcall_value_1_rex64_v"
21709 [(set (match_operand 0 "" "")
21710 (call (mem:QI (reg:DI R11_REG))
21711 (match_operand:DI 1 "" "")))]
21712 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21714 [(set_attr "type" "callv")])
21716 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21717 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21718 ;; caught for use by garbage collectors and the like. Using an insn that
21719 ;; maps to SIGILL makes it more likely the program will rightfully die.
21720 ;; Keeping with tradition, "6" is in honor of #UD.
21721 (define_insn "trap"
21722 [(trap_if (const_int 1) (const_int 6))]
21724 { return ASM_SHORT "0x0b0f"; }
21725 [(set_attr "length" "2")])
21727 (define_expand "sse_prologue_save"
21728 [(parallel [(set (match_operand:BLK 0 "" "")
21729 (unspec:BLK [(reg:DI 21)
21736 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21737 (use (match_operand:DI 1 "register_operand" ""))
21738 (use (match_operand:DI 2 "immediate_operand" ""))
21739 (use (label_ref:DI (match_operand 3 "" "")))])]
21743 (define_insn "*sse_prologue_save_insn"
21744 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21745 (match_operand:DI 4 "const_int_operand" "n")))
21746 (unspec:BLK [(reg:DI 21)
21753 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21754 (use (match_operand:DI 1 "register_operand" "r"))
21755 (use (match_operand:DI 2 "const_int_operand" "i"))
21756 (use (label_ref:DI (match_operand 3 "" "X")))]
21758 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21759 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21762 operands[0] = gen_rtx_MEM (Pmode,
21763 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21764 /* VEX instruction with a REX prefix will #UD. */
21765 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21766 gcc_unreachable ();
21768 output_asm_insn ("jmp\t%A1", operands);
21769 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21771 operands[4] = adjust_address (operands[0], DImode, i*16);
21772 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21773 PUT_MODE (operands[4], TImode);
21774 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21775 output_asm_insn ("rex", operands);
21776 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21778 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21779 CODE_LABEL_NUMBER (operands[3]));
21782 [(set_attr "type" "other")
21783 (set_attr "length_immediate" "0")
21784 (set_attr "length_address" "0")
21785 (set (attr "length")
21787 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21788 (const_string "34")
21789 (const_string "42")))
21790 (set_attr "memory" "store")
21791 (set_attr "modrm" "0")
21792 (set_attr "prefix" "maybe_vex")
21793 (set_attr "mode" "DI")])
21795 (define_expand "prefetch"
21796 [(prefetch (match_operand 0 "address_operand" "")
21797 (match_operand:SI 1 "const_int_operand" "")
21798 (match_operand:SI 2 "const_int_operand" ""))]
21799 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21801 int rw = INTVAL (operands[1]);
21802 int locality = INTVAL (operands[2]);
21804 gcc_assert (rw == 0 || rw == 1);
21805 gcc_assert (locality >= 0 && locality <= 3);
21806 gcc_assert (GET_MODE (operands[0]) == Pmode
21807 || GET_MODE (operands[0]) == VOIDmode);
21809 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21810 supported by SSE counterpart or the SSE prefetch is not available
21811 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21813 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21814 operands[2] = GEN_INT (3);
21816 operands[1] = const0_rtx;
21819 (define_insn "*prefetch_sse"
21820 [(prefetch (match_operand:SI 0 "address_operand" "p")
21822 (match_operand:SI 1 "const_int_operand" ""))]
21823 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21825 static const char * const patterns[4] = {
21826 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21829 int locality = INTVAL (operands[1]);
21830 gcc_assert (locality >= 0 && locality <= 3);
21832 return patterns[locality];
21834 [(set_attr "type" "sse")
21835 (set_attr "atom_sse_attr" "prefetch")
21836 (set_attr "memory" "none")])
21838 (define_insn "*prefetch_sse_rex"
21839 [(prefetch (match_operand:DI 0 "address_operand" "p")
21841 (match_operand:SI 1 "const_int_operand" ""))]
21842 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21844 static const char * const patterns[4] = {
21845 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21848 int locality = INTVAL (operands[1]);
21849 gcc_assert (locality >= 0 && locality <= 3);
21851 return patterns[locality];
21853 [(set_attr "type" "sse")
21854 (set_attr "atom_sse_attr" "prefetch")
21855 (set_attr "memory" "none")])
21857 (define_insn "*prefetch_3dnow"
21858 [(prefetch (match_operand:SI 0 "address_operand" "p")
21859 (match_operand:SI 1 "const_int_operand" "n")
21861 "TARGET_3DNOW && !TARGET_64BIT"
21863 if (INTVAL (operands[1]) == 0)
21864 return "prefetch\t%a0";
21866 return "prefetchw\t%a0";
21868 [(set_attr "type" "mmx")
21869 (set_attr "memory" "none")])
21871 (define_insn "*prefetch_3dnow_rex"
21872 [(prefetch (match_operand:DI 0 "address_operand" "p")
21873 (match_operand:SI 1 "const_int_operand" "n")
21875 "TARGET_3DNOW && TARGET_64BIT"
21877 if (INTVAL (operands[1]) == 0)
21878 return "prefetch\t%a0";
21880 return "prefetchw\t%a0";
21882 [(set_attr "type" "mmx")
21883 (set_attr "memory" "none")])
21885 (define_expand "stack_protect_set"
21886 [(match_operand 0 "memory_operand" "")
21887 (match_operand 1 "memory_operand" "")]
21890 #ifdef TARGET_THREAD_SSP_OFFSET
21892 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21893 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21895 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21896 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21899 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21901 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21906 (define_insn "stack_protect_set_si"
21907 [(set (match_operand:SI 0 "memory_operand" "=m")
21908 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21909 (set (match_scratch:SI 2 "=&r") (const_int 0))
21910 (clobber (reg:CC FLAGS_REG))]
21912 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21913 [(set_attr "type" "multi")])
21915 (define_insn "stack_protect_set_di"
21916 [(set (match_operand:DI 0 "memory_operand" "=m")
21917 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21918 (set (match_scratch:DI 2 "=&r") (const_int 0))
21919 (clobber (reg:CC FLAGS_REG))]
21921 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21922 [(set_attr "type" "multi")])
21924 (define_insn "stack_tls_protect_set_si"
21925 [(set (match_operand:SI 0 "memory_operand" "=m")
21926 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21927 (set (match_scratch:SI 2 "=&r") (const_int 0))
21928 (clobber (reg:CC FLAGS_REG))]
21930 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21931 [(set_attr "type" "multi")])
21933 (define_insn "stack_tls_protect_set_di"
21934 [(set (match_operand:DI 0 "memory_operand" "=m")
21935 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21936 (set (match_scratch:DI 2 "=&r") (const_int 0))
21937 (clobber (reg:CC FLAGS_REG))]
21940 /* The kernel uses a different segment register for performance reasons; a
21941 system call would not have to trash the userspace segment register,
21942 which would be expensive */
21943 if (ix86_cmodel != CM_KERNEL)
21944 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21946 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21948 [(set_attr "type" "multi")])
21950 (define_expand "stack_protect_test"
21951 [(match_operand 0 "memory_operand" "")
21952 (match_operand 1 "memory_operand" "")
21953 (match_operand 2 "" "")]
21956 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21958 #ifdef TARGET_THREAD_SSP_OFFSET
21960 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21961 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21963 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21964 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21967 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21969 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21972 ix86_compare_op0 = flags;
21973 ix86_compare_op1 = const0_rtx;
21974 emit_jump_insn (gen_beq (operands[2]));
21978 (define_insn "stack_protect_test_si"
21979 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21980 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21981 (match_operand:SI 2 "memory_operand" "m")]
21983 (clobber (match_scratch:SI 3 "=&r"))]
21985 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21986 [(set_attr "type" "multi")])
21988 (define_insn "stack_protect_test_di"
21989 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21990 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21991 (match_operand:DI 2 "memory_operand" "m")]
21993 (clobber (match_scratch:DI 3 "=&r"))]
21995 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21996 [(set_attr "type" "multi")])
21998 (define_insn "stack_tls_protect_test_si"
21999 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22000 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22001 (match_operand:SI 2 "const_int_operand" "i")]
22002 UNSPEC_SP_TLS_TEST))
22003 (clobber (match_scratch:SI 3 "=r"))]
22005 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22006 [(set_attr "type" "multi")])
22008 (define_insn "stack_tls_protect_test_di"
22009 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22010 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22011 (match_operand:DI 2 "const_int_operand" "i")]
22012 UNSPEC_SP_TLS_TEST))
22013 (clobber (match_scratch:DI 3 "=r"))]
22016 /* The kernel uses a different segment register for performance reasons; a
22017 system call would not have to trash the userspace segment register,
22018 which would be expensive */
22019 if (ix86_cmodel != CM_KERNEL)
22020 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22022 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22024 [(set_attr "type" "multi")])
22026 (define_mode_iterator CRC32MODE [QI HI SI])
22027 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22028 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22030 (define_insn "sse4_2_crc32<mode>"
22031 [(set (match_operand:SI 0 "register_operand" "=r")
22033 [(match_operand:SI 1 "register_operand" "0")
22034 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22037 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22038 [(set_attr "type" "sselog1")
22039 (set_attr "prefix_rep" "1")
22040 (set_attr "prefix_extra" "1")
22041 (set_attr "mode" "SI")])
22043 (define_insn "sse4_2_crc32di"
22044 [(set (match_operand:DI 0 "register_operand" "=r")
22046 [(match_operand:DI 1 "register_operand" "0")
22047 (match_operand:DI 2 "nonimmediate_operand" "rm")]
22049 "TARGET_SSE4_2 && TARGET_64BIT"
22050 "crc32q\t{%2, %0|%0, %2}"
22051 [(set_attr "type" "sselog1")
22052 (set_attr "prefix_rep" "1")
22053 (set_attr "prefix_extra" "1")
22054 (set_attr "mode" "DI")])
22058 (include "sync.md")