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,
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 ;; Describe a user's asm statement.
616 (define_asm_attributes
617 [(set_attr "length" "128")
618 (set_attr "type" "multi")])
620 ;; All integer comparison codes.
621 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
623 ;; All floating-point comparison codes.
624 (define_code_iterator fp_cond [unordered ordered
625 uneq unge ungt unle unlt ltgt ])
627 (define_code_iterator plusminus [plus minus])
629 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
631 ;; Base name for define_insn
632 (define_code_attr plusminus_insn
633 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
634 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
636 ;; Base name for insn mnemonic.
637 (define_code_attr plusminus_mnemonic
638 [(plus "add") (ss_plus "adds") (us_plus "addus")
639 (minus "sub") (ss_minus "subs") (us_minus "subus")])
641 ;; Mark commutative operators as such in constraints.
642 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
643 (minus "") (ss_minus "") (us_minus "")])
645 ;; Mapping of signed max and min
646 (define_code_iterator smaxmin [smax smin])
648 ;; Mapping of unsigned max and min
649 (define_code_iterator umaxmin [umax umin])
651 ;; Mapping of signed/unsigned max and min
652 (define_code_iterator maxmin [smax smin umax umin])
654 ;; Base name for integer and FP insn mnemonic
655 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
656 (umax "maxu") (umin "minu")])
657 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
659 ;; Mapping of parallel logic operators
660 (define_code_iterator plogic [and ior xor])
662 ;; Base name for insn mnemonic.
663 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
665 ;; Mapping of abs neg operators
666 (define_code_iterator absneg [abs neg])
668 ;; Base name for x87 insn mnemonic.
669 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
671 ;; All single word integer modes.
672 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
674 ;; Single word integer modes without QImode.
675 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
677 ;; Instruction suffix for integer modes.
678 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
680 ;; Register class for integer modes.
681 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
683 ;; Immediate operand constraint for integer modes.
684 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
686 ;; General operand predicate for integer modes.
687 (define_mode_attr general_operand
688 [(QI "general_operand")
689 (HI "general_operand")
690 (SI "general_operand")
691 (DI "x86_64_general_operand")])
693 ;; SSE and x87 SFmode and DFmode floating point modes
694 (define_mode_iterator MODEF [SF DF])
696 ;; All x87 floating point modes
697 (define_mode_iterator X87MODEF [SF DF XF])
699 ;; All integer modes handled by x87 fisttp operator.
700 (define_mode_iterator X87MODEI [HI SI DI])
702 ;; All integer modes handled by integer x87 operators.
703 (define_mode_iterator X87MODEI12 [HI SI])
705 ;; All integer modes handled by SSE cvtts?2si* operators.
706 (define_mode_iterator SSEMODEI24 [SI DI])
708 ;; SSE asm suffix for floating point modes
709 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
711 ;; SSE vector mode corresponding to a scalar mode
712 (define_mode_attr ssevecmode
713 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
715 ;; Instruction suffix for REX 64bit operators.
716 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
718 ;; This mode iterator allows :P to be used for patterns that operate on
719 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
720 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
723 ;; Scheduling descriptions
725 (include "pentium.md")
728 (include "athlon.md")
732 ;; Operand and operator predicates and constraints
734 (include "predicates.md")
735 (include "constraints.md")
738 ;; Compare instructions.
740 ;; All compare insns have expanders that save the operands away without
741 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
742 ;; after the cmp) will actually emit the cmpM.
744 (define_expand "cmpti"
745 [(set (reg:CC FLAGS_REG)
746 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
747 (match_operand:TI 1 "x86_64_general_operand" "")))]
750 if (MEM_P (operands[0]) && MEM_P (operands[1]))
751 operands[0] = force_reg (TImode, operands[0]);
752 ix86_compare_op0 = operands[0];
753 ix86_compare_op1 = operands[1];
757 (define_expand "cmpdi"
758 [(set (reg:CC FLAGS_REG)
759 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
760 (match_operand:DI 1 "x86_64_general_operand" "")))]
763 if (MEM_P (operands[0]) && MEM_P (operands[1]))
764 operands[0] = force_reg (DImode, operands[0]);
765 ix86_compare_op0 = operands[0];
766 ix86_compare_op1 = operands[1];
770 (define_expand "cmpsi"
771 [(set (reg:CC FLAGS_REG)
772 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
773 (match_operand:SI 1 "general_operand" "")))]
776 if (MEM_P (operands[0]) && MEM_P (operands[1]))
777 operands[0] = force_reg (SImode, operands[0]);
778 ix86_compare_op0 = operands[0];
779 ix86_compare_op1 = operands[1];
783 (define_expand "cmphi"
784 [(set (reg:CC FLAGS_REG)
785 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
786 (match_operand:HI 1 "general_operand" "")))]
789 if (MEM_P (operands[0]) && MEM_P (operands[1]))
790 operands[0] = force_reg (HImode, operands[0]);
791 ix86_compare_op0 = operands[0];
792 ix86_compare_op1 = operands[1];
796 (define_expand "cmpqi"
797 [(set (reg:CC FLAGS_REG)
798 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
799 (match_operand:QI 1 "general_operand" "")))]
802 if (MEM_P (operands[0]) && MEM_P (operands[1]))
803 operands[0] = force_reg (QImode, operands[0]);
804 ix86_compare_op0 = operands[0];
805 ix86_compare_op1 = operands[1];
809 (define_insn "cmpdi_ccno_1_rex64"
810 [(set (reg FLAGS_REG)
811 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
812 (match_operand:DI 1 "const0_operand" "")))]
813 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
816 cmp{q}\t{%1, %0|%0, %1}"
817 [(set_attr "type" "test,icmp")
818 (set_attr "length_immediate" "0,1")
819 (set_attr "mode" "DI")])
821 (define_insn "*cmpdi_minus_1_rex64"
822 [(set (reg FLAGS_REG)
823 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
824 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
826 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
827 "cmp{q}\t{%1, %0|%0, %1}"
828 [(set_attr "type" "icmp")
829 (set_attr "mode" "DI")])
831 (define_expand "cmpdi_1_rex64"
832 [(set (reg:CC FLAGS_REG)
833 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
834 (match_operand:DI 1 "general_operand" "")))]
838 (define_insn "cmpdi_1_insn_rex64"
839 [(set (reg FLAGS_REG)
840 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
841 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
842 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
843 "cmp{q}\t{%1, %0|%0, %1}"
844 [(set_attr "type" "icmp")
845 (set_attr "mode" "DI")])
848 (define_insn "*cmpsi_ccno_1"
849 [(set (reg FLAGS_REG)
850 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
851 (match_operand:SI 1 "const0_operand" "")))]
852 "ix86_match_ccmode (insn, CCNOmode)"
855 cmp{l}\t{%1, %0|%0, %1}"
856 [(set_attr "type" "test,icmp")
857 (set_attr "length_immediate" "0,1")
858 (set_attr "mode" "SI")])
860 (define_insn "*cmpsi_minus_1"
861 [(set (reg FLAGS_REG)
862 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
863 (match_operand:SI 1 "general_operand" "ri,mr"))
865 "ix86_match_ccmode (insn, CCGOCmode)"
866 "cmp{l}\t{%1, %0|%0, %1}"
867 [(set_attr "type" "icmp")
868 (set_attr "mode" "SI")])
870 (define_expand "cmpsi_1"
871 [(set (reg:CC FLAGS_REG)
872 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
873 (match_operand:SI 1 "general_operand" "")))]
877 (define_insn "*cmpsi_1_insn"
878 [(set (reg FLAGS_REG)
879 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
880 (match_operand:SI 1 "general_operand" "ri,mr")))]
881 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
882 && ix86_match_ccmode (insn, CCmode)"
883 "cmp{l}\t{%1, %0|%0, %1}"
884 [(set_attr "type" "icmp")
885 (set_attr "mode" "SI")])
887 (define_insn "*cmphi_ccno_1"
888 [(set (reg FLAGS_REG)
889 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
890 (match_operand:HI 1 "const0_operand" "")))]
891 "ix86_match_ccmode (insn, CCNOmode)"
894 cmp{w}\t{%1, %0|%0, %1}"
895 [(set_attr "type" "test,icmp")
896 (set_attr "length_immediate" "0,1")
897 (set_attr "mode" "HI")])
899 (define_insn "*cmphi_minus_1"
900 [(set (reg FLAGS_REG)
901 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
902 (match_operand:HI 1 "general_operand" "rn,mr"))
904 "ix86_match_ccmode (insn, CCGOCmode)"
905 "cmp{w}\t{%1, %0|%0, %1}"
906 [(set_attr "type" "icmp")
907 (set_attr "mode" "HI")])
909 (define_insn "*cmphi_1"
910 [(set (reg FLAGS_REG)
911 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
912 (match_operand:HI 1 "general_operand" "rn,mr")))]
913 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
914 && ix86_match_ccmode (insn, CCmode)"
915 "cmp{w}\t{%1, %0|%0, %1}"
916 [(set_attr "type" "icmp")
917 (set_attr "mode" "HI")])
919 (define_insn "*cmpqi_ccno_1"
920 [(set (reg FLAGS_REG)
921 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
922 (match_operand:QI 1 "const0_operand" "")))]
923 "ix86_match_ccmode (insn, CCNOmode)"
926 cmp{b}\t{$0, %0|%0, 0}"
927 [(set_attr "type" "test,icmp")
928 (set_attr "length_immediate" "0,1")
929 (set_attr "mode" "QI")])
931 (define_insn "*cmpqi_1"
932 [(set (reg FLAGS_REG)
933 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
934 (match_operand:QI 1 "general_operand" "qn,mq")))]
935 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
936 && ix86_match_ccmode (insn, CCmode)"
937 "cmp{b}\t{%1, %0|%0, %1}"
938 [(set_attr "type" "icmp")
939 (set_attr "mode" "QI")])
941 (define_insn "*cmpqi_minus_1"
942 [(set (reg FLAGS_REG)
943 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
944 (match_operand:QI 1 "general_operand" "qn,mq"))
946 "ix86_match_ccmode (insn, CCGOCmode)"
947 "cmp{b}\t{%1, %0|%0, %1}"
948 [(set_attr "type" "icmp")
949 (set_attr "mode" "QI")])
951 (define_insn "*cmpqi_ext_1"
952 [(set (reg FLAGS_REG)
954 (match_operand:QI 0 "general_operand" "Qm")
957 (match_operand 1 "ext_register_operand" "Q")
960 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
961 "cmp{b}\t{%h1, %0|%0, %h1}"
962 [(set_attr "type" "icmp")
963 (set_attr "mode" "QI")])
965 (define_insn "*cmpqi_ext_1_rex64"
966 [(set (reg FLAGS_REG)
968 (match_operand:QI 0 "register_operand" "Q")
971 (match_operand 1 "ext_register_operand" "Q")
974 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
975 "cmp{b}\t{%h1, %0|%0, %h1}"
976 [(set_attr "type" "icmp")
977 (set_attr "mode" "QI")])
979 (define_insn "*cmpqi_ext_2"
980 [(set (reg FLAGS_REG)
984 (match_operand 0 "ext_register_operand" "Q")
987 (match_operand:QI 1 "const0_operand" "")))]
988 "ix86_match_ccmode (insn, CCNOmode)"
990 [(set_attr "type" "test")
991 (set_attr "length_immediate" "0")
992 (set_attr "mode" "QI")])
994 (define_expand "cmpqi_ext_3"
995 [(set (reg:CC FLAGS_REG)
999 (match_operand 0 "ext_register_operand" "")
1002 (match_operand:QI 1 "general_operand" "")))]
1006 (define_insn "cmpqi_ext_3_insn"
1007 [(set (reg FLAGS_REG)
1011 (match_operand 0 "ext_register_operand" "Q")
1014 (match_operand:QI 1 "general_operand" "Qmn")))]
1015 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1016 "cmp{b}\t{%1, %h0|%h0, %1}"
1017 [(set_attr "type" "icmp")
1018 (set_attr "mode" "QI")])
1020 (define_insn "cmpqi_ext_3_insn_rex64"
1021 [(set (reg FLAGS_REG)
1025 (match_operand 0 "ext_register_operand" "Q")
1028 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1029 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1030 "cmp{b}\t{%1, %h0|%h0, %1}"
1031 [(set_attr "type" "icmp")
1032 (set_attr "mode" "QI")])
1034 (define_insn "*cmpqi_ext_4"
1035 [(set (reg FLAGS_REG)
1039 (match_operand 0 "ext_register_operand" "Q")
1044 (match_operand 1 "ext_register_operand" "Q")
1046 (const_int 8)) 0)))]
1047 "ix86_match_ccmode (insn, CCmode)"
1048 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1049 [(set_attr "type" "icmp")
1050 (set_attr "mode" "QI")])
1052 ;; These implement float point compares.
1053 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1054 ;; which would allow mix and match FP modes on the compares. Which is what
1055 ;; the old patterns did, but with many more of them.
1057 (define_expand "cmpxf"
1058 [(set (reg:CC FLAGS_REG)
1059 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1060 (match_operand:XF 1 "nonmemory_operand" "")))]
1063 ix86_compare_op0 = operands[0];
1064 ix86_compare_op1 = operands[1];
1068 (define_expand "cmp<mode>"
1069 [(set (reg:CC FLAGS_REG)
1070 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1071 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1072 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1074 ix86_compare_op0 = operands[0];
1075 ix86_compare_op1 = operands[1];
1079 ;; FP compares, step 1:
1080 ;; Set the FP condition codes.
1082 ;; CCFPmode compare with exceptions
1083 ;; CCFPUmode compare with no exceptions
1085 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1086 ;; used to manage the reg stack popping would not be preserved.
1088 (define_insn "*cmpfp_0"
1089 [(set (match_operand:HI 0 "register_operand" "=a")
1092 (match_operand 1 "register_operand" "f")
1093 (match_operand 2 "const0_operand" ""))]
1095 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1097 "* return output_fp_compare (insn, operands, 0, 0);"
1098 [(set_attr "type" "multi")
1099 (set_attr "unit" "i387")
1101 (cond [(match_operand:SF 1 "" "")
1103 (match_operand:DF 1 "" "")
1106 (const_string "XF")))])
1108 (define_insn_and_split "*cmpfp_0_cc"
1109 [(set (reg:CCFP FLAGS_REG)
1111 (match_operand 1 "register_operand" "f")
1112 (match_operand 2 "const0_operand" "")))
1113 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1114 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1115 && TARGET_SAHF && !TARGET_CMOVE
1116 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1118 "&& reload_completed"
1121 [(compare:CCFP (match_dup 1)(match_dup 2))]
1123 (set (reg:CC FLAGS_REG)
1124 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1126 [(set_attr "type" "multi")
1127 (set_attr "unit" "i387")
1129 (cond [(match_operand:SF 1 "" "")
1131 (match_operand:DF 1 "" "")
1134 (const_string "XF")))])
1136 (define_insn "*cmpfp_xf"
1137 [(set (match_operand:HI 0 "register_operand" "=a")
1140 (match_operand:XF 1 "register_operand" "f")
1141 (match_operand:XF 2 "register_operand" "f"))]
1144 "* return output_fp_compare (insn, operands, 0, 0);"
1145 [(set_attr "type" "multi")
1146 (set_attr "unit" "i387")
1147 (set_attr "mode" "XF")])
1149 (define_insn_and_split "*cmpfp_xf_cc"
1150 [(set (reg:CCFP FLAGS_REG)
1152 (match_operand:XF 1 "register_operand" "f")
1153 (match_operand:XF 2 "register_operand" "f")))
1154 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1156 && TARGET_SAHF && !TARGET_CMOVE"
1158 "&& reload_completed"
1161 [(compare:CCFP (match_dup 1)(match_dup 2))]
1163 (set (reg:CC FLAGS_REG)
1164 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1166 [(set_attr "type" "multi")
1167 (set_attr "unit" "i387")
1168 (set_attr "mode" "XF")])
1170 (define_insn "*cmpfp_<mode>"
1171 [(set (match_operand:HI 0 "register_operand" "=a")
1174 (match_operand:MODEF 1 "register_operand" "f")
1175 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1178 "* return output_fp_compare (insn, operands, 0, 0);"
1179 [(set_attr "type" "multi")
1180 (set_attr "unit" "i387")
1181 (set_attr "mode" "<MODE>")])
1183 (define_insn_and_split "*cmpfp_<mode>_cc"
1184 [(set (reg:CCFP FLAGS_REG)
1186 (match_operand:MODEF 1 "register_operand" "f")
1187 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1188 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1190 && TARGET_SAHF && !TARGET_CMOVE"
1192 "&& reload_completed"
1195 [(compare:CCFP (match_dup 1)(match_dup 2))]
1197 (set (reg:CC FLAGS_REG)
1198 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1200 [(set_attr "type" "multi")
1201 (set_attr "unit" "i387")
1202 (set_attr "mode" "<MODE>")])
1204 (define_insn "*cmpfp_u"
1205 [(set (match_operand:HI 0 "register_operand" "=a")
1208 (match_operand 1 "register_operand" "f")
1209 (match_operand 2 "register_operand" "f"))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213 "* return output_fp_compare (insn, operands, 0, 1);"
1214 [(set_attr "type" "multi")
1215 (set_attr "unit" "i387")
1217 (cond [(match_operand:SF 1 "" "")
1219 (match_operand:DF 1 "" "")
1222 (const_string "XF")))])
1224 (define_insn_and_split "*cmpfp_u_cc"
1225 [(set (reg:CCFPU FLAGS_REG)
1227 (match_operand 1 "register_operand" "f")
1228 (match_operand 2 "register_operand" "f")))
1229 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231 && TARGET_SAHF && !TARGET_CMOVE
1232 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1234 "&& reload_completed"
1237 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1239 (set (reg:CC FLAGS_REG)
1240 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1242 [(set_attr "type" "multi")
1243 (set_attr "unit" "i387")
1245 (cond [(match_operand:SF 1 "" "")
1247 (match_operand:DF 1 "" "")
1250 (const_string "XF")))])
1252 (define_insn "*cmpfp_<mode>"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1256 (match_operand 1 "register_operand" "f")
1257 (match_operator 3 "float_operator"
1258 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1260 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1261 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1262 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1263 "* return output_fp_compare (insn, operands, 0, 0);"
1264 [(set_attr "type" "multi")
1265 (set_attr "unit" "i387")
1266 (set_attr "fp_int_src" "true")
1267 (set_attr "mode" "<MODE>")])
1269 (define_insn_and_split "*cmpfp_<mode>_cc"
1270 [(set (reg:CCFP FLAGS_REG)
1272 (match_operand 1 "register_operand" "f")
1273 (match_operator 3 "float_operator"
1274 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1275 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1276 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1277 && TARGET_SAHF && !TARGET_CMOVE
1278 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1279 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1281 "&& reload_completed"
1286 (match_op_dup 3 [(match_dup 2)]))]
1288 (set (reg:CC FLAGS_REG)
1289 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1291 [(set_attr "type" "multi")
1292 (set_attr "unit" "i387")
1293 (set_attr "fp_int_src" "true")
1294 (set_attr "mode" "<MODE>")])
1296 ;; FP compares, step 2
1297 ;; Move the fpsw to ax.
1299 (define_insn "x86_fnstsw_1"
1300 [(set (match_operand:HI 0 "register_operand" "=a")
1301 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1304 [(set_attr "length" "2")
1305 (set_attr "mode" "SI")
1306 (set_attr "unit" "i387")])
1308 ;; FP compares, step 3
1309 ;; Get ax into flags, general case.
1311 (define_insn "x86_sahf_1"
1312 [(set (reg:CC FLAGS_REG)
1313 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1317 #ifdef HAVE_AS_IX86_SAHF
1320 return ".byte\t0x9e";
1323 [(set_attr "length" "1")
1324 (set_attr "athlon_decode" "vector")
1325 (set_attr "amdfam10_decode" "direct")
1326 (set_attr "mode" "SI")])
1328 ;; Pentium Pro can do steps 1 through 3 in one go.
1329 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1330 (define_insn "*cmpfp_i_mixed"
1331 [(set (reg:CCFP FLAGS_REG)
1332 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1333 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1334 "TARGET_MIX_SSE_I387
1335 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1336 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1337 "* return output_fp_compare (insn, operands, 1, 0);"
1338 [(set_attr "type" "fcmp,ssecomi")
1339 (set_attr "prefix" "orig,maybe_vex")
1341 (if_then_else (match_operand:SF 1 "" "")
1343 (const_string "DF")))
1344 (set_attr "athlon_decode" "vector")
1345 (set_attr "amdfam10_decode" "direct")])
1347 (define_insn "*cmpfp_i_sse"
1348 [(set (reg:CCFP FLAGS_REG)
1349 (compare:CCFP (match_operand 0 "register_operand" "x")
1350 (match_operand 1 "nonimmediate_operand" "xm")))]
1352 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1353 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1354 "* return output_fp_compare (insn, operands, 1, 0);"
1355 [(set_attr "type" "ssecomi")
1356 (set_attr "prefix" "maybe_vex")
1358 (if_then_else (match_operand:SF 1 "" "")
1360 (const_string "DF")))
1361 (set_attr "athlon_decode" "vector")
1362 (set_attr "amdfam10_decode" "direct")])
1364 (define_insn "*cmpfp_i_i387"
1365 [(set (reg:CCFP FLAGS_REG)
1366 (compare:CCFP (match_operand 0 "register_operand" "f")
1367 (match_operand 1 "register_operand" "f")))]
1368 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1370 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1371 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372 "* return output_fp_compare (insn, operands, 1, 0);"
1373 [(set_attr "type" "fcmp")
1375 (cond [(match_operand:SF 1 "" "")
1377 (match_operand:DF 1 "" "")
1380 (const_string "XF")))
1381 (set_attr "athlon_decode" "vector")
1382 (set_attr "amdfam10_decode" "direct")])
1384 (define_insn "*cmpfp_iu_mixed"
1385 [(set (reg:CCFPU FLAGS_REG)
1386 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1387 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1388 "TARGET_MIX_SSE_I387
1389 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1390 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1391 "* return output_fp_compare (insn, operands, 1, 1);"
1392 [(set_attr "type" "fcmp,ssecomi")
1393 (set_attr "prefix" "orig,maybe_vex")
1395 (if_then_else (match_operand:SF 1 "" "")
1397 (const_string "DF")))
1398 (set_attr "athlon_decode" "vector")
1399 (set_attr "amdfam10_decode" "direct")])
1401 (define_insn "*cmpfp_iu_sse"
1402 [(set (reg:CCFPU FLAGS_REG)
1403 (compare:CCFPU (match_operand 0 "register_operand" "x")
1404 (match_operand 1 "nonimmediate_operand" "xm")))]
1406 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1407 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1408 "* return output_fp_compare (insn, operands, 1, 1);"
1409 [(set_attr "type" "ssecomi")
1410 (set_attr "prefix" "maybe_vex")
1412 (if_then_else (match_operand:SF 1 "" "")
1414 (const_string "DF")))
1415 (set_attr "athlon_decode" "vector")
1416 (set_attr "amdfam10_decode" "direct")])
1418 (define_insn "*cmpfp_iu_387"
1419 [(set (reg:CCFPU FLAGS_REG)
1420 (compare:CCFPU (match_operand 0 "register_operand" "f")
1421 (match_operand 1 "register_operand" "f")))]
1422 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1424 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1425 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426 "* return output_fp_compare (insn, operands, 1, 1);"
1427 [(set_attr "type" "fcmp")
1429 (cond [(match_operand:SF 1 "" "")
1431 (match_operand:DF 1 "" "")
1434 (const_string "XF")))
1435 (set_attr "athlon_decode" "vector")
1436 (set_attr "amdfam10_decode" "direct")])
1438 ;; Move instructions.
1440 ;; General case of fullword move.
1442 (define_expand "movsi"
1443 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1444 (match_operand:SI 1 "general_operand" ""))]
1446 "ix86_expand_move (SImode, operands); DONE;")
1448 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1451 ;; %%% We don't use a post-inc memory reference because x86 is not a
1452 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1453 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1454 ;; targets without our curiosities, and it is just as easy to represent
1455 ;; this differently.
1457 (define_insn "*pushsi2"
1458 [(set (match_operand:SI 0 "push_operand" "=<")
1459 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1462 [(set_attr "type" "push")
1463 (set_attr "mode" "SI")])
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushsi2_rex64"
1467 [(set (match_operand:SI 0 "push_operand" "=X")
1468 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1471 [(set_attr "type" "push")
1472 (set_attr "mode" "SI")])
1474 (define_insn "*pushsi2_prologue"
1475 [(set (match_operand:SI 0 "push_operand" "=<")
1476 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1477 (clobber (mem:BLK (scratch)))]
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "SI")])
1483 (define_insn "*popsi1_epilogue"
1484 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1485 (mem:SI (reg:SI SP_REG)))
1486 (set (reg:SI SP_REG)
1487 (plus:SI (reg:SI SP_REG) (const_int 4)))
1488 (clobber (mem:BLK (scratch)))]
1491 [(set_attr "type" "pop")
1492 (set_attr "mode" "SI")])
1494 (define_insn "popsi1"
1495 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1496 (mem:SI (reg:SI SP_REG)))
1497 (set (reg:SI SP_REG)
1498 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1501 [(set_attr "type" "pop")
1502 (set_attr "mode" "SI")])
1504 (define_insn "*movsi_xor"
1505 [(set (match_operand:SI 0 "register_operand" "=r")
1506 (match_operand:SI 1 "const0_operand" ""))
1507 (clobber (reg:CC FLAGS_REG))]
1510 [(set_attr "type" "alu1")
1511 (set_attr "mode" "SI")
1512 (set_attr "length_immediate" "0")])
1514 (define_insn "*movsi_or"
1515 [(set (match_operand:SI 0 "register_operand" "=r")
1516 (match_operand:SI 1 "immediate_operand" "i"))
1517 (clobber (reg:CC FLAGS_REG))]
1519 && operands[1] == constm1_rtx"
1521 operands[1] = constm1_rtx;
1522 return "or{l}\t{%1, %0|%0, %1}";
1524 [(set_attr "type" "alu1")
1525 (set_attr "mode" "SI")
1526 (set_attr "length_immediate" "1")])
1528 (define_insn "*movsi_1"
1529 [(set (match_operand:SI 0 "nonimmediate_operand"
1530 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1531 (match_operand:SI 1 "general_operand"
1532 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1533 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1535 switch (get_attr_type (insn))
1538 if (get_attr_mode (insn) == MODE_TI)
1539 return "%vpxor\t%0, %d0";
1540 return "%vxorps\t%0, %d0";
1543 switch (get_attr_mode (insn))
1546 return "%vmovdqa\t{%1, %0|%0, %1}";
1548 return "%vmovaps\t{%1, %0|%0, %1}";
1550 return "%vmovd\t{%1, %0|%0, %1}";
1552 return "%vmovss\t{%1, %0|%0, %1}";
1558 return "pxor\t%0, %0";
1561 if (get_attr_mode (insn) == MODE_DI)
1562 return "movq\t{%1, %0|%0, %1}";
1563 return "movd\t{%1, %0|%0, %1}";
1566 return "lea{l}\t{%1, %0|%0, %1}";
1569 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1570 return "mov{l}\t{%1, %0|%0, %1}";
1574 (cond [(eq_attr "alternative" "2")
1575 (const_string "mmx")
1576 (eq_attr "alternative" "3,4,5")
1577 (const_string "mmxmov")
1578 (eq_attr "alternative" "6")
1579 (const_string "sselog1")
1580 (eq_attr "alternative" "7,8,9,10,11")
1581 (const_string "ssemov")
1582 (match_operand:DI 1 "pic_32bit_operand" "")
1583 (const_string "lea")
1585 (const_string "imov")))
1586 (set (attr "prefix")
1587 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1588 (const_string "orig")
1589 (const_string "maybe_vex")))
1591 (cond [(eq_attr "alternative" "2,3")
1593 (eq_attr "alternative" "6,7")
1595 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1596 (const_string "V4SF")
1597 (const_string "TI"))
1598 (and (eq_attr "alternative" "8,9,10,11")
1599 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1602 (const_string "SI")))])
1604 ;; Stores and loads of ax to arbitrary constant address.
1605 ;; We fake an second form of instruction to force reload to load address
1606 ;; into register when rax is not available
1607 (define_insn "*movabssi_1_rex64"
1608 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1609 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1610 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1612 movabs{l}\t{%1, %P0|%P0, %1}
1613 mov{l}\t{%1, %a0|%a0, %1}"
1614 [(set_attr "type" "imov")
1615 (set_attr "modrm" "0,*")
1616 (set_attr "length_address" "8,0")
1617 (set_attr "length_immediate" "0,*")
1618 (set_attr "memory" "store")
1619 (set_attr "mode" "SI")])
1621 (define_insn "*movabssi_2_rex64"
1622 [(set (match_operand:SI 0 "register_operand" "=a,r")
1623 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1624 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1626 movabs{l}\t{%P1, %0|%0, %P1}
1627 mov{l}\t{%a1, %0|%0, %a1}"
1628 [(set_attr "type" "imov")
1629 (set_attr "modrm" "0,*")
1630 (set_attr "length_address" "8,0")
1631 (set_attr "length_immediate" "0")
1632 (set_attr "memory" "load")
1633 (set_attr "mode" "SI")])
1635 (define_insn "*swapsi"
1636 [(set (match_operand:SI 0 "register_operand" "+r")
1637 (match_operand:SI 1 "register_operand" "+r"))
1642 [(set_attr "type" "imov")
1643 (set_attr "mode" "SI")
1644 (set_attr "pent_pair" "np")
1645 (set_attr "athlon_decode" "vector")
1646 (set_attr "amdfam10_decode" "double")])
1648 (define_expand "movhi"
1649 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1650 (match_operand:HI 1 "general_operand" ""))]
1652 "ix86_expand_move (HImode, operands); DONE;")
1654 (define_insn "*pushhi2"
1655 [(set (match_operand:HI 0 "push_operand" "=X")
1656 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1659 [(set_attr "type" "push")
1660 (set_attr "mode" "SI")])
1662 ;; For 64BIT abi we always round up to 8 bytes.
1663 (define_insn "*pushhi2_rex64"
1664 [(set (match_operand:HI 0 "push_operand" "=X")
1665 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1668 [(set_attr "type" "push")
1669 (set_attr "mode" "DI")])
1671 (define_insn "*movhi_1"
1672 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1673 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1674 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1676 switch (get_attr_type (insn))
1679 /* movzwl is faster than movw on p2 due to partial word stalls,
1680 though not as fast as an aligned movl. */
1681 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1683 if (get_attr_mode (insn) == MODE_SI)
1684 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1686 return "mov{w}\t{%1, %0|%0, %1}";
1690 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1691 (const_string "imov")
1692 (and (eq_attr "alternative" "0")
1693 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1695 (eq (symbol_ref "TARGET_HIMODE_MATH")
1697 (const_string "imov")
1698 (and (eq_attr "alternative" "1,2")
1699 (match_operand:HI 1 "aligned_operand" ""))
1700 (const_string "imov")
1701 (and (ne (symbol_ref "TARGET_MOVX")
1703 (eq_attr "alternative" "0,2"))
1704 (const_string "imovx")
1706 (const_string "imov")))
1708 (cond [(eq_attr "type" "imovx")
1710 (and (eq_attr "alternative" "1,2")
1711 (match_operand:HI 1 "aligned_operand" ""))
1713 (and (eq_attr "alternative" "0")
1714 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1716 (eq (symbol_ref "TARGET_HIMODE_MATH")
1720 (const_string "HI")))])
1722 ;; Stores and loads of ax to arbitrary constant address.
1723 ;; We fake an second form of instruction to force reload to load address
1724 ;; into register when rax is not available
1725 (define_insn "*movabshi_1_rex64"
1726 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1727 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1728 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1730 movabs{w}\t{%1, %P0|%P0, %1}
1731 mov{w}\t{%1, %a0|%a0, %1}"
1732 [(set_attr "type" "imov")
1733 (set_attr "modrm" "0,*")
1734 (set_attr "length_address" "8,0")
1735 (set_attr "length_immediate" "0,*")
1736 (set_attr "memory" "store")
1737 (set_attr "mode" "HI")])
1739 (define_insn "*movabshi_2_rex64"
1740 [(set (match_operand:HI 0 "register_operand" "=a,r")
1741 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1742 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1744 movabs{w}\t{%P1, %0|%0, %P1}
1745 mov{w}\t{%a1, %0|%0, %a1}"
1746 [(set_attr "type" "imov")
1747 (set_attr "modrm" "0,*")
1748 (set_attr "length_address" "8,0")
1749 (set_attr "length_immediate" "0")
1750 (set_attr "memory" "load")
1751 (set_attr "mode" "HI")])
1753 (define_insn "*swaphi_1"
1754 [(set (match_operand:HI 0 "register_operand" "+r")
1755 (match_operand:HI 1 "register_operand" "+r"))
1758 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1760 [(set_attr "type" "imov")
1761 (set_attr "mode" "SI")
1762 (set_attr "pent_pair" "np")
1763 (set_attr "athlon_decode" "vector")
1764 (set_attr "amdfam10_decode" "double")])
1766 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1767 (define_insn "*swaphi_2"
1768 [(set (match_operand:HI 0 "register_operand" "+r")
1769 (match_operand:HI 1 "register_operand" "+r"))
1772 "TARGET_PARTIAL_REG_STALL"
1774 [(set_attr "type" "imov")
1775 (set_attr "mode" "HI")
1776 (set_attr "pent_pair" "np")
1777 (set_attr "athlon_decode" "vector")])
1779 (define_expand "movstricthi"
1780 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1781 (match_operand:HI 1 "general_operand" ""))]
1784 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1786 /* Don't generate memory->memory moves, go through a register */
1787 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1788 operands[1] = force_reg (HImode, operands[1]);
1791 (define_insn "*movstricthi_1"
1792 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1793 (match_operand:HI 1 "general_operand" "rn,m"))]
1794 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1796 "mov{w}\t{%1, %0|%0, %1}"
1797 [(set_attr "type" "imov")
1798 (set_attr "mode" "HI")])
1800 (define_insn "*movstricthi_xor"
1801 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1802 (match_operand:HI 1 "const0_operand" ""))
1803 (clobber (reg:CC FLAGS_REG))]
1806 [(set_attr "type" "alu1")
1807 (set_attr "mode" "HI")
1808 (set_attr "length_immediate" "0")])
1810 (define_expand "movqi"
1811 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1812 (match_operand:QI 1 "general_operand" ""))]
1814 "ix86_expand_move (QImode, operands); DONE;")
1816 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1817 ;; "push a byte". But actually we use pushl, which has the effect
1818 ;; of rounding the amount pushed up to a word.
1820 (define_insn "*pushqi2"
1821 [(set (match_operand:QI 0 "push_operand" "=X")
1822 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1825 [(set_attr "type" "push")
1826 (set_attr "mode" "SI")])
1828 ;; For 64BIT abi we always round up to 8 bytes.
1829 (define_insn "*pushqi2_rex64"
1830 [(set (match_operand:QI 0 "push_operand" "=X")
1831 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1834 [(set_attr "type" "push")
1835 (set_attr "mode" "DI")])
1837 ;; Situation is quite tricky about when to choose full sized (SImode) move
1838 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1839 ;; partial register dependency machines (such as AMD Athlon), where QImode
1840 ;; moves issue extra dependency and for partial register stalls machines
1841 ;; that don't use QImode patterns (and QImode move cause stall on the next
1844 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1845 ;; register stall machines with, where we use QImode instructions, since
1846 ;; partial register stall can be caused there. Then we use movzx.
1847 (define_insn "*movqi_1"
1848 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1849 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1850 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852 switch (get_attr_type (insn))
1855 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1856 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1858 if (get_attr_mode (insn) == MODE_SI)
1859 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1861 return "mov{b}\t{%1, %0|%0, %1}";
1865 (cond [(and (eq_attr "alternative" "5")
1866 (not (match_operand:QI 1 "aligned_operand" "")))
1867 (const_string "imovx")
1868 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1869 (const_string "imov")
1870 (and (eq_attr "alternative" "3")
1871 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1873 (eq (symbol_ref "TARGET_QIMODE_MATH")
1875 (const_string "imov")
1876 (eq_attr "alternative" "3,5")
1877 (const_string "imovx")
1878 (and (ne (symbol_ref "TARGET_MOVX")
1880 (eq_attr "alternative" "2"))
1881 (const_string "imovx")
1883 (const_string "imov")))
1885 (cond [(eq_attr "alternative" "3,4,5")
1887 (eq_attr "alternative" "6")
1889 (eq_attr "type" "imovx")
1891 (and (eq_attr "type" "imov")
1892 (and (eq_attr "alternative" "0,1")
1893 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1895 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1897 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1900 ;; Avoid partial register stalls when not using QImode arithmetic
1901 (and (eq_attr "type" "imov")
1902 (and (eq_attr "alternative" "0,1")
1903 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1905 (eq (symbol_ref "TARGET_QIMODE_MATH")
1909 (const_string "QI")))])
1911 (define_insn "*swapqi_1"
1912 [(set (match_operand:QI 0 "register_operand" "+r")
1913 (match_operand:QI 1 "register_operand" "+r"))
1916 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1918 [(set_attr "type" "imov")
1919 (set_attr "mode" "SI")
1920 (set_attr "pent_pair" "np")
1921 (set_attr "athlon_decode" "vector")
1922 (set_attr "amdfam10_decode" "vector")])
1924 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1925 (define_insn "*swapqi_2"
1926 [(set (match_operand:QI 0 "register_operand" "+q")
1927 (match_operand:QI 1 "register_operand" "+q"))
1930 "TARGET_PARTIAL_REG_STALL"
1932 [(set_attr "type" "imov")
1933 (set_attr "mode" "QI")
1934 (set_attr "pent_pair" "np")
1935 (set_attr "athlon_decode" "vector")])
1937 (define_expand "movstrictqi"
1938 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1939 (match_operand:QI 1 "general_operand" ""))]
1942 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1944 /* Don't generate memory->memory moves, go through a register. */
1945 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1946 operands[1] = force_reg (QImode, operands[1]);
1949 (define_insn "*movstrictqi_1"
1950 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1951 (match_operand:QI 1 "general_operand" "*qn,m"))]
1952 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1953 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1954 "mov{b}\t{%1, %0|%0, %1}"
1955 [(set_attr "type" "imov")
1956 (set_attr "mode" "QI")])
1958 (define_insn "*movstrictqi_xor"
1959 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1960 (match_operand:QI 1 "const0_operand" ""))
1961 (clobber (reg:CC FLAGS_REG))]
1964 [(set_attr "type" "alu1")
1965 (set_attr "mode" "QI")
1966 (set_attr "length_immediate" "0")])
1968 (define_insn "*movsi_extv_1"
1969 [(set (match_operand:SI 0 "register_operand" "=R")
1970 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1974 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1975 [(set_attr "type" "imovx")
1976 (set_attr "mode" "SI")])
1978 (define_insn "*movhi_extv_1"
1979 [(set (match_operand:HI 0 "register_operand" "=R")
1980 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1984 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1985 [(set_attr "type" "imovx")
1986 (set_attr "mode" "SI")])
1988 (define_insn "*movqi_extv_1"
1989 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1990 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1995 switch (get_attr_type (insn))
1998 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2000 return "mov{b}\t{%h1, %0|%0, %h1}";
2004 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2005 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2006 (ne (symbol_ref "TARGET_MOVX")
2008 (const_string "imovx")
2009 (const_string "imov")))
2011 (if_then_else (eq_attr "type" "imovx")
2013 (const_string "QI")))])
2015 (define_insn "*movqi_extv_1_rex64"
2016 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2017 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2022 switch (get_attr_type (insn))
2025 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2027 return "mov{b}\t{%h1, %0|%0, %h1}";
2031 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2032 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2033 (ne (symbol_ref "TARGET_MOVX")
2035 (const_string "imovx")
2036 (const_string "imov")))
2038 (if_then_else (eq_attr "type" "imovx")
2040 (const_string "QI")))])
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsqi_1_rex64"
2046 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2048 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2050 movabs{b}\t{%1, %P0|%P0, %1}
2051 mov{b}\t{%1, %a0|%a0, %1}"
2052 [(set_attr "type" "imov")
2053 (set_attr "modrm" "0,*")
2054 (set_attr "length_address" "8,0")
2055 (set_attr "length_immediate" "0,*")
2056 (set_attr "memory" "store")
2057 (set_attr "mode" "QI")])
2059 (define_insn "*movabsqi_2_rex64"
2060 [(set (match_operand:QI 0 "register_operand" "=a,r")
2061 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2064 movabs{b}\t{%P1, %0|%0, %P1}
2065 mov{b}\t{%a1, %0|%0, %a1}"
2066 [(set_attr "type" "imov")
2067 (set_attr "modrm" "0,*")
2068 (set_attr "length_address" "8,0")
2069 (set_attr "length_immediate" "0")
2070 (set_attr "memory" "load")
2071 (set_attr "mode" "QI")])
2073 (define_insn "*movdi_extzv_1"
2074 [(set (match_operand:DI 0 "register_operand" "=R")
2075 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2079 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2080 [(set_attr "type" "imovx")
2081 (set_attr "mode" "DI")])
2083 (define_insn "*movsi_extzv_1"
2084 [(set (match_operand:SI 0 "register_operand" "=R")
2085 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2089 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2090 [(set_attr "type" "imovx")
2091 (set_attr "mode" "SI")])
2093 (define_insn "*movqi_extzv_2"
2094 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2095 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2100 switch (get_attr_type (insn))
2103 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2105 return "mov{b}\t{%h1, %0|%0, %h1}";
2109 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2110 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2111 (ne (symbol_ref "TARGET_MOVX")
2113 (const_string "imovx")
2114 (const_string "imov")))
2116 (if_then_else (eq_attr "type" "imovx")
2118 (const_string "QI")))])
2120 (define_insn "*movqi_extzv_2_rex64"
2121 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2122 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2127 switch (get_attr_type (insn))
2130 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2132 return "mov{b}\t{%h1, %0|%0, %h1}";
2136 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2137 (ne (symbol_ref "TARGET_MOVX")
2139 (const_string "imovx")
2140 (const_string "imov")))
2142 (if_then_else (eq_attr "type" "imovx")
2144 (const_string "QI")))])
2146 (define_insn "movsi_insv_1"
2147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2150 (match_operand:SI 1 "general_operand" "Qmn"))]
2152 "mov{b}\t{%b1, %h0|%h0, %b1}"
2153 [(set_attr "type" "imov")
2154 (set_attr "mode" "QI")])
2156 (define_insn "*movsi_insv_1_rex64"
2157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2160 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2162 "mov{b}\t{%b1, %h0|%h0, %b1}"
2163 [(set_attr "type" "imov")
2164 (set_attr "mode" "QI")])
2166 (define_insn "movdi_insv_1_rex64"
2167 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2170 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2172 "mov{b}\t{%b1, %h0|%h0, %b1}"
2173 [(set_attr "type" "imov")
2174 (set_attr "mode" "QI")])
2176 (define_insn "*movqi_insv_2"
2177 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2180 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2183 "mov{b}\t{%h1, %h0|%h0, %h1}"
2184 [(set_attr "type" "imov")
2185 (set_attr "mode" "QI")])
2187 (define_expand "movdi"
2188 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2189 (match_operand:DI 1 "general_operand" ""))]
2191 "ix86_expand_move (DImode, operands); DONE;")
2193 (define_insn "*pushdi"
2194 [(set (match_operand:DI 0 "push_operand" "=<")
2195 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2199 (define_insn "*pushdi2_rex64"
2200 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2201 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2206 [(set_attr "type" "push,multi")
2207 (set_attr "mode" "DI")])
2209 ;; Convert impossible pushes of immediate to existing instructions.
2210 ;; First try to get scratch register and go through it. In case this
2211 ;; fails, push sign extended lower part first and then overwrite
2212 ;; upper part by 32bit move.
2214 [(match_scratch:DI 2 "r")
2215 (set (match_operand:DI 0 "push_operand" "")
2216 (match_operand:DI 1 "immediate_operand" ""))]
2217 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2218 && !x86_64_immediate_operand (operands[1], DImode)"
2219 [(set (match_dup 2) (match_dup 1))
2220 (set (match_dup 0) (match_dup 2))]
2223 ;; We need to define this as both peepholer and splitter for case
2224 ;; peephole2 pass is not run.
2225 ;; "&& 1" is needed to keep it from matching the previous pattern.
2227 [(set (match_operand:DI 0 "push_operand" "")
2228 (match_operand:DI 1 "immediate_operand" ""))]
2229 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2230 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2231 [(set (match_dup 0) (match_dup 1))
2232 (set (match_dup 2) (match_dup 3))]
2233 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2234 operands[1] = gen_lowpart (DImode, operands[2]);
2235 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2240 [(set (match_operand:DI 0 "push_operand" "")
2241 (match_operand:DI 1 "immediate_operand" ""))]
2242 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2243 ? epilogue_completed : reload_completed)
2244 && !symbolic_operand (operands[1], DImode)
2245 && !x86_64_immediate_operand (operands[1], DImode)"
2246 [(set (match_dup 0) (match_dup 1))
2247 (set (match_dup 2) (match_dup 3))]
2248 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2249 operands[1] = gen_lowpart (DImode, operands[2]);
2250 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2254 (define_insn "*pushdi2_prologue_rex64"
2255 [(set (match_operand:DI 0 "push_operand" "=<")
2256 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2257 (clobber (mem:BLK (scratch)))]
2260 [(set_attr "type" "push")
2261 (set_attr "mode" "DI")])
2263 (define_insn "*popdi1_epilogue_rex64"
2264 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2265 (mem:DI (reg:DI SP_REG)))
2266 (set (reg:DI SP_REG)
2267 (plus:DI (reg:DI SP_REG) (const_int 8)))
2268 (clobber (mem:BLK (scratch)))]
2271 [(set_attr "type" "pop")
2272 (set_attr "mode" "DI")])
2274 (define_insn "popdi1"
2275 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2276 (mem:DI (reg:DI SP_REG)))
2277 (set (reg:DI SP_REG)
2278 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2281 [(set_attr "type" "pop")
2282 (set_attr "mode" "DI")])
2284 (define_insn "*movdi_xor_rex64"
2285 [(set (match_operand:DI 0 "register_operand" "=r")
2286 (match_operand:DI 1 "const0_operand" ""))
2287 (clobber (reg:CC FLAGS_REG))]
2289 && reload_completed"
2291 [(set_attr "type" "alu1")
2292 (set_attr "mode" "SI")
2293 (set_attr "length_immediate" "0")])
2295 (define_insn "*movdi_or_rex64"
2296 [(set (match_operand:DI 0 "register_operand" "=r")
2297 (match_operand:DI 1 "const_int_operand" "i"))
2298 (clobber (reg:CC FLAGS_REG))]
2301 && operands[1] == constm1_rtx"
2303 operands[1] = constm1_rtx;
2304 return "or{q}\t{%1, %0|%0, %1}";
2306 [(set_attr "type" "alu1")
2307 (set_attr "mode" "DI")
2308 (set_attr "length_immediate" "1")])
2310 (define_insn "*movdi_2"
2311 [(set (match_operand:DI 0 "nonimmediate_operand"
2312 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2313 (match_operand:DI 1 "general_operand"
2314 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2315 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2320 movq\t{%1, %0|%0, %1}
2321 movq\t{%1, %0|%0, %1}
2323 %vmovq\t{%1, %0|%0, %1}
2324 %vmovdqa\t{%1, %0|%0, %1}
2325 %vmovq\t{%1, %0|%0, %1}
2327 movlps\t{%1, %0|%0, %1}
2328 movaps\t{%1, %0|%0, %1}
2329 movlps\t{%1, %0|%0, %1}"
2330 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2331 (set (attr "prefix")
2332 (if_then_else (eq_attr "alternative" "5,6,7,8")
2333 (const_string "vex")
2334 (const_string "orig")))
2335 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2338 [(set (match_operand:DI 0 "push_operand" "")
2339 (match_operand:DI 1 "general_operand" ""))]
2340 "!TARGET_64BIT && reload_completed
2341 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2343 "ix86_split_long_move (operands); DONE;")
2345 ;; %%% This multiword shite has got to go.
2347 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2348 (match_operand:DI 1 "general_operand" ""))]
2349 "!TARGET_64BIT && reload_completed
2350 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2351 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2353 "ix86_split_long_move (operands); DONE;")
2355 (define_insn "*movdi_1_rex64"
2356 [(set (match_operand:DI 0 "nonimmediate_operand"
2357 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2358 (match_operand:DI 1 "general_operand"
2359 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2360 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2362 switch (get_attr_type (insn))
2365 if (SSE_REG_P (operands[0]))
2366 return "movq2dq\t{%1, %0|%0, %1}";
2368 return "movdq2q\t{%1, %0|%0, %1}";
2373 if (get_attr_mode (insn) == MODE_TI)
2374 return "vmovdqa\t{%1, %0|%0, %1}";
2376 return "vmovq\t{%1, %0|%0, %1}";
2379 if (get_attr_mode (insn) == MODE_TI)
2380 return "movdqa\t{%1, %0|%0, %1}";
2384 /* Moves from and into integer register is done using movd
2385 opcode with REX prefix. */
2386 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2387 return "movd\t{%1, %0|%0, %1}";
2388 return "movq\t{%1, %0|%0, %1}";
2391 return "%vpxor\t%0, %d0";
2394 return "pxor\t%0, %0";
2400 return "lea{q}\t{%a1, %0|%0, %a1}";
2403 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2404 if (get_attr_mode (insn) == MODE_SI)
2405 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2406 else if (which_alternative == 2)
2407 return "movabs{q}\t{%1, %0|%0, %1}";
2409 return "mov{q}\t{%1, %0|%0, %1}";
2413 (cond [(eq_attr "alternative" "5")
2414 (const_string "mmx")
2415 (eq_attr "alternative" "6,7,8,9,10")
2416 (const_string "mmxmov")
2417 (eq_attr "alternative" "11")
2418 (const_string "sselog1")
2419 (eq_attr "alternative" "12,13,14,15,16")
2420 (const_string "ssemov")
2421 (eq_attr "alternative" "17,18")
2422 (const_string "ssecvt")
2423 (eq_attr "alternative" "4")
2424 (const_string "multi")
2425 (match_operand:DI 1 "pic_32bit_operand" "")
2426 (const_string "lea")
2428 (const_string "imov")))
2429 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2430 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2431 (set (attr "prefix")
2432 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2433 (const_string "maybe_vex")
2434 (const_string "orig")))
2435 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2437 ;; Stores and loads of ax to arbitrary constant address.
2438 ;; We fake an second form of instruction to force reload to load address
2439 ;; into register when rax is not available
2440 (define_insn "*movabsdi_1_rex64"
2441 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2442 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2443 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2445 movabs{q}\t{%1, %P0|%P0, %1}
2446 mov{q}\t{%1, %a0|%a0, %1}"
2447 [(set_attr "type" "imov")
2448 (set_attr "modrm" "0,*")
2449 (set_attr "length_address" "8,0")
2450 (set_attr "length_immediate" "0,*")
2451 (set_attr "memory" "store")
2452 (set_attr "mode" "DI")])
2454 (define_insn "*movabsdi_2_rex64"
2455 [(set (match_operand:DI 0 "register_operand" "=a,r")
2456 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2457 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2459 movabs{q}\t{%P1, %0|%0, %P1}
2460 mov{q}\t{%a1, %0|%0, %a1}"
2461 [(set_attr "type" "imov")
2462 (set_attr "modrm" "0,*")
2463 (set_attr "length_address" "8,0")
2464 (set_attr "length_immediate" "0")
2465 (set_attr "memory" "load")
2466 (set_attr "mode" "DI")])
2468 ;; Convert impossible stores of immediate to existing instructions.
2469 ;; First try to get scratch register and go through it. In case this
2470 ;; fails, move by 32bit parts.
2472 [(match_scratch:DI 2 "r")
2473 (set (match_operand:DI 0 "memory_operand" "")
2474 (match_operand:DI 1 "immediate_operand" ""))]
2475 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2476 && !x86_64_immediate_operand (operands[1], DImode)"
2477 [(set (match_dup 2) (match_dup 1))
2478 (set (match_dup 0) (match_dup 2))]
2481 ;; We need to define this as both peepholer and splitter for case
2482 ;; peephole2 pass is not run.
2483 ;; "&& 1" is needed to keep it from matching the previous pattern.
2485 [(set (match_operand:DI 0 "memory_operand" "")
2486 (match_operand:DI 1 "immediate_operand" ""))]
2487 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2488 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2489 [(set (match_dup 2) (match_dup 3))
2490 (set (match_dup 4) (match_dup 5))]
2491 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2494 [(set (match_operand:DI 0 "memory_operand" "")
2495 (match_operand:DI 1 "immediate_operand" ""))]
2496 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2497 ? epilogue_completed : reload_completed)
2498 && !symbolic_operand (operands[1], DImode)
2499 && !x86_64_immediate_operand (operands[1], DImode)"
2500 [(set (match_dup 2) (match_dup 3))
2501 (set (match_dup 4) (match_dup 5))]
2502 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2504 (define_insn "*swapdi_rex64"
2505 [(set (match_operand:DI 0 "register_operand" "+r")
2506 (match_operand:DI 1 "register_operand" "+r"))
2511 [(set_attr "type" "imov")
2512 (set_attr "mode" "DI")
2513 (set_attr "pent_pair" "np")
2514 (set_attr "athlon_decode" "vector")
2515 (set_attr "amdfam10_decode" "double")])
2517 (define_expand "movoi"
2518 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2519 (match_operand:OI 1 "general_operand" ""))]
2521 "ix86_expand_move (OImode, operands); DONE;")
2523 (define_insn "*movoi_internal"
2524 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2525 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2529 switch (which_alternative)
2532 return "vxorps\t%0, %0, %0";
2535 if (misaligned_operand (operands[0], OImode)
2536 || misaligned_operand (operands[1], OImode))
2537 return "vmovdqu\t{%1, %0|%0, %1}";
2539 return "vmovdqa\t{%1, %0|%0, %1}";
2544 [(set_attr "type" "sselog1,ssemov,ssemov")
2545 (set_attr "prefix" "vex")
2546 (set_attr "mode" "OI")])
2548 (define_expand "movti"
2549 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2550 (match_operand:TI 1 "nonimmediate_operand" ""))]
2551 "TARGET_SSE || TARGET_64BIT"
2554 ix86_expand_move (TImode, operands);
2555 else if (push_operand (operands[0], TImode))
2556 ix86_expand_push (TImode, operands[1]);
2558 ix86_expand_vector_move (TImode, operands);
2562 (define_insn "*movti_internal"
2563 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2564 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2565 "TARGET_SSE && !TARGET_64BIT
2566 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2568 switch (which_alternative)
2571 if (get_attr_mode (insn) == MODE_V4SF)
2572 return "%vxorps\t%0, %d0";
2574 return "%vpxor\t%0, %d0";
2577 /* TDmode values are passed as TImode on the stack. Moving them
2578 to stack may result in unaligned memory access. */
2579 if (misaligned_operand (operands[0], TImode)
2580 || misaligned_operand (operands[1], TImode))
2582 if (get_attr_mode (insn) == MODE_V4SF)
2583 return "%vmovups\t{%1, %0|%0, %1}";
2585 return "%vmovdqu\t{%1, %0|%0, %1}";
2589 if (get_attr_mode (insn) == MODE_V4SF)
2590 return "%vmovaps\t{%1, %0|%0, %1}";
2592 return "%vmovdqa\t{%1, %0|%0, %1}";
2598 [(set_attr "type" "sselog1,ssemov,ssemov")
2599 (set_attr "prefix" "maybe_vex")
2601 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2602 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2603 (const_string "V4SF")
2604 (and (eq_attr "alternative" "2")
2605 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2607 (const_string "V4SF")]
2608 (const_string "TI")))])
2610 (define_insn "*movti_rex64"
2611 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2612 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2616 switch (which_alternative)
2622 if (get_attr_mode (insn) == MODE_V4SF)
2623 return "%vxorps\t%0, %d0";
2625 return "%vpxor\t%0, %d0";
2628 /* TDmode values are passed as TImode on the stack. Moving them
2629 to stack may result in unaligned memory access. */
2630 if (misaligned_operand (operands[0], TImode)
2631 || misaligned_operand (operands[1], TImode))
2633 if (get_attr_mode (insn) == MODE_V4SF)
2634 return "%vmovups\t{%1, %0|%0, %1}";
2636 return "%vmovdqu\t{%1, %0|%0, %1}";
2640 if (get_attr_mode (insn) == MODE_V4SF)
2641 return "%vmovaps\t{%1, %0|%0, %1}";
2643 return "%vmovdqa\t{%1, %0|%0, %1}";
2649 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2650 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2652 (cond [(eq_attr "alternative" "2,3")
2654 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2656 (const_string "V4SF")
2657 (const_string "TI"))
2658 (eq_attr "alternative" "4")
2660 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2662 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2664 (const_string "V4SF")
2665 (const_string "TI"))]
2666 (const_string "DI")))])
2669 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2670 (match_operand:TI 1 "general_operand" ""))]
2671 "reload_completed && !SSE_REG_P (operands[0])
2672 && !SSE_REG_P (operands[1])"
2674 "ix86_split_long_move (operands); DONE;")
2676 ;; This expands to what emit_move_complex would generate if we didn't
2677 ;; have a movti pattern. Having this avoids problems with reload on
2678 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2679 ;; to have around all the time.
2680 (define_expand "movcdi"
2681 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2682 (match_operand:CDI 1 "general_operand" ""))]
2685 if (push_operand (operands[0], CDImode))
2686 emit_move_complex_push (CDImode, operands[0], operands[1]);
2688 emit_move_complex_parts (operands[0], operands[1]);
2692 (define_expand "movsf"
2693 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2694 (match_operand:SF 1 "general_operand" ""))]
2696 "ix86_expand_move (SFmode, operands); DONE;")
2698 (define_insn "*pushsf"
2699 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2700 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2703 /* Anything else should be already split before reg-stack. */
2704 gcc_assert (which_alternative == 1);
2705 return "push{l}\t%1";
2707 [(set_attr "type" "multi,push,multi")
2708 (set_attr "unit" "i387,*,*")
2709 (set_attr "mode" "SF,SI,SF")])
2711 (define_insn "*pushsf_rex64"
2712 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2713 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2716 /* Anything else should be already split before reg-stack. */
2717 gcc_assert (which_alternative == 1);
2718 return "push{q}\t%q1";
2720 [(set_attr "type" "multi,push,multi")
2721 (set_attr "unit" "i387,*,*")
2722 (set_attr "mode" "SF,DI,SF")])
2725 [(set (match_operand:SF 0 "push_operand" "")
2726 (match_operand:SF 1 "memory_operand" ""))]
2728 && MEM_P (operands[1])
2729 && (operands[2] = find_constant_src (insn))"
2734 ;; %%% Kill this when call knows how to work this out.
2736 [(set (match_operand:SF 0 "push_operand" "")
2737 (match_operand:SF 1 "any_fp_register_operand" ""))]
2739 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2740 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2743 [(set (match_operand:SF 0 "push_operand" "")
2744 (match_operand:SF 1 "any_fp_register_operand" ""))]
2746 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2747 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2749 (define_insn "*movsf_1"
2750 [(set (match_operand:SF 0 "nonimmediate_operand"
2751 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2752 (match_operand:SF 1 "general_operand"
2753 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2754 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2755 && (reload_in_progress || reload_completed
2756 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2757 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2758 && standard_80387_constant_p (operands[1]))
2759 || GET_CODE (operands[1]) != CONST_DOUBLE
2760 || memory_operand (operands[0], SFmode))"
2762 switch (which_alternative)
2766 return output_387_reg_move (insn, operands);
2769 return standard_80387_constant_opcode (operands[1]);
2773 return "mov{l}\t{%1, %0|%0, %1}";
2775 if (get_attr_mode (insn) == MODE_TI)
2776 return "%vpxor\t%0, %d0";
2778 return "%vxorps\t%0, %d0";
2780 if (get_attr_mode (insn) == MODE_V4SF)
2781 return "%vmovaps\t{%1, %0|%0, %1}";
2783 return "%vmovss\t{%1, %d0|%d0, %1}";
2786 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2787 : "vmovss\t{%1, %0|%0, %1}";
2789 return "movss\t{%1, %0|%0, %1}";
2791 return "%vmovss\t{%1, %0|%0, %1}";
2793 case 9: case 10: case 14: case 15:
2794 return "movd\t{%1, %0|%0, %1}";
2796 return "%vmovd\t{%1, %0|%0, %1}";
2799 return "movq\t{%1, %0|%0, %1}";
2805 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2806 (set (attr "prefix")
2807 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2808 (const_string "maybe_vex")
2809 (const_string "orig")))
2811 (cond [(eq_attr "alternative" "3,4,9,10")
2813 (eq_attr "alternative" "5")
2815 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2817 (ne (symbol_ref "TARGET_SSE2")
2819 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2822 (const_string "V4SF"))
2823 /* For architectures resolving dependencies on
2824 whole SSE registers use APS move to break dependency
2825 chains, otherwise use short move to avoid extra work.
2827 Do the same for architectures resolving dependencies on
2828 the parts. While in DF mode it is better to always handle
2829 just register parts, the SF mode is different due to lack
2830 of instructions to load just part of the register. It is
2831 better to maintain the whole registers in single format
2832 to avoid problems on using packed logical operations. */
2833 (eq_attr "alternative" "6")
2835 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2837 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2839 (const_string "V4SF")
2840 (const_string "SF"))
2841 (eq_attr "alternative" "11")
2842 (const_string "DI")]
2843 (const_string "SF")))])
2845 (define_insn "*swapsf"
2846 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2847 (match_operand:SF 1 "fp_register_operand" "+f"))
2850 "reload_completed || TARGET_80387"
2852 if (STACK_TOP_P (operands[0]))
2857 [(set_attr "type" "fxch")
2858 (set_attr "mode" "SF")])
2860 (define_expand "movdf"
2861 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2862 (match_operand:DF 1 "general_operand" ""))]
2864 "ix86_expand_move (DFmode, operands); DONE;")
2866 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2867 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2868 ;; On the average, pushdf using integers can be still shorter. Allow this
2869 ;; pattern for optimize_size too.
2871 (define_insn "*pushdf_nointeger"
2872 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2873 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2874 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2876 /* This insn should be already split before reg-stack. */
2879 [(set_attr "type" "multi")
2880 (set_attr "unit" "i387,*,*,*")
2881 (set_attr "mode" "DF,SI,SI,DF")])
2883 (define_insn "*pushdf_integer"
2884 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2885 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2886 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2888 /* This insn should be already split before reg-stack. */
2891 [(set_attr "type" "multi")
2892 (set_attr "unit" "i387,*,*")
2893 (set_attr "mode" "DF,SI,DF")])
2895 ;; %%% Kill this when call knows how to work this out.
2897 [(set (match_operand:DF 0 "push_operand" "")
2898 (match_operand:DF 1 "any_fp_register_operand" ""))]
2900 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2901 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2905 [(set (match_operand:DF 0 "push_operand" "")
2906 (match_operand:DF 1 "general_operand" ""))]
2909 "ix86_split_long_move (operands); DONE;")
2911 ;; Moving is usually shorter when only FP registers are used. This separate
2912 ;; movdf pattern avoids the use of integer registers for FP operations
2913 ;; when optimizing for size.
2915 (define_insn "*movdf_nointeger"
2916 [(set (match_operand:DF 0 "nonimmediate_operand"
2917 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2918 (match_operand:DF 1 "general_operand"
2919 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2920 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2921 && ((optimize_function_for_size_p (cfun)
2922 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2923 && (reload_in_progress || reload_completed
2924 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2925 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2926 && optimize_function_for_size_p (cfun)
2927 && !memory_operand (operands[0], DFmode)
2928 && standard_80387_constant_p (operands[1]))
2929 || GET_CODE (operands[1]) != CONST_DOUBLE
2930 || ((optimize_function_for_size_p (cfun)
2931 || !TARGET_MEMORY_MISMATCH_STALL
2932 || reload_in_progress || reload_completed)
2933 && memory_operand (operands[0], DFmode)))"
2935 switch (which_alternative)
2939 return output_387_reg_move (insn, operands);
2942 return standard_80387_constant_opcode (operands[1]);
2948 switch (get_attr_mode (insn))
2951 return "%vxorps\t%0, %d0";
2953 return "%vxorpd\t%0, %d0";
2955 return "%vpxor\t%0, %d0";
2962 switch (get_attr_mode (insn))
2965 return "%vmovaps\t{%1, %0|%0, %1}";
2967 return "%vmovapd\t{%1, %0|%0, %1}";
2969 return "%vmovdqa\t{%1, %0|%0, %1}";
2971 return "%vmovq\t{%1, %0|%0, %1}";
2975 if (REG_P (operands[0]) && REG_P (operands[1]))
2976 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2978 return "vmovsd\t{%1, %0|%0, %1}";
2981 return "movsd\t{%1, %0|%0, %1}";
2985 if (REG_P (operands[0]))
2986 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2988 return "vmovlpd\t{%1, %0|%0, %1}";
2991 return "movlpd\t{%1, %0|%0, %1}";
2995 if (REG_P (operands[0]))
2996 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2998 return "vmovlps\t{%1, %0|%0, %1}";
3001 return "movlps\t{%1, %0|%0, %1}";
3010 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3011 (set (attr "prefix")
3012 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3013 (const_string "orig")
3014 (const_string "maybe_vex")))
3016 (cond [(eq_attr "alternative" "0,1,2")
3018 (eq_attr "alternative" "3,4")
3021 /* For SSE1, we have many fewer alternatives. */
3022 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3023 (cond [(eq_attr "alternative" "5,6")
3024 (const_string "V4SF")
3026 (const_string "V2SF"))
3028 /* xorps is one byte shorter. */
3029 (eq_attr "alternative" "5")
3030 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3032 (const_string "V4SF")
3033 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3037 (const_string "V2DF"))
3039 /* For architectures resolving dependencies on
3040 whole SSE registers use APD move to break dependency
3041 chains, otherwise use short move to avoid extra work.
3043 movaps encodes one byte shorter. */
3044 (eq_attr "alternative" "6")
3046 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3048 (const_string "V4SF")
3049 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3051 (const_string "V2DF")
3053 (const_string "DF"))
3054 /* For architectures resolving dependencies on register
3055 parts we may avoid extra work to zero out upper part
3057 (eq_attr "alternative" "7")
3059 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3061 (const_string "V1DF")
3062 (const_string "DF"))
3064 (const_string "DF")))])
3066 (define_insn "*movdf_integer_rex64"
3067 [(set (match_operand:DF 0 "nonimmediate_operand"
3068 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3069 (match_operand:DF 1 "general_operand"
3070 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3071 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3072 && (reload_in_progress || reload_completed
3073 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3074 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3075 && optimize_function_for_size_p (cfun)
3076 && standard_80387_constant_p (operands[1]))
3077 || GET_CODE (operands[1]) != CONST_DOUBLE
3078 || memory_operand (operands[0], DFmode))"
3080 switch (which_alternative)
3084 return output_387_reg_move (insn, operands);
3087 return standard_80387_constant_opcode (operands[1]);
3094 switch (get_attr_mode (insn))
3097 return "%vxorps\t%0, %d0";
3099 return "%vxorpd\t%0, %d0";
3101 return "%vpxor\t%0, %d0";
3108 switch (get_attr_mode (insn))
3111 return "%vmovaps\t{%1, %0|%0, %1}";
3113 return "%vmovapd\t{%1, %0|%0, %1}";
3115 return "%vmovdqa\t{%1, %0|%0, %1}";
3117 return "%vmovq\t{%1, %0|%0, %1}";
3121 if (REG_P (operands[0]) && REG_P (operands[1]))
3122 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3124 return "vmovsd\t{%1, %0|%0, %1}";
3127 return "movsd\t{%1, %0|%0, %1}";
3129 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3131 return "%vmovlps\t{%1, %d0|%d0, %1}";
3138 return "%vmovd\t{%1, %0|%0, %1}";
3144 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3145 (set (attr "prefix")
3146 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3147 (const_string "orig")
3148 (const_string "maybe_vex")))
3150 (cond [(eq_attr "alternative" "0,1,2")
3152 (eq_attr "alternative" "3,4,9,10")
3155 /* For SSE1, we have many fewer alternatives. */
3156 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3157 (cond [(eq_attr "alternative" "5,6")
3158 (const_string "V4SF")
3160 (const_string "V2SF"))
3162 /* xorps is one byte shorter. */
3163 (eq_attr "alternative" "5")
3164 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3166 (const_string "V4SF")
3167 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3171 (const_string "V2DF"))
3173 /* For architectures resolving dependencies on
3174 whole SSE registers use APD move to break dependency
3175 chains, otherwise use short move to avoid extra work.
3177 movaps encodes one byte shorter. */
3178 (eq_attr "alternative" "6")
3180 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3182 (const_string "V4SF")
3183 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3185 (const_string "V2DF")
3187 (const_string "DF"))
3188 /* For architectures resolving dependencies on register
3189 parts we may avoid extra work to zero out upper part
3191 (eq_attr "alternative" "7")
3193 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3195 (const_string "V1DF")
3196 (const_string "DF"))
3198 (const_string "DF")))])
3200 (define_insn "*movdf_integer"
3201 [(set (match_operand:DF 0 "nonimmediate_operand"
3202 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3203 (match_operand:DF 1 "general_operand"
3204 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3205 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3206 && optimize_function_for_speed_p (cfun)
3207 && TARGET_INTEGER_DFMODE_MOVES
3208 && (reload_in_progress || reload_completed
3209 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3211 && optimize_function_for_size_p (cfun)
3212 && standard_80387_constant_p (operands[1]))
3213 || GET_CODE (operands[1]) != CONST_DOUBLE
3214 || memory_operand (operands[0], DFmode))"
3216 switch (which_alternative)
3220 return output_387_reg_move (insn, operands);
3223 return standard_80387_constant_opcode (operands[1]);
3230 switch (get_attr_mode (insn))
3233 return "xorps\t%0, %0";
3235 return "xorpd\t%0, %0";
3237 return "pxor\t%0, %0";
3244 switch (get_attr_mode (insn))
3247 return "movaps\t{%1, %0|%0, %1}";
3249 return "movapd\t{%1, %0|%0, %1}";
3251 return "movdqa\t{%1, %0|%0, %1}";
3253 return "movq\t{%1, %0|%0, %1}";
3255 return "movsd\t{%1, %0|%0, %1}";
3257 return "movlpd\t{%1, %0|%0, %1}";
3259 return "movlps\t{%1, %0|%0, %1}";
3268 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3270 (cond [(eq_attr "alternative" "0,1,2")
3272 (eq_attr "alternative" "3,4")
3275 /* For SSE1, we have many fewer alternatives. */
3276 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3277 (cond [(eq_attr "alternative" "5,6")
3278 (const_string "V4SF")
3280 (const_string "V2SF"))
3282 /* xorps is one byte shorter. */
3283 (eq_attr "alternative" "5")
3284 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3286 (const_string "V4SF")
3287 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3291 (const_string "V2DF"))
3293 /* For architectures resolving dependencies on
3294 whole SSE registers use APD move to break dependency
3295 chains, otherwise use short move to avoid extra work.
3297 movaps encodes one byte shorter. */
3298 (eq_attr "alternative" "6")
3300 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3302 (const_string "V4SF")
3303 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3305 (const_string "V2DF")
3307 (const_string "DF"))
3308 /* For architectures resolving dependencies on register
3309 parts we may avoid extra work to zero out upper part
3311 (eq_attr "alternative" "7")
3313 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3315 (const_string "V1DF")
3316 (const_string "DF"))
3318 (const_string "DF")))])
3321 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3322 (match_operand:DF 1 "general_operand" ""))]
3324 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3325 && ! (ANY_FP_REG_P (operands[0]) ||
3326 (GET_CODE (operands[0]) == SUBREG
3327 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3328 && ! (ANY_FP_REG_P (operands[1]) ||
3329 (GET_CODE (operands[1]) == SUBREG
3330 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3332 "ix86_split_long_move (operands); DONE;")
3334 (define_insn "*swapdf"
3335 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3336 (match_operand:DF 1 "fp_register_operand" "+f"))
3339 "reload_completed || TARGET_80387"
3341 if (STACK_TOP_P (operands[0]))
3346 [(set_attr "type" "fxch")
3347 (set_attr "mode" "DF")])
3349 (define_expand "movxf"
3350 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3351 (match_operand:XF 1 "general_operand" ""))]
3353 "ix86_expand_move (XFmode, operands); DONE;")
3355 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3356 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3357 ;; Pushing using integer instructions is longer except for constants
3358 ;; and direct memory references.
3359 ;; (assuming that any given constant is pushed only once, but this ought to be
3360 ;; handled elsewhere).
3362 (define_insn "*pushxf_nointeger"
3363 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3364 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3365 "optimize_function_for_size_p (cfun)"
3367 /* This insn should be already split before reg-stack. */
3370 [(set_attr "type" "multi")
3371 (set_attr "unit" "i387,*,*")
3372 (set_attr "mode" "XF,SI,SI")])
3374 (define_insn "*pushxf_integer"
3375 [(set (match_operand:XF 0 "push_operand" "=<,<")
3376 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3377 "optimize_function_for_speed_p (cfun)"
3379 /* This insn should be already split before reg-stack. */
3382 [(set_attr "type" "multi")
3383 (set_attr "unit" "i387,*")
3384 (set_attr "mode" "XF,SI")])
3387 [(set (match_operand 0 "push_operand" "")
3388 (match_operand 1 "general_operand" ""))]
3390 && (GET_MODE (operands[0]) == XFmode
3391 || GET_MODE (operands[0]) == DFmode)
3392 && !ANY_FP_REG_P (operands[1])"
3394 "ix86_split_long_move (operands); DONE;")
3397 [(set (match_operand:XF 0 "push_operand" "")
3398 (match_operand:XF 1 "any_fp_register_operand" ""))]
3400 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3401 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3402 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3404 ;; Do not use integer registers when optimizing for size
3405 (define_insn "*movxf_nointeger"
3406 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3407 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3408 "optimize_function_for_size_p (cfun)
3409 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3410 && (reload_in_progress || reload_completed
3411 || standard_80387_constant_p (operands[1])
3412 || GET_CODE (operands[1]) != CONST_DOUBLE
3413 || memory_operand (operands[0], XFmode))"
3415 switch (which_alternative)
3419 return output_387_reg_move (insn, operands);
3422 return standard_80387_constant_opcode (operands[1]);
3430 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3431 (set_attr "mode" "XF,XF,XF,SI,SI")])
3433 (define_insn "*movxf_integer"
3434 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3435 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3436 "optimize_function_for_speed_p (cfun)
3437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3438 && (reload_in_progress || reload_completed
3439 || GET_CODE (operands[1]) != CONST_DOUBLE
3440 || memory_operand (operands[0], XFmode))"
3442 switch (which_alternative)
3446 return output_387_reg_move (insn, operands);
3449 return standard_80387_constant_opcode (operands[1]);
3458 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3459 (set_attr "mode" "XF,XF,XF,SI,SI")])
3461 (define_expand "movtf"
3462 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3463 (match_operand:TF 1 "nonimmediate_operand" ""))]
3466 ix86_expand_move (TFmode, operands);
3470 (define_insn "*movtf_internal"
3471 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3472 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3474 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3476 switch (which_alternative)
3480 if (get_attr_mode (insn) == MODE_V4SF)
3481 return "%vmovaps\t{%1, %0|%0, %1}";
3483 return "%vmovdqa\t{%1, %0|%0, %1}";
3485 if (get_attr_mode (insn) == MODE_V4SF)
3486 return "%vxorps\t%0, %d0";
3488 return "%vpxor\t%0, %d0";
3496 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3497 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3499 (cond [(eq_attr "alternative" "0,2")
3501 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3503 (const_string "V4SF")
3504 (const_string "TI"))
3505 (eq_attr "alternative" "1")
3507 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3509 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3511 (const_string "V4SF")
3512 (const_string "TI"))]
3513 (const_string "DI")))])
3515 (define_insn "*pushtf_sse"
3516 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3517 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3520 /* This insn should be already split before reg-stack. */
3523 [(set_attr "type" "multi")
3524 (set_attr "unit" "sse,*,*")
3525 (set_attr "mode" "TF,SI,SI")])
3528 [(set (match_operand:TF 0 "push_operand" "")
3529 (match_operand:TF 1 "general_operand" ""))]
3530 "TARGET_SSE2 && reload_completed
3531 && !SSE_REG_P (operands[1])"
3533 "ix86_split_long_move (operands); DONE;")
3536 [(set (match_operand:TF 0 "push_operand" "")
3537 (match_operand:TF 1 "any_fp_register_operand" ""))]
3539 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3540 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3544 [(set (match_operand 0 "nonimmediate_operand" "")
3545 (match_operand 1 "general_operand" ""))]
3547 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3548 && GET_MODE (operands[0]) == XFmode
3549 && ! (ANY_FP_REG_P (operands[0]) ||
3550 (GET_CODE (operands[0]) == SUBREG
3551 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3552 && ! (ANY_FP_REG_P (operands[1]) ||
3553 (GET_CODE (operands[1]) == SUBREG
3554 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3556 "ix86_split_long_move (operands); DONE;")
3559 [(set (match_operand 0 "register_operand" "")
3560 (match_operand 1 "memory_operand" ""))]
3562 && MEM_P (operands[1])
3563 && (GET_MODE (operands[0]) == TFmode
3564 || GET_MODE (operands[0]) == XFmode
3565 || GET_MODE (operands[0]) == SFmode
3566 || GET_MODE (operands[0]) == DFmode)
3567 && (operands[2] = find_constant_src (insn))"
3568 [(set (match_dup 0) (match_dup 2))]
3570 rtx c = operands[2];
3571 rtx r = operands[0];
3573 if (GET_CODE (r) == SUBREG)
3578 if (!standard_sse_constant_p (c))
3581 else if (FP_REG_P (r))
3583 if (!standard_80387_constant_p (c))
3586 else if (MMX_REG_P (r))
3591 [(set (match_operand 0 "register_operand" "")
3592 (float_extend (match_operand 1 "memory_operand" "")))]
3594 && MEM_P (operands[1])
3595 && (GET_MODE (operands[0]) == TFmode
3596 || GET_MODE (operands[0]) == XFmode
3597 || GET_MODE (operands[0]) == SFmode
3598 || GET_MODE (operands[0]) == DFmode)
3599 && (operands[2] = find_constant_src (insn))"
3600 [(set (match_dup 0) (match_dup 2))]
3602 rtx c = operands[2];
3603 rtx r = operands[0];
3605 if (GET_CODE (r) == SUBREG)
3610 if (!standard_sse_constant_p (c))
3613 else if (FP_REG_P (r))
3615 if (!standard_80387_constant_p (c))
3618 else if (MMX_REG_P (r))
3622 (define_insn "swapxf"
3623 [(set (match_operand:XF 0 "register_operand" "+f")
3624 (match_operand:XF 1 "register_operand" "+f"))
3629 if (STACK_TOP_P (operands[0]))
3634 [(set_attr "type" "fxch")
3635 (set_attr "mode" "XF")])
3637 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3639 [(set (match_operand:X87MODEF 0 "register_operand" "")
3640 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3641 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3642 && (standard_80387_constant_p (operands[1]) == 8
3643 || standard_80387_constant_p (operands[1]) == 9)"
3644 [(set (match_dup 0)(match_dup 1))
3646 (neg:X87MODEF (match_dup 0)))]
3650 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3651 if (real_isnegzero (&r))
3652 operands[1] = CONST0_RTX (<MODE>mode);
3654 operands[1] = CONST1_RTX (<MODE>mode);
3658 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3659 (match_operand:TF 1 "general_operand" ""))]
3661 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3663 "ix86_split_long_move (operands); DONE;")
3665 ;; Zero extension instructions
3667 (define_expand "zero_extendhisi2"
3668 [(set (match_operand:SI 0 "register_operand" "")
3669 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3672 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3674 operands[1] = force_reg (HImode, operands[1]);
3675 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3680 (define_insn "zero_extendhisi2_and"
3681 [(set (match_operand:SI 0 "register_operand" "=r")
3682 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3683 (clobber (reg:CC FLAGS_REG))]
3684 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3686 [(set_attr "type" "alu1")
3687 (set_attr "mode" "SI")])
3690 [(set (match_operand:SI 0 "register_operand" "")
3691 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3692 (clobber (reg:CC FLAGS_REG))]
3693 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3694 && optimize_function_for_speed_p (cfun)"
3695 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3696 (clobber (reg:CC FLAGS_REG))])]
3699 (define_insn "*zero_extendhisi2_movzwl"
3700 [(set (match_operand:SI 0 "register_operand" "=r")
3701 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3702 "!TARGET_ZERO_EXTEND_WITH_AND
3703 || optimize_function_for_size_p (cfun)"
3704 "movz{wl|x}\t{%1, %0|%0, %1}"
3705 [(set_attr "type" "imovx")
3706 (set_attr "mode" "SI")])
3708 (define_expand "zero_extendqihi2"
3710 [(set (match_operand:HI 0 "register_operand" "")
3711 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3712 (clobber (reg:CC FLAGS_REG))])]
3716 (define_insn "*zero_extendqihi2_and"
3717 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3718 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3719 (clobber (reg:CC FLAGS_REG))]
3720 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3722 [(set_attr "type" "alu1")
3723 (set_attr "mode" "HI")])
3725 (define_insn "*zero_extendqihi2_movzbw_and"
3726 [(set (match_operand:HI 0 "register_operand" "=r,r")
3727 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3728 (clobber (reg:CC FLAGS_REG))]
3729 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3731 [(set_attr "type" "imovx,alu1")
3732 (set_attr "mode" "HI")])
3734 ; zero extend to SImode here to avoid partial register stalls
3735 (define_insn "*zero_extendqihi2_movzbl"
3736 [(set (match_operand:HI 0 "register_operand" "=r")
3737 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3738 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3739 && reload_completed"
3740 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3744 ;; For the movzbw case strip only the clobber
3746 [(set (match_operand:HI 0 "register_operand" "")
3747 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3748 (clobber (reg:CC FLAGS_REG))]
3750 && (!TARGET_ZERO_EXTEND_WITH_AND
3751 || optimize_function_for_size_p (cfun))
3752 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3753 [(set (match_operand:HI 0 "register_operand" "")
3754 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3756 ;; When source and destination does not overlap, clear destination
3757 ;; first and then do the movb
3759 [(set (match_operand:HI 0 "register_operand" "")
3760 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3761 (clobber (reg:CC FLAGS_REG))]
3763 && ANY_QI_REG_P (operands[0])
3764 && (TARGET_ZERO_EXTEND_WITH_AND
3765 && optimize_function_for_speed_p (cfun))
3766 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3767 [(set (match_dup 0) (const_int 0))
3768 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3769 "operands[2] = gen_lowpart (QImode, operands[0]);")
3771 ;; Rest is handled by single and.
3773 [(set (match_operand:HI 0 "register_operand" "")
3774 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3775 (clobber (reg:CC FLAGS_REG))]
3777 && true_regnum (operands[0]) == true_regnum (operands[1])"
3778 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3779 (clobber (reg:CC FLAGS_REG))])]
3782 (define_expand "zero_extendqisi2"
3784 [(set (match_operand:SI 0 "register_operand" "")
3785 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3786 (clobber (reg:CC FLAGS_REG))])]
3790 (define_insn "*zero_extendqisi2_and"
3791 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3792 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3793 (clobber (reg:CC FLAGS_REG))]
3794 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3796 [(set_attr "type" "alu1")
3797 (set_attr "mode" "SI")])
3799 (define_insn "*zero_extendqisi2_movzbw_and"
3800 [(set (match_operand:SI 0 "register_operand" "=r,r")
3801 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3802 (clobber (reg:CC FLAGS_REG))]
3803 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3805 [(set_attr "type" "imovx,alu1")
3806 (set_attr "mode" "SI")])
3808 (define_insn "*zero_extendqisi2_movzbw"
3809 [(set (match_operand:SI 0 "register_operand" "=r")
3810 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3811 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3812 && reload_completed"
3813 "movz{bl|x}\t{%1, %0|%0, %1}"
3814 [(set_attr "type" "imovx")
3815 (set_attr "mode" "SI")])
3817 ;; For the movzbl case strip only the clobber
3819 [(set (match_operand:SI 0 "register_operand" "")
3820 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3821 (clobber (reg:CC FLAGS_REG))]
3823 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3824 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3826 (zero_extend:SI (match_dup 1)))])
3828 ;; When source and destination does not overlap, clear destination
3829 ;; first and then do the movb
3831 [(set (match_operand:SI 0 "register_operand" "")
3832 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3833 (clobber (reg:CC FLAGS_REG))]
3835 && ANY_QI_REG_P (operands[0])
3836 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3837 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3838 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3839 [(set (match_dup 0) (const_int 0))
3840 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3841 "operands[2] = gen_lowpart (QImode, operands[0]);")
3843 ;; Rest is handled by single and.
3845 [(set (match_operand:SI 0 "register_operand" "")
3846 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3847 (clobber (reg:CC FLAGS_REG))]
3849 && true_regnum (operands[0]) == true_regnum (operands[1])"
3850 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3851 (clobber (reg:CC FLAGS_REG))])]
3854 ;; %%% Kill me once multi-word ops are sane.
3855 (define_expand "zero_extendsidi2"
3856 [(set (match_operand:DI 0 "register_operand" "")
3857 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3862 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3867 (define_insn "zero_extendsidi2_32"
3868 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3870 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3871 (clobber (reg:CC FLAGS_REG))]
3877 movd\t{%1, %0|%0, %1}
3878 movd\t{%1, %0|%0, %1}
3879 %vmovd\t{%1, %0|%0, %1}
3880 %vmovd\t{%1, %0|%0, %1}"
3881 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3882 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3883 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3885 (define_insn "zero_extendsidi2_rex64"
3886 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3888 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3891 mov\t{%k1, %k0|%k0, %k1}
3893 movd\t{%1, %0|%0, %1}
3894 movd\t{%1, %0|%0, %1}
3895 %vmovd\t{%1, %0|%0, %1}
3896 %vmovd\t{%1, %0|%0, %1}"
3897 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3898 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3899 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3902 [(set (match_operand:DI 0 "memory_operand" "")
3903 (zero_extend:DI (match_dup 0)))]
3905 [(set (match_dup 4) (const_int 0))]
3906 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3909 [(set (match_operand:DI 0 "register_operand" "")
3910 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3911 (clobber (reg:CC FLAGS_REG))]
3912 "!TARGET_64BIT && reload_completed
3913 && true_regnum (operands[0]) == true_regnum (operands[1])"
3914 [(set (match_dup 4) (const_int 0))]
3915 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3918 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3919 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3920 (clobber (reg:CC FLAGS_REG))]
3921 "!TARGET_64BIT && reload_completed
3922 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3923 [(set (match_dup 3) (match_dup 1))
3924 (set (match_dup 4) (const_int 0))]
3925 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3927 (define_insn "zero_extendhidi2"
3928 [(set (match_operand:DI 0 "register_operand" "=r")
3929 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3931 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "DI")])
3935 (define_insn "zero_extendqidi2"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3939 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3940 [(set_attr "type" "imovx")
3941 (set_attr "mode" "DI")])
3943 ;; Sign extension instructions
3945 (define_expand "extendsidi2"
3946 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3947 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3948 (clobber (reg:CC FLAGS_REG))
3949 (clobber (match_scratch:SI 2 ""))])]
3954 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3959 (define_insn "*extendsidi2_1"
3960 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3961 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3962 (clobber (reg:CC FLAGS_REG))
3963 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3967 (define_insn "extendsidi2_rex64"
3968 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3969 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3973 movs{lq|x}\t{%1,%0|%0, %1}"
3974 [(set_attr "type" "imovx")
3975 (set_attr "mode" "DI")
3976 (set_attr "prefix_0f" "0")
3977 (set_attr "modrm" "0,1")])
3979 (define_insn "extendhidi2"
3980 [(set (match_operand:DI 0 "register_operand" "=r")
3981 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3983 "movs{wq|x}\t{%1,%0|%0, %1}"
3984 [(set_attr "type" "imovx")
3985 (set_attr "mode" "DI")])
3987 (define_insn "extendqidi2"
3988 [(set (match_operand:DI 0 "register_operand" "=r")
3989 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3991 "movs{bq|x}\t{%1,%0|%0, %1}"
3992 [(set_attr "type" "imovx")
3993 (set_attr "mode" "DI")])
3995 ;; Extend to memory case when source register does die.
3997 [(set (match_operand:DI 0 "memory_operand" "")
3998 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3999 (clobber (reg:CC FLAGS_REG))
4000 (clobber (match_operand:SI 2 "register_operand" ""))]
4002 && dead_or_set_p (insn, operands[1])
4003 && !reg_mentioned_p (operands[1], operands[0]))"
4004 [(set (match_dup 3) (match_dup 1))
4005 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4006 (clobber (reg:CC FLAGS_REG))])
4007 (set (match_dup 4) (match_dup 1))]
4008 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4010 ;; Extend to memory case when source register does not die.
4012 [(set (match_operand:DI 0 "memory_operand" "")
4013 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4014 (clobber (reg:CC FLAGS_REG))
4015 (clobber (match_operand:SI 2 "register_operand" ""))]
4019 split_di (&operands[0], 1, &operands[3], &operands[4]);
4021 emit_move_insn (operands[3], operands[1]);
4023 /* Generate a cltd if possible and doing so it profitable. */
4024 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4025 && true_regnum (operands[1]) == AX_REG
4026 && true_regnum (operands[2]) == DX_REG)
4028 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4032 emit_move_insn (operands[2], operands[1]);
4033 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4035 emit_move_insn (operands[4], operands[2]);
4039 ;; Extend to register case. Optimize case where source and destination
4040 ;; registers match and cases where we can use cltd.
4042 [(set (match_operand:DI 0 "register_operand" "")
4043 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4044 (clobber (reg:CC FLAGS_REG))
4045 (clobber (match_scratch:SI 2 ""))]
4049 split_di (&operands[0], 1, &operands[3], &operands[4]);
4051 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4052 emit_move_insn (operands[3], operands[1]);
4054 /* Generate a cltd if possible and doing so it profitable. */
4055 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4056 && true_regnum (operands[3]) == AX_REG)
4058 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4062 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4063 emit_move_insn (operands[4], operands[1]);
4065 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4069 (define_insn "extendhisi2"
4070 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4071 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4074 switch (get_attr_prefix_0f (insn))
4077 return "{cwtl|cwde}";
4079 return "movs{wl|x}\t{%1,%0|%0, %1}";
4082 [(set_attr "type" "imovx")
4083 (set_attr "mode" "SI")
4084 (set (attr "prefix_0f")
4085 ;; movsx is short decodable while cwtl is vector decoded.
4086 (if_then_else (and (eq_attr "cpu" "!k6")
4087 (eq_attr "alternative" "0"))
4089 (const_string "1")))
4091 (if_then_else (eq_attr "prefix_0f" "0")
4093 (const_string "1")))])
4095 (define_insn "*extendhisi2_zext"
4096 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4098 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4101 switch (get_attr_prefix_0f (insn))
4104 return "{cwtl|cwde}";
4106 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4109 [(set_attr "type" "imovx")
4110 (set_attr "mode" "SI")
4111 (set (attr "prefix_0f")
4112 ;; movsx is short decodable while cwtl is vector decoded.
4113 (if_then_else (and (eq_attr "cpu" "!k6")
4114 (eq_attr "alternative" "0"))
4116 (const_string "1")))
4118 (if_then_else (eq_attr "prefix_0f" "0")
4120 (const_string "1")))])
4122 (define_insn "extendqihi2"
4123 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4124 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4127 switch (get_attr_prefix_0f (insn))
4130 return "{cbtw|cbw}";
4132 return "movs{bw|x}\t{%1,%0|%0, %1}";
4135 [(set_attr "type" "imovx")
4136 (set_attr "mode" "HI")
4137 (set (attr "prefix_0f")
4138 ;; movsx is short decodable while cwtl is vector decoded.
4139 (if_then_else (and (eq_attr "cpu" "!k6")
4140 (eq_attr "alternative" "0"))
4142 (const_string "1")))
4144 (if_then_else (eq_attr "prefix_0f" "0")
4146 (const_string "1")))])
4148 (define_insn "extendqisi2"
4149 [(set (match_operand:SI 0 "register_operand" "=r")
4150 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4152 "movs{bl|x}\t{%1,%0|%0, %1}"
4153 [(set_attr "type" "imovx")
4154 (set_attr "mode" "SI")])
4156 (define_insn "*extendqisi2_zext"
4157 [(set (match_operand:DI 0 "register_operand" "=r")
4159 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4161 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4162 [(set_attr "type" "imovx")
4163 (set_attr "mode" "SI")])
4165 ;; Conversions between float and double.
4167 ;; These are all no-ops in the model used for the 80387. So just
4170 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4171 (define_insn "*dummy_extendsfdf2"
4172 [(set (match_operand:DF 0 "push_operand" "=<")
4173 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4178 [(set (match_operand:DF 0 "push_operand" "")
4179 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4181 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4182 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4184 (define_insn "*dummy_extendsfxf2"
4185 [(set (match_operand:XF 0 "push_operand" "=<")
4186 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4191 [(set (match_operand:XF 0 "push_operand" "")
4192 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4194 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4195 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4196 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4199 [(set (match_operand:XF 0 "push_operand" "")
4200 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4202 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4203 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4204 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4206 (define_expand "extendsfdf2"
4207 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4208 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4209 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4211 /* ??? Needed for compress_float_constant since all fp constants
4212 are LEGITIMATE_CONSTANT_P. */
4213 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4215 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4216 && standard_80387_constant_p (operands[1]) > 0)
4218 operands[1] = simplify_const_unary_operation
4219 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4220 emit_move_insn_1 (operands[0], operands[1]);
4223 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4227 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4229 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4231 We do the conversion post reload to avoid producing of 128bit spills
4232 that might lead to ICE on 32bit target. The sequence unlikely combine
4235 [(set (match_operand:DF 0 "register_operand" "")
4237 (match_operand:SF 1 "nonimmediate_operand" "")))]
4238 "TARGET_USE_VECTOR_FP_CONVERTS
4239 && optimize_insn_for_speed_p ()
4240 && reload_completed && SSE_REG_P (operands[0])"
4245 (parallel [(const_int 0) (const_int 1)]))))]
4247 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4248 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4249 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4250 Try to avoid move when unpacking can be done in source. */
4251 if (REG_P (operands[1]))
4253 /* If it is unsafe to overwrite upper half of source, we need
4254 to move to destination and unpack there. */
4255 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4256 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4257 && true_regnum (operands[0]) != true_regnum (operands[1]))
4259 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4260 emit_move_insn (tmp, operands[1]);
4263 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4264 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4267 emit_insn (gen_vec_setv4sf_0 (operands[3],
4268 CONST0_RTX (V4SFmode), operands[1]));
4271 (define_insn "*extendsfdf2_mixed"
4272 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4274 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4275 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4277 switch (which_alternative)
4281 return output_387_reg_move (insn, operands);
4284 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4290 [(set_attr "type" "fmov,fmov,ssecvt")
4291 (set_attr "prefix" "orig,orig,maybe_vex")
4292 (set_attr "mode" "SF,XF,DF")])
4294 (define_insn "*extendsfdf2_sse"
4295 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4296 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4297 "TARGET_SSE2 && TARGET_SSE_MATH"
4298 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4299 [(set_attr "type" "ssecvt")
4300 (set_attr "prefix" "maybe_vex")
4301 (set_attr "mode" "DF")])
4303 (define_insn "*extendsfdf2_i387"
4304 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4305 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4307 "* return output_387_reg_move (insn, operands);"
4308 [(set_attr "type" "fmov")
4309 (set_attr "mode" "SF,XF")])
4311 (define_expand "extend<mode>xf2"
4312 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4313 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4316 /* ??? Needed for compress_float_constant since all fp constants
4317 are LEGITIMATE_CONSTANT_P. */
4318 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4320 if (standard_80387_constant_p (operands[1]) > 0)
4322 operands[1] = simplify_const_unary_operation
4323 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4324 emit_move_insn_1 (operands[0], operands[1]);
4327 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4331 (define_insn "*extend<mode>xf2_i387"
4332 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4334 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4336 "* return output_387_reg_move (insn, operands);"
4337 [(set_attr "type" "fmov")
4338 (set_attr "mode" "<MODE>,XF")])
4340 ;; %%% This seems bad bad news.
4341 ;; This cannot output into an f-reg because there is no way to be sure
4342 ;; of truncating in that case. Otherwise this is just like a simple move
4343 ;; insn. So we pretend we can output to a reg in order to get better
4344 ;; register preferencing, but we really use a stack slot.
4346 ;; Conversion from DFmode to SFmode.
4348 (define_expand "truncdfsf2"
4349 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4351 (match_operand:DF 1 "nonimmediate_operand" "")))]
4352 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4354 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4356 else if (flag_unsafe_math_optimizations)
4360 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4361 rtx temp = assign_386_stack_local (SFmode, slot);
4362 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4367 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4369 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4371 We do the conversion post reload to avoid producing of 128bit spills
4372 that might lead to ICE on 32bit target. The sequence unlikely combine
4375 [(set (match_operand:SF 0 "register_operand" "")
4377 (match_operand:DF 1 "nonimmediate_operand" "")))]
4378 "TARGET_USE_VECTOR_FP_CONVERTS
4379 && optimize_insn_for_speed_p ()
4380 && reload_completed && SSE_REG_P (operands[0])"
4383 (float_truncate:V2SF
4387 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4388 operands[3] = CONST0_RTX (V2SFmode);
4389 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4390 /* Use movsd for loading from memory, unpcklpd for registers.
4391 Try to avoid move when unpacking can be done in source, or SSE3
4392 movddup is available. */
4393 if (REG_P (operands[1]))
4396 && true_regnum (operands[0]) != true_regnum (operands[1])
4397 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4398 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4400 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4401 emit_move_insn (tmp, operands[1]);
4404 else if (!TARGET_SSE3)
4405 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4406 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4409 emit_insn (gen_sse2_loadlpd (operands[4],
4410 CONST0_RTX (V2DFmode), operands[1]));
4413 (define_expand "truncdfsf2_with_temp"
4414 [(parallel [(set (match_operand:SF 0 "" "")
4415 (float_truncate:SF (match_operand:DF 1 "" "")))
4416 (clobber (match_operand:SF 2 "" ""))])]
4419 (define_insn "*truncdfsf_fast_mixed"
4420 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4422 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4423 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4425 switch (which_alternative)
4428 return output_387_reg_move (insn, operands);
4430 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4435 [(set_attr "type" "fmov,ssecvt")
4436 (set_attr "prefix" "orig,maybe_vex")
4437 (set_attr "mode" "SF")])
4439 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4440 ;; because nothing we do here is unsafe.
4441 (define_insn "*truncdfsf_fast_sse"
4442 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4444 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4445 "TARGET_SSE2 && TARGET_SSE_MATH"
4446 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4447 [(set_attr "type" "ssecvt")
4448 (set_attr "prefix" "maybe_vex")
4449 (set_attr "mode" "SF")])
4451 (define_insn "*truncdfsf_fast_i387"
4452 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4454 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4455 "TARGET_80387 && flag_unsafe_math_optimizations"
4456 "* return output_387_reg_move (insn, operands);"
4457 [(set_attr "type" "fmov")
4458 (set_attr "mode" "SF")])
4460 (define_insn "*truncdfsf_mixed"
4461 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4463 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4464 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4465 "TARGET_MIX_SSE_I387"
4467 switch (which_alternative)
4470 return output_387_reg_move (insn, operands);
4472 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4478 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4479 (set_attr "unit" "*,*,i387,i387,i387")
4480 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4481 (set_attr "mode" "SF")])
4483 (define_insn "*truncdfsf_i387"
4484 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4486 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4487 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4490 switch (which_alternative)
4493 return output_387_reg_move (insn, operands);
4499 [(set_attr "type" "fmov,multi,multi,multi")
4500 (set_attr "unit" "*,i387,i387,i387")
4501 (set_attr "mode" "SF")])
4503 (define_insn "*truncdfsf2_i387_1"
4504 [(set (match_operand:SF 0 "memory_operand" "=m")
4506 (match_operand:DF 1 "register_operand" "f")))]
4508 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4509 && !TARGET_MIX_SSE_I387"
4510 "* return output_387_reg_move (insn, operands);"
4511 [(set_attr "type" "fmov")
4512 (set_attr "mode" "SF")])
4515 [(set (match_operand:SF 0 "register_operand" "")
4517 (match_operand:DF 1 "fp_register_operand" "")))
4518 (clobber (match_operand 2 "" ""))]
4520 [(set (match_dup 2) (match_dup 1))
4521 (set (match_dup 0) (match_dup 2))]
4523 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4526 ;; Conversion from XFmode to {SF,DF}mode
4528 (define_expand "truncxf<mode>2"
4529 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4530 (float_truncate:MODEF
4531 (match_operand:XF 1 "register_operand" "")))
4532 (clobber (match_dup 2))])]
4535 if (flag_unsafe_math_optimizations)
4537 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4538 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4539 if (reg != operands[0])
4540 emit_move_insn (operands[0], reg);
4545 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4546 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4550 (define_insn "*truncxfsf2_mixed"
4551 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4553 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4554 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4557 gcc_assert (!which_alternative);
4558 return output_387_reg_move (insn, operands);
4560 [(set_attr "type" "fmov,multi,multi,multi")
4561 (set_attr "unit" "*,i387,i387,i387")
4562 (set_attr "mode" "SF")])
4564 (define_insn "*truncxfdf2_mixed"
4565 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4567 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4568 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4571 gcc_assert (!which_alternative);
4572 return output_387_reg_move (insn, operands);
4574 [(set_attr "type" "fmov,multi,multi,multi")
4575 (set_attr "unit" "*,i387,i387,i387")
4576 (set_attr "mode" "DF")])
4578 (define_insn "truncxf<mode>2_i387_noop"
4579 [(set (match_operand:MODEF 0 "register_operand" "=f")
4580 (float_truncate:MODEF
4581 (match_operand:XF 1 "register_operand" "f")))]
4582 "TARGET_80387 && flag_unsafe_math_optimizations"
4583 "* return output_387_reg_move (insn, operands);"
4584 [(set_attr "type" "fmov")
4585 (set_attr "mode" "<MODE>")])
4587 (define_insn "*truncxf<mode>2_i387"
4588 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4589 (float_truncate:MODEF
4590 (match_operand:XF 1 "register_operand" "f")))]
4592 "* return output_387_reg_move (insn, operands);"
4593 [(set_attr "type" "fmov")
4594 (set_attr "mode" "<MODE>")])
4597 [(set (match_operand:MODEF 0 "register_operand" "")
4598 (float_truncate:MODEF
4599 (match_operand:XF 1 "register_operand" "")))
4600 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4601 "TARGET_80387 && reload_completed"
4602 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4603 (set (match_dup 0) (match_dup 2))]
4607 [(set (match_operand:MODEF 0 "memory_operand" "")
4608 (float_truncate:MODEF
4609 (match_operand:XF 1 "register_operand" "")))
4610 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4612 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4615 ;; Signed conversion to DImode.
4617 (define_expand "fix_truncxfdi2"
4618 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4619 (fix:DI (match_operand:XF 1 "register_operand" "")))
4620 (clobber (reg:CC FLAGS_REG))])]
4625 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4630 (define_expand "fix_trunc<mode>di2"
4631 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4632 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4633 (clobber (reg:CC FLAGS_REG))])]
4634 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4637 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4639 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4642 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4644 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4645 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4646 if (out != operands[0])
4647 emit_move_insn (operands[0], out);
4652 ;; Signed conversion to SImode.
4654 (define_expand "fix_truncxfsi2"
4655 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4656 (fix:SI (match_operand:XF 1 "register_operand" "")))
4657 (clobber (reg:CC FLAGS_REG))])]
4662 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4667 (define_expand "fix_trunc<mode>si2"
4668 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4669 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4670 (clobber (reg:CC FLAGS_REG))])]
4671 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4674 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4676 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4679 if (SSE_FLOAT_MODE_P (<MODE>mode))
4681 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4682 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4683 if (out != operands[0])
4684 emit_move_insn (operands[0], out);
4689 ;; Signed conversion to HImode.
4691 (define_expand "fix_trunc<mode>hi2"
4692 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4693 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4694 (clobber (reg:CC FLAGS_REG))])]
4696 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4700 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4705 ;; Unsigned conversion to SImode.
4707 (define_expand "fixuns_trunc<mode>si2"
4709 [(set (match_operand:SI 0 "register_operand" "")
4711 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4713 (clobber (match_scratch:<ssevecmode> 3 ""))
4714 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4715 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4717 enum machine_mode mode = <MODE>mode;
4718 enum machine_mode vecmode = <ssevecmode>mode;
4719 REAL_VALUE_TYPE TWO31r;
4722 if (optimize_insn_for_size_p ())
4725 real_ldexp (&TWO31r, &dconst1, 31);
4726 two31 = const_double_from_real_value (TWO31r, mode);
4727 two31 = ix86_build_const_vector (mode, true, two31);
4728 operands[2] = force_reg (vecmode, two31);
4731 (define_insn_and_split "*fixuns_trunc<mode>_1"
4732 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4734 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4735 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4736 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4737 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4738 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4739 && optimize_function_for_speed_p (cfun)"
4741 "&& reload_completed"
4744 ix86_split_convert_uns_si_sse (operands);
4748 ;; Unsigned conversion to HImode.
4749 ;; Without these patterns, we'll try the unsigned SI conversion which
4750 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4752 (define_expand "fixuns_trunc<mode>hi2"
4754 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4755 (set (match_operand:HI 0 "nonimmediate_operand" "")
4756 (subreg:HI (match_dup 2) 0))]
4757 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4758 "operands[2] = gen_reg_rtx (SImode);")
4760 ;; When SSE is available, it is always faster to use it!
4761 (define_insn "fix_trunc<mode>di_sse"
4762 [(set (match_operand:DI 0 "register_operand" "=r,r")
4763 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4764 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4765 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4766 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4767 [(set_attr "type" "sseicvt")
4768 (set_attr "prefix" "maybe_vex")
4769 (set_attr "mode" "<MODE>")
4770 (set_attr "athlon_decode" "double,vector")
4771 (set_attr "amdfam10_decode" "double,double")])
4773 (define_insn "fix_trunc<mode>si_sse"
4774 [(set (match_operand:SI 0 "register_operand" "=r,r")
4775 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4776 "SSE_FLOAT_MODE_P (<MODE>mode)
4777 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4778 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4779 [(set_attr "type" "sseicvt")
4780 (set_attr "prefix" "maybe_vex")
4781 (set_attr "mode" "<MODE>")
4782 (set_attr "athlon_decode" "double,vector")
4783 (set_attr "amdfam10_decode" "double,double")])
4785 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4787 [(set (match_operand:MODEF 0 "register_operand" "")
4788 (match_operand:MODEF 1 "memory_operand" ""))
4789 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4790 (fix:SSEMODEI24 (match_dup 0)))]
4791 "TARGET_SHORTEN_X87_SSE
4792 && peep2_reg_dead_p (2, operands[0])"
4793 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4796 ;; Avoid vector decoded forms of the instruction.
4798 [(match_scratch:DF 2 "Y2")
4799 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4800 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4801 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4802 [(set (match_dup 2) (match_dup 1))
4803 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4807 [(match_scratch:SF 2 "x")
4808 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4809 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4810 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4811 [(set (match_dup 2) (match_dup 1))
4812 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4815 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4816 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4817 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4818 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4820 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4821 && (TARGET_64BIT || <MODE>mode != DImode))
4823 && !(reload_completed || reload_in_progress)"
4828 if (memory_operand (operands[0], VOIDmode))
4829 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4832 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4833 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4839 [(set_attr "type" "fisttp")
4840 (set_attr "mode" "<MODE>")])
4842 (define_insn "fix_trunc<mode>_i387_fisttp"
4843 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4844 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4845 (clobber (match_scratch:XF 2 "=&1f"))]
4846 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4848 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4849 && (TARGET_64BIT || <MODE>mode != DImode))
4850 && TARGET_SSE_MATH)"
4851 "* return output_fix_trunc (insn, operands, 1);"
4852 [(set_attr "type" "fisttp")
4853 (set_attr "mode" "<MODE>")])
4855 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4856 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4857 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4858 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4859 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4860 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4862 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4863 && (TARGET_64BIT || <MODE>mode != DImode))
4864 && TARGET_SSE_MATH)"
4866 [(set_attr "type" "fisttp")
4867 (set_attr "mode" "<MODE>")])
4870 [(set (match_operand:X87MODEI 0 "register_operand" "")
4871 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4872 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4873 (clobber (match_scratch 3 ""))]
4875 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4876 (clobber (match_dup 3))])
4877 (set (match_dup 0) (match_dup 2))]
4881 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4882 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4883 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4884 (clobber (match_scratch 3 ""))]
4886 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4887 (clobber (match_dup 3))])]
4890 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4891 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4892 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4893 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4894 ;; function in i386.c.
4895 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4896 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4897 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4898 (clobber (reg:CC FLAGS_REG))]
4899 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4901 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4902 && (TARGET_64BIT || <MODE>mode != DImode))
4903 && !(reload_completed || reload_in_progress)"
4908 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4910 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4911 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4912 if (memory_operand (operands[0], VOIDmode))
4913 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4914 operands[2], operands[3]));
4917 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4918 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4919 operands[2], operands[3],
4924 [(set_attr "type" "fistp")
4925 (set_attr "i387_cw" "trunc")
4926 (set_attr "mode" "<MODE>")])
4928 (define_insn "fix_truncdi_i387"
4929 [(set (match_operand:DI 0 "memory_operand" "=m")
4930 (fix:DI (match_operand 1 "register_operand" "f")))
4931 (use (match_operand:HI 2 "memory_operand" "m"))
4932 (use (match_operand:HI 3 "memory_operand" "m"))
4933 (clobber (match_scratch:XF 4 "=&1f"))]
4934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4936 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937 "* return output_fix_trunc (insn, operands, 0);"
4938 [(set_attr "type" "fistp")
4939 (set_attr "i387_cw" "trunc")
4940 (set_attr "mode" "DI")])
4942 (define_insn "fix_truncdi_i387_with_temp"
4943 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4944 (fix:DI (match_operand 1 "register_operand" "f,f")))
4945 (use (match_operand:HI 2 "memory_operand" "m,m"))
4946 (use (match_operand:HI 3 "memory_operand" "m,m"))
4947 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4948 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4949 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4951 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4953 [(set_attr "type" "fistp")
4954 (set_attr "i387_cw" "trunc")
4955 (set_attr "mode" "DI")])
4958 [(set (match_operand:DI 0 "register_operand" "")
4959 (fix:DI (match_operand 1 "register_operand" "")))
4960 (use (match_operand:HI 2 "memory_operand" ""))
4961 (use (match_operand:HI 3 "memory_operand" ""))
4962 (clobber (match_operand:DI 4 "memory_operand" ""))
4963 (clobber (match_scratch 5 ""))]
4965 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4968 (clobber (match_dup 5))])
4969 (set (match_dup 0) (match_dup 4))]
4973 [(set (match_operand:DI 0 "memory_operand" "")
4974 (fix:DI (match_operand 1 "register_operand" "")))
4975 (use (match_operand:HI 2 "memory_operand" ""))
4976 (use (match_operand:HI 3 "memory_operand" ""))
4977 (clobber (match_operand:DI 4 "memory_operand" ""))
4978 (clobber (match_scratch 5 ""))]
4980 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4983 (clobber (match_dup 5))])]
4986 (define_insn "fix_trunc<mode>_i387"
4987 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4988 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4989 (use (match_operand:HI 2 "memory_operand" "m"))
4990 (use (match_operand:HI 3 "memory_operand" "m"))]
4991 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4993 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4994 "* return output_fix_trunc (insn, operands, 0);"
4995 [(set_attr "type" "fistp")
4996 (set_attr "i387_cw" "trunc")
4997 (set_attr "mode" "<MODE>")])
4999 (define_insn "fix_trunc<mode>_i387_with_temp"
5000 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5001 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5002 (use (match_operand:HI 2 "memory_operand" "m,m"))
5003 (use (match_operand:HI 3 "memory_operand" "m,m"))
5004 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5005 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5007 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5009 [(set_attr "type" "fistp")
5010 (set_attr "i387_cw" "trunc")
5011 (set_attr "mode" "<MODE>")])
5014 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5015 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5016 (use (match_operand:HI 2 "memory_operand" ""))
5017 (use (match_operand:HI 3 "memory_operand" ""))
5018 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5020 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5022 (use (match_dup 3))])
5023 (set (match_dup 0) (match_dup 4))]
5027 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5028 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5029 (use (match_operand:HI 2 "memory_operand" ""))
5030 (use (match_operand:HI 3 "memory_operand" ""))
5031 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5033 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5035 (use (match_dup 3))])]
5038 (define_insn "x86_fnstcw_1"
5039 [(set (match_operand:HI 0 "memory_operand" "=m")
5040 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5043 [(set_attr "length" "2")
5044 (set_attr "mode" "HI")
5045 (set_attr "unit" "i387")])
5047 (define_insn "x86_fldcw_1"
5048 [(set (reg:HI FPCR_REG)
5049 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5052 [(set_attr "length" "2")
5053 (set_attr "mode" "HI")
5054 (set_attr "unit" "i387")
5055 (set_attr "athlon_decode" "vector")
5056 (set_attr "amdfam10_decode" "vector")])
5058 ;; Conversion between fixed point and floating point.
5060 ;; Even though we only accept memory inputs, the backend _really_
5061 ;; wants to be able to do this between registers.
5063 (define_expand "floathi<mode>2"
5064 [(set (match_operand:X87MODEF 0 "register_operand" "")
5065 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5068 || TARGET_MIX_SSE_I387)"
5071 ;; Pre-reload splitter to add memory clobber to the pattern.
5072 (define_insn_and_split "*floathi<mode>2_1"
5073 [(set (match_operand:X87MODEF 0 "register_operand" "")
5074 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5077 || TARGET_MIX_SSE_I387)
5078 && !(reload_completed || reload_in_progress)"
5081 [(parallel [(set (match_dup 0)
5082 (float:X87MODEF (match_dup 1)))
5083 (clobber (match_dup 2))])]
5084 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5086 (define_insn "*floathi<mode>2_i387_with_temp"
5087 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5088 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5089 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5092 || TARGET_MIX_SSE_I387)"
5094 [(set_attr "type" "fmov,multi")
5095 (set_attr "mode" "<MODE>")
5096 (set_attr "unit" "*,i387")
5097 (set_attr "fp_int_src" "true")])
5099 (define_insn "*floathi<mode>2_i387"
5100 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5101 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5103 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5104 || TARGET_MIX_SSE_I387)"
5106 [(set_attr "type" "fmov")
5107 (set_attr "mode" "<MODE>")
5108 (set_attr "fp_int_src" "true")])
5111 [(set (match_operand:X87MODEF 0 "register_operand" "")
5112 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5113 (clobber (match_operand:HI 2 "memory_operand" ""))]
5115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5116 || TARGET_MIX_SSE_I387)
5117 && reload_completed"
5118 [(set (match_dup 2) (match_dup 1))
5119 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5123 [(set (match_operand:X87MODEF 0 "register_operand" "")
5124 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5125 (clobber (match_operand:HI 2 "memory_operand" ""))]
5127 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5128 || TARGET_MIX_SSE_I387)
5129 && reload_completed"
5130 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5133 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5134 [(set (match_operand:X87MODEF 0 "register_operand" "")
5136 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5138 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5139 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5142 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5143 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5144 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5146 rtx reg = gen_reg_rtx (XFmode);
5147 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5148 /* Avoid references to nonexistent function in dead code in XFmode case. */
5149 #define gen_truncxfxf2 gen_truncxfdf2
5150 emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5151 #undef gen_truncxfxf2
5156 ;; Pre-reload splitter to add memory clobber to the pattern.
5157 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5158 [(set (match_operand:X87MODEF 0 "register_operand" "")
5159 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5161 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5162 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5163 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5164 || TARGET_MIX_SSE_I387))
5165 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5166 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5167 && ((<SSEMODEI24:MODE>mode == SImode
5168 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5169 && optimize_function_for_speed_p (cfun)
5170 && flag_trapping_math)
5171 || !(TARGET_INTER_UNIT_CONVERSIONS
5172 || optimize_function_for_size_p (cfun)))))
5173 && !(reload_completed || reload_in_progress)"
5176 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5177 (clobber (match_dup 2))])]
5179 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5181 /* Avoid store forwarding (partial memory) stall penalty
5182 by passing DImode value through XMM registers. */
5183 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5184 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5185 && optimize_function_for_speed_p (cfun))
5187 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5194 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5195 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5197 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5198 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5199 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5200 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5202 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5203 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5204 (set_attr "unit" "*,i387,*,*,*")
5205 (set_attr "athlon_decode" "*,*,double,direct,double")
5206 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5207 (set_attr "fp_int_src" "true")])
5209 (define_insn "*floatsi<mode>2_vector_mixed"
5210 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5211 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5212 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5213 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5217 [(set_attr "type" "fmov,sseicvt")
5218 (set_attr "mode" "<MODE>,<ssevecmode>")
5219 (set_attr "unit" "i387,*")
5220 (set_attr "athlon_decode" "*,direct")
5221 (set_attr "amdfam10_decode" "*,double")
5222 (set_attr "fp_int_src" "true")])
5224 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5225 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5227 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5228 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5229 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5230 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5232 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5233 (set_attr "mode" "<MODEF:MODE>")
5234 (set_attr "unit" "*,i387,*,*")
5235 (set_attr "athlon_decode" "*,*,double,direct")
5236 (set_attr "amdfam10_decode" "*,*,vector,double")
5237 (set_attr "fp_int_src" "true")])
5240 [(set (match_operand:MODEF 0 "register_operand" "")
5241 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5242 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5243 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5244 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5245 && TARGET_INTER_UNIT_CONVERSIONS
5247 && (SSE_REG_P (operands[0])
5248 || (GET_CODE (operands[0]) == SUBREG
5249 && SSE_REG_P (operands[0])))"
5250 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5254 [(set (match_operand:MODEF 0 "register_operand" "")
5255 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5256 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5257 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5258 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5259 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5261 && (SSE_REG_P (operands[0])
5262 || (GET_CODE (operands[0]) == SUBREG
5263 && SSE_REG_P (operands[0])))"
5264 [(set (match_dup 2) (match_dup 1))
5265 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5268 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5269 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5271 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5272 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5273 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5274 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5277 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5278 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5279 [(set_attr "type" "fmov,sseicvt,sseicvt")
5280 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5281 (set_attr "mode" "<MODEF:MODE>")
5282 (set_attr "unit" "i387,*,*")
5283 (set_attr "athlon_decode" "*,double,direct")
5284 (set_attr "amdfam10_decode" "*,vector,double")
5285 (set_attr "fp_int_src" "true")])
5287 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5288 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5290 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5291 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5292 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5293 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5296 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5297 [(set_attr "type" "fmov,sseicvt")
5298 (set_attr "prefix" "orig,maybe_vex")
5299 (set_attr "mode" "<MODEF:MODE>")
5300 (set_attr "athlon_decode" "*,direct")
5301 (set_attr "amdfam10_decode" "*,double")
5302 (set_attr "fp_int_src" "true")])
5304 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5305 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5307 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5308 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5309 "TARGET_SSE2 && TARGET_SSE_MATH
5310 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5312 [(set_attr "type" "sseicvt")
5313 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5314 (set_attr "athlon_decode" "double,direct,double")
5315 (set_attr "amdfam10_decode" "vector,double,double")
5316 (set_attr "fp_int_src" "true")])
5318 (define_insn "*floatsi<mode>2_vector_sse"
5319 [(set (match_operand:MODEF 0 "register_operand" "=x")
5320 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5321 "TARGET_SSE2 && TARGET_SSE_MATH
5322 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5324 [(set_attr "type" "sseicvt")
5325 (set_attr "mode" "<MODE>")
5326 (set_attr "athlon_decode" "direct")
5327 (set_attr "amdfam10_decode" "double")
5328 (set_attr "fp_int_src" "true")])
5331 [(set (match_operand:MODEF 0 "register_operand" "")
5332 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5333 (clobber (match_operand:SI 2 "memory_operand" ""))]
5334 "TARGET_SSE2 && TARGET_SSE_MATH
5335 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5337 && (SSE_REG_P (operands[0])
5338 || (GET_CODE (operands[0]) == SUBREG
5339 && SSE_REG_P (operands[0])))"
5342 rtx op1 = operands[1];
5344 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5346 if (GET_CODE (op1) == SUBREG)
5347 op1 = SUBREG_REG (op1);
5349 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5351 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5352 emit_insn (gen_sse2_loadld (operands[4],
5353 CONST0_RTX (V4SImode), operands[1]));
5355 /* We can ignore possible trapping value in the
5356 high part of SSE register for non-trapping math. */
5357 else if (SSE_REG_P (op1) && !flag_trapping_math)
5358 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5361 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5362 emit_move_insn (operands[2], operands[1]);
5363 emit_insn (gen_sse2_loadld (operands[4],
5364 CONST0_RTX (V4SImode), operands[2]));
5367 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5372 [(set (match_operand:MODEF 0 "register_operand" "")
5373 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5374 (clobber (match_operand:SI 2 "memory_operand" ""))]
5375 "TARGET_SSE2 && TARGET_SSE_MATH
5376 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5378 && (SSE_REG_P (operands[0])
5379 || (GET_CODE (operands[0]) == SUBREG
5380 && SSE_REG_P (operands[0])))"
5383 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5385 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5387 emit_insn (gen_sse2_loadld (operands[4],
5388 CONST0_RTX (V4SImode), operands[1]));
5390 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5395 [(set (match_operand:MODEF 0 "register_operand" "")
5396 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5397 "TARGET_SSE2 && TARGET_SSE_MATH
5398 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5400 && (SSE_REG_P (operands[0])
5401 || (GET_CODE (operands[0]) == SUBREG
5402 && SSE_REG_P (operands[0])))"
5405 rtx op1 = operands[1];
5407 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5409 if (GET_CODE (op1) == SUBREG)
5410 op1 = SUBREG_REG (op1);
5412 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5414 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5415 emit_insn (gen_sse2_loadld (operands[4],
5416 CONST0_RTX (V4SImode), operands[1]));
5418 /* We can ignore possible trapping value in the
5419 high part of SSE register for non-trapping math. */
5420 else if (SSE_REG_P (op1) && !flag_trapping_math)
5421 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5425 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5430 [(set (match_operand:MODEF 0 "register_operand" "")
5431 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5432 "TARGET_SSE2 && TARGET_SSE_MATH
5433 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5435 && (SSE_REG_P (operands[0])
5436 || (GET_CODE (operands[0]) == SUBREG
5437 && SSE_REG_P (operands[0])))"
5440 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5442 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5444 emit_insn (gen_sse2_loadld (operands[4],
5445 CONST0_RTX (V4SImode), operands[1]));
5447 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5451 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5452 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5454 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5455 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5456 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5457 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5459 [(set_attr "type" "sseicvt")
5460 (set_attr "mode" "<MODEF:MODE>")
5461 (set_attr "athlon_decode" "double,direct")
5462 (set_attr "amdfam10_decode" "vector,double")
5463 (set_attr "fp_int_src" "true")])
5465 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5466 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5468 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5469 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5470 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5471 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5472 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5473 [(set_attr "type" "sseicvt")
5474 (set_attr "prefix" "maybe_vex")
5475 (set_attr "mode" "<MODEF:MODE>")
5476 (set_attr "athlon_decode" "double,direct")
5477 (set_attr "amdfam10_decode" "vector,double")
5478 (set_attr "fp_int_src" "true")])
5481 [(set (match_operand:MODEF 0 "register_operand" "")
5482 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5483 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5484 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5485 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5486 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5488 && (SSE_REG_P (operands[0])
5489 || (GET_CODE (operands[0]) == SUBREG
5490 && SSE_REG_P (operands[0])))"
5491 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5494 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5495 [(set (match_operand:MODEF 0 "register_operand" "=x")
5497 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5498 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5501 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5502 [(set_attr "type" "sseicvt")
5503 (set_attr "prefix" "maybe_vex")
5504 (set_attr "mode" "<MODEF:MODE>")
5505 (set_attr "athlon_decode" "direct")
5506 (set_attr "amdfam10_decode" "double")
5507 (set_attr "fp_int_src" "true")])
5510 [(set (match_operand:MODEF 0 "register_operand" "")
5511 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5512 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5513 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5514 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5515 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5517 && (SSE_REG_P (operands[0])
5518 || (GET_CODE (operands[0]) == SUBREG
5519 && SSE_REG_P (operands[0])))"
5520 [(set (match_dup 2) (match_dup 1))
5521 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5525 [(set (match_operand:MODEF 0 "register_operand" "")
5526 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5527 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5528 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5529 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5531 && (SSE_REG_P (operands[0])
5532 || (GET_CODE (operands[0]) == SUBREG
5533 && SSE_REG_P (operands[0])))"
5534 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5537 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5538 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5540 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5541 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5543 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5547 [(set_attr "type" "fmov,multi")
5548 (set_attr "mode" "<X87MODEF:MODE>")
5549 (set_attr "unit" "*,i387")
5550 (set_attr "fp_int_src" "true")])
5552 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5553 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5555 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5557 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5559 [(set_attr "type" "fmov")
5560 (set_attr "mode" "<X87MODEF:MODE>")
5561 (set_attr "fp_int_src" "true")])
5564 [(set (match_operand:X87MODEF 0 "register_operand" "")
5565 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5566 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5568 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5570 && FP_REG_P (operands[0])"
5571 [(set (match_dup 2) (match_dup 1))
5572 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5576 [(set (match_operand:X87MODEF 0 "register_operand" "")
5577 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5578 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5580 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5582 && FP_REG_P (operands[0])"
5583 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5586 ;; Avoid store forwarding (partial memory) stall penalty
5587 ;; by passing DImode value through XMM registers. */
5589 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5590 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5592 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5593 (clobber (match_scratch:V4SI 3 "=X,x"))
5594 (clobber (match_scratch:V4SI 4 "=X,x"))
5595 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5596 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5597 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5598 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5600 [(set_attr "type" "multi")
5601 (set_attr "mode" "<X87MODEF:MODE>")
5602 (set_attr "unit" "i387")
5603 (set_attr "fp_int_src" "true")])
5606 [(set (match_operand:X87MODEF 0 "register_operand" "")
5607 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5608 (clobber (match_scratch:V4SI 3 ""))
5609 (clobber (match_scratch:V4SI 4 ""))
5610 (clobber (match_operand:DI 2 "memory_operand" ""))]
5611 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5612 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5613 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5615 && FP_REG_P (operands[0])"
5616 [(set (match_dup 2) (match_dup 3))
5617 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5619 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5620 Assemble the 64-bit DImode value in an xmm register. */
5621 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5622 gen_rtx_SUBREG (SImode, operands[1], 0)));
5623 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5624 gen_rtx_SUBREG (SImode, operands[1], 4)));
5625 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5627 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5631 [(set (match_operand:X87MODEF 0 "register_operand" "")
5632 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5633 (clobber (match_scratch:V4SI 3 ""))
5634 (clobber (match_scratch:V4SI 4 ""))
5635 (clobber (match_operand:DI 2 "memory_operand" ""))]
5636 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5637 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5638 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5640 && FP_REG_P (operands[0])"
5641 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5644 ;; Avoid store forwarding (partial memory) stall penalty by extending
5645 ;; SImode value to DImode through XMM register instead of pushing two
5646 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5647 ;; targets benefit from this optimization. Also note that fild
5648 ;; loads from memory only.
5650 (define_insn "*floatunssi<mode>2_1"
5651 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5652 (unsigned_float:X87MODEF
5653 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5654 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5655 (clobber (match_scratch:SI 3 "=X,x"))]
5657 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, SImode)
5660 [(set_attr "type" "multi")
5661 (set_attr "mode" "<MODE>")])
5664 [(set (match_operand:X87MODEF 0 "register_operand" "")
5665 (unsigned_float:X87MODEF
5666 (match_operand:SI 1 "register_operand" "")))
5667 (clobber (match_operand:DI 2 "memory_operand" ""))
5668 (clobber (match_scratch:SI 3 ""))]
5670 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, SImode)
5672 && reload_completed"
5673 [(set (match_dup 2) (match_dup 1))
5675 (float:X87MODEF (match_dup 2)))]
5676 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5679 [(set (match_operand:X87MODEF 0 "register_operand" "")
5680 (unsigned_float:X87MODEF
5681 (match_operand:SI 1 "memory_operand" "")))
5682 (clobber (match_operand:DI 2 "memory_operand" ""))
5683 (clobber (match_scratch:SI 3 ""))]
5685 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, SImode)
5687 && reload_completed"
5688 [(set (match_dup 2) (match_dup 3))
5690 (float:X87MODEF (match_dup 2)))]
5692 emit_move_insn (operands[3], operands[1]);
5693 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5696 (define_expand "floatunssi<mode>2"
5698 [(set (match_operand:X87MODEF 0 "register_operand" "")
5699 (unsigned_float:X87MODEF
5700 (match_operand:SI 1 "nonimmediate_operand" "")))
5701 (clobber (match_dup 2))
5702 (clobber (match_scratch:SI 3 ""))])]
5704 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, SImode)
5706 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5708 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5710 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5715 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5716 operands[2] = assign_386_stack_local (DImode, slot);
5720 (define_expand "floatunsdisf2"
5721 [(use (match_operand:SF 0 "register_operand" ""))
5722 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5723 "TARGET_64BIT && TARGET_SSE_MATH"
5724 "x86_emit_floatuns (operands); DONE;")
5726 (define_expand "floatunsdidf2"
5727 [(use (match_operand:DF 0 "register_operand" ""))
5728 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5729 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5730 && TARGET_SSE2 && TARGET_SSE_MATH"
5733 x86_emit_floatuns (operands);
5735 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5741 ;; %%% splits for addditi3
5743 (define_expand "addti3"
5744 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5745 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5746 (match_operand:TI 2 "x86_64_general_operand" "")))]
5748 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5750 (define_insn "*addti3_1"
5751 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5752 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5753 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5754 (clobber (reg:CC FLAGS_REG))]
5755 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5759 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5760 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5761 (match_operand:TI 2 "x86_64_general_operand" "")))
5762 (clobber (reg:CC FLAGS_REG))]
5763 "TARGET_64BIT && reload_completed"
5764 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5766 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5767 (parallel [(set (match_dup 3)
5768 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5771 (clobber (reg:CC FLAGS_REG))])]
5772 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5774 ;; %%% splits for addsidi3
5775 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5776 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5777 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5779 (define_expand "adddi3"
5780 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5781 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5782 (match_operand:DI 2 "x86_64_general_operand" "")))]
5784 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5786 (define_insn "*adddi3_1"
5787 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5788 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5789 (match_operand:DI 2 "general_operand" "roiF,riF")))
5790 (clobber (reg:CC FLAGS_REG))]
5791 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5795 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5796 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5797 (match_operand:DI 2 "general_operand" "")))
5798 (clobber (reg:CC FLAGS_REG))]
5799 "!TARGET_64BIT && reload_completed"
5800 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5802 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5803 (parallel [(set (match_dup 3)
5804 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5807 (clobber (reg:CC FLAGS_REG))])]
5808 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5810 (define_insn "adddi3_carry_rex64"
5811 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5812 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5813 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5814 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5817 "adc{q}\t{%2, %0|%0, %2}"
5818 [(set_attr "type" "alu")
5819 (set_attr "pent_pair" "pu")
5820 (set_attr "mode" "DI")])
5822 (define_insn "*adddi3_cc_rex64"
5823 [(set (reg:CC FLAGS_REG)
5824 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5825 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5827 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5828 (plus:DI (match_dup 1) (match_dup 2)))]
5829 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5830 "add{q}\t{%2, %0|%0, %2}"
5831 [(set_attr "type" "alu")
5832 (set_attr "mode" "DI")])
5834 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5835 [(set (reg:CCC FLAGS_REG)
5838 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5839 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5841 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5842 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5843 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5844 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5845 [(set_attr "type" "alu")
5846 (set_attr "mode" "<MODE>")])
5848 (define_insn "*add<mode>3_cconly_overflow"
5849 [(set (reg:CCC FLAGS_REG)
5851 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5852 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5854 (clobber (match_scratch:SWI 0 "=<r>"))]
5855 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5856 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5857 [(set_attr "type" "alu")
5858 (set_attr "mode" "<MODE>")])
5860 (define_insn "*sub<mode>3_cconly_overflow"
5861 [(set (reg:CCC FLAGS_REG)
5863 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5864 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5867 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5868 [(set_attr "type" "icmp")
5869 (set_attr "mode" "<MODE>")])
5871 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5872 [(set (reg:CCC FLAGS_REG)
5874 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5875 (match_operand:SI 2 "general_operand" "g"))
5877 (set (match_operand:DI 0 "register_operand" "=r")
5878 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5879 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5880 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5881 [(set_attr "type" "alu")
5882 (set_attr "mode" "SI")])
5884 (define_insn "addqi3_carry"
5885 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5886 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5887 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5888 (match_operand:QI 2 "general_operand" "qn,qm")))
5889 (clobber (reg:CC FLAGS_REG))]
5890 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5891 "adc{b}\t{%2, %0|%0, %2}"
5892 [(set_attr "type" "alu")
5893 (set_attr "pent_pair" "pu")
5894 (set_attr "mode" "QI")])
5896 (define_insn "addhi3_carry"
5897 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5898 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5899 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5900 (match_operand:HI 2 "general_operand" "rn,rm")))
5901 (clobber (reg:CC FLAGS_REG))]
5902 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5903 "adc{w}\t{%2, %0|%0, %2}"
5904 [(set_attr "type" "alu")
5905 (set_attr "pent_pair" "pu")
5906 (set_attr "mode" "HI")])
5908 (define_insn "addsi3_carry"
5909 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5910 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5911 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5912 (match_operand:SI 2 "general_operand" "ri,rm")))
5913 (clobber (reg:CC FLAGS_REG))]
5914 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5915 "adc{l}\t{%2, %0|%0, %2}"
5916 [(set_attr "type" "alu")
5917 (set_attr "pent_pair" "pu")
5918 (set_attr "mode" "SI")])
5920 (define_insn "*addsi3_carry_zext"
5921 [(set (match_operand:DI 0 "register_operand" "=r")
5923 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5924 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5925 (match_operand:SI 2 "general_operand" "g"))))
5926 (clobber (reg:CC FLAGS_REG))]
5927 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5928 "adc{l}\t{%2, %k0|%k0, %2}"
5929 [(set_attr "type" "alu")
5930 (set_attr "pent_pair" "pu")
5931 (set_attr "mode" "SI")])
5933 (define_insn "*addsi3_cc"
5934 [(set (reg:CC FLAGS_REG)
5935 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5936 (match_operand:SI 2 "general_operand" "ri,rm")]
5938 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5939 (plus:SI (match_dup 1) (match_dup 2)))]
5940 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5941 "add{l}\t{%2, %0|%0, %2}"
5942 [(set_attr "type" "alu")
5943 (set_attr "mode" "SI")])
5945 (define_insn "addqi3_cc"
5946 [(set (reg:CC FLAGS_REG)
5947 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5948 (match_operand:QI 2 "general_operand" "qn,qm")]
5950 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5951 (plus:QI (match_dup 1) (match_dup 2)))]
5952 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5953 "add{b}\t{%2, %0|%0, %2}"
5954 [(set_attr "type" "alu")
5955 (set_attr "mode" "QI")])
5957 (define_expand "addsi3"
5958 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5959 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5960 (match_operand:SI 2 "general_operand" "")))]
5962 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5964 (define_insn "*lea_1"
5965 [(set (match_operand:SI 0 "register_operand" "=r")
5966 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5968 "lea{l}\t{%a1, %0|%0, %a1}"
5969 [(set_attr "type" "lea")
5970 (set_attr "mode" "SI")])
5972 (define_insn "*lea_1_rex64"
5973 [(set (match_operand:SI 0 "register_operand" "=r")
5974 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5976 "lea{l}\t{%a1, %0|%0, %a1}"
5977 [(set_attr "type" "lea")
5978 (set_attr "mode" "SI")])
5980 (define_insn "*lea_1_zext"
5981 [(set (match_operand:DI 0 "register_operand" "=r")
5983 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5985 "lea{l}\t{%a1, %k0|%k0, %a1}"
5986 [(set_attr "type" "lea")
5987 (set_attr "mode" "SI")])
5989 (define_insn "*lea_2_rex64"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5991 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5993 "lea{q}\t{%a1, %0|%0, %a1}"
5994 [(set_attr "type" "lea")
5995 (set_attr "mode" "DI")])
5997 ;; The lea patterns for non-Pmodes needs to be matched by several
5998 ;; insns converted to real lea by splitters.
6000 (define_insn_and_split "*lea_general_1"
6001 [(set (match_operand 0 "register_operand" "=r")
6002 (plus (plus (match_operand 1 "index_register_operand" "l")
6003 (match_operand 2 "register_operand" "r"))
6004 (match_operand 3 "immediate_operand" "i")))]
6005 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6006 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6007 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6008 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6009 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6010 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6011 || GET_MODE (operands[3]) == VOIDmode)"
6013 "&& reload_completed"
6017 operands[0] = gen_lowpart (SImode, operands[0]);
6018 operands[1] = gen_lowpart (Pmode, operands[1]);
6019 operands[2] = gen_lowpart (Pmode, operands[2]);
6020 operands[3] = gen_lowpart (Pmode, operands[3]);
6021 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6023 if (Pmode != SImode)
6024 pat = gen_rtx_SUBREG (SImode, pat, 0);
6025 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6028 [(set_attr "type" "lea")
6029 (set_attr "mode" "SI")])
6031 (define_insn_and_split "*lea_general_1_zext"
6032 [(set (match_operand:DI 0 "register_operand" "=r")
6034 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6035 (match_operand:SI 2 "register_operand" "r"))
6036 (match_operand:SI 3 "immediate_operand" "i"))))]
6039 "&& reload_completed"
6041 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6043 (match_dup 3)) 0)))]
6045 operands[1] = gen_lowpart (Pmode, operands[1]);
6046 operands[2] = gen_lowpart (Pmode, operands[2]);
6047 operands[3] = gen_lowpart (Pmode, operands[3]);
6049 [(set_attr "type" "lea")
6050 (set_attr "mode" "SI")])
6052 (define_insn_and_split "*lea_general_2"
6053 [(set (match_operand 0 "register_operand" "=r")
6054 (plus (mult (match_operand 1 "index_register_operand" "l")
6055 (match_operand 2 "const248_operand" "i"))
6056 (match_operand 3 "nonmemory_operand" "ri")))]
6057 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6058 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6059 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6060 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6061 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6062 || GET_MODE (operands[3]) == VOIDmode)"
6064 "&& reload_completed"
6068 operands[0] = gen_lowpart (SImode, operands[0]);
6069 operands[1] = gen_lowpart (Pmode, operands[1]);
6070 operands[3] = gen_lowpart (Pmode, operands[3]);
6071 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6073 if (Pmode != SImode)
6074 pat = gen_rtx_SUBREG (SImode, pat, 0);
6075 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6078 [(set_attr "type" "lea")
6079 (set_attr "mode" "SI")])
6081 (define_insn_and_split "*lea_general_2_zext"
6082 [(set (match_operand:DI 0 "register_operand" "=r")
6084 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6085 (match_operand:SI 2 "const248_operand" "n"))
6086 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6089 "&& reload_completed"
6091 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6093 (match_dup 3)) 0)))]
6095 operands[1] = gen_lowpart (Pmode, operands[1]);
6096 operands[3] = gen_lowpart (Pmode, operands[3]);
6098 [(set_attr "type" "lea")
6099 (set_attr "mode" "SI")])
6101 (define_insn_and_split "*lea_general_3"
6102 [(set (match_operand 0 "register_operand" "=r")
6103 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6104 (match_operand 2 "const248_operand" "i"))
6105 (match_operand 3 "register_operand" "r"))
6106 (match_operand 4 "immediate_operand" "i")))]
6107 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6108 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6109 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6110 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6111 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6113 "&& reload_completed"
6117 operands[0] = gen_lowpart (SImode, operands[0]);
6118 operands[1] = gen_lowpart (Pmode, operands[1]);
6119 operands[3] = gen_lowpart (Pmode, operands[3]);
6120 operands[4] = gen_lowpart (Pmode, operands[4]);
6121 pat = gen_rtx_PLUS (Pmode,
6122 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6126 if (Pmode != SImode)
6127 pat = gen_rtx_SUBREG (SImode, pat, 0);
6128 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6131 [(set_attr "type" "lea")
6132 (set_attr "mode" "SI")])
6134 (define_insn_and_split "*lea_general_3_zext"
6135 [(set (match_operand:DI 0 "register_operand" "=r")
6137 (plus:SI (plus:SI (mult:SI
6138 (match_operand:SI 1 "index_register_operand" "l")
6139 (match_operand:SI 2 "const248_operand" "n"))
6140 (match_operand:SI 3 "register_operand" "r"))
6141 (match_operand:SI 4 "immediate_operand" "i"))))]
6144 "&& reload_completed"
6146 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6149 (match_dup 4)) 0)))]
6151 operands[1] = gen_lowpart (Pmode, operands[1]);
6152 operands[3] = gen_lowpart (Pmode, operands[3]);
6153 operands[4] = gen_lowpart (Pmode, operands[4]);
6155 [(set_attr "type" "lea")
6156 (set_attr "mode" "SI")])
6158 (define_insn "*adddi_1_rex64"
6159 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6160 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6161 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6162 (clobber (reg:CC FLAGS_REG))]
6163 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6165 switch (get_attr_type (insn))
6168 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6169 return "lea{q}\t{%a2, %0|%0, %a2}";
6172 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6173 if (operands[2] == const1_rtx)
6174 return "inc{q}\t%0";
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{q}\t%0";
6182 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6184 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6185 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6186 if (CONST_INT_P (operands[2])
6187 /* Avoid overflows. */
6188 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6189 && (INTVAL (operands[2]) == 128
6190 || (INTVAL (operands[2]) < 0
6191 && INTVAL (operands[2]) != -128)))
6193 operands[2] = GEN_INT (-INTVAL (operands[2]));
6194 return "sub{q}\t{%2, %0|%0, %2}";
6196 return "add{q}\t{%2, %0|%0, %2}";
6200 (cond [(eq_attr "alternative" "2")
6201 (const_string "lea")
6202 ; Current assemblers are broken and do not allow @GOTOFF in
6203 ; ought but a memory context.
6204 (match_operand:DI 2 "pic_symbolic_operand" "")
6205 (const_string "lea")
6206 (match_operand:DI 2 "incdec_operand" "")
6207 (const_string "incdec")
6209 (const_string "alu")))
6210 (set_attr "mode" "DI")])
6212 ;; Convert lea to the lea pattern to avoid flags dependency.
6214 [(set (match_operand:DI 0 "register_operand" "")
6215 (plus:DI (match_operand:DI 1 "register_operand" "")
6216 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6217 (clobber (reg:CC FLAGS_REG))]
6218 "TARGET_64BIT && reload_completed
6219 && true_regnum (operands[0]) != true_regnum (operands[1])"
6221 (plus:DI (match_dup 1)
6225 (define_insn "*adddi_2_rex64"
6226 [(set (reg FLAGS_REG)
6228 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6229 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6231 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6232 (plus:DI (match_dup 1) (match_dup 2)))]
6233 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6234 && ix86_binary_operator_ok (PLUS, DImode, operands)
6235 /* Current assemblers are broken and do not allow @GOTOFF in
6236 ought but a memory context. */
6237 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6239 switch (get_attr_type (insn))
6242 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6243 if (operands[2] == const1_rtx)
6244 return "inc{q}\t%0";
6247 gcc_assert (operands[2] == constm1_rtx);
6248 return "dec{q}\t%0";
6252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6253 /* ???? We ought to handle there the 32bit case too
6254 - do we need new constraint? */
6255 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6256 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6257 if (CONST_INT_P (operands[2])
6258 /* Avoid overflows. */
6259 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6260 && (INTVAL (operands[2]) == 128
6261 || (INTVAL (operands[2]) < 0
6262 && INTVAL (operands[2]) != -128)))
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6265 return "sub{q}\t{%2, %0|%0, %2}";
6267 return "add{q}\t{%2, %0|%0, %2}";
6271 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6272 (const_string "incdec")
6273 (const_string "alu")))
6274 (set_attr "mode" "DI")])
6276 (define_insn "*adddi_3_rex64"
6277 [(set (reg FLAGS_REG)
6278 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6279 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6280 (clobber (match_scratch:DI 0 "=r"))]
6282 && ix86_match_ccmode (insn, CCZmode)
6283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6284 /* Current assemblers are broken and do not allow @GOTOFF in
6285 ought but a memory context. */
6286 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6288 switch (get_attr_type (insn))
6291 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6292 if (operands[2] == const1_rtx)
6293 return "inc{q}\t%0";
6296 gcc_assert (operands[2] == constm1_rtx);
6297 return "dec{q}\t%0";
6301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6302 /* ???? We ought to handle there the 32bit case too
6303 - do we need new constraint? */
6304 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6305 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6306 if (CONST_INT_P (operands[2])
6307 /* Avoid overflows. */
6308 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6309 && (INTVAL (operands[2]) == 128
6310 || (INTVAL (operands[2]) < 0
6311 && INTVAL (operands[2]) != -128)))
6313 operands[2] = GEN_INT (-INTVAL (operands[2]));
6314 return "sub{q}\t{%2, %0|%0, %2}";
6316 return "add{q}\t{%2, %0|%0, %2}";
6320 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6321 (const_string "incdec")
6322 (const_string "alu")))
6323 (set_attr "mode" "DI")])
6325 ; For comparisons against 1, -1 and 128, we may generate better code
6326 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6327 ; is matched then. We can't accept general immediate, because for
6328 ; case of overflows, the result is messed up.
6329 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6331 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6332 ; only for comparisons not depending on it.
6333 (define_insn "*adddi_4_rex64"
6334 [(set (reg FLAGS_REG)
6335 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6336 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6337 (clobber (match_scratch:DI 0 "=rm"))]
6339 && ix86_match_ccmode (insn, CCGCmode)"
6341 switch (get_attr_type (insn))
6344 if (operands[2] == constm1_rtx)
6345 return "inc{q}\t%0";
6348 gcc_assert (operands[2] == const1_rtx);
6349 return "dec{q}\t%0";
6353 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6354 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6355 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6356 if ((INTVAL (operands[2]) == -128
6357 || (INTVAL (operands[2]) > 0
6358 && INTVAL (operands[2]) != 128))
6359 /* Avoid overflows. */
6360 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6361 return "sub{q}\t{%2, %0|%0, %2}";
6362 operands[2] = GEN_INT (-INTVAL (operands[2]));
6363 return "add{q}\t{%2, %0|%0, %2}";
6367 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6368 (const_string "incdec")
6369 (const_string "alu")))
6370 (set_attr "mode" "DI")])
6372 (define_insn "*adddi_5_rex64"
6373 [(set (reg FLAGS_REG)
6375 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6376 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6378 (clobber (match_scratch:DI 0 "=r"))]
6380 && ix86_match_ccmode (insn, CCGOCmode)
6381 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6382 /* Current assemblers are broken and do not allow @GOTOFF in
6383 ought but a memory context. */
6384 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6386 switch (get_attr_type (insn))
6389 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6390 if (operands[2] == const1_rtx)
6391 return "inc{q}\t%0";
6394 gcc_assert (operands[2] == constm1_rtx);
6395 return "dec{q}\t%0";
6399 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6400 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6401 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6402 if (CONST_INT_P (operands[2])
6403 /* Avoid overflows. */
6404 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6405 && (INTVAL (operands[2]) == 128
6406 || (INTVAL (operands[2]) < 0
6407 && INTVAL (operands[2]) != -128)))
6409 operands[2] = GEN_INT (-INTVAL (operands[2]));
6410 return "sub{q}\t{%2, %0|%0, %2}";
6412 return "add{q}\t{%2, %0|%0, %2}";
6416 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6417 (const_string "incdec")
6418 (const_string "alu")))
6419 (set_attr "mode" "DI")])
6422 (define_insn "*addsi_1"
6423 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6424 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6425 (match_operand:SI 2 "general_operand" "g,ri,li")))
6426 (clobber (reg:CC FLAGS_REG))]
6427 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6429 switch (get_attr_type (insn))
6432 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6433 return "lea{l}\t{%a2, %0|%0, %a2}";
6436 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6437 if (operands[2] == const1_rtx)
6438 return "inc{l}\t%0";
6441 gcc_assert (operands[2] == constm1_rtx);
6442 return "dec{l}\t%0";
6446 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6448 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6449 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6450 if (CONST_INT_P (operands[2])
6451 && (INTVAL (operands[2]) == 128
6452 || (INTVAL (operands[2]) < 0
6453 && INTVAL (operands[2]) != -128)))
6455 operands[2] = GEN_INT (-INTVAL (operands[2]));
6456 return "sub{l}\t{%2, %0|%0, %2}";
6458 return "add{l}\t{%2, %0|%0, %2}";
6462 (cond [(eq_attr "alternative" "2")
6463 (const_string "lea")
6464 ; Current assemblers are broken and do not allow @GOTOFF in
6465 ; ought but a memory context.
6466 (match_operand:SI 2 "pic_symbolic_operand" "")
6467 (const_string "lea")
6468 (match_operand:SI 2 "incdec_operand" "")
6469 (const_string "incdec")
6471 (const_string "alu")))
6472 (set_attr "mode" "SI")])
6474 ;; Convert lea to the lea pattern to avoid flags dependency.
6476 [(set (match_operand 0 "register_operand" "")
6477 (plus (match_operand 1 "register_operand" "")
6478 (match_operand 2 "nonmemory_operand" "")))
6479 (clobber (reg:CC FLAGS_REG))]
6481 && true_regnum (operands[0]) != true_regnum (operands[1])"
6485 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6486 may confuse gen_lowpart. */
6487 if (GET_MODE (operands[0]) != Pmode)
6489 operands[1] = gen_lowpart (Pmode, operands[1]);
6490 operands[2] = gen_lowpart (Pmode, operands[2]);
6492 operands[0] = gen_lowpart (SImode, operands[0]);
6493 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6494 if (Pmode != SImode)
6495 pat = gen_rtx_SUBREG (SImode, pat, 0);
6496 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6500 ;; It may seem that nonimmediate operand is proper one for operand 1.
6501 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6502 ;; we take care in ix86_binary_operator_ok to not allow two memory
6503 ;; operands so proper swapping will be done in reload. This allow
6504 ;; patterns constructed from addsi_1 to match.
6505 (define_insn "addsi_1_zext"
6506 [(set (match_operand:DI 0 "register_operand" "=r,r")
6508 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6509 (match_operand:SI 2 "general_operand" "g,li"))))
6510 (clobber (reg:CC FLAGS_REG))]
6511 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6513 switch (get_attr_type (insn))
6516 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6517 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6520 if (operands[2] == const1_rtx)
6521 return "inc{l}\t%k0";
6524 gcc_assert (operands[2] == constm1_rtx);
6525 return "dec{l}\t%k0";
6529 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6530 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6531 if (CONST_INT_P (operands[2])
6532 && (INTVAL (operands[2]) == 128
6533 || (INTVAL (operands[2]) < 0
6534 && INTVAL (operands[2]) != -128)))
6536 operands[2] = GEN_INT (-INTVAL (operands[2]));
6537 return "sub{l}\t{%2, %k0|%k0, %2}";
6539 return "add{l}\t{%2, %k0|%k0, %2}";
6543 (cond [(eq_attr "alternative" "1")
6544 (const_string "lea")
6545 ; Current assemblers are broken and do not allow @GOTOFF in
6546 ; ought but a memory context.
6547 (match_operand:SI 2 "pic_symbolic_operand" "")
6548 (const_string "lea")
6549 (match_operand:SI 2 "incdec_operand" "")
6550 (const_string "incdec")
6552 (const_string "alu")))
6553 (set_attr "mode" "SI")])
6555 ;; Convert lea to the lea pattern to avoid flags dependency.
6557 [(set (match_operand:DI 0 "register_operand" "")
6559 (plus:SI (match_operand:SI 1 "register_operand" "")
6560 (match_operand:SI 2 "nonmemory_operand" ""))))
6561 (clobber (reg:CC FLAGS_REG))]
6562 "TARGET_64BIT && reload_completed
6563 && true_regnum (operands[0]) != true_regnum (operands[1])"
6565 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6567 operands[1] = gen_lowpart (Pmode, operands[1]);
6568 operands[2] = gen_lowpart (Pmode, operands[2]);
6571 (define_insn "*addsi_2"
6572 [(set (reg FLAGS_REG)
6574 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6575 (match_operand:SI 2 "general_operand" "g,ri"))
6577 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6578 (plus:SI (match_dup 1) (match_dup 2)))]
6579 "ix86_match_ccmode (insn, CCGOCmode)
6580 && ix86_binary_operator_ok (PLUS, SImode, operands)
6581 /* Current assemblers are broken and do not allow @GOTOFF in
6582 ought but a memory context. */
6583 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6585 switch (get_attr_type (insn))
6588 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6589 if (operands[2] == const1_rtx)
6590 return "inc{l}\t%0";
6593 gcc_assert (operands[2] == constm1_rtx);
6594 return "dec{l}\t%0";
6598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6599 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6600 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6601 if (CONST_INT_P (operands[2])
6602 && (INTVAL (operands[2]) == 128
6603 || (INTVAL (operands[2]) < 0
6604 && INTVAL (operands[2]) != -128)))
6606 operands[2] = GEN_INT (-INTVAL (operands[2]));
6607 return "sub{l}\t{%2, %0|%0, %2}";
6609 return "add{l}\t{%2, %0|%0, %2}";
6613 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6614 (const_string "incdec")
6615 (const_string "alu")))
6616 (set_attr "mode" "SI")])
6618 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6619 (define_insn "*addsi_2_zext"
6620 [(set (reg FLAGS_REG)
6622 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6623 (match_operand:SI 2 "general_operand" "g"))
6625 (set (match_operand:DI 0 "register_operand" "=r")
6626 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6627 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6628 && ix86_binary_operator_ok (PLUS, SImode, operands)
6629 /* Current assemblers are broken and do not allow @GOTOFF in
6630 ought but a memory context. */
6631 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6633 switch (get_attr_type (insn))
6636 if (operands[2] == const1_rtx)
6637 return "inc{l}\t%k0";
6640 gcc_assert (operands[2] == constm1_rtx);
6641 return "dec{l}\t%k0";
6645 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6646 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6647 if (CONST_INT_P (operands[2])
6648 && (INTVAL (operands[2]) == 128
6649 || (INTVAL (operands[2]) < 0
6650 && INTVAL (operands[2]) != -128)))
6652 operands[2] = GEN_INT (-INTVAL (operands[2]));
6653 return "sub{l}\t{%2, %k0|%k0, %2}";
6655 return "add{l}\t{%2, %k0|%k0, %2}";
6659 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6660 (const_string "incdec")
6661 (const_string "alu")))
6662 (set_attr "mode" "SI")])
6664 (define_insn "*addsi_3"
6665 [(set (reg FLAGS_REG)
6666 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6667 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6668 (clobber (match_scratch:SI 0 "=r"))]
6669 "ix86_match_ccmode (insn, CCZmode)
6670 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6671 /* Current assemblers are broken and do not allow @GOTOFF in
6672 ought but a memory context. */
6673 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6675 switch (get_attr_type (insn))
6678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6679 if (operands[2] == const1_rtx)
6680 return "inc{l}\t%0";
6683 gcc_assert (operands[2] == constm1_rtx);
6684 return "dec{l}\t%0";
6688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6689 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6690 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6691 if (CONST_INT_P (operands[2])
6692 && (INTVAL (operands[2]) == 128
6693 || (INTVAL (operands[2]) < 0
6694 && INTVAL (operands[2]) != -128)))
6696 operands[2] = GEN_INT (-INTVAL (operands[2]));
6697 return "sub{l}\t{%2, %0|%0, %2}";
6699 return "add{l}\t{%2, %0|%0, %2}";
6703 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6704 (const_string "incdec")
6705 (const_string "alu")))
6706 (set_attr "mode" "SI")])
6708 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6709 (define_insn "*addsi_3_zext"
6710 [(set (reg FLAGS_REG)
6711 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6712 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6713 (set (match_operand:DI 0 "register_operand" "=r")
6714 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6715 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6716 && ix86_binary_operator_ok (PLUS, SImode, operands)
6717 /* Current assemblers are broken and do not allow @GOTOFF in
6718 ought but a memory context. */
6719 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6721 switch (get_attr_type (insn))
6724 if (operands[2] == const1_rtx)
6725 return "inc{l}\t%k0";
6728 gcc_assert (operands[2] == constm1_rtx);
6729 return "dec{l}\t%k0";
6733 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6734 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6735 if (CONST_INT_P (operands[2])
6736 && (INTVAL (operands[2]) == 128
6737 || (INTVAL (operands[2]) < 0
6738 && INTVAL (operands[2]) != -128)))
6740 operands[2] = GEN_INT (-INTVAL (operands[2]));
6741 return "sub{l}\t{%2, %k0|%k0, %2}";
6743 return "add{l}\t{%2, %k0|%k0, %2}";
6747 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6748 (const_string "incdec")
6749 (const_string "alu")))
6750 (set_attr "mode" "SI")])
6752 ; For comparisons against 1, -1 and 128, we may generate better code
6753 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6754 ; is matched then. We can't accept general immediate, because for
6755 ; case of overflows, the result is messed up.
6756 ; This pattern also don't hold of 0x80000000, since the value overflows
6758 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6759 ; only for comparisons not depending on it.
6760 (define_insn "*addsi_4"
6761 [(set (reg FLAGS_REG)
6762 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6763 (match_operand:SI 2 "const_int_operand" "n")))
6764 (clobber (match_scratch:SI 0 "=rm"))]
6765 "ix86_match_ccmode (insn, CCGCmode)
6766 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6768 switch (get_attr_type (insn))
6771 if (operands[2] == constm1_rtx)
6772 return "inc{l}\t%0";
6775 gcc_assert (operands[2] == const1_rtx);
6776 return "dec{l}\t%0";
6780 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6781 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6782 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6783 if ((INTVAL (operands[2]) == -128
6784 || (INTVAL (operands[2]) > 0
6785 && INTVAL (operands[2]) != 128)))
6786 return "sub{l}\t{%2, %0|%0, %2}";
6787 operands[2] = GEN_INT (-INTVAL (operands[2]));
6788 return "add{l}\t{%2, %0|%0, %2}";
6792 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6793 (const_string "incdec")
6794 (const_string "alu")))
6795 (set_attr "mode" "SI")])
6797 (define_insn "*addsi_5"
6798 [(set (reg FLAGS_REG)
6800 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6801 (match_operand:SI 2 "general_operand" "g"))
6803 (clobber (match_scratch:SI 0 "=r"))]
6804 "ix86_match_ccmode (insn, CCGOCmode)
6805 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6806 /* Current assemblers are broken and do not allow @GOTOFF in
6807 ought but a memory context. */
6808 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6810 switch (get_attr_type (insn))
6813 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6814 if (operands[2] == const1_rtx)
6815 return "inc{l}\t%0";
6818 gcc_assert (operands[2] == constm1_rtx);
6819 return "dec{l}\t%0";
6823 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6824 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6825 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6826 if (CONST_INT_P (operands[2])
6827 && (INTVAL (operands[2]) == 128
6828 || (INTVAL (operands[2]) < 0
6829 && INTVAL (operands[2]) != -128)))
6831 operands[2] = GEN_INT (-INTVAL (operands[2]));
6832 return "sub{l}\t{%2, %0|%0, %2}";
6834 return "add{l}\t{%2, %0|%0, %2}";
6838 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6839 (const_string "incdec")
6840 (const_string "alu")))
6841 (set_attr "mode" "SI")])
6843 (define_expand "addhi3"
6844 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6845 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6846 (match_operand:HI 2 "general_operand" "")))]
6847 "TARGET_HIMODE_MATH"
6848 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6850 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6851 ;; type optimizations enabled by define-splits. This is not important
6852 ;; for PII, and in fact harmful because of partial register stalls.
6854 (define_insn "*addhi_1_lea"
6855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6856 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6857 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6858 (clobber (reg:CC FLAGS_REG))]
6859 "!TARGET_PARTIAL_REG_STALL
6860 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6862 switch (get_attr_type (insn))
6867 if (operands[2] == const1_rtx)
6868 return "inc{w}\t%0";
6871 gcc_assert (operands[2] == constm1_rtx);
6872 return "dec{w}\t%0";
6876 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6877 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6878 if (CONST_INT_P (operands[2])
6879 && (INTVAL (operands[2]) == 128
6880 || (INTVAL (operands[2]) < 0
6881 && INTVAL (operands[2]) != -128)))
6883 operands[2] = GEN_INT (-INTVAL (operands[2]));
6884 return "sub{w}\t{%2, %0|%0, %2}";
6886 return "add{w}\t{%2, %0|%0, %2}";
6890 (if_then_else (eq_attr "alternative" "2")
6891 (const_string "lea")
6892 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6893 (const_string "incdec")
6894 (const_string "alu"))))
6895 (set_attr "mode" "HI,HI,SI")])
6897 (define_insn "*addhi_1"
6898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6899 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6900 (match_operand:HI 2 "general_operand" "rn,rm")))
6901 (clobber (reg:CC FLAGS_REG))]
6902 "TARGET_PARTIAL_REG_STALL
6903 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6905 switch (get_attr_type (insn))
6908 if (operands[2] == const1_rtx)
6909 return "inc{w}\t%0";
6912 gcc_assert (operands[2] == constm1_rtx);
6913 return "dec{w}\t%0";
6917 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6918 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6919 if (CONST_INT_P (operands[2])
6920 && (INTVAL (operands[2]) == 128
6921 || (INTVAL (operands[2]) < 0
6922 && INTVAL (operands[2]) != -128)))
6924 operands[2] = GEN_INT (-INTVAL (operands[2]));
6925 return "sub{w}\t{%2, %0|%0, %2}";
6927 return "add{w}\t{%2, %0|%0, %2}";
6931 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6932 (const_string "incdec")
6933 (const_string "alu")))
6934 (set_attr "mode" "HI")])
6936 (define_insn "*addhi_2"
6937 [(set (reg FLAGS_REG)
6939 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6940 (match_operand:HI 2 "general_operand" "rmn,rn"))
6942 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6943 (plus:HI (match_dup 1) (match_dup 2)))]
6944 "ix86_match_ccmode (insn, CCGOCmode)
6945 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6947 switch (get_attr_type (insn))
6950 if (operands[2] == const1_rtx)
6951 return "inc{w}\t%0";
6954 gcc_assert (operands[2] == constm1_rtx);
6955 return "dec{w}\t%0";
6959 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6960 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6961 if (CONST_INT_P (operands[2])
6962 && (INTVAL (operands[2]) == 128
6963 || (INTVAL (operands[2]) < 0
6964 && INTVAL (operands[2]) != -128)))
6966 operands[2] = GEN_INT (-INTVAL (operands[2]));
6967 return "sub{w}\t{%2, %0|%0, %2}";
6969 return "add{w}\t{%2, %0|%0, %2}";
6973 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6974 (const_string "incdec")
6975 (const_string "alu")))
6976 (set_attr "mode" "HI")])
6978 (define_insn "*addhi_3"
6979 [(set (reg FLAGS_REG)
6980 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6981 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6982 (clobber (match_scratch:HI 0 "=r"))]
6983 "ix86_match_ccmode (insn, CCZmode)
6984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6986 switch (get_attr_type (insn))
6989 if (operands[2] == const1_rtx)
6990 return "inc{w}\t%0";
6993 gcc_assert (operands[2] == constm1_rtx);
6994 return "dec{w}\t%0";
6998 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6999 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7000 if (CONST_INT_P (operands[2])
7001 && (INTVAL (operands[2]) == 128
7002 || (INTVAL (operands[2]) < 0
7003 && INTVAL (operands[2]) != -128)))
7005 operands[2] = GEN_INT (-INTVAL (operands[2]));
7006 return "sub{w}\t{%2, %0|%0, %2}";
7008 return "add{w}\t{%2, %0|%0, %2}";
7012 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7013 (const_string "incdec")
7014 (const_string "alu")))
7015 (set_attr "mode" "HI")])
7017 ; See comments above addsi_4 for details.
7018 (define_insn "*addhi_4"
7019 [(set (reg FLAGS_REG)
7020 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7021 (match_operand:HI 2 "const_int_operand" "n")))
7022 (clobber (match_scratch:HI 0 "=rm"))]
7023 "ix86_match_ccmode (insn, CCGCmode)
7024 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7026 switch (get_attr_type (insn))
7029 if (operands[2] == constm1_rtx)
7030 return "inc{w}\t%0";
7033 gcc_assert (operands[2] == const1_rtx);
7034 return "dec{w}\t%0";
7038 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7039 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7040 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7041 if ((INTVAL (operands[2]) == -128
7042 || (INTVAL (operands[2]) > 0
7043 && INTVAL (operands[2]) != 128)))
7044 return "sub{w}\t{%2, %0|%0, %2}";
7045 operands[2] = GEN_INT (-INTVAL (operands[2]));
7046 return "add{w}\t{%2, %0|%0, %2}";
7050 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7051 (const_string "incdec")
7052 (const_string "alu")))
7053 (set_attr "mode" "SI")])
7056 (define_insn "*addhi_5"
7057 [(set (reg FLAGS_REG)
7059 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7060 (match_operand:HI 2 "general_operand" "rmn"))
7062 (clobber (match_scratch:HI 0 "=r"))]
7063 "ix86_match_ccmode (insn, CCGOCmode)
7064 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7066 switch (get_attr_type (insn))
7069 if (operands[2] == const1_rtx)
7070 return "inc{w}\t%0";
7073 gcc_assert (operands[2] == constm1_rtx);
7074 return "dec{w}\t%0";
7078 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7079 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7080 if (CONST_INT_P (operands[2])
7081 && (INTVAL (operands[2]) == 128
7082 || (INTVAL (operands[2]) < 0
7083 && INTVAL (operands[2]) != -128)))
7085 operands[2] = GEN_INT (-INTVAL (operands[2]));
7086 return "sub{w}\t{%2, %0|%0, %2}";
7088 return "add{w}\t{%2, %0|%0, %2}";
7092 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7093 (const_string "incdec")
7094 (const_string "alu")))
7095 (set_attr "mode" "HI")])
7097 (define_expand "addqi3"
7098 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7099 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7100 (match_operand:QI 2 "general_operand" "")))]
7101 "TARGET_QIMODE_MATH"
7102 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7104 ;; %%% Potential partial reg stall on alternative 2. What to do?
7105 (define_insn "*addqi_1_lea"
7106 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7107 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7108 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7109 (clobber (reg:CC FLAGS_REG))]
7110 "!TARGET_PARTIAL_REG_STALL
7111 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7113 int widen = (which_alternative == 2);
7114 switch (get_attr_type (insn))
7119 if (operands[2] == const1_rtx)
7120 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7123 gcc_assert (operands[2] == constm1_rtx);
7124 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7128 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7129 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7130 if (CONST_INT_P (operands[2])
7131 && (INTVAL (operands[2]) == 128
7132 || (INTVAL (operands[2]) < 0
7133 && INTVAL (operands[2]) != -128)))
7135 operands[2] = GEN_INT (-INTVAL (operands[2]));
7137 return "sub{l}\t{%2, %k0|%k0, %2}";
7139 return "sub{b}\t{%2, %0|%0, %2}";
7142 return "add{l}\t{%k2, %k0|%k0, %k2}";
7144 return "add{b}\t{%2, %0|%0, %2}";
7148 (if_then_else (eq_attr "alternative" "3")
7149 (const_string "lea")
7150 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7151 (const_string "incdec")
7152 (const_string "alu"))))
7153 (set_attr "mode" "QI,QI,SI,SI")])
7155 (define_insn "*addqi_1"
7156 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7157 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7158 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7159 (clobber (reg:CC FLAGS_REG))]
7160 "TARGET_PARTIAL_REG_STALL
7161 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7163 int widen = (which_alternative == 2);
7164 switch (get_attr_type (insn))
7167 if (operands[2] == const1_rtx)
7168 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7171 gcc_assert (operands[2] == constm1_rtx);
7172 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7176 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7177 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7178 if (CONST_INT_P (operands[2])
7179 && (INTVAL (operands[2]) == 128
7180 || (INTVAL (operands[2]) < 0
7181 && INTVAL (operands[2]) != -128)))
7183 operands[2] = GEN_INT (-INTVAL (operands[2]));
7185 return "sub{l}\t{%2, %k0|%k0, %2}";
7187 return "sub{b}\t{%2, %0|%0, %2}";
7190 return "add{l}\t{%k2, %k0|%k0, %k2}";
7192 return "add{b}\t{%2, %0|%0, %2}";
7196 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7197 (const_string "incdec")
7198 (const_string "alu")))
7199 (set_attr "mode" "QI,QI,SI")])
7201 (define_insn "*addqi_1_slp"
7202 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7203 (plus:QI (match_dup 0)
7204 (match_operand:QI 1 "general_operand" "qn,qnm")))
7205 (clobber (reg:CC FLAGS_REG))]
7206 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7207 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7209 switch (get_attr_type (insn))
7212 if (operands[1] == const1_rtx)
7213 return "inc{b}\t%0";
7216 gcc_assert (operands[1] == constm1_rtx);
7217 return "dec{b}\t%0";
7221 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7222 if (CONST_INT_P (operands[1])
7223 && INTVAL (operands[1]) < 0)
7225 operands[1] = GEN_INT (-INTVAL (operands[1]));
7226 return "sub{b}\t{%1, %0|%0, %1}";
7228 return "add{b}\t{%1, %0|%0, %1}";
7232 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7233 (const_string "incdec")
7234 (const_string "alu1")))
7235 (set (attr "memory")
7236 (if_then_else (match_operand 1 "memory_operand" "")
7237 (const_string "load")
7238 (const_string "none")))
7239 (set_attr "mode" "QI")])
7241 (define_insn "*addqi_2"
7242 [(set (reg FLAGS_REG)
7244 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7245 (match_operand:QI 2 "general_operand" "qmn,qn"))
7247 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7248 (plus:QI (match_dup 1) (match_dup 2)))]
7249 "ix86_match_ccmode (insn, CCGOCmode)
7250 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7252 switch (get_attr_type (insn))
7255 if (operands[2] == const1_rtx)
7256 return "inc{b}\t%0";
7259 gcc_assert (operands[2] == constm1_rtx
7260 || (CONST_INT_P (operands[2])
7261 && INTVAL (operands[2]) == 255));
7262 return "dec{b}\t%0";
7266 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7267 if (CONST_INT_P (operands[2])
7268 && INTVAL (operands[2]) < 0)
7270 operands[2] = GEN_INT (-INTVAL (operands[2]));
7271 return "sub{b}\t{%2, %0|%0, %2}";
7273 return "add{b}\t{%2, %0|%0, %2}";
7277 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7278 (const_string "incdec")
7279 (const_string "alu")))
7280 (set_attr "mode" "QI")])
7282 (define_insn "*addqi_3"
7283 [(set (reg FLAGS_REG)
7284 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7285 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7286 (clobber (match_scratch:QI 0 "=q"))]
7287 "ix86_match_ccmode (insn, CCZmode)
7288 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7290 switch (get_attr_type (insn))
7293 if (operands[2] == const1_rtx)
7294 return "inc{b}\t%0";
7297 gcc_assert (operands[2] == constm1_rtx
7298 || (CONST_INT_P (operands[2])
7299 && INTVAL (operands[2]) == 255));
7300 return "dec{b}\t%0";
7304 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7305 if (CONST_INT_P (operands[2])
7306 && INTVAL (operands[2]) < 0)
7308 operands[2] = GEN_INT (-INTVAL (operands[2]));
7309 return "sub{b}\t{%2, %0|%0, %2}";
7311 return "add{b}\t{%2, %0|%0, %2}";
7315 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7316 (const_string "incdec")
7317 (const_string "alu")))
7318 (set_attr "mode" "QI")])
7320 ; See comments above addsi_4 for details.
7321 (define_insn "*addqi_4"
7322 [(set (reg FLAGS_REG)
7323 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7324 (match_operand:QI 2 "const_int_operand" "n")))
7325 (clobber (match_scratch:QI 0 "=qm"))]
7326 "ix86_match_ccmode (insn, CCGCmode)
7327 && (INTVAL (operands[2]) & 0xff) != 0x80"
7329 switch (get_attr_type (insn))
7332 if (operands[2] == constm1_rtx
7333 || (CONST_INT_P (operands[2])
7334 && INTVAL (operands[2]) == 255))
7335 return "inc{b}\t%0";
7338 gcc_assert (operands[2] == const1_rtx);
7339 return "dec{b}\t%0";
7343 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7344 if (INTVAL (operands[2]) < 0)
7346 operands[2] = GEN_INT (-INTVAL (operands[2]));
7347 return "add{b}\t{%2, %0|%0, %2}";
7349 return "sub{b}\t{%2, %0|%0, %2}";
7353 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7354 (const_string "incdec")
7355 (const_string "alu")))
7356 (set_attr "mode" "QI")])
7359 (define_insn "*addqi_5"
7360 [(set (reg FLAGS_REG)
7362 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7363 (match_operand:QI 2 "general_operand" "qmn"))
7365 (clobber (match_scratch:QI 0 "=q"))]
7366 "ix86_match_ccmode (insn, CCGOCmode)
7367 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7369 switch (get_attr_type (insn))
7372 if (operands[2] == const1_rtx)
7373 return "inc{b}\t%0";
7376 gcc_assert (operands[2] == constm1_rtx
7377 || (CONST_INT_P (operands[2])
7378 && INTVAL (operands[2]) == 255));
7379 return "dec{b}\t%0";
7383 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7384 if (CONST_INT_P (operands[2])
7385 && INTVAL (operands[2]) < 0)
7387 operands[2] = GEN_INT (-INTVAL (operands[2]));
7388 return "sub{b}\t{%2, %0|%0, %2}";
7390 return "add{b}\t{%2, %0|%0, %2}";
7394 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7395 (const_string "incdec")
7396 (const_string "alu")))
7397 (set_attr "mode" "QI")])
7400 (define_insn "addqi_ext_1"
7401 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7406 (match_operand 1 "ext_register_operand" "0")
7409 (match_operand:QI 2 "general_operand" "Qmn")))
7410 (clobber (reg:CC FLAGS_REG))]
7413 switch (get_attr_type (insn))
7416 if (operands[2] == const1_rtx)
7417 return "inc{b}\t%h0";
7420 gcc_assert (operands[2] == constm1_rtx
7421 || (CONST_INT_P (operands[2])
7422 && INTVAL (operands[2]) == 255));
7423 return "dec{b}\t%h0";
7427 return "add{b}\t{%2, %h0|%h0, %2}";
7431 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7432 (const_string "incdec")
7433 (const_string "alu")))
7434 (set_attr "mode" "QI")])
7436 (define_insn "*addqi_ext_1_rex64"
7437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7442 (match_operand 1 "ext_register_operand" "0")
7445 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7446 (clobber (reg:CC FLAGS_REG))]
7449 switch (get_attr_type (insn))
7452 if (operands[2] == const1_rtx)
7453 return "inc{b}\t%h0";
7456 gcc_assert (operands[2] == constm1_rtx
7457 || (CONST_INT_P (operands[2])
7458 && INTVAL (operands[2]) == 255));
7459 return "dec{b}\t%h0";
7463 return "add{b}\t{%2, %h0|%h0, %2}";
7467 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7468 (const_string "incdec")
7469 (const_string "alu")))
7470 (set_attr "mode" "QI")])
7472 (define_insn "*addqi_ext_2"
7473 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7478 (match_operand 1 "ext_register_operand" "%0")
7482 (match_operand 2 "ext_register_operand" "Q")
7485 (clobber (reg:CC FLAGS_REG))]
7487 "add{b}\t{%h2, %h0|%h0, %h2}"
7488 [(set_attr "type" "alu")
7489 (set_attr "mode" "QI")])
7491 ;; The patterns that match these are at the end of this file.
7493 (define_expand "addxf3"
7494 [(set (match_operand:XF 0 "register_operand" "")
7495 (plus:XF (match_operand:XF 1 "register_operand" "")
7496 (match_operand:XF 2 "register_operand" "")))]
7500 (define_expand "add<mode>3"
7501 [(set (match_operand:MODEF 0 "register_operand" "")
7502 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7503 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7504 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7505 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7508 ;; Subtract instructions
7510 ;; %%% splits for subditi3
7512 (define_expand "subti3"
7513 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7514 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7515 (match_operand:TI 2 "x86_64_general_operand" "")))]
7517 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7519 (define_insn "*subti3_1"
7520 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7521 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7522 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7523 (clobber (reg:CC FLAGS_REG))]
7524 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7528 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7529 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7530 (match_operand:TI 2 "x86_64_general_operand" "")))
7531 (clobber (reg:CC FLAGS_REG))]
7532 "TARGET_64BIT && reload_completed"
7533 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7534 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7535 (parallel [(set (match_dup 3)
7536 (minus:DI (match_dup 4)
7537 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7539 (clobber (reg:CC FLAGS_REG))])]
7540 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7542 ;; %%% splits for subsidi3
7544 (define_expand "subdi3"
7545 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7546 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7547 (match_operand:DI 2 "x86_64_general_operand" "")))]
7549 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7551 (define_insn "*subdi3_1"
7552 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7553 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7554 (match_operand:DI 2 "general_operand" "roiF,riF")))
7555 (clobber (reg:CC FLAGS_REG))]
7556 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7560 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7561 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7562 (match_operand:DI 2 "general_operand" "")))
7563 (clobber (reg:CC FLAGS_REG))]
7564 "!TARGET_64BIT && reload_completed"
7565 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7566 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7567 (parallel [(set (match_dup 3)
7568 (minus:SI (match_dup 4)
7569 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7571 (clobber (reg:CC FLAGS_REG))])]
7572 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7574 (define_insn "subdi3_carry_rex64"
7575 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7576 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7577 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7578 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7579 (clobber (reg:CC FLAGS_REG))]
7580 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7581 "sbb{q}\t{%2, %0|%0, %2}"
7582 [(set_attr "type" "alu")
7583 (set_attr "pent_pair" "pu")
7584 (set_attr "mode" "DI")])
7586 (define_insn "*subdi_1_rex64"
7587 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7588 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7589 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7590 (clobber (reg:CC FLAGS_REG))]
7591 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7592 "sub{q}\t{%2, %0|%0, %2}"
7593 [(set_attr "type" "alu")
7594 (set_attr "mode" "DI")])
7596 (define_insn "*subdi_2_rex64"
7597 [(set (reg FLAGS_REG)
7599 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7600 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7602 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7603 (minus:DI (match_dup 1) (match_dup 2)))]
7604 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7605 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7606 "sub{q}\t{%2, %0|%0, %2}"
7607 [(set_attr "type" "alu")
7608 (set_attr "mode" "DI")])
7610 (define_insn "*subdi_3_rex63"
7611 [(set (reg FLAGS_REG)
7612 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7613 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7614 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7615 (minus:DI (match_dup 1) (match_dup 2)))]
7616 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7617 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7618 "sub{q}\t{%2, %0|%0, %2}"
7619 [(set_attr "type" "alu")
7620 (set_attr "mode" "DI")])
7622 (define_insn "subqi3_carry"
7623 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7624 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7625 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7626 (match_operand:QI 2 "general_operand" "qn,qm"))))
7627 (clobber (reg:CC FLAGS_REG))]
7628 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7629 "sbb{b}\t{%2, %0|%0, %2}"
7630 [(set_attr "type" "alu")
7631 (set_attr "pent_pair" "pu")
7632 (set_attr "mode" "QI")])
7634 (define_insn "subhi3_carry"
7635 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7636 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7637 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7638 (match_operand:HI 2 "general_operand" "rn,rm"))))
7639 (clobber (reg:CC FLAGS_REG))]
7640 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7641 "sbb{w}\t{%2, %0|%0, %2}"
7642 [(set_attr "type" "alu")
7643 (set_attr "pent_pair" "pu")
7644 (set_attr "mode" "HI")])
7646 (define_insn "subsi3_carry"
7647 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7648 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7649 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7650 (match_operand:SI 2 "general_operand" "ri,rm"))))
7651 (clobber (reg:CC FLAGS_REG))]
7652 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7653 "sbb{l}\t{%2, %0|%0, %2}"
7654 [(set_attr "type" "alu")
7655 (set_attr "pent_pair" "pu")
7656 (set_attr "mode" "SI")])
7658 (define_insn "subsi3_carry_zext"
7659 [(set (match_operand:DI 0 "register_operand" "=r")
7661 (minus:SI (match_operand:SI 1 "register_operand" "0")
7662 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7663 (match_operand:SI 2 "general_operand" "g")))))
7664 (clobber (reg:CC FLAGS_REG))]
7665 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7666 "sbb{l}\t{%2, %k0|%k0, %2}"
7667 [(set_attr "type" "alu")
7668 (set_attr "pent_pair" "pu")
7669 (set_attr "mode" "SI")])
7671 (define_expand "subsi3"
7672 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7673 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7674 (match_operand:SI 2 "general_operand" "")))]
7676 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7678 (define_insn "*subsi_1"
7679 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7680 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7681 (match_operand:SI 2 "general_operand" "ri,rm")))
7682 (clobber (reg:CC FLAGS_REG))]
7683 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7684 "sub{l}\t{%2, %0|%0, %2}"
7685 [(set_attr "type" "alu")
7686 (set_attr "mode" "SI")])
7688 (define_insn "*subsi_1_zext"
7689 [(set (match_operand:DI 0 "register_operand" "=r")
7691 (minus:SI (match_operand:SI 1 "register_operand" "0")
7692 (match_operand:SI 2 "general_operand" "g"))))
7693 (clobber (reg:CC FLAGS_REG))]
7694 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7695 "sub{l}\t{%2, %k0|%k0, %2}"
7696 [(set_attr "type" "alu")
7697 (set_attr "mode" "SI")])
7699 (define_insn "*subsi_2"
7700 [(set (reg FLAGS_REG)
7702 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7703 (match_operand:SI 2 "general_operand" "ri,rm"))
7705 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7706 (minus:SI (match_dup 1) (match_dup 2)))]
7707 "ix86_match_ccmode (insn, CCGOCmode)
7708 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7709 "sub{l}\t{%2, %0|%0, %2}"
7710 [(set_attr "type" "alu")
7711 (set_attr "mode" "SI")])
7713 (define_insn "*subsi_2_zext"
7714 [(set (reg FLAGS_REG)
7716 (minus:SI (match_operand:SI 1 "register_operand" "0")
7717 (match_operand:SI 2 "general_operand" "g"))
7719 (set (match_operand:DI 0 "register_operand" "=r")
7721 (minus:SI (match_dup 1)
7723 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7724 && 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_3"
7730 [(set (reg FLAGS_REG)
7731 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7732 (match_operand:SI 2 "general_operand" "ri,rm")))
7733 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7734 (minus:SI (match_dup 1) (match_dup 2)))]
7735 "ix86_match_ccmode (insn, CCmode)
7736 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7737 "sub{l}\t{%2, %0|%0, %2}"
7738 [(set_attr "type" "alu")
7739 (set_attr "mode" "SI")])
7741 (define_insn "*subsi_3_zext"
7742 [(set (reg FLAGS_REG)
7743 (compare (match_operand:SI 1 "register_operand" "0")
7744 (match_operand:SI 2 "general_operand" "g")))
7745 (set (match_operand:DI 0 "register_operand" "=r")
7747 (minus:SI (match_dup 1)
7749 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7750 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7751 "sub{l}\t{%2, %1|%1, %2}"
7752 [(set_attr "type" "alu")
7753 (set_attr "mode" "DI")])
7755 (define_expand "subhi3"
7756 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7757 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7758 (match_operand:HI 2 "general_operand" "")))]
7759 "TARGET_HIMODE_MATH"
7760 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7762 (define_insn "*subhi_1"
7763 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7764 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7765 (match_operand:HI 2 "general_operand" "rn,rm")))
7766 (clobber (reg:CC FLAGS_REG))]
7767 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7768 "sub{w}\t{%2, %0|%0, %2}"
7769 [(set_attr "type" "alu")
7770 (set_attr "mode" "HI")])
7772 (define_insn "*subhi_2"
7773 [(set (reg FLAGS_REG)
7775 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7776 (match_operand:HI 2 "general_operand" "rn,rm"))
7778 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7779 (minus:HI (match_dup 1) (match_dup 2)))]
7780 "ix86_match_ccmode (insn, CCGOCmode)
7781 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7782 "sub{w}\t{%2, %0|%0, %2}"
7783 [(set_attr "type" "alu")
7784 (set_attr "mode" "HI")])
7786 (define_insn "*subhi_3"
7787 [(set (reg FLAGS_REG)
7788 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7789 (match_operand:HI 2 "general_operand" "rn,rm")))
7790 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7791 (minus:HI (match_dup 1) (match_dup 2)))]
7792 "ix86_match_ccmode (insn, CCmode)
7793 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7794 "sub{w}\t{%2, %0|%0, %2}"
7795 [(set_attr "type" "alu")
7796 (set_attr "mode" "HI")])
7798 (define_expand "subqi3"
7799 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7800 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7801 (match_operand:QI 2 "general_operand" "")))]
7802 "TARGET_QIMODE_MATH"
7803 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7805 (define_insn "*subqi_1"
7806 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7807 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7808 (match_operand:QI 2 "general_operand" "qn,qm")))
7809 (clobber (reg:CC FLAGS_REG))]
7810 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7811 "sub{b}\t{%2, %0|%0, %2}"
7812 [(set_attr "type" "alu")
7813 (set_attr "mode" "QI")])
7815 (define_insn "*subqi_1_slp"
7816 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7817 (minus:QI (match_dup 0)
7818 (match_operand:QI 1 "general_operand" "qn,qm")))
7819 (clobber (reg:CC FLAGS_REG))]
7820 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7821 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7822 "sub{b}\t{%1, %0|%0, %1}"
7823 [(set_attr "type" "alu1")
7824 (set_attr "mode" "QI")])
7826 (define_insn "*subqi_2"
7827 [(set (reg FLAGS_REG)
7829 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7830 (match_operand:QI 2 "general_operand" "qn,qm"))
7832 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7833 (minus:QI (match_dup 1) (match_dup 2)))]
7834 "ix86_match_ccmode (insn, CCGOCmode)
7835 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7836 "sub{b}\t{%2, %0|%0, %2}"
7837 [(set_attr "type" "alu")
7838 (set_attr "mode" "QI")])
7840 (define_insn "*subqi_3"
7841 [(set (reg FLAGS_REG)
7842 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7843 (match_operand:QI 2 "general_operand" "qn,qm")))
7844 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7845 (minus:QI (match_dup 1) (match_dup 2)))]
7846 "ix86_match_ccmode (insn, CCmode)
7847 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7848 "sub{b}\t{%2, %0|%0, %2}"
7849 [(set_attr "type" "alu")
7850 (set_attr "mode" "QI")])
7852 ;; The patterns that match these are at the end of this file.
7854 (define_expand "subxf3"
7855 [(set (match_operand:XF 0 "register_operand" "")
7856 (minus:XF (match_operand:XF 1 "register_operand" "")
7857 (match_operand:XF 2 "register_operand" "")))]
7861 (define_expand "sub<mode>3"
7862 [(set (match_operand:MODEF 0 "register_operand" "")
7863 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7864 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7865 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7866 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7869 ;; Multiply instructions
7871 (define_expand "muldi3"
7872 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7873 (mult:DI (match_operand:DI 1 "register_operand" "")
7874 (match_operand:DI 2 "x86_64_general_operand" "")))
7875 (clobber (reg:CC FLAGS_REG))])]
7880 ;; IMUL reg64, reg64, imm8 Direct
7881 ;; IMUL reg64, mem64, imm8 VectorPath
7882 ;; IMUL reg64, reg64, imm32 Direct
7883 ;; IMUL reg64, mem64, imm32 VectorPath
7884 ;; IMUL reg64, reg64 Direct
7885 ;; IMUL reg64, mem64 Direct
7887 (define_insn "*muldi3_1_rex64"
7888 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7889 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7890 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7891 (clobber (reg:CC FLAGS_REG))]
7893 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7895 imul{q}\t{%2, %1, %0|%0, %1, %2}
7896 imul{q}\t{%2, %1, %0|%0, %1, %2}
7897 imul{q}\t{%2, %0|%0, %2}"
7898 [(set_attr "type" "imul")
7899 (set_attr "prefix_0f" "0,0,1")
7900 (set (attr "athlon_decode")
7901 (cond [(eq_attr "cpu" "athlon")
7902 (const_string "vector")
7903 (eq_attr "alternative" "1")
7904 (const_string "vector")
7905 (and (eq_attr "alternative" "2")
7906 (match_operand 1 "memory_operand" ""))
7907 (const_string "vector")]
7908 (const_string "direct")))
7909 (set (attr "amdfam10_decode")
7910 (cond [(and (eq_attr "alternative" "0,1")
7911 (match_operand 1 "memory_operand" ""))
7912 (const_string "vector")]
7913 (const_string "direct")))
7914 (set_attr "mode" "DI")])
7916 (define_expand "mulsi3"
7917 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7918 (mult:SI (match_operand:SI 1 "register_operand" "")
7919 (match_operand:SI 2 "general_operand" "")))
7920 (clobber (reg:CC FLAGS_REG))])]
7925 ;; IMUL reg32, reg32, imm8 Direct
7926 ;; IMUL reg32, mem32, imm8 VectorPath
7927 ;; IMUL reg32, reg32, imm32 Direct
7928 ;; IMUL reg32, mem32, imm32 VectorPath
7929 ;; IMUL reg32, reg32 Direct
7930 ;; IMUL reg32, mem32 Direct
7932 (define_insn "*mulsi3_1"
7933 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7934 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7935 (match_operand:SI 2 "general_operand" "K,i,mr")))
7936 (clobber (reg:CC FLAGS_REG))]
7937 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7939 imul{l}\t{%2, %1, %0|%0, %1, %2}
7940 imul{l}\t{%2, %1, %0|%0, %1, %2}
7941 imul{l}\t{%2, %0|%0, %2}"
7942 [(set_attr "type" "imul")
7943 (set_attr "prefix_0f" "0,0,1")
7944 (set (attr "athlon_decode")
7945 (cond [(eq_attr "cpu" "athlon")
7946 (const_string "vector")
7947 (eq_attr "alternative" "1")
7948 (const_string "vector")
7949 (and (eq_attr "alternative" "2")
7950 (match_operand 1 "memory_operand" ""))
7951 (const_string "vector")]
7952 (const_string "direct")))
7953 (set (attr "amdfam10_decode")
7954 (cond [(and (eq_attr "alternative" "0,1")
7955 (match_operand 1 "memory_operand" ""))
7956 (const_string "vector")]
7957 (const_string "direct")))
7958 (set_attr "mode" "SI")])
7960 (define_insn "*mulsi3_1_zext"
7961 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7963 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7964 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7965 (clobber (reg:CC FLAGS_REG))]
7967 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7969 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7970 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7971 imul{l}\t{%2, %k0|%k0, %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_expand "mulhi3"
7991 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7992 (mult:HI (match_operand:HI 1 "register_operand" "")
7993 (match_operand:HI 2 "general_operand" "")))
7994 (clobber (reg:CC FLAGS_REG))])]
7995 "TARGET_HIMODE_MATH"
7999 ;; IMUL reg16, reg16, imm8 VectorPath
8000 ;; IMUL reg16, mem16, imm8 VectorPath
8001 ;; IMUL reg16, reg16, imm16 VectorPath
8002 ;; IMUL reg16, mem16, imm16 VectorPath
8003 ;; IMUL reg16, reg16 Direct
8004 ;; IMUL reg16, mem16 Direct
8005 (define_insn "*mulhi3_1"
8006 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8007 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8008 (match_operand:HI 2 "general_operand" "K,n,mr")))
8009 (clobber (reg:CC FLAGS_REG))]
8010 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8012 imul{w}\t{%2, %1, %0|%0, %1, %2}
8013 imul{w}\t{%2, %1, %0|%0, %1, %2}
8014 imul{w}\t{%2, %0|%0, %2}"
8015 [(set_attr "type" "imul")
8016 (set_attr "prefix_0f" "0,0,1")
8017 (set (attr "athlon_decode")
8018 (cond [(eq_attr "cpu" "athlon")
8019 (const_string "vector")
8020 (eq_attr "alternative" "1,2")
8021 (const_string "vector")]
8022 (const_string "direct")))
8023 (set (attr "amdfam10_decode")
8024 (cond [(eq_attr "alternative" "0,1")
8025 (const_string "vector")]
8026 (const_string "direct")))
8027 (set_attr "mode" "HI")])
8029 (define_expand "mulqi3"
8030 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8031 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8032 (match_operand:QI 2 "register_operand" "")))
8033 (clobber (reg:CC FLAGS_REG))])]
8034 "TARGET_QIMODE_MATH"
8041 (define_insn "*mulqi3_1"
8042 [(set (match_operand:QI 0 "register_operand" "=a")
8043 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8044 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8045 (clobber (reg:CC FLAGS_REG))]
8047 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8049 [(set_attr "type" "imul")
8050 (set_attr "length_immediate" "0")
8051 (set (attr "athlon_decode")
8052 (if_then_else (eq_attr "cpu" "athlon")
8053 (const_string "vector")
8054 (const_string "direct")))
8055 (set_attr "amdfam10_decode" "direct")
8056 (set_attr "mode" "QI")])
8058 (define_expand "umulqihi3"
8059 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8060 (mult:HI (zero_extend:HI
8061 (match_operand:QI 1 "nonimmediate_operand" ""))
8063 (match_operand:QI 2 "register_operand" ""))))
8064 (clobber (reg:CC FLAGS_REG))])]
8065 "TARGET_QIMODE_MATH"
8068 (define_insn "*umulqihi3_1"
8069 [(set (match_operand:HI 0 "register_operand" "=a")
8070 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8071 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8072 (clobber (reg:CC FLAGS_REG))]
8074 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8076 [(set_attr "type" "imul")
8077 (set_attr "length_immediate" "0")
8078 (set (attr "athlon_decode")
8079 (if_then_else (eq_attr "cpu" "athlon")
8080 (const_string "vector")
8081 (const_string "direct")))
8082 (set_attr "amdfam10_decode" "direct")
8083 (set_attr "mode" "QI")])
8085 (define_expand "mulqihi3"
8086 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8087 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8088 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8089 (clobber (reg:CC FLAGS_REG))])]
8090 "TARGET_QIMODE_MATH"
8093 (define_insn "*mulqihi3_insn"
8094 [(set (match_operand:HI 0 "register_operand" "=a")
8095 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8096 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8097 (clobber (reg:CC FLAGS_REG))]
8099 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8101 [(set_attr "type" "imul")
8102 (set_attr "length_immediate" "0")
8103 (set (attr "athlon_decode")
8104 (if_then_else (eq_attr "cpu" "athlon")
8105 (const_string "vector")
8106 (const_string "direct")))
8107 (set_attr "amdfam10_decode" "direct")
8108 (set_attr "mode" "QI")])
8110 (define_expand "umulditi3"
8111 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8112 (mult:TI (zero_extend:TI
8113 (match_operand:DI 1 "nonimmediate_operand" ""))
8115 (match_operand:DI 2 "register_operand" ""))))
8116 (clobber (reg:CC FLAGS_REG))])]
8120 (define_insn "*umulditi3_insn"
8121 [(set (match_operand:TI 0 "register_operand" "=A")
8122 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8123 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8124 (clobber (reg:CC FLAGS_REG))]
8126 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8128 [(set_attr "type" "imul")
8129 (set_attr "length_immediate" "0")
8130 (set (attr "athlon_decode")
8131 (if_then_else (eq_attr "cpu" "athlon")
8132 (const_string "vector")
8133 (const_string "double")))
8134 (set_attr "amdfam10_decode" "double")
8135 (set_attr "mode" "DI")])
8137 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8138 (define_expand "umulsidi3"
8139 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8140 (mult:DI (zero_extend:DI
8141 (match_operand:SI 1 "nonimmediate_operand" ""))
8143 (match_operand:SI 2 "register_operand" ""))))
8144 (clobber (reg:CC FLAGS_REG))])]
8148 (define_insn "*umulsidi3_insn"
8149 [(set (match_operand:DI 0 "register_operand" "=A")
8150 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8151 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8152 (clobber (reg:CC FLAGS_REG))]
8154 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8156 [(set_attr "type" "imul")
8157 (set_attr "length_immediate" "0")
8158 (set (attr "athlon_decode")
8159 (if_then_else (eq_attr "cpu" "athlon")
8160 (const_string "vector")
8161 (const_string "double")))
8162 (set_attr "amdfam10_decode" "double")
8163 (set_attr "mode" "SI")])
8165 (define_expand "mulditi3"
8166 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8167 (mult:TI (sign_extend:TI
8168 (match_operand:DI 1 "nonimmediate_operand" ""))
8170 (match_operand:DI 2 "register_operand" ""))))
8171 (clobber (reg:CC FLAGS_REG))])]
8175 (define_insn "*mulditi3_insn"
8176 [(set (match_operand:TI 0 "register_operand" "=A")
8177 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8178 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8179 (clobber (reg:CC FLAGS_REG))]
8181 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8183 [(set_attr "type" "imul")
8184 (set_attr "length_immediate" "0")
8185 (set (attr "athlon_decode")
8186 (if_then_else (eq_attr "cpu" "athlon")
8187 (const_string "vector")
8188 (const_string "double")))
8189 (set_attr "amdfam10_decode" "double")
8190 (set_attr "mode" "DI")])
8192 (define_expand "mulsidi3"
8193 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8194 (mult:DI (sign_extend:DI
8195 (match_operand:SI 1 "nonimmediate_operand" ""))
8197 (match_operand:SI 2 "register_operand" ""))))
8198 (clobber (reg:CC FLAGS_REG))])]
8202 (define_insn "*mulsidi3_insn"
8203 [(set (match_operand:DI 0 "register_operand" "=A")
8204 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8205 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8206 (clobber (reg:CC FLAGS_REG))]
8208 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8210 [(set_attr "type" "imul")
8211 (set_attr "length_immediate" "0")
8212 (set (attr "athlon_decode")
8213 (if_then_else (eq_attr "cpu" "athlon")
8214 (const_string "vector")
8215 (const_string "double")))
8216 (set_attr "amdfam10_decode" "double")
8217 (set_attr "mode" "SI")])
8219 (define_expand "umuldi3_highpart"
8220 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8223 (mult:TI (zero_extend:TI
8224 (match_operand:DI 1 "nonimmediate_operand" ""))
8226 (match_operand:DI 2 "register_operand" "")))
8228 (clobber (match_scratch:DI 3 ""))
8229 (clobber (reg:CC FLAGS_REG))])]
8233 (define_insn "*umuldi3_highpart_rex64"
8234 [(set (match_operand:DI 0 "register_operand" "=d")
8237 (mult:TI (zero_extend:TI
8238 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8240 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8242 (clobber (match_scratch:DI 3 "=1"))
8243 (clobber (reg:CC FLAGS_REG))]
8245 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8247 [(set_attr "type" "imul")
8248 (set_attr "length_immediate" "0")
8249 (set (attr "athlon_decode")
8250 (if_then_else (eq_attr "cpu" "athlon")
8251 (const_string "vector")
8252 (const_string "double")))
8253 (set_attr "amdfam10_decode" "double")
8254 (set_attr "mode" "DI")])
8256 (define_expand "umulsi3_highpart"
8257 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8260 (mult:DI (zero_extend:DI
8261 (match_operand:SI 1 "nonimmediate_operand" ""))
8263 (match_operand:SI 2 "register_operand" "")))
8265 (clobber (match_scratch:SI 3 ""))
8266 (clobber (reg:CC FLAGS_REG))])]
8270 (define_insn "*umulsi3_highpart_insn"
8271 [(set (match_operand:SI 0 "register_operand" "=d")
8274 (mult:DI (zero_extend:DI
8275 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8277 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8279 (clobber (match_scratch:SI 3 "=1"))
8280 (clobber (reg:CC FLAGS_REG))]
8281 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8283 [(set_attr "type" "imul")
8284 (set_attr "length_immediate" "0")
8285 (set (attr "athlon_decode")
8286 (if_then_else (eq_attr "cpu" "athlon")
8287 (const_string "vector")
8288 (const_string "double")))
8289 (set_attr "amdfam10_decode" "double")
8290 (set_attr "mode" "SI")])
8292 (define_insn "*umulsi3_highpart_zext"
8293 [(set (match_operand:DI 0 "register_operand" "=d")
8294 (zero_extend:DI (truncate:SI
8296 (mult:DI (zero_extend:DI
8297 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8299 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8301 (clobber (match_scratch:SI 3 "=1"))
8302 (clobber (reg:CC FLAGS_REG))]
8304 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8306 [(set_attr "type" "imul")
8307 (set_attr "length_immediate" "0")
8308 (set (attr "athlon_decode")
8309 (if_then_else (eq_attr "cpu" "athlon")
8310 (const_string "vector")
8311 (const_string "double")))
8312 (set_attr "amdfam10_decode" "double")
8313 (set_attr "mode" "SI")])
8315 (define_expand "smuldi3_highpart"
8316 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8319 (mult:TI (sign_extend:TI
8320 (match_operand:DI 1 "nonimmediate_operand" ""))
8322 (match_operand:DI 2 "register_operand" "")))
8324 (clobber (match_scratch:DI 3 ""))
8325 (clobber (reg:CC FLAGS_REG))])]
8329 (define_insn "*smuldi3_highpart_rex64"
8330 [(set (match_operand:DI 0 "register_operand" "=d")
8333 (mult:TI (sign_extend:TI
8334 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8336 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8338 (clobber (match_scratch:DI 3 "=1"))
8339 (clobber (reg:CC FLAGS_REG))]
8341 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8343 [(set_attr "type" "imul")
8344 (set (attr "athlon_decode")
8345 (if_then_else (eq_attr "cpu" "athlon")
8346 (const_string "vector")
8347 (const_string "double")))
8348 (set_attr "amdfam10_decode" "double")
8349 (set_attr "mode" "DI")])
8351 (define_expand "smulsi3_highpart"
8352 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8355 (mult:DI (sign_extend:DI
8356 (match_operand:SI 1 "nonimmediate_operand" ""))
8358 (match_operand:SI 2 "register_operand" "")))
8360 (clobber (match_scratch:SI 3 ""))
8361 (clobber (reg:CC FLAGS_REG))])]
8365 (define_insn "*smulsi3_highpart_insn"
8366 [(set (match_operand:SI 0 "register_operand" "=d")
8369 (mult:DI (sign_extend:DI
8370 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8372 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8374 (clobber (match_scratch:SI 3 "=1"))
8375 (clobber (reg:CC FLAGS_REG))]
8376 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8378 [(set_attr "type" "imul")
8379 (set (attr "athlon_decode")
8380 (if_then_else (eq_attr "cpu" "athlon")
8381 (const_string "vector")
8382 (const_string "double")))
8383 (set_attr "amdfam10_decode" "double")
8384 (set_attr "mode" "SI")])
8386 (define_insn "*smulsi3_highpart_zext"
8387 [(set (match_operand:DI 0 "register_operand" "=d")
8388 (zero_extend:DI (truncate:SI
8390 (mult:DI (sign_extend:DI
8391 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8393 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8395 (clobber (match_scratch:SI 3 "=1"))
8396 (clobber (reg:CC FLAGS_REG))]
8398 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8400 [(set_attr "type" "imul")
8401 (set (attr "athlon_decode")
8402 (if_then_else (eq_attr "cpu" "athlon")
8403 (const_string "vector")
8404 (const_string "double")))
8405 (set_attr "amdfam10_decode" "double")
8406 (set_attr "mode" "SI")])
8408 ;; The patterns that match these are at the end of this file.
8410 (define_expand "mulxf3"
8411 [(set (match_operand:XF 0 "register_operand" "")
8412 (mult:XF (match_operand:XF 1 "register_operand" "")
8413 (match_operand:XF 2 "register_operand" "")))]
8417 (define_expand "mul<mode>3"
8418 [(set (match_operand:MODEF 0 "register_operand" "")
8419 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8420 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8421 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8422 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8425 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8428 ;; Divide instructions
8430 (define_insn "divqi3"
8431 [(set (match_operand:QI 0 "register_operand" "=a")
8432 (div:QI (match_operand:HI 1 "register_operand" "0")
8433 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8434 (clobber (reg:CC FLAGS_REG))]
8435 "TARGET_QIMODE_MATH"
8437 [(set_attr "type" "idiv")
8438 (set_attr "mode" "QI")])
8440 (define_insn "udivqi3"
8441 [(set (match_operand:QI 0 "register_operand" "=a")
8442 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8443 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8444 (clobber (reg:CC FLAGS_REG))]
8445 "TARGET_QIMODE_MATH"
8447 [(set_attr "type" "idiv")
8448 (set_attr "mode" "QI")])
8450 ;; The patterns that match these are at the end of this file.
8452 (define_expand "divxf3"
8453 [(set (match_operand:XF 0 "register_operand" "")
8454 (div:XF (match_operand:XF 1 "register_operand" "")
8455 (match_operand:XF 2 "register_operand" "")))]
8459 (define_expand "divdf3"
8460 [(set (match_operand:DF 0 "register_operand" "")
8461 (div:DF (match_operand:DF 1 "register_operand" "")
8462 (match_operand:DF 2 "nonimmediate_operand" "")))]
8463 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8464 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8467 (define_expand "divsf3"
8468 [(set (match_operand:SF 0 "register_operand" "")
8469 (div:SF (match_operand:SF 1 "register_operand" "")
8470 (match_operand:SF 2 "nonimmediate_operand" "")))]
8471 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8474 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8475 && flag_finite_math_only && !flag_trapping_math
8476 && flag_unsafe_math_optimizations)
8478 ix86_emit_swdivsf (operands[0], operands[1],
8479 operands[2], SFmode);
8484 ;; Remainder instructions.
8486 (define_expand "divmoddi4"
8487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8488 (div:DI (match_operand:DI 1 "register_operand" "")
8489 (match_operand:DI 2 "nonimmediate_operand" "")))
8490 (set (match_operand:DI 3 "register_operand" "")
8491 (mod:DI (match_dup 1) (match_dup 2)))
8492 (clobber (reg:CC FLAGS_REG))])]
8496 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8497 ;; Penalize eax case slightly because it results in worse scheduling
8499 (define_insn "*divmoddi4_nocltd_rex64"
8500 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8501 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8502 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8503 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8504 (mod:DI (match_dup 2) (match_dup 3)))
8505 (clobber (reg:CC FLAGS_REG))]
8506 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8508 [(set_attr "type" "multi")])
8510 (define_insn "*divmoddi4_cltd_rex64"
8511 [(set (match_operand:DI 0 "register_operand" "=a")
8512 (div:DI (match_operand:DI 2 "register_operand" "a")
8513 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8514 (set (match_operand:DI 1 "register_operand" "=&d")
8515 (mod:DI (match_dup 2) (match_dup 3)))
8516 (clobber (reg:CC FLAGS_REG))]
8517 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8519 [(set_attr "type" "multi")])
8521 (define_insn "*divmoddi_noext_rex64"
8522 [(set (match_operand:DI 0 "register_operand" "=a")
8523 (div:DI (match_operand:DI 1 "register_operand" "0")
8524 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8525 (set (match_operand:DI 3 "register_operand" "=d")
8526 (mod:DI (match_dup 1) (match_dup 2)))
8527 (use (match_operand:DI 4 "register_operand" "3"))
8528 (clobber (reg:CC FLAGS_REG))]
8531 [(set_attr "type" "idiv")
8532 (set_attr "mode" "DI")])
8535 [(set (match_operand:DI 0 "register_operand" "")
8536 (div:DI (match_operand:DI 1 "register_operand" "")
8537 (match_operand:DI 2 "nonimmediate_operand" "")))
8538 (set (match_operand:DI 3 "register_operand" "")
8539 (mod:DI (match_dup 1) (match_dup 2)))
8540 (clobber (reg:CC FLAGS_REG))]
8541 "TARGET_64BIT && reload_completed"
8542 [(parallel [(set (match_dup 3)
8543 (ashiftrt:DI (match_dup 4) (const_int 63)))
8544 (clobber (reg:CC FLAGS_REG))])
8545 (parallel [(set (match_dup 0)
8546 (div:DI (reg:DI 0) (match_dup 2)))
8548 (mod:DI (reg:DI 0) (match_dup 2)))
8550 (clobber (reg:CC FLAGS_REG))])]
8552 /* Avoid use of cltd in favor of a mov+shift. */
8553 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8555 if (true_regnum (operands[1]))
8556 emit_move_insn (operands[0], operands[1]);
8558 emit_move_insn (operands[3], operands[1]);
8559 operands[4] = operands[3];
8563 gcc_assert (!true_regnum (operands[1]));
8564 operands[4] = operands[1];
8569 (define_expand "divmodsi4"
8570 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8571 (div:SI (match_operand:SI 1 "register_operand" "")
8572 (match_operand:SI 2 "nonimmediate_operand" "")))
8573 (set (match_operand:SI 3 "register_operand" "")
8574 (mod:SI (match_dup 1) (match_dup 2)))
8575 (clobber (reg:CC FLAGS_REG))])]
8579 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8580 ;; Penalize eax case slightly because it results in worse scheduling
8582 (define_insn "*divmodsi4_nocltd"
8583 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8584 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8585 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8586 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8587 (mod:SI (match_dup 2) (match_dup 3)))
8588 (clobber (reg:CC FLAGS_REG))]
8589 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8591 [(set_attr "type" "multi")])
8593 (define_insn "*divmodsi4_cltd"
8594 [(set (match_operand:SI 0 "register_operand" "=a")
8595 (div:SI (match_operand:SI 2 "register_operand" "a")
8596 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8597 (set (match_operand:SI 1 "register_operand" "=&d")
8598 (mod:SI (match_dup 2) (match_dup 3)))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8602 [(set_attr "type" "multi")])
8604 (define_insn "*divmodsi_noext"
8605 [(set (match_operand:SI 0 "register_operand" "=a")
8606 (div:SI (match_operand:SI 1 "register_operand" "0")
8607 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8608 (set (match_operand:SI 3 "register_operand" "=d")
8609 (mod:SI (match_dup 1) (match_dup 2)))
8610 (use (match_operand:SI 4 "register_operand" "3"))
8611 (clobber (reg:CC FLAGS_REG))]
8614 [(set_attr "type" "idiv")
8615 (set_attr "mode" "SI")])
8618 [(set (match_operand:SI 0 "register_operand" "")
8619 (div:SI (match_operand:SI 1 "register_operand" "")
8620 (match_operand:SI 2 "nonimmediate_operand" "")))
8621 (set (match_operand:SI 3 "register_operand" "")
8622 (mod:SI (match_dup 1) (match_dup 2)))
8623 (clobber (reg:CC FLAGS_REG))]
8625 [(parallel [(set (match_dup 3)
8626 (ashiftrt:SI (match_dup 4) (const_int 31)))
8627 (clobber (reg:CC FLAGS_REG))])
8628 (parallel [(set (match_dup 0)
8629 (div:SI (reg:SI 0) (match_dup 2)))
8631 (mod:SI (reg:SI 0) (match_dup 2)))
8633 (clobber (reg:CC FLAGS_REG))])]
8635 /* Avoid use of cltd in favor of a mov+shift. */
8636 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8638 if (true_regnum (operands[1]))
8639 emit_move_insn (operands[0], operands[1]);
8641 emit_move_insn (operands[3], operands[1]);
8642 operands[4] = operands[3];
8646 gcc_assert (!true_regnum (operands[1]));
8647 operands[4] = operands[1];
8651 (define_insn "divmodhi4"
8652 [(set (match_operand:HI 0 "register_operand" "=a")
8653 (div:HI (match_operand:HI 1 "register_operand" "0")
8654 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8655 (set (match_operand:HI 3 "register_operand" "=&d")
8656 (mod:HI (match_dup 1) (match_dup 2)))
8657 (clobber (reg:CC FLAGS_REG))]
8658 "TARGET_HIMODE_MATH"
8660 [(set_attr "type" "multi")
8661 (set_attr "length_immediate" "0")
8662 (set_attr "mode" "SI")])
8664 (define_insn "udivmoddi4"
8665 [(set (match_operand:DI 0 "register_operand" "=a")
8666 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8667 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8668 (set (match_operand:DI 3 "register_operand" "=&d")
8669 (umod:DI (match_dup 1) (match_dup 2)))
8670 (clobber (reg:CC FLAGS_REG))]
8672 "xor{q}\t%3, %3\;div{q}\t%2"
8673 [(set_attr "type" "multi")
8674 (set_attr "length_immediate" "0")
8675 (set_attr "mode" "DI")])
8677 (define_insn "*udivmoddi4_noext"
8678 [(set (match_operand:DI 0 "register_operand" "=a")
8679 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8680 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8681 (set (match_operand:DI 3 "register_operand" "=d")
8682 (umod:DI (match_dup 1) (match_dup 2)))
8684 (clobber (reg:CC FLAGS_REG))]
8687 [(set_attr "type" "idiv")
8688 (set_attr "mode" "DI")])
8691 [(set (match_operand:DI 0 "register_operand" "")
8692 (udiv:DI (match_operand:DI 1 "register_operand" "")
8693 (match_operand:DI 2 "nonimmediate_operand" "")))
8694 (set (match_operand:DI 3 "register_operand" "")
8695 (umod:DI (match_dup 1) (match_dup 2)))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "TARGET_64BIT && reload_completed"
8698 [(set (match_dup 3) (const_int 0))
8699 (parallel [(set (match_dup 0)
8700 (udiv:DI (match_dup 1) (match_dup 2)))
8702 (umod:DI (match_dup 1) (match_dup 2)))
8704 (clobber (reg:CC FLAGS_REG))])]
8707 (define_insn "udivmodsi4"
8708 [(set (match_operand:SI 0 "register_operand" "=a")
8709 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8710 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8711 (set (match_operand:SI 3 "register_operand" "=&d")
8712 (umod:SI (match_dup 1) (match_dup 2)))
8713 (clobber (reg:CC FLAGS_REG))]
8715 "xor{l}\t%3, %3\;div{l}\t%2"
8716 [(set_attr "type" "multi")
8717 (set_attr "length_immediate" "0")
8718 (set_attr "mode" "SI")])
8720 (define_insn "*udivmodsi4_noext"
8721 [(set (match_operand:SI 0 "register_operand" "=a")
8722 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8723 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8724 (set (match_operand:SI 3 "register_operand" "=d")
8725 (umod:SI (match_dup 1) (match_dup 2)))
8727 (clobber (reg:CC FLAGS_REG))]
8730 [(set_attr "type" "idiv")
8731 (set_attr "mode" "SI")])
8734 [(set (match_operand:SI 0 "register_operand" "")
8735 (udiv:SI (match_operand:SI 1 "register_operand" "")
8736 (match_operand:SI 2 "nonimmediate_operand" "")))
8737 (set (match_operand:SI 3 "register_operand" "")
8738 (umod:SI (match_dup 1) (match_dup 2)))
8739 (clobber (reg:CC FLAGS_REG))]
8741 [(set (match_dup 3) (const_int 0))
8742 (parallel [(set (match_dup 0)
8743 (udiv:SI (match_dup 1) (match_dup 2)))
8745 (umod:SI (match_dup 1) (match_dup 2)))
8747 (clobber (reg:CC FLAGS_REG))])]
8750 (define_expand "udivmodhi4"
8751 [(set (match_dup 4) (const_int 0))
8752 (parallel [(set (match_operand:HI 0 "register_operand" "")
8753 (udiv:HI (match_operand:HI 1 "register_operand" "")
8754 (match_operand:HI 2 "nonimmediate_operand" "")))
8755 (set (match_operand:HI 3 "register_operand" "")
8756 (umod:HI (match_dup 1) (match_dup 2)))
8758 (clobber (reg:CC FLAGS_REG))])]
8759 "TARGET_HIMODE_MATH"
8760 "operands[4] = gen_reg_rtx (HImode);")
8762 (define_insn "*udivmodhi_noext"
8763 [(set (match_operand:HI 0 "register_operand" "=a")
8764 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8765 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8766 (set (match_operand:HI 3 "register_operand" "=d")
8767 (umod:HI (match_dup 1) (match_dup 2)))
8768 (use (match_operand:HI 4 "register_operand" "3"))
8769 (clobber (reg:CC FLAGS_REG))]
8772 [(set_attr "type" "idiv")
8773 (set_attr "mode" "HI")])
8775 ;; We cannot use div/idiv for double division, because it causes
8776 ;; "division by zero" on the overflow and that's not what we expect
8777 ;; from truncate. Because true (non truncating) double division is
8778 ;; never generated, we can't create this insn anyway.
8781 ; [(set (match_operand:SI 0 "register_operand" "=a")
8783 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8785 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8786 ; (set (match_operand:SI 3 "register_operand" "=d")
8788 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8789 ; (clobber (reg:CC FLAGS_REG))]
8791 ; "div{l}\t{%2, %0|%0, %2}"
8792 ; [(set_attr "type" "idiv")])
8794 ;;- Logical AND instructions
8796 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8797 ;; Note that this excludes ah.
8799 (define_insn "*testdi_1_rex64"
8800 [(set (reg FLAGS_REG)
8802 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8803 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8805 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8806 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8808 test{l}\t{%k1, %k0|%k0, %k1}
8809 test{l}\t{%k1, %k0|%k0, %k1}
8810 test{q}\t{%1, %0|%0, %1}
8811 test{q}\t{%1, %0|%0, %1}
8812 test{q}\t{%1, %0|%0, %1}"
8813 [(set_attr "type" "test")
8814 (set_attr "modrm" "0,1,0,1,1")
8815 (set_attr "mode" "SI,SI,DI,DI,DI")
8816 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8818 (define_insn "testsi_1"
8819 [(set (reg FLAGS_REG)
8821 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8822 (match_operand:SI 1 "general_operand" "i,i,ri"))
8824 "ix86_match_ccmode (insn, CCNOmode)
8825 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8826 "test{l}\t{%1, %0|%0, %1}"
8827 [(set_attr "type" "test")
8828 (set_attr "modrm" "0,1,1")
8829 (set_attr "mode" "SI")
8830 (set_attr "pent_pair" "uv,np,uv")])
8832 (define_expand "testsi_ccno_1"
8833 [(set (reg:CCNO FLAGS_REG)
8835 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8836 (match_operand:SI 1 "nonmemory_operand" ""))
8841 (define_insn "*testhi_1"
8842 [(set (reg FLAGS_REG)
8843 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8844 (match_operand:HI 1 "general_operand" "n,n,rn"))
8846 "ix86_match_ccmode (insn, CCNOmode)
8847 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8848 "test{w}\t{%1, %0|%0, %1}"
8849 [(set_attr "type" "test")
8850 (set_attr "modrm" "0,1,1")
8851 (set_attr "mode" "HI")
8852 (set_attr "pent_pair" "uv,np,uv")])
8854 (define_expand "testqi_ccz_1"
8855 [(set (reg:CCZ FLAGS_REG)
8856 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8857 (match_operand:QI 1 "nonmemory_operand" ""))
8862 (define_insn "*testqi_1_maybe_si"
8863 [(set (reg FLAGS_REG)
8866 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8867 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8869 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8870 && ix86_match_ccmode (insn,
8871 CONST_INT_P (operands[1])
8872 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8874 if (which_alternative == 3)
8876 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8877 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8878 return "test{l}\t{%1, %k0|%k0, %1}";
8880 return "test{b}\t{%1, %0|%0, %1}";
8882 [(set_attr "type" "test")
8883 (set_attr "modrm" "0,1,1,1")
8884 (set_attr "mode" "QI,QI,QI,SI")
8885 (set_attr "pent_pair" "uv,np,uv,np")])
8887 (define_insn "*testqi_1"
8888 [(set (reg FLAGS_REG)
8891 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8892 (match_operand:QI 1 "general_operand" "n,n,qn"))
8894 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8895 && ix86_match_ccmode (insn, CCNOmode)"
8896 "test{b}\t{%1, %0|%0, %1}"
8897 [(set_attr "type" "test")
8898 (set_attr "modrm" "0,1,1")
8899 (set_attr "mode" "QI")
8900 (set_attr "pent_pair" "uv,np,uv")])
8902 (define_expand "testqi_ext_ccno_0"
8903 [(set (reg:CCNO FLAGS_REG)
8907 (match_operand 0 "ext_register_operand" "")
8910 (match_operand 1 "const_int_operand" ""))
8915 (define_insn "*testqi_ext_0"
8916 [(set (reg FLAGS_REG)
8920 (match_operand 0 "ext_register_operand" "Q")
8923 (match_operand 1 "const_int_operand" "n"))
8925 "ix86_match_ccmode (insn, CCNOmode)"
8926 "test{b}\t{%1, %h0|%h0, %1}"
8927 [(set_attr "type" "test")
8928 (set_attr "mode" "QI")
8929 (set_attr "length_immediate" "1")
8930 (set_attr "pent_pair" "np")])
8932 (define_insn "*testqi_ext_1"
8933 [(set (reg FLAGS_REG)
8937 (match_operand 0 "ext_register_operand" "Q")
8941 (match_operand:QI 1 "general_operand" "Qm")))
8943 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8944 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8945 "test{b}\t{%1, %h0|%h0, %1}"
8946 [(set_attr "type" "test")
8947 (set_attr "mode" "QI")])
8949 (define_insn "*testqi_ext_1_rex64"
8950 [(set (reg FLAGS_REG)
8954 (match_operand 0 "ext_register_operand" "Q")
8958 (match_operand:QI 1 "register_operand" "Q")))
8960 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8961 "test{b}\t{%1, %h0|%h0, %1}"
8962 [(set_attr "type" "test")
8963 (set_attr "mode" "QI")])
8965 (define_insn "*testqi_ext_2"
8966 [(set (reg FLAGS_REG)
8970 (match_operand 0 "ext_register_operand" "Q")
8974 (match_operand 1 "ext_register_operand" "Q")
8978 "ix86_match_ccmode (insn, CCNOmode)"
8979 "test{b}\t{%h1, %h0|%h0, %h1}"
8980 [(set_attr "type" "test")
8981 (set_attr "mode" "QI")])
8983 ;; Combine likes to form bit extractions for some tests. Humor it.
8984 (define_insn "*testqi_ext_3"
8985 [(set (reg FLAGS_REG)
8986 (compare (zero_extract:SI
8987 (match_operand 0 "nonimmediate_operand" "rm")
8988 (match_operand:SI 1 "const_int_operand" "")
8989 (match_operand:SI 2 "const_int_operand" ""))
8991 "ix86_match_ccmode (insn, CCNOmode)
8992 && INTVAL (operands[1]) > 0
8993 && INTVAL (operands[2]) >= 0
8994 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8995 && (GET_MODE (operands[0]) == SImode
8996 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8997 || GET_MODE (operands[0]) == HImode
8998 || GET_MODE (operands[0]) == QImode)"
9001 (define_insn "*testqi_ext_3_rex64"
9002 [(set (reg FLAGS_REG)
9003 (compare (zero_extract:DI
9004 (match_operand 0 "nonimmediate_operand" "rm")
9005 (match_operand:DI 1 "const_int_operand" "")
9006 (match_operand:DI 2 "const_int_operand" ""))
9009 && ix86_match_ccmode (insn, CCNOmode)
9010 && INTVAL (operands[1]) > 0
9011 && INTVAL (operands[2]) >= 0
9012 /* Ensure that resulting mask is zero or sign extended operand. */
9013 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9014 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9015 && INTVAL (operands[1]) > 32))
9016 && (GET_MODE (operands[0]) == SImode
9017 || GET_MODE (operands[0]) == DImode
9018 || GET_MODE (operands[0]) == HImode
9019 || GET_MODE (operands[0]) == QImode)"
9023 [(set (match_operand 0 "flags_reg_operand" "")
9024 (match_operator 1 "compare_operator"
9026 (match_operand 2 "nonimmediate_operand" "")
9027 (match_operand 3 "const_int_operand" "")
9028 (match_operand 4 "const_int_operand" ""))
9030 "ix86_match_ccmode (insn, CCNOmode)"
9031 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9033 rtx val = operands[2];
9034 HOST_WIDE_INT len = INTVAL (operands[3]);
9035 HOST_WIDE_INT pos = INTVAL (operands[4]);
9037 enum machine_mode mode, submode;
9039 mode = GET_MODE (val);
9042 /* ??? Combine likes to put non-volatile mem extractions in QImode
9043 no matter the size of the test. So find a mode that works. */
9044 if (! MEM_VOLATILE_P (val))
9046 mode = smallest_mode_for_size (pos + len, MODE_INT);
9047 val = adjust_address (val, mode, 0);
9050 else if (GET_CODE (val) == SUBREG
9051 && (submode = GET_MODE (SUBREG_REG (val)),
9052 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9053 && pos + len <= GET_MODE_BITSIZE (submode))
9055 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9057 val = SUBREG_REG (val);
9059 else if (mode == HImode && pos + len <= 8)
9061 /* Small HImode tests can be converted to QImode. */
9063 val = gen_lowpart (QImode, val);
9066 if (len == HOST_BITS_PER_WIDE_INT)
9069 mask = ((HOST_WIDE_INT)1 << len) - 1;
9072 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9075 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9076 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9077 ;; this is relatively important trick.
9078 ;; Do the conversion only post-reload to avoid limiting of the register class
9081 [(set (match_operand 0 "flags_reg_operand" "")
9082 (match_operator 1 "compare_operator"
9083 [(and (match_operand 2 "register_operand" "")
9084 (match_operand 3 "const_int_operand" ""))
9087 && QI_REG_P (operands[2])
9088 && GET_MODE (operands[2]) != QImode
9089 && ((ix86_match_ccmode (insn, CCZmode)
9090 && !(INTVAL (operands[3]) & ~(255 << 8)))
9091 || (ix86_match_ccmode (insn, CCNOmode)
9092 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9095 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9098 "operands[2] = gen_lowpart (SImode, operands[2]);
9099 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9102 [(set (match_operand 0 "flags_reg_operand" "")
9103 (match_operator 1 "compare_operator"
9104 [(and (match_operand 2 "nonimmediate_operand" "")
9105 (match_operand 3 "const_int_operand" ""))
9108 && GET_MODE (operands[2]) != QImode
9109 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9110 && ((ix86_match_ccmode (insn, CCZmode)
9111 && !(INTVAL (operands[3]) & ~255))
9112 || (ix86_match_ccmode (insn, CCNOmode)
9113 && !(INTVAL (operands[3]) & ~127)))"
9115 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9117 "operands[2] = gen_lowpart (QImode, operands[2]);
9118 operands[3] = gen_lowpart (QImode, operands[3]);")
9121 ;; %%% This used to optimize known byte-wide and operations to memory,
9122 ;; and sometimes to QImode registers. If this is considered useful,
9123 ;; it should be done with splitters.
9125 (define_expand "anddi3"
9126 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9127 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9128 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9130 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9132 (define_insn "*anddi_1_rex64"
9133 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9134 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9135 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9139 switch (get_attr_type (insn))
9143 enum machine_mode mode;
9145 gcc_assert (CONST_INT_P (operands[2]));
9146 if (INTVAL (operands[2]) == 0xff)
9150 gcc_assert (INTVAL (operands[2]) == 0xffff);
9154 operands[1] = gen_lowpart (mode, operands[1]);
9156 return "movz{bq|x}\t{%1,%0|%0, %1}";
9158 return "movz{wq|x}\t{%1,%0|%0, %1}";
9162 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9163 if (get_attr_mode (insn) == MODE_SI)
9164 return "and{l}\t{%k2, %k0|%k0, %k2}";
9166 return "and{q}\t{%2, %0|%0, %2}";
9169 [(set_attr "type" "alu,alu,alu,imovx")
9170 (set_attr "length_immediate" "*,*,*,0")
9171 (set_attr "mode" "SI,DI,DI,DI")])
9173 (define_insn "*anddi_2"
9174 [(set (reg FLAGS_REG)
9175 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9176 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9178 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9179 (and:DI (match_dup 1) (match_dup 2)))]
9180 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9181 && ix86_binary_operator_ok (AND, DImode, operands)"
9183 and{l}\t{%k2, %k0|%k0, %k2}
9184 and{q}\t{%2, %0|%0, %2}
9185 and{q}\t{%2, %0|%0, %2}"
9186 [(set_attr "type" "alu")
9187 (set_attr "mode" "SI,DI,DI")])
9189 (define_expand "andsi3"
9190 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9191 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9192 (match_operand:SI 2 "general_operand" "")))]
9194 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9196 (define_insn "*andsi_1"
9197 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9198 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9199 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9200 (clobber (reg:CC FLAGS_REG))]
9201 "ix86_binary_operator_ok (AND, SImode, operands)"
9203 switch (get_attr_type (insn))
9207 enum machine_mode mode;
9209 gcc_assert (CONST_INT_P (operands[2]));
9210 if (INTVAL (operands[2]) == 0xff)
9214 gcc_assert (INTVAL (operands[2]) == 0xffff);
9218 operands[1] = gen_lowpart (mode, operands[1]);
9220 return "movz{bl|x}\t{%1,%0|%0, %1}";
9222 return "movz{wl|x}\t{%1,%0|%0, %1}";
9226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9227 return "and{l}\t{%2, %0|%0, %2}";
9230 [(set_attr "type" "alu,alu,imovx")
9231 (set_attr "length_immediate" "*,*,0")
9232 (set_attr "mode" "SI")])
9235 [(set (match_operand 0 "register_operand" "")
9237 (const_int -65536)))
9238 (clobber (reg:CC FLAGS_REG))]
9239 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9240 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9241 "operands[1] = gen_lowpart (HImode, operands[0]);")
9244 [(set (match_operand 0 "ext_register_operand" "")
9247 (clobber (reg:CC FLAGS_REG))]
9248 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9249 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9250 "operands[1] = gen_lowpart (QImode, operands[0]);")
9253 [(set (match_operand 0 "ext_register_operand" "")
9255 (const_int -65281)))
9256 (clobber (reg:CC FLAGS_REG))]
9257 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9258 [(parallel [(set (zero_extract:SI (match_dup 0)
9262 (zero_extract:SI (match_dup 0)
9265 (zero_extract:SI (match_dup 0)
9268 (clobber (reg:CC FLAGS_REG))])]
9269 "operands[0] = gen_lowpart (SImode, operands[0]);")
9271 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9272 (define_insn "*andsi_1_zext"
9273 [(set (match_operand:DI 0 "register_operand" "=r")
9275 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9276 (match_operand:SI 2 "general_operand" "g"))))
9277 (clobber (reg:CC FLAGS_REG))]
9278 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9279 "and{l}\t{%2, %k0|%k0, %2}"
9280 [(set_attr "type" "alu")
9281 (set_attr "mode" "SI")])
9283 (define_insn "*andsi_2"
9284 [(set (reg FLAGS_REG)
9285 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9286 (match_operand:SI 2 "general_operand" "g,ri"))
9288 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9289 (and:SI (match_dup 1) (match_dup 2)))]
9290 "ix86_match_ccmode (insn, CCNOmode)
9291 && ix86_binary_operator_ok (AND, SImode, operands)"
9292 "and{l}\t{%2, %0|%0, %2}"
9293 [(set_attr "type" "alu")
9294 (set_attr "mode" "SI")])
9296 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9297 (define_insn "*andsi_2_zext"
9298 [(set (reg FLAGS_REG)
9299 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9300 (match_operand:SI 2 "general_operand" "g"))
9302 (set (match_operand:DI 0 "register_operand" "=r")
9303 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9304 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9305 && ix86_binary_operator_ok (AND, SImode, operands)"
9306 "and{l}\t{%2, %k0|%k0, %2}"
9307 [(set_attr "type" "alu")
9308 (set_attr "mode" "SI")])
9310 (define_expand "andhi3"
9311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9312 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9313 (match_operand:HI 2 "general_operand" "")))]
9314 "TARGET_HIMODE_MATH"
9315 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9317 (define_insn "*andhi_1"
9318 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9319 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9320 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9321 (clobber (reg:CC FLAGS_REG))]
9322 "ix86_binary_operator_ok (AND, HImode, operands)"
9324 switch (get_attr_type (insn))
9327 gcc_assert (CONST_INT_P (operands[2]));
9328 gcc_assert (INTVAL (operands[2]) == 0xff);
9329 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9332 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9334 return "and{w}\t{%2, %0|%0, %2}";
9337 [(set_attr "type" "alu,alu,imovx")
9338 (set_attr "length_immediate" "*,*,0")
9339 (set_attr "mode" "HI,HI,SI")])
9341 (define_insn "*andhi_2"
9342 [(set (reg FLAGS_REG)
9343 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9344 (match_operand:HI 2 "general_operand" "rmn,rn"))
9346 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9347 (and:HI (match_dup 1) (match_dup 2)))]
9348 "ix86_match_ccmode (insn, CCNOmode)
9349 && ix86_binary_operator_ok (AND, HImode, operands)"
9350 "and{w}\t{%2, %0|%0, %2}"
9351 [(set_attr "type" "alu")
9352 (set_attr "mode" "HI")])
9354 (define_expand "andqi3"
9355 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9356 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9357 (match_operand:QI 2 "general_operand" "")))]
9358 "TARGET_QIMODE_MATH"
9359 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9361 ;; %%% Potential partial reg stall on alternative 2. What to do?
9362 (define_insn "*andqi_1"
9363 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9364 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9365 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9366 (clobber (reg:CC FLAGS_REG))]
9367 "ix86_binary_operator_ok (AND, QImode, operands)"
9369 and{b}\t{%2, %0|%0, %2}
9370 and{b}\t{%2, %0|%0, %2}
9371 and{l}\t{%k2, %k0|%k0, %k2}"
9372 [(set_attr "type" "alu")
9373 (set_attr "mode" "QI,QI,SI")])
9375 (define_insn "*andqi_1_slp"
9376 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9377 (and:QI (match_dup 0)
9378 (match_operand:QI 1 "general_operand" "qn,qmn")))
9379 (clobber (reg:CC FLAGS_REG))]
9380 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9381 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9382 "and{b}\t{%1, %0|%0, %1}"
9383 [(set_attr "type" "alu1")
9384 (set_attr "mode" "QI")])
9386 (define_insn "*andqi_2_maybe_si"
9387 [(set (reg FLAGS_REG)
9389 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9390 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9392 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9393 (and:QI (match_dup 1) (match_dup 2)))]
9394 "ix86_binary_operator_ok (AND, QImode, operands)
9395 && ix86_match_ccmode (insn,
9396 CONST_INT_P (operands[2])
9397 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9399 if (which_alternative == 2)
9401 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9402 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9403 return "and{l}\t{%2, %k0|%k0, %2}";
9405 return "and{b}\t{%2, %0|%0, %2}";
9407 [(set_attr "type" "alu")
9408 (set_attr "mode" "QI,QI,SI")])
9410 (define_insn "*andqi_2"
9411 [(set (reg FLAGS_REG)
9413 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9414 (match_operand:QI 2 "general_operand" "qmn,qn"))
9416 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9417 (and:QI (match_dup 1) (match_dup 2)))]
9418 "ix86_match_ccmode (insn, CCNOmode)
9419 && ix86_binary_operator_ok (AND, QImode, operands)"
9420 "and{b}\t{%2, %0|%0, %2}"
9421 [(set_attr "type" "alu")
9422 (set_attr "mode" "QI")])
9424 (define_insn "*andqi_2_slp"
9425 [(set (reg FLAGS_REG)
9427 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9428 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9430 (set (strict_low_part (match_dup 0))
9431 (and:QI (match_dup 0) (match_dup 1)))]
9432 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9433 && ix86_match_ccmode (insn, CCNOmode)
9434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9435 "and{b}\t{%1, %0|%0, %1}"
9436 [(set_attr "type" "alu1")
9437 (set_attr "mode" "QI")])
9439 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9440 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9441 ;; for a QImode operand, which of course failed.
9443 (define_insn "andqi_ext_0"
9444 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9449 (match_operand 1 "ext_register_operand" "0")
9452 (match_operand 2 "const_int_operand" "n")))
9453 (clobber (reg:CC FLAGS_REG))]
9455 "and{b}\t{%2, %h0|%h0, %2}"
9456 [(set_attr "type" "alu")
9457 (set_attr "length_immediate" "1")
9458 (set_attr "mode" "QI")])
9460 ;; Generated by peephole translating test to and. This shows up
9461 ;; often in fp comparisons.
9463 (define_insn "*andqi_ext_0_cc"
9464 [(set (reg FLAGS_REG)
9468 (match_operand 1 "ext_register_operand" "0")
9471 (match_operand 2 "const_int_operand" "n"))
9473 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9482 "ix86_match_ccmode (insn, CCNOmode)"
9483 "and{b}\t{%2, %h0|%h0, %2}"
9484 [(set_attr "type" "alu")
9485 (set_attr "length_immediate" "1")
9486 (set_attr "mode" "QI")])
9488 (define_insn "*andqi_ext_1"
9489 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9494 (match_operand 1 "ext_register_operand" "0")
9498 (match_operand:QI 2 "general_operand" "Qm"))))
9499 (clobber (reg:CC FLAGS_REG))]
9501 "and{b}\t{%2, %h0|%h0, %2}"
9502 [(set_attr "type" "alu")
9503 (set_attr "length_immediate" "0")
9504 (set_attr "mode" "QI")])
9506 (define_insn "*andqi_ext_1_rex64"
9507 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9512 (match_operand 1 "ext_register_operand" "0")
9516 (match_operand 2 "ext_register_operand" "Q"))))
9517 (clobber (reg:CC FLAGS_REG))]
9519 "and{b}\t{%2, %h0|%h0, %2}"
9520 [(set_attr "type" "alu")
9521 (set_attr "length_immediate" "0")
9522 (set_attr "mode" "QI")])
9524 (define_insn "*andqi_ext_2"
9525 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9530 (match_operand 1 "ext_register_operand" "%0")
9534 (match_operand 2 "ext_register_operand" "Q")
9537 (clobber (reg:CC FLAGS_REG))]
9539 "and{b}\t{%h2, %h0|%h0, %h2}"
9540 [(set_attr "type" "alu")
9541 (set_attr "length_immediate" "0")
9542 (set_attr "mode" "QI")])
9544 ;; Convert wide AND instructions with immediate operand to shorter QImode
9545 ;; equivalents when possible.
9546 ;; Don't do the splitting with memory operands, since it introduces risk
9547 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9548 ;; for size, but that can (should?) be handled by generic code instead.
9550 [(set (match_operand 0 "register_operand" "")
9551 (and (match_operand 1 "register_operand" "")
9552 (match_operand 2 "const_int_operand" "")))
9553 (clobber (reg:CC FLAGS_REG))]
9555 && QI_REG_P (operands[0])
9556 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9557 && !(~INTVAL (operands[2]) & ~(255 << 8))
9558 && GET_MODE (operands[0]) != QImode"
9559 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9560 (and:SI (zero_extract:SI (match_dup 1)
9561 (const_int 8) (const_int 8))
9563 (clobber (reg:CC FLAGS_REG))])]
9564 "operands[0] = gen_lowpart (SImode, operands[0]);
9565 operands[1] = gen_lowpart (SImode, operands[1]);
9566 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9568 ;; Since AND can be encoded with sign extended immediate, this is only
9569 ;; profitable when 7th bit is not set.
9571 [(set (match_operand 0 "register_operand" "")
9572 (and (match_operand 1 "general_operand" "")
9573 (match_operand 2 "const_int_operand" "")))
9574 (clobber (reg:CC FLAGS_REG))]
9576 && ANY_QI_REG_P (operands[0])
9577 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9578 && !(~INTVAL (operands[2]) & ~255)
9579 && !(INTVAL (operands[2]) & 128)
9580 && GET_MODE (operands[0]) != QImode"
9581 [(parallel [(set (strict_low_part (match_dup 0))
9582 (and:QI (match_dup 1)
9584 (clobber (reg:CC FLAGS_REG))])]
9585 "operands[0] = gen_lowpart (QImode, operands[0]);
9586 operands[1] = gen_lowpart (QImode, operands[1]);
9587 operands[2] = gen_lowpart (QImode, operands[2]);")
9589 ;; Logical inclusive OR instructions
9591 ;; %%% This used to optimize known byte-wide and operations to memory.
9592 ;; If this is considered useful, it should be done with splitters.
9594 (define_expand "iordi3"
9595 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9596 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9597 (match_operand:DI 2 "x86_64_general_operand" "")))]
9599 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9601 (define_insn "*iordi_1_rex64"
9602 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9603 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9604 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9605 (clobber (reg:CC FLAGS_REG))]
9607 && ix86_binary_operator_ok (IOR, DImode, operands)"
9608 "or{q}\t{%2, %0|%0, %2}"
9609 [(set_attr "type" "alu")
9610 (set_attr "mode" "DI")])
9612 (define_insn "*iordi_2_rex64"
9613 [(set (reg FLAGS_REG)
9614 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9615 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9617 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9618 (ior:DI (match_dup 1) (match_dup 2)))]
9620 && ix86_match_ccmode (insn, CCNOmode)
9621 && ix86_binary_operator_ok (IOR, DImode, operands)"
9622 "or{q}\t{%2, %0|%0, %2}"
9623 [(set_attr "type" "alu")
9624 (set_attr "mode" "DI")])
9626 (define_insn "*iordi_3_rex64"
9627 [(set (reg FLAGS_REG)
9628 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9629 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9631 (clobber (match_scratch:DI 0 "=r"))]
9633 && ix86_match_ccmode (insn, CCNOmode)
9634 && ix86_binary_operator_ok (IOR, DImode, operands)"
9635 "or{q}\t{%2, %0|%0, %2}"
9636 [(set_attr "type" "alu")
9637 (set_attr "mode" "DI")])
9640 (define_expand "iorsi3"
9641 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9642 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9643 (match_operand:SI 2 "general_operand" "")))]
9645 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9647 (define_insn "*iorsi_1"
9648 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9649 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9650 (match_operand:SI 2 "general_operand" "ri,g")))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "ix86_binary_operator_ok (IOR, SImode, operands)"
9653 "or{l}\t{%2, %0|%0, %2}"
9654 [(set_attr "type" "alu")
9655 (set_attr "mode" "SI")])
9657 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9658 (define_insn "*iorsi_1_zext"
9659 [(set (match_operand:DI 0 "register_operand" "=r")
9661 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9662 (match_operand:SI 2 "general_operand" "g"))))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9665 "or{l}\t{%2, %k0|%k0, %2}"
9666 [(set_attr "type" "alu")
9667 (set_attr "mode" "SI")])
9669 (define_insn "*iorsi_1_zext_imm"
9670 [(set (match_operand:DI 0 "register_operand" "=r")
9671 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9672 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9673 (clobber (reg:CC FLAGS_REG))]
9675 "or{l}\t{%2, %k0|%k0, %2}"
9676 [(set_attr "type" "alu")
9677 (set_attr "mode" "SI")])
9679 (define_insn "*iorsi_2"
9680 [(set (reg FLAGS_REG)
9681 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9682 (match_operand:SI 2 "general_operand" "g,ri"))
9684 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9685 (ior:SI (match_dup 1) (match_dup 2)))]
9686 "ix86_match_ccmode (insn, CCNOmode)
9687 && ix86_binary_operator_ok (IOR, SImode, operands)"
9688 "or{l}\t{%2, %0|%0, %2}"
9689 [(set_attr "type" "alu")
9690 (set_attr "mode" "SI")])
9692 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9693 ;; ??? Special case for immediate operand is missing - it is tricky.
9694 (define_insn "*iorsi_2_zext"
9695 [(set (reg FLAGS_REG)
9696 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9697 (match_operand:SI 2 "general_operand" "g"))
9699 (set (match_operand:DI 0 "register_operand" "=r")
9700 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9701 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9702 && ix86_binary_operator_ok (IOR, SImode, operands)"
9703 "or{l}\t{%2, %k0|%k0, %2}"
9704 [(set_attr "type" "alu")
9705 (set_attr "mode" "SI")])
9707 (define_insn "*iorsi_2_zext_imm"
9708 [(set (reg FLAGS_REG)
9709 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9710 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9712 (set (match_operand:DI 0 "register_operand" "=r")
9713 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9714 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9715 && ix86_binary_operator_ok (IOR, SImode, operands)"
9716 "or{l}\t{%2, %k0|%k0, %2}"
9717 [(set_attr "type" "alu")
9718 (set_attr "mode" "SI")])
9720 (define_insn "*iorsi_3"
9721 [(set (reg FLAGS_REG)
9722 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9723 (match_operand:SI 2 "general_operand" "g"))
9725 (clobber (match_scratch:SI 0 "=r"))]
9726 "ix86_match_ccmode (insn, CCNOmode)
9727 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9728 "or{l}\t{%2, %0|%0, %2}"
9729 [(set_attr "type" "alu")
9730 (set_attr "mode" "SI")])
9732 (define_expand "iorhi3"
9733 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9734 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9735 (match_operand:HI 2 "general_operand" "")))]
9736 "TARGET_HIMODE_MATH"
9737 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9739 (define_insn "*iorhi_1"
9740 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9741 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9742 (match_operand:HI 2 "general_operand" "rmn,rn")))
9743 (clobber (reg:CC FLAGS_REG))]
9744 "ix86_binary_operator_ok (IOR, HImode, operands)"
9745 "or{w}\t{%2, %0|%0, %2}"
9746 [(set_attr "type" "alu")
9747 (set_attr "mode" "HI")])
9749 (define_insn "*iorhi_2"
9750 [(set (reg FLAGS_REG)
9751 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9752 (match_operand:HI 2 "general_operand" "rmn,rn"))
9754 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9755 (ior:HI (match_dup 1) (match_dup 2)))]
9756 "ix86_match_ccmode (insn, CCNOmode)
9757 && ix86_binary_operator_ok (IOR, HImode, operands)"
9758 "or{w}\t{%2, %0|%0, %2}"
9759 [(set_attr "type" "alu")
9760 (set_attr "mode" "HI")])
9762 (define_insn "*iorhi_3"
9763 [(set (reg FLAGS_REG)
9764 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9765 (match_operand:HI 2 "general_operand" "rmn"))
9767 (clobber (match_scratch:HI 0 "=r"))]
9768 "ix86_match_ccmode (insn, CCNOmode)
9769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9770 "or{w}\t{%2, %0|%0, %2}"
9771 [(set_attr "type" "alu")
9772 (set_attr "mode" "HI")])
9774 (define_expand "iorqi3"
9775 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9776 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9777 (match_operand:QI 2 "general_operand" "")))]
9778 "TARGET_QIMODE_MATH"
9779 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9781 ;; %%% Potential partial reg stall on alternative 2. What to do?
9782 (define_insn "*iorqi_1"
9783 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9784 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9785 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "ix86_binary_operator_ok (IOR, QImode, operands)"
9789 or{b}\t{%2, %0|%0, %2}
9790 or{b}\t{%2, %0|%0, %2}
9791 or{l}\t{%k2, %k0|%k0, %k2}"
9792 [(set_attr "type" "alu")
9793 (set_attr "mode" "QI,QI,SI")])
9795 (define_insn "*iorqi_1_slp"
9796 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9797 (ior:QI (match_dup 0)
9798 (match_operand:QI 1 "general_operand" "qmn,qn")))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9801 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9802 "or{b}\t{%1, %0|%0, %1}"
9803 [(set_attr "type" "alu1")
9804 (set_attr "mode" "QI")])
9806 (define_insn "*iorqi_2"
9807 [(set (reg FLAGS_REG)
9808 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9809 (match_operand:QI 2 "general_operand" "qmn,qn"))
9811 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9812 (ior:QI (match_dup 1) (match_dup 2)))]
9813 "ix86_match_ccmode (insn, CCNOmode)
9814 && ix86_binary_operator_ok (IOR, QImode, operands)"
9815 "or{b}\t{%2, %0|%0, %2}"
9816 [(set_attr "type" "alu")
9817 (set_attr "mode" "QI")])
9819 (define_insn "*iorqi_2_slp"
9820 [(set (reg FLAGS_REG)
9821 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9822 (match_operand:QI 1 "general_operand" "qmn,qn"))
9824 (set (strict_low_part (match_dup 0))
9825 (ior:QI (match_dup 0) (match_dup 1)))]
9826 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9827 && ix86_match_ccmode (insn, CCNOmode)
9828 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9829 "or{b}\t{%1, %0|%0, %1}"
9830 [(set_attr "type" "alu1")
9831 (set_attr "mode" "QI")])
9833 (define_insn "*iorqi_3"
9834 [(set (reg FLAGS_REG)
9835 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9836 (match_operand:QI 2 "general_operand" "qmn"))
9838 (clobber (match_scratch:QI 0 "=q"))]
9839 "ix86_match_ccmode (insn, CCNOmode)
9840 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9841 "or{b}\t{%2, %0|%0, %2}"
9842 [(set_attr "type" "alu")
9843 (set_attr "mode" "QI")])
9845 (define_insn "*iorqi_ext_0"
9846 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9851 (match_operand 1 "ext_register_operand" "0")
9854 (match_operand 2 "const_int_operand" "n")))
9855 (clobber (reg:CC FLAGS_REG))]
9856 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9857 "or{b}\t{%2, %h0|%h0, %2}"
9858 [(set_attr "type" "alu")
9859 (set_attr "length_immediate" "1")
9860 (set_attr "mode" "QI")])
9862 (define_insn "*iorqi_ext_1"
9863 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9868 (match_operand 1 "ext_register_operand" "0")
9872 (match_operand:QI 2 "general_operand" "Qm"))))
9873 (clobber (reg:CC FLAGS_REG))]
9875 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9876 "or{b}\t{%2, %h0|%h0, %2}"
9877 [(set_attr "type" "alu")
9878 (set_attr "length_immediate" "0")
9879 (set_attr "mode" "QI")])
9881 (define_insn "*iorqi_ext_1_rex64"
9882 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9887 (match_operand 1 "ext_register_operand" "0")
9891 (match_operand 2 "ext_register_operand" "Q"))))
9892 (clobber (reg:CC FLAGS_REG))]
9894 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9895 "or{b}\t{%2, %h0|%h0, %2}"
9896 [(set_attr "type" "alu")
9897 (set_attr "length_immediate" "0")
9898 (set_attr "mode" "QI")])
9900 (define_insn "*iorqi_ext_2"
9901 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9905 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9908 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9911 (clobber (reg:CC FLAGS_REG))]
9912 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9913 "ior{b}\t{%h2, %h0|%h0, %h2}"
9914 [(set_attr "type" "alu")
9915 (set_attr "length_immediate" "0")
9916 (set_attr "mode" "QI")])
9919 [(set (match_operand 0 "register_operand" "")
9920 (ior (match_operand 1 "register_operand" "")
9921 (match_operand 2 "const_int_operand" "")))
9922 (clobber (reg:CC FLAGS_REG))]
9924 && QI_REG_P (operands[0])
9925 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9926 && !(INTVAL (operands[2]) & ~(255 << 8))
9927 && GET_MODE (operands[0]) != QImode"
9928 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9929 (ior:SI (zero_extract:SI (match_dup 1)
9930 (const_int 8) (const_int 8))
9932 (clobber (reg:CC FLAGS_REG))])]
9933 "operands[0] = gen_lowpart (SImode, operands[0]);
9934 operands[1] = gen_lowpart (SImode, operands[1]);
9935 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9937 ;; Since OR can be encoded with sign extended immediate, this is only
9938 ;; profitable when 7th bit is set.
9940 [(set (match_operand 0 "register_operand" "")
9941 (ior (match_operand 1 "general_operand" "")
9942 (match_operand 2 "const_int_operand" "")))
9943 (clobber (reg:CC FLAGS_REG))]
9945 && ANY_QI_REG_P (operands[0])
9946 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9947 && !(INTVAL (operands[2]) & ~255)
9948 && (INTVAL (operands[2]) & 128)
9949 && GET_MODE (operands[0]) != QImode"
9950 [(parallel [(set (strict_low_part (match_dup 0))
9951 (ior:QI (match_dup 1)
9953 (clobber (reg:CC FLAGS_REG))])]
9954 "operands[0] = gen_lowpart (QImode, operands[0]);
9955 operands[1] = gen_lowpart (QImode, operands[1]);
9956 operands[2] = gen_lowpart (QImode, operands[2]);")
9958 ;; Logical XOR instructions
9960 ;; %%% This used to optimize known byte-wide and operations to memory.
9961 ;; If this is considered useful, it should be done with splitters.
9963 (define_expand "xordi3"
9964 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9965 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9966 (match_operand:DI 2 "x86_64_general_operand" "")))]
9968 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9970 (define_insn "*xordi_1_rex64"
9971 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9972 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9973 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9974 (clobber (reg:CC FLAGS_REG))]
9976 && ix86_binary_operator_ok (XOR, DImode, operands)"
9977 "xor{q}\t{%2, %0|%0, %2}"
9978 [(set_attr "type" "alu")
9979 (set_attr "mode" "DI")])
9981 (define_insn "*xordi_2_rex64"
9982 [(set (reg FLAGS_REG)
9983 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9984 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9986 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9987 (xor:DI (match_dup 1) (match_dup 2)))]
9989 && ix86_match_ccmode (insn, CCNOmode)
9990 && ix86_binary_operator_ok (XOR, DImode, operands)"
9991 "xor{q}\t{%2, %0|%0, %2}"
9992 [(set_attr "type" "alu")
9993 (set_attr "mode" "DI")])
9995 (define_insn "*xordi_3_rex64"
9996 [(set (reg FLAGS_REG)
9997 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9998 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10000 (clobber (match_scratch:DI 0 "=r"))]
10002 && ix86_match_ccmode (insn, CCNOmode)
10003 && ix86_binary_operator_ok (XOR, DImode, operands)"
10004 "xor{q}\t{%2, %0|%0, %2}"
10005 [(set_attr "type" "alu")
10006 (set_attr "mode" "DI")])
10008 (define_expand "xorsi3"
10009 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10010 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10011 (match_operand:SI 2 "general_operand" "")))]
10013 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10015 (define_insn "*xorsi_1"
10016 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10017 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10018 (match_operand:SI 2 "general_operand" "ri,rm")))
10019 (clobber (reg:CC FLAGS_REG))]
10020 "ix86_binary_operator_ok (XOR, SImode, operands)"
10021 "xor{l}\t{%2, %0|%0, %2}"
10022 [(set_attr "type" "alu")
10023 (set_attr "mode" "SI")])
10025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10026 ;; Add speccase for immediates
10027 (define_insn "*xorsi_1_zext"
10028 [(set (match_operand:DI 0 "register_operand" "=r")
10030 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10031 (match_operand:SI 2 "general_operand" "g"))))
10032 (clobber (reg:CC FLAGS_REG))]
10033 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10034 "xor{l}\t{%2, %k0|%k0, %2}"
10035 [(set_attr "type" "alu")
10036 (set_attr "mode" "SI")])
10038 (define_insn "*xorsi_1_zext_imm"
10039 [(set (match_operand:DI 0 "register_operand" "=r")
10040 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10041 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10042 (clobber (reg:CC FLAGS_REG))]
10043 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10044 "xor{l}\t{%2, %k0|%k0, %2}"
10045 [(set_attr "type" "alu")
10046 (set_attr "mode" "SI")])
10048 (define_insn "*xorsi_2"
10049 [(set (reg FLAGS_REG)
10050 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10051 (match_operand:SI 2 "general_operand" "g,ri"))
10053 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10054 (xor:SI (match_dup 1) (match_dup 2)))]
10055 "ix86_match_ccmode (insn, CCNOmode)
10056 && ix86_binary_operator_ok (XOR, SImode, operands)"
10057 "xor{l}\t{%2, %0|%0, %2}"
10058 [(set_attr "type" "alu")
10059 (set_attr "mode" "SI")])
10061 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10062 ;; ??? Special case for immediate operand is missing - it is tricky.
10063 (define_insn "*xorsi_2_zext"
10064 [(set (reg FLAGS_REG)
10065 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10066 (match_operand:SI 2 "general_operand" "g"))
10068 (set (match_operand:DI 0 "register_operand" "=r")
10069 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10070 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10071 && ix86_binary_operator_ok (XOR, SImode, operands)"
10072 "xor{l}\t{%2, %k0|%k0, %2}"
10073 [(set_attr "type" "alu")
10074 (set_attr "mode" "SI")])
10076 (define_insn "*xorsi_2_zext_imm"
10077 [(set (reg FLAGS_REG)
10078 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10079 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10081 (set (match_operand:DI 0 "register_operand" "=r")
10082 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10083 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10084 && ix86_binary_operator_ok (XOR, SImode, operands)"
10085 "xor{l}\t{%2, %k0|%k0, %2}"
10086 [(set_attr "type" "alu")
10087 (set_attr "mode" "SI")])
10089 (define_insn "*xorsi_3"
10090 [(set (reg FLAGS_REG)
10091 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10092 (match_operand:SI 2 "general_operand" "g"))
10094 (clobber (match_scratch:SI 0 "=r"))]
10095 "ix86_match_ccmode (insn, CCNOmode)
10096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10097 "xor{l}\t{%2, %0|%0, %2}"
10098 [(set_attr "type" "alu")
10099 (set_attr "mode" "SI")])
10101 (define_expand "xorhi3"
10102 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10103 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10104 (match_operand:HI 2 "general_operand" "")))]
10105 "TARGET_HIMODE_MATH"
10106 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10108 (define_insn "*xorhi_1"
10109 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10110 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10111 (match_operand:HI 2 "general_operand" "rmn,rn")))
10112 (clobber (reg:CC FLAGS_REG))]
10113 "ix86_binary_operator_ok (XOR, HImode, operands)"
10114 "xor{w}\t{%2, %0|%0, %2}"
10115 [(set_attr "type" "alu")
10116 (set_attr "mode" "HI")])
10118 (define_insn "*xorhi_2"
10119 [(set (reg FLAGS_REG)
10120 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10121 (match_operand:HI 2 "general_operand" "rmn,rn"))
10123 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10124 (xor:HI (match_dup 1) (match_dup 2)))]
10125 "ix86_match_ccmode (insn, CCNOmode)
10126 && ix86_binary_operator_ok (XOR, HImode, operands)"
10127 "xor{w}\t{%2, %0|%0, %2}"
10128 [(set_attr "type" "alu")
10129 (set_attr "mode" "HI")])
10131 (define_insn "*xorhi_3"
10132 [(set (reg FLAGS_REG)
10133 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10134 (match_operand:HI 2 "general_operand" "rmn"))
10136 (clobber (match_scratch:HI 0 "=r"))]
10137 "ix86_match_ccmode (insn, CCNOmode)
10138 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10139 "xor{w}\t{%2, %0|%0, %2}"
10140 [(set_attr "type" "alu")
10141 (set_attr "mode" "HI")])
10143 (define_expand "xorqi3"
10144 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10145 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10146 (match_operand:QI 2 "general_operand" "")))]
10147 "TARGET_QIMODE_MATH"
10148 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10150 ;; %%% Potential partial reg stall on alternative 2. What to do?
10151 (define_insn "*xorqi_1"
10152 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10153 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10154 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10155 (clobber (reg:CC FLAGS_REG))]
10156 "ix86_binary_operator_ok (XOR, QImode, operands)"
10158 xor{b}\t{%2, %0|%0, %2}
10159 xor{b}\t{%2, %0|%0, %2}
10160 xor{l}\t{%k2, %k0|%k0, %k2}"
10161 [(set_attr "type" "alu")
10162 (set_attr "mode" "QI,QI,SI")])
10164 (define_insn "*xorqi_1_slp"
10165 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10166 (xor:QI (match_dup 0)
10167 (match_operand:QI 1 "general_operand" "qn,qmn")))
10168 (clobber (reg:CC FLAGS_REG))]
10169 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10170 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10171 "xor{b}\t{%1, %0|%0, %1}"
10172 [(set_attr "type" "alu1")
10173 (set_attr "mode" "QI")])
10175 (define_insn "*xorqi_ext_0"
10176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10181 (match_operand 1 "ext_register_operand" "0")
10184 (match_operand 2 "const_int_operand" "n")))
10185 (clobber (reg:CC FLAGS_REG))]
10186 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10187 "xor{b}\t{%2, %h0|%h0, %2}"
10188 [(set_attr "type" "alu")
10189 (set_attr "length_immediate" "1")
10190 (set_attr "mode" "QI")])
10192 (define_insn "*xorqi_ext_1"
10193 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10198 (match_operand 1 "ext_register_operand" "0")
10202 (match_operand:QI 2 "general_operand" "Qm"))))
10203 (clobber (reg:CC FLAGS_REG))]
10205 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10206 "xor{b}\t{%2, %h0|%h0, %2}"
10207 [(set_attr "type" "alu")
10208 (set_attr "length_immediate" "0")
10209 (set_attr "mode" "QI")])
10211 (define_insn "*xorqi_ext_1_rex64"
10212 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10217 (match_operand 1 "ext_register_operand" "0")
10221 (match_operand 2 "ext_register_operand" "Q"))))
10222 (clobber (reg:CC FLAGS_REG))]
10224 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10225 "xor{b}\t{%2, %h0|%h0, %2}"
10226 [(set_attr "type" "alu")
10227 (set_attr "length_immediate" "0")
10228 (set_attr "mode" "QI")])
10230 (define_insn "*xorqi_ext_2"
10231 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10235 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10238 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10241 (clobber (reg:CC FLAGS_REG))]
10242 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10243 "xor{b}\t{%h2, %h0|%h0, %h2}"
10244 [(set_attr "type" "alu")
10245 (set_attr "length_immediate" "0")
10246 (set_attr "mode" "QI")])
10248 (define_insn "*xorqi_cc_1"
10249 [(set (reg FLAGS_REG)
10251 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10252 (match_operand:QI 2 "general_operand" "qmn,qn"))
10254 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10255 (xor:QI (match_dup 1) (match_dup 2)))]
10256 "ix86_match_ccmode (insn, CCNOmode)
10257 && ix86_binary_operator_ok (XOR, QImode, operands)"
10258 "xor{b}\t{%2, %0|%0, %2}"
10259 [(set_attr "type" "alu")
10260 (set_attr "mode" "QI")])
10262 (define_insn "*xorqi_2_slp"
10263 [(set (reg FLAGS_REG)
10264 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10265 (match_operand:QI 1 "general_operand" "qmn,qn"))
10267 (set (strict_low_part (match_dup 0))
10268 (xor:QI (match_dup 0) (match_dup 1)))]
10269 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10270 && ix86_match_ccmode (insn, CCNOmode)
10271 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10272 "xor{b}\t{%1, %0|%0, %1}"
10273 [(set_attr "type" "alu1")
10274 (set_attr "mode" "QI")])
10276 (define_insn "*xorqi_cc_2"
10277 [(set (reg FLAGS_REG)
10279 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10280 (match_operand:QI 2 "general_operand" "qmn"))
10282 (clobber (match_scratch:QI 0 "=q"))]
10283 "ix86_match_ccmode (insn, CCNOmode)
10284 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10285 "xor{b}\t{%2, %0|%0, %2}"
10286 [(set_attr "type" "alu")
10287 (set_attr "mode" "QI")])
10289 (define_insn "*xorqi_cc_ext_1"
10290 [(set (reg FLAGS_REG)
10294 (match_operand 1 "ext_register_operand" "0")
10297 (match_operand:QI 2 "general_operand" "qmn"))
10299 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10303 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10305 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10306 "xor{b}\t{%2, %h0|%h0, %2}"
10307 [(set_attr "type" "alu")
10308 (set_attr "mode" "QI")])
10310 (define_insn "*xorqi_cc_ext_1_rex64"
10311 [(set (reg FLAGS_REG)
10315 (match_operand 1 "ext_register_operand" "0")
10318 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10320 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10324 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10326 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10327 "xor{b}\t{%2, %h0|%h0, %2}"
10328 [(set_attr "type" "alu")
10329 (set_attr "mode" "QI")])
10331 (define_expand "xorqi_cc_ext_1"
10333 (set (reg:CCNO FLAGS_REG)
10337 (match_operand 1 "ext_register_operand" "")
10340 (match_operand:QI 2 "general_operand" ""))
10342 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10346 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10352 [(set (match_operand 0 "register_operand" "")
10353 (xor (match_operand 1 "register_operand" "")
10354 (match_operand 2 "const_int_operand" "")))
10355 (clobber (reg:CC FLAGS_REG))]
10357 && QI_REG_P (operands[0])
10358 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10359 && !(INTVAL (operands[2]) & ~(255 << 8))
10360 && GET_MODE (operands[0]) != QImode"
10361 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10362 (xor:SI (zero_extract:SI (match_dup 1)
10363 (const_int 8) (const_int 8))
10365 (clobber (reg:CC FLAGS_REG))])]
10366 "operands[0] = gen_lowpart (SImode, operands[0]);
10367 operands[1] = gen_lowpart (SImode, operands[1]);
10368 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10370 ;; Since XOR can be encoded with sign extended immediate, this is only
10371 ;; profitable when 7th bit is set.
10373 [(set (match_operand 0 "register_operand" "")
10374 (xor (match_operand 1 "general_operand" "")
10375 (match_operand 2 "const_int_operand" "")))
10376 (clobber (reg:CC FLAGS_REG))]
10378 && ANY_QI_REG_P (operands[0])
10379 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10380 && !(INTVAL (operands[2]) & ~255)
10381 && (INTVAL (operands[2]) & 128)
10382 && GET_MODE (operands[0]) != QImode"
10383 [(parallel [(set (strict_low_part (match_dup 0))
10384 (xor:QI (match_dup 1)
10386 (clobber (reg:CC FLAGS_REG))])]
10387 "operands[0] = gen_lowpart (QImode, operands[0]);
10388 operands[1] = gen_lowpart (QImode, operands[1]);
10389 operands[2] = gen_lowpart (QImode, operands[2]);")
10391 ;; Negation instructions
10393 (define_expand "negti2"
10394 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10395 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10397 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10399 (define_insn "*negti2_1"
10400 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10401 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10402 (clobber (reg:CC FLAGS_REG))]
10404 && ix86_unary_operator_ok (NEG, TImode, operands)"
10408 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10409 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "TARGET_64BIT && reload_completed"
10413 [(set (reg:CCZ FLAGS_REG)
10414 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10415 (set (match_dup 0) (neg:DI (match_dup 1)))])
10417 [(set (match_dup 2)
10418 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10421 (clobber (reg:CC FLAGS_REG))])
10423 [(set (match_dup 2)
10424 (neg:DI (match_dup 2)))
10425 (clobber (reg:CC FLAGS_REG))])]
10426 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10428 (define_expand "negdi2"
10429 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10430 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10432 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10434 (define_insn "*negdi2_1"
10435 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10436 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10437 (clobber (reg:CC FLAGS_REG))]
10439 && ix86_unary_operator_ok (NEG, DImode, operands)"
10443 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10444 (neg:DI (match_operand:DI 1 "general_operand" "")))
10445 (clobber (reg:CC FLAGS_REG))]
10446 "!TARGET_64BIT && reload_completed"
10448 [(set (reg:CCZ FLAGS_REG)
10449 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10450 (set (match_dup 0) (neg:SI (match_dup 1)))])
10452 [(set (match_dup 2)
10453 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10456 (clobber (reg:CC FLAGS_REG))])
10458 [(set (match_dup 2)
10459 (neg:SI (match_dup 2)))
10460 (clobber (reg:CC FLAGS_REG))])]
10461 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10463 (define_insn "*negdi2_1_rex64"
10464 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10465 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10466 (clobber (reg:CC FLAGS_REG))]
10467 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10469 [(set_attr "type" "negnot")
10470 (set_attr "mode" "DI")])
10472 ;; The problem with neg is that it does not perform (compare x 0),
10473 ;; it really performs (compare 0 x), which leaves us with the zero
10474 ;; flag being the only useful item.
10476 (define_insn "*negdi2_cmpz_rex64"
10477 [(set (reg:CCZ FLAGS_REG)
10478 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10480 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10481 (neg:DI (match_dup 1)))]
10482 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10484 [(set_attr "type" "negnot")
10485 (set_attr "mode" "DI")])
10488 (define_expand "negsi2"
10489 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10490 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10492 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10494 (define_insn "*negsi2_1"
10495 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10496 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "ix86_unary_operator_ok (NEG, SImode, operands)"
10500 [(set_attr "type" "negnot")
10501 (set_attr "mode" "SI")])
10503 ;; Combine is quite creative about this pattern.
10504 (define_insn "*negsi2_1_zext"
10505 [(set (match_operand:DI 0 "register_operand" "=r")
10506 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10509 (clobber (reg:CC FLAGS_REG))]
10510 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10512 [(set_attr "type" "negnot")
10513 (set_attr "mode" "SI")])
10515 ;; The problem with neg is that it does not perform (compare x 0),
10516 ;; it really performs (compare 0 x), which leaves us with the zero
10517 ;; flag being the only useful item.
10519 (define_insn "*negsi2_cmpz"
10520 [(set (reg:CCZ FLAGS_REG)
10521 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10523 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10524 (neg:SI (match_dup 1)))]
10525 "ix86_unary_operator_ok (NEG, SImode, operands)"
10527 [(set_attr "type" "negnot")
10528 (set_attr "mode" "SI")])
10530 (define_insn "*negsi2_cmpz_zext"
10531 [(set (reg:CCZ FLAGS_REG)
10532 (compare:CCZ (lshiftrt:DI
10534 (match_operand:DI 1 "register_operand" "0")
10538 (set (match_operand:DI 0 "register_operand" "=r")
10539 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10542 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10544 [(set_attr "type" "negnot")
10545 (set_attr "mode" "SI")])
10547 (define_expand "neghi2"
10548 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10549 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10550 "TARGET_HIMODE_MATH"
10551 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10553 (define_insn "*neghi2_1"
10554 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10555 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10556 (clobber (reg:CC FLAGS_REG))]
10557 "ix86_unary_operator_ok (NEG, HImode, operands)"
10559 [(set_attr "type" "negnot")
10560 (set_attr "mode" "HI")])
10562 (define_insn "*neghi2_cmpz"
10563 [(set (reg:CCZ FLAGS_REG)
10564 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10566 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10567 (neg:HI (match_dup 1)))]
10568 "ix86_unary_operator_ok (NEG, HImode, operands)"
10570 [(set_attr "type" "negnot")
10571 (set_attr "mode" "HI")])
10573 (define_expand "negqi2"
10574 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10575 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10576 "TARGET_QIMODE_MATH"
10577 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10579 (define_insn "*negqi2_1"
10580 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10581 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10582 (clobber (reg:CC FLAGS_REG))]
10583 "ix86_unary_operator_ok (NEG, QImode, operands)"
10585 [(set_attr "type" "negnot")
10586 (set_attr "mode" "QI")])
10588 (define_insn "*negqi2_cmpz"
10589 [(set (reg:CCZ FLAGS_REG)
10590 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10592 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10593 (neg:QI (match_dup 1)))]
10594 "ix86_unary_operator_ok (NEG, QImode, operands)"
10596 [(set_attr "type" "negnot")
10597 (set_attr "mode" "QI")])
10599 ;; Changing of sign for FP values is doable using integer unit too.
10601 (define_expand "<code><mode>2"
10602 [(set (match_operand:X87MODEF 0 "register_operand" "")
10603 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10604 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10605 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10607 (define_insn "*absneg<mode>2_mixed"
10608 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10609 (match_operator:MODEF 3 "absneg_operator"
10610 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10611 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10612 (clobber (reg:CC FLAGS_REG))]
10613 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10616 (define_insn "*absneg<mode>2_sse"
10617 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10618 (match_operator:MODEF 3 "absneg_operator"
10619 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10620 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10621 (clobber (reg:CC FLAGS_REG))]
10622 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10625 (define_insn "*absneg<mode>2_i387"
10626 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10627 (match_operator:X87MODEF 3 "absneg_operator"
10628 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10629 (use (match_operand 2 "" ""))
10630 (clobber (reg:CC FLAGS_REG))]
10631 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10634 (define_expand "<code>tf2"
10635 [(set (match_operand:TF 0 "register_operand" "")
10636 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10638 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10640 (define_insn "*absnegtf2_sse"
10641 [(set (match_operand:TF 0 "register_operand" "=x,x")
10642 (match_operator:TF 3 "absneg_operator"
10643 [(match_operand:TF 1 "register_operand" "0,x")]))
10644 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10645 (clobber (reg:CC FLAGS_REG))]
10649 ;; Splitters for fp abs and neg.
10652 [(set (match_operand 0 "fp_register_operand" "")
10653 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10654 (use (match_operand 2 "" ""))
10655 (clobber (reg:CC FLAGS_REG))]
10657 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10660 [(set (match_operand 0 "register_operand" "")
10661 (match_operator 3 "absneg_operator"
10662 [(match_operand 1 "register_operand" "")]))
10663 (use (match_operand 2 "nonimmediate_operand" ""))
10664 (clobber (reg:CC FLAGS_REG))]
10665 "reload_completed && SSE_REG_P (operands[0])"
10666 [(set (match_dup 0) (match_dup 3))]
10668 enum machine_mode mode = GET_MODE (operands[0]);
10669 enum machine_mode vmode = GET_MODE (operands[2]);
10672 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10673 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10674 if (operands_match_p (operands[0], operands[2]))
10677 operands[1] = operands[2];
10680 if (GET_CODE (operands[3]) == ABS)
10681 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10683 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10688 [(set (match_operand:SF 0 "register_operand" "")
10689 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10690 (use (match_operand:V4SF 2 "" ""))
10691 (clobber (reg:CC FLAGS_REG))]
10693 [(parallel [(set (match_dup 0) (match_dup 1))
10694 (clobber (reg:CC FLAGS_REG))])]
10697 operands[0] = gen_lowpart (SImode, operands[0]);
10698 if (GET_CODE (operands[1]) == ABS)
10700 tmp = gen_int_mode (0x7fffffff, SImode);
10701 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10705 tmp = gen_int_mode (0x80000000, SImode);
10706 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10712 [(set (match_operand:DF 0 "register_operand" "")
10713 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10714 (use (match_operand 2 "" ""))
10715 (clobber (reg:CC FLAGS_REG))]
10717 [(parallel [(set (match_dup 0) (match_dup 1))
10718 (clobber (reg:CC FLAGS_REG))])]
10723 tmp = gen_lowpart (DImode, operands[0]);
10724 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10727 if (GET_CODE (operands[1]) == ABS)
10730 tmp = gen_rtx_NOT (DImode, tmp);
10734 operands[0] = gen_highpart (SImode, operands[0]);
10735 if (GET_CODE (operands[1]) == ABS)
10737 tmp = gen_int_mode (0x7fffffff, SImode);
10738 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10742 tmp = gen_int_mode (0x80000000, SImode);
10743 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10750 [(set (match_operand:XF 0 "register_operand" "")
10751 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10752 (use (match_operand 2 "" ""))
10753 (clobber (reg:CC FLAGS_REG))]
10755 [(parallel [(set (match_dup 0) (match_dup 1))
10756 (clobber (reg:CC FLAGS_REG))])]
10759 operands[0] = gen_rtx_REG (SImode,
10760 true_regnum (operands[0])
10761 + (TARGET_64BIT ? 1 : 2));
10762 if (GET_CODE (operands[1]) == ABS)
10764 tmp = GEN_INT (0x7fff);
10765 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10769 tmp = GEN_INT (0x8000);
10770 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10775 ;; Conditionalize these after reload. If they match before reload, we
10776 ;; lose the clobber and ability to use integer instructions.
10778 (define_insn "*<code><mode>2_1"
10779 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10780 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10782 && (reload_completed
10783 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10785 [(set_attr "type" "fsgn")
10786 (set_attr "mode" "<MODE>")])
10788 (define_insn "*<code>extendsfdf2"
10789 [(set (match_operand:DF 0 "register_operand" "=f")
10790 (absneg:DF (float_extend:DF
10791 (match_operand:SF 1 "register_operand" "0"))))]
10792 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10794 [(set_attr "type" "fsgn")
10795 (set_attr "mode" "DF")])
10797 (define_insn "*<code>extendsfxf2"
10798 [(set (match_operand:XF 0 "register_operand" "=f")
10799 (absneg:XF (float_extend:XF
10800 (match_operand:SF 1 "register_operand" "0"))))]
10803 [(set_attr "type" "fsgn")
10804 (set_attr "mode" "XF")])
10806 (define_insn "*<code>extenddfxf2"
10807 [(set (match_operand:XF 0 "register_operand" "=f")
10808 (absneg:XF (float_extend:XF
10809 (match_operand:DF 1 "register_operand" "0"))))]
10812 [(set_attr "type" "fsgn")
10813 (set_attr "mode" "XF")])
10815 ;; Copysign instructions
10817 (define_mode_iterator CSGNMODE [SF DF TF])
10818 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10820 (define_expand "copysign<mode>3"
10821 [(match_operand:CSGNMODE 0 "register_operand" "")
10822 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10823 (match_operand:CSGNMODE 2 "register_operand" "")]
10824 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10825 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10827 ix86_expand_copysign (operands);
10831 (define_insn_and_split "copysign<mode>3_const"
10832 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10834 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10835 (match_operand:CSGNMODE 2 "register_operand" "0")
10836 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10838 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10839 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10841 "&& reload_completed"
10844 ix86_split_copysign_const (operands);
10848 (define_insn "copysign<mode>3_var"
10849 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10851 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10852 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10853 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10854 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10856 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10857 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10858 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10862 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10864 [(match_operand:CSGNMODE 2 "register_operand" "")
10865 (match_operand:CSGNMODE 3 "register_operand" "")
10866 (match_operand:<CSGNVMODE> 4 "" "")
10867 (match_operand:<CSGNVMODE> 5 "" "")]
10869 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10870 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10871 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10872 && reload_completed"
10875 ix86_split_copysign_var (operands);
10879 ;; One complement instructions
10881 (define_expand "one_cmpldi2"
10882 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10883 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10885 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10887 (define_insn "*one_cmpldi2_1_rex64"
10888 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10889 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10890 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10892 [(set_attr "type" "negnot")
10893 (set_attr "mode" "DI")])
10895 (define_insn "*one_cmpldi2_2_rex64"
10896 [(set (reg FLAGS_REG)
10897 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10899 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10900 (not:DI (match_dup 1)))]
10901 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10902 && ix86_unary_operator_ok (NOT, DImode, operands)"
10904 [(set_attr "type" "alu1")
10905 (set_attr "mode" "DI")])
10908 [(set (match_operand 0 "flags_reg_operand" "")
10909 (match_operator 2 "compare_operator"
10910 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10912 (set (match_operand:DI 1 "nonimmediate_operand" "")
10913 (not:DI (match_dup 3)))]
10914 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10915 [(parallel [(set (match_dup 0)
10917 [(xor:DI (match_dup 3) (const_int -1))
10920 (xor:DI (match_dup 3) (const_int -1)))])]
10923 (define_expand "one_cmplsi2"
10924 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10925 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10927 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10929 (define_insn "*one_cmplsi2_1"
10930 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10931 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10932 "ix86_unary_operator_ok (NOT, SImode, operands)"
10934 [(set_attr "type" "negnot")
10935 (set_attr "mode" "SI")])
10937 ;; ??? Currently never generated - xor is used instead.
10938 (define_insn "*one_cmplsi2_1_zext"
10939 [(set (match_operand:DI 0 "register_operand" "=r")
10940 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10941 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10943 [(set_attr "type" "negnot")
10944 (set_attr "mode" "SI")])
10946 (define_insn "*one_cmplsi2_2"
10947 [(set (reg FLAGS_REG)
10948 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10950 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10951 (not:SI (match_dup 1)))]
10952 "ix86_match_ccmode (insn, CCNOmode)
10953 && ix86_unary_operator_ok (NOT, SImode, operands)"
10955 [(set_attr "type" "alu1")
10956 (set_attr "mode" "SI")])
10959 [(set (match_operand 0 "flags_reg_operand" "")
10960 (match_operator 2 "compare_operator"
10961 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10963 (set (match_operand:SI 1 "nonimmediate_operand" "")
10964 (not:SI (match_dup 3)))]
10965 "ix86_match_ccmode (insn, CCNOmode)"
10966 [(parallel [(set (match_dup 0)
10967 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10970 (xor:SI (match_dup 3) (const_int -1)))])]
10973 ;; ??? Currently never generated - xor is used instead.
10974 (define_insn "*one_cmplsi2_2_zext"
10975 [(set (reg FLAGS_REG)
10976 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10978 (set (match_operand:DI 0 "register_operand" "=r")
10979 (zero_extend:DI (not:SI (match_dup 1))))]
10980 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10981 && ix86_unary_operator_ok (NOT, SImode, operands)"
10983 [(set_attr "type" "alu1")
10984 (set_attr "mode" "SI")])
10987 [(set (match_operand 0 "flags_reg_operand" "")
10988 (match_operator 2 "compare_operator"
10989 [(not:SI (match_operand:SI 3 "register_operand" ""))
10991 (set (match_operand:DI 1 "register_operand" "")
10992 (zero_extend:DI (not:SI (match_dup 3))))]
10993 "ix86_match_ccmode (insn, CCNOmode)"
10994 [(parallel [(set (match_dup 0)
10995 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10998 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11001 (define_expand "one_cmplhi2"
11002 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11003 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11004 "TARGET_HIMODE_MATH"
11005 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11007 (define_insn "*one_cmplhi2_1"
11008 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11009 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11010 "ix86_unary_operator_ok (NOT, HImode, operands)"
11012 [(set_attr "type" "negnot")
11013 (set_attr "mode" "HI")])
11015 (define_insn "*one_cmplhi2_2"
11016 [(set (reg FLAGS_REG)
11017 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11019 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11020 (not:HI (match_dup 1)))]
11021 "ix86_match_ccmode (insn, CCNOmode)
11022 && ix86_unary_operator_ok (NEG, HImode, operands)"
11024 [(set_attr "type" "alu1")
11025 (set_attr "mode" "HI")])
11028 [(set (match_operand 0 "flags_reg_operand" "")
11029 (match_operator 2 "compare_operator"
11030 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11032 (set (match_operand:HI 1 "nonimmediate_operand" "")
11033 (not:HI (match_dup 3)))]
11034 "ix86_match_ccmode (insn, CCNOmode)"
11035 [(parallel [(set (match_dup 0)
11036 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11039 (xor:HI (match_dup 3) (const_int -1)))])]
11042 ;; %%% Potential partial reg stall on alternative 1. What to do?
11043 (define_expand "one_cmplqi2"
11044 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11045 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11046 "TARGET_QIMODE_MATH"
11047 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11049 (define_insn "*one_cmplqi2_1"
11050 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11051 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11052 "ix86_unary_operator_ok (NOT, QImode, operands)"
11056 [(set_attr "type" "negnot")
11057 (set_attr "mode" "QI,SI")])
11059 (define_insn "*one_cmplqi2_2"
11060 [(set (reg FLAGS_REG)
11061 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11063 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11064 (not:QI (match_dup 1)))]
11065 "ix86_match_ccmode (insn, CCNOmode)
11066 && ix86_unary_operator_ok (NOT, QImode, operands)"
11068 [(set_attr "type" "alu1")
11069 (set_attr "mode" "QI")])
11072 [(set (match_operand 0 "flags_reg_operand" "")
11073 (match_operator 2 "compare_operator"
11074 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11076 (set (match_operand:QI 1 "nonimmediate_operand" "")
11077 (not:QI (match_dup 3)))]
11078 "ix86_match_ccmode (insn, CCNOmode)"
11079 [(parallel [(set (match_dup 0)
11080 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11083 (xor:QI (match_dup 3) (const_int -1)))])]
11086 ;; Arithmetic shift instructions
11088 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11089 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11090 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11091 ;; from the assembler input.
11093 ;; This instruction shifts the target reg/mem as usual, but instead of
11094 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11095 ;; is a left shift double, bits are taken from the high order bits of
11096 ;; reg, else if the insn is a shift right double, bits are taken from the
11097 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11098 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11100 ;; Since sh[lr]d does not change the `reg' operand, that is done
11101 ;; separately, making all shifts emit pairs of shift double and normal
11102 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11103 ;; support a 63 bit shift, each shift where the count is in a reg expands
11104 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11106 ;; If the shift count is a constant, we need never emit more than one
11107 ;; shift pair, instead using moves and sign extension for counts greater
11110 (define_expand "ashlti3"
11111 [(set (match_operand:TI 0 "register_operand" "")
11112 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11113 (match_operand:QI 2 "nonmemory_operand" "")))]
11115 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11117 ;; This pattern must be defined before *ashlti3_1 to prevent
11118 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11120 (define_insn "*avx_ashlti3"
11121 [(set (match_operand:TI 0 "register_operand" "=x")
11122 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11123 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11126 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11127 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11129 [(set_attr "type" "sseishft")
11130 (set_attr "prefix" "vex")
11131 (set_attr "mode" "TI")])
11133 (define_insn "sse2_ashlti3"
11134 [(set (match_operand:TI 0 "register_operand" "=x")
11135 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11136 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11139 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11140 return "pslldq\t{%2, %0|%0, %2}";
11142 [(set_attr "type" "sseishft")
11143 (set_attr "prefix_data16" "1")
11144 (set_attr "mode" "TI")])
11146 (define_insn "*ashlti3_1"
11147 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11148 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11149 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11150 (clobber (reg:CC FLAGS_REG))]
11153 [(set_attr "type" "multi")])
11156 [(match_scratch:DI 3 "r")
11157 (parallel [(set (match_operand:TI 0 "register_operand" "")
11158 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11159 (match_operand:QI 2 "nonmemory_operand" "")))
11160 (clobber (reg:CC FLAGS_REG))])
11164 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11167 [(set (match_operand:TI 0 "register_operand" "")
11168 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11169 (match_operand:QI 2 "nonmemory_operand" "")))
11170 (clobber (reg:CC FLAGS_REG))]
11171 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11172 ? epilogue_completed : reload_completed)"
11174 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11176 (define_insn "x86_64_shld"
11177 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11178 (ior:DI (ashift:DI (match_dup 0)
11179 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11180 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11181 (minus:QI (const_int 64) (match_dup 2)))))
11182 (clobber (reg:CC FLAGS_REG))]
11184 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11185 [(set_attr "type" "ishift")
11186 (set_attr "prefix_0f" "1")
11187 (set_attr "mode" "DI")
11188 (set_attr "athlon_decode" "vector")
11189 (set_attr "amdfam10_decode" "vector")])
11191 (define_expand "x86_64_shift_adj_1"
11192 [(set (reg:CCZ FLAGS_REG)
11193 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11196 (set (match_operand:DI 0 "register_operand" "")
11197 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11198 (match_operand:DI 1 "register_operand" "")
11201 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11202 (match_operand:DI 3 "register_operand" "r")
11207 (define_expand "x86_64_shift_adj_2"
11208 [(use (match_operand:DI 0 "register_operand" ""))
11209 (use (match_operand:DI 1 "register_operand" ""))
11210 (use (match_operand:QI 2 "register_operand" ""))]
11213 rtx label = gen_label_rtx ();
11216 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11218 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11219 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11220 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11221 gen_rtx_LABEL_REF (VOIDmode, label),
11223 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11224 JUMP_LABEL (tmp) = label;
11226 emit_move_insn (operands[0], operands[1]);
11227 ix86_expand_clear (operands[1]);
11229 emit_label (label);
11230 LABEL_NUSES (label) = 1;
11235 (define_expand "ashldi3"
11236 [(set (match_operand:DI 0 "shiftdi_operand" "")
11237 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11238 (match_operand:QI 2 "nonmemory_operand" "")))]
11240 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11242 (define_insn "*ashldi3_1_rex64"
11243 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11244 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11245 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11246 (clobber (reg:CC FLAGS_REG))]
11247 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11249 switch (get_attr_type (insn))
11252 gcc_assert (operands[2] == const1_rtx);
11253 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11254 return "add{q}\t%0, %0";
11257 gcc_assert (CONST_INT_P (operands[2]));
11258 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11259 operands[1] = gen_rtx_MULT (DImode, operands[1],
11260 GEN_INT (1 << INTVAL (operands[2])));
11261 return "lea{q}\t{%a1, %0|%0, %a1}";
11264 if (REG_P (operands[2]))
11265 return "sal{q}\t{%b2, %0|%0, %b2}";
11266 else if (operands[2] == const1_rtx
11267 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11268 return "sal{q}\t%0";
11270 return "sal{q}\t{%2, %0|%0, %2}";
11273 [(set (attr "type")
11274 (cond [(eq_attr "alternative" "1")
11275 (const_string "lea")
11276 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11278 (match_operand 0 "register_operand" ""))
11279 (match_operand 2 "const1_operand" ""))
11280 (const_string "alu")
11282 (const_string "ishift")))
11283 (set_attr "mode" "DI")])
11285 ;; Convert lea to the lea pattern to avoid flags dependency.
11287 [(set (match_operand:DI 0 "register_operand" "")
11288 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11289 (match_operand:QI 2 "immediate_operand" "")))
11290 (clobber (reg:CC FLAGS_REG))]
11291 "TARGET_64BIT && reload_completed
11292 && true_regnum (operands[0]) != true_regnum (operands[1])"
11293 [(set (match_dup 0)
11294 (mult:DI (match_dup 1)
11296 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11298 ;; This pattern can't accept a variable shift count, since shifts by
11299 ;; zero don't affect the flags. We assume that shifts by constant
11300 ;; zero are optimized away.
11301 (define_insn "*ashldi3_cmp_rex64"
11302 [(set (reg FLAGS_REG)
11304 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11305 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11307 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11308 (ashift:DI (match_dup 1) (match_dup 2)))]
11310 && (optimize_function_for_size_p (cfun)
11311 || !TARGET_PARTIAL_FLAG_REG_STALL
11312 || (operands[2] == const1_rtx
11314 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11315 && ix86_match_ccmode (insn, CCGOCmode)
11316 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11318 switch (get_attr_type (insn))
11321 gcc_assert (operands[2] == const1_rtx);
11322 return "add{q}\t%0, %0";
11325 if (REG_P (operands[2]))
11326 return "sal{q}\t{%b2, %0|%0, %b2}";
11327 else if (operands[2] == const1_rtx
11328 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11329 return "sal{q}\t%0";
11331 return "sal{q}\t{%2, %0|%0, %2}";
11334 [(set (attr "type")
11335 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11337 (match_operand 0 "register_operand" ""))
11338 (match_operand 2 "const1_operand" ""))
11339 (const_string "alu")
11341 (const_string "ishift")))
11342 (set_attr "mode" "DI")])
11344 (define_insn "*ashldi3_cconly_rex64"
11345 [(set (reg FLAGS_REG)
11347 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11348 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11350 (clobber (match_scratch:DI 0 "=r"))]
11352 && (optimize_function_for_size_p (cfun)
11353 || !TARGET_PARTIAL_FLAG_REG_STALL
11354 || (operands[2] == const1_rtx
11356 || TARGET_DOUBLE_WITH_ADD)))
11357 && ix86_match_ccmode (insn, CCGOCmode)
11358 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11360 switch (get_attr_type (insn))
11363 gcc_assert (operands[2] == const1_rtx);
11364 return "add{q}\t%0, %0";
11367 if (REG_P (operands[2]))
11368 return "sal{q}\t{%b2, %0|%0, %b2}";
11369 else if (operands[2] == const1_rtx
11370 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11371 return "sal{q}\t%0";
11373 return "sal{q}\t{%2, %0|%0, %2}";
11376 [(set (attr "type")
11377 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11379 (match_operand 0 "register_operand" ""))
11380 (match_operand 2 "const1_operand" ""))
11381 (const_string "alu")
11383 (const_string "ishift")))
11384 (set_attr "mode" "DI")])
11386 (define_insn "*ashldi3_1"
11387 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11388 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11389 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11390 (clobber (reg:CC FLAGS_REG))]
11393 [(set_attr "type" "multi")])
11395 ;; By default we don't ask for a scratch register, because when DImode
11396 ;; values are manipulated, registers are already at a premium. But if
11397 ;; we have one handy, we won't turn it away.
11399 [(match_scratch:SI 3 "r")
11400 (parallel [(set (match_operand:DI 0 "register_operand" "")
11401 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11402 (match_operand:QI 2 "nonmemory_operand" "")))
11403 (clobber (reg:CC FLAGS_REG))])
11405 "!TARGET_64BIT && TARGET_CMOVE"
11407 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11410 [(set (match_operand:DI 0 "register_operand" "")
11411 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11412 (match_operand:QI 2 "nonmemory_operand" "")))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11415 ? epilogue_completed : reload_completed)"
11417 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11419 (define_insn "x86_shld"
11420 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11421 (ior:SI (ashift:SI (match_dup 0)
11422 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11423 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11424 (minus:QI (const_int 32) (match_dup 2)))))
11425 (clobber (reg:CC FLAGS_REG))]
11427 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11428 [(set_attr "type" "ishift")
11429 (set_attr "prefix_0f" "1")
11430 (set_attr "mode" "SI")
11431 (set_attr "pent_pair" "np")
11432 (set_attr "athlon_decode" "vector")
11433 (set_attr "amdfam10_decode" "vector")])
11435 (define_expand "x86_shift_adj_1"
11436 [(set (reg:CCZ FLAGS_REG)
11437 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11440 (set (match_operand:SI 0 "register_operand" "")
11441 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11442 (match_operand:SI 1 "register_operand" "")
11445 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11446 (match_operand:SI 3 "register_operand" "r")
11451 (define_expand "x86_shift_adj_2"
11452 [(use (match_operand:SI 0 "register_operand" ""))
11453 (use (match_operand:SI 1 "register_operand" ""))
11454 (use (match_operand:QI 2 "register_operand" ""))]
11457 rtx label = gen_label_rtx ();
11460 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11462 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11463 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11464 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11465 gen_rtx_LABEL_REF (VOIDmode, label),
11467 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11468 JUMP_LABEL (tmp) = label;
11470 emit_move_insn (operands[0], operands[1]);
11471 ix86_expand_clear (operands[1]);
11473 emit_label (label);
11474 LABEL_NUSES (label) = 1;
11479 (define_expand "ashlsi3"
11480 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11481 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11482 (match_operand:QI 2 "nonmemory_operand" "")))]
11484 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11486 (define_insn "*ashlsi3_1"
11487 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11488 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11489 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11490 (clobber (reg:CC FLAGS_REG))]
11491 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11493 switch (get_attr_type (insn))
11496 gcc_assert (operands[2] == const1_rtx);
11497 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11498 return "add{l}\t%0, %0";
11504 if (REG_P (operands[2]))
11505 return "sal{l}\t{%b2, %0|%0, %b2}";
11506 else if (operands[2] == const1_rtx
11507 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11508 return "sal{l}\t%0";
11510 return "sal{l}\t{%2, %0|%0, %2}";
11513 [(set (attr "type")
11514 (cond [(eq_attr "alternative" "1")
11515 (const_string "lea")
11516 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11518 (match_operand 0 "register_operand" ""))
11519 (match_operand 2 "const1_operand" ""))
11520 (const_string "alu")
11522 (const_string "ishift")))
11523 (set_attr "mode" "SI")])
11525 ;; Convert lea to the lea pattern to avoid flags dependency.
11527 [(set (match_operand 0 "register_operand" "")
11528 (ashift (match_operand 1 "index_register_operand" "")
11529 (match_operand:QI 2 "const_int_operand" "")))
11530 (clobber (reg:CC FLAGS_REG))]
11532 && true_regnum (operands[0]) != true_regnum (operands[1])
11533 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11537 enum machine_mode mode = GET_MODE (operands[0]);
11539 if (GET_MODE_SIZE (mode) < 4)
11540 operands[0] = gen_lowpart (SImode, operands[0]);
11542 operands[1] = gen_lowpart (Pmode, operands[1]);
11543 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11545 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11546 if (Pmode != SImode)
11547 pat = gen_rtx_SUBREG (SImode, pat, 0);
11548 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11552 ;; Rare case of shifting RSP is handled by generating move and shift
11554 [(set (match_operand 0 "register_operand" "")
11555 (ashift (match_operand 1 "register_operand" "")
11556 (match_operand:QI 2 "const_int_operand" "")))
11557 (clobber (reg:CC FLAGS_REG))]
11559 && true_regnum (operands[0]) != true_regnum (operands[1])"
11563 emit_move_insn (operands[0], operands[1]);
11564 pat = gen_rtx_SET (VOIDmode, operands[0],
11565 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11566 operands[0], operands[2]));
11567 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11568 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11572 (define_insn "*ashlsi3_1_zext"
11573 [(set (match_operand:DI 0 "register_operand" "=r,r")
11574 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11575 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11576 (clobber (reg:CC FLAGS_REG))]
11577 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11579 switch (get_attr_type (insn))
11582 gcc_assert (operands[2] == const1_rtx);
11583 return "add{l}\t%k0, %k0";
11589 if (REG_P (operands[2]))
11590 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11591 else if (operands[2] == const1_rtx
11592 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11593 return "sal{l}\t%k0";
11595 return "sal{l}\t{%2, %k0|%k0, %2}";
11598 [(set (attr "type")
11599 (cond [(eq_attr "alternative" "1")
11600 (const_string "lea")
11601 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11603 (match_operand 2 "const1_operand" ""))
11604 (const_string "alu")
11606 (const_string "ishift")))
11607 (set_attr "mode" "SI")])
11609 ;; Convert lea to the lea pattern to avoid flags dependency.
11611 [(set (match_operand:DI 0 "register_operand" "")
11612 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11613 (match_operand:QI 2 "const_int_operand" ""))))
11614 (clobber (reg:CC FLAGS_REG))]
11615 "TARGET_64BIT && reload_completed
11616 && true_regnum (operands[0]) != true_regnum (operands[1])"
11617 [(set (match_dup 0) (zero_extend:DI
11618 (subreg:SI (mult:SI (match_dup 1)
11619 (match_dup 2)) 0)))]
11621 operands[1] = gen_lowpart (Pmode, operands[1]);
11622 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11625 ;; This pattern can't accept a variable shift count, since shifts by
11626 ;; zero don't affect the flags. We assume that shifts by constant
11627 ;; zero are optimized away.
11628 (define_insn "*ashlsi3_cmp"
11629 [(set (reg FLAGS_REG)
11631 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11632 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11634 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11635 (ashift:SI (match_dup 1) (match_dup 2)))]
11636 "(optimize_function_for_size_p (cfun)
11637 || !TARGET_PARTIAL_FLAG_REG_STALL
11638 || (operands[2] == const1_rtx
11640 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11641 && ix86_match_ccmode (insn, CCGOCmode)
11642 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11644 switch (get_attr_type (insn))
11647 gcc_assert (operands[2] == const1_rtx);
11648 return "add{l}\t%0, %0";
11651 if (REG_P (operands[2]))
11652 return "sal{l}\t{%b2, %0|%0, %b2}";
11653 else if (operands[2] == const1_rtx
11654 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11655 return "sal{l}\t%0";
11657 return "sal{l}\t{%2, %0|%0, %2}";
11660 [(set (attr "type")
11661 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11663 (match_operand 0 "register_operand" ""))
11664 (match_operand 2 "const1_operand" ""))
11665 (const_string "alu")
11667 (const_string "ishift")))
11668 (set_attr "mode" "SI")])
11670 (define_insn "*ashlsi3_cconly"
11671 [(set (reg FLAGS_REG)
11673 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11674 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11676 (clobber (match_scratch:SI 0 "=r"))]
11677 "(optimize_function_for_size_p (cfun)
11678 || !TARGET_PARTIAL_FLAG_REG_STALL
11679 || (operands[2] == const1_rtx
11681 || TARGET_DOUBLE_WITH_ADD)))
11682 && ix86_match_ccmode (insn, CCGOCmode)
11683 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11685 switch (get_attr_type (insn))
11688 gcc_assert (operands[2] == const1_rtx);
11689 return "add{l}\t%0, %0";
11692 if (REG_P (operands[2]))
11693 return "sal{l}\t{%b2, %0|%0, %b2}";
11694 else if (operands[2] == const1_rtx
11695 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11696 return "sal{l}\t%0";
11698 return "sal{l}\t{%2, %0|%0, %2}";
11701 [(set (attr "type")
11702 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11704 (match_operand 0 "register_operand" ""))
11705 (match_operand 2 "const1_operand" ""))
11706 (const_string "alu")
11708 (const_string "ishift")))
11709 (set_attr "mode" "SI")])
11711 (define_insn "*ashlsi3_cmp_zext"
11712 [(set (reg FLAGS_REG)
11714 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11715 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11717 (set (match_operand:DI 0 "register_operand" "=r")
11718 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11720 && (optimize_function_for_size_p (cfun)
11721 || !TARGET_PARTIAL_FLAG_REG_STALL
11722 || (operands[2] == const1_rtx
11724 || TARGET_DOUBLE_WITH_ADD)))
11725 && ix86_match_ccmode (insn, CCGOCmode)
11726 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11728 switch (get_attr_type (insn))
11731 gcc_assert (operands[2] == const1_rtx);
11732 return "add{l}\t%k0, %k0";
11735 if (REG_P (operands[2]))
11736 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11737 else if (operands[2] == const1_rtx
11738 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11739 return "sal{l}\t%k0";
11741 return "sal{l}\t{%2, %k0|%k0, %2}";
11744 [(set (attr "type")
11745 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11747 (match_operand 2 "const1_operand" ""))
11748 (const_string "alu")
11750 (const_string "ishift")))
11751 (set_attr "mode" "SI")])
11753 (define_expand "ashlhi3"
11754 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11755 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11756 (match_operand:QI 2 "nonmemory_operand" "")))]
11757 "TARGET_HIMODE_MATH"
11758 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11760 (define_insn "*ashlhi3_1_lea"
11761 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11762 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11763 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11764 (clobber (reg:CC FLAGS_REG))]
11765 "!TARGET_PARTIAL_REG_STALL
11766 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11768 switch (get_attr_type (insn))
11773 gcc_assert (operands[2] == const1_rtx);
11774 return "add{w}\t%0, %0";
11777 if (REG_P (operands[2]))
11778 return "sal{w}\t{%b2, %0|%0, %b2}";
11779 else if (operands[2] == const1_rtx
11780 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11781 return "sal{w}\t%0";
11783 return "sal{w}\t{%2, %0|%0, %2}";
11786 [(set (attr "type")
11787 (cond [(eq_attr "alternative" "1")
11788 (const_string "lea")
11789 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11791 (match_operand 0 "register_operand" ""))
11792 (match_operand 2 "const1_operand" ""))
11793 (const_string "alu")
11795 (const_string "ishift")))
11796 (set_attr "mode" "HI,SI")])
11798 (define_insn "*ashlhi3_1"
11799 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11800 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11801 (match_operand:QI 2 "nonmemory_operand" "cI")))
11802 (clobber (reg:CC FLAGS_REG))]
11803 "TARGET_PARTIAL_REG_STALL
11804 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11806 switch (get_attr_type (insn))
11809 gcc_assert (operands[2] == const1_rtx);
11810 return "add{w}\t%0, %0";
11813 if (REG_P (operands[2]))
11814 return "sal{w}\t{%b2, %0|%0, %b2}";
11815 else if (operands[2] == const1_rtx
11816 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11817 return "sal{w}\t%0";
11819 return "sal{w}\t{%2, %0|%0, %2}";
11822 [(set (attr "type")
11823 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11825 (match_operand 0 "register_operand" ""))
11826 (match_operand 2 "const1_operand" ""))
11827 (const_string "alu")
11829 (const_string "ishift")))
11830 (set_attr "mode" "HI")])
11832 ;; This pattern can't accept a variable shift count, since shifts by
11833 ;; zero don't affect the flags. We assume that shifts by constant
11834 ;; zero are optimized away.
11835 (define_insn "*ashlhi3_cmp"
11836 [(set (reg FLAGS_REG)
11838 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11839 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11841 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11842 (ashift:HI (match_dup 1) (match_dup 2)))]
11843 "(optimize_function_for_size_p (cfun)
11844 || !TARGET_PARTIAL_FLAG_REG_STALL
11845 || (operands[2] == const1_rtx
11847 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11848 && ix86_match_ccmode (insn, CCGOCmode)
11849 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11851 switch (get_attr_type (insn))
11854 gcc_assert (operands[2] == const1_rtx);
11855 return "add{w}\t%0, %0";
11858 if (REG_P (operands[2]))
11859 return "sal{w}\t{%b2, %0|%0, %b2}";
11860 else if (operands[2] == const1_rtx
11861 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11862 return "sal{w}\t%0";
11864 return "sal{w}\t{%2, %0|%0, %2}";
11867 [(set (attr "type")
11868 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11870 (match_operand 0 "register_operand" ""))
11871 (match_operand 2 "const1_operand" ""))
11872 (const_string "alu")
11874 (const_string "ishift")))
11875 (set_attr "mode" "HI")])
11877 (define_insn "*ashlhi3_cconly"
11878 [(set (reg FLAGS_REG)
11880 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11881 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11883 (clobber (match_scratch:HI 0 "=r"))]
11884 "(optimize_function_for_size_p (cfun)
11885 || !TARGET_PARTIAL_FLAG_REG_STALL
11886 || (operands[2] == const1_rtx
11888 || TARGET_DOUBLE_WITH_ADD)))
11889 && ix86_match_ccmode (insn, CCGOCmode)
11890 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11892 switch (get_attr_type (insn))
11895 gcc_assert (operands[2] == const1_rtx);
11896 return "add{w}\t%0, %0";
11899 if (REG_P (operands[2]))
11900 return "sal{w}\t{%b2, %0|%0, %b2}";
11901 else if (operands[2] == const1_rtx
11902 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11903 return "sal{w}\t%0";
11905 return "sal{w}\t{%2, %0|%0, %2}";
11908 [(set (attr "type")
11909 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11911 (match_operand 0 "register_operand" ""))
11912 (match_operand 2 "const1_operand" ""))
11913 (const_string "alu")
11915 (const_string "ishift")))
11916 (set_attr "mode" "HI")])
11918 (define_expand "ashlqi3"
11919 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11920 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11921 (match_operand:QI 2 "nonmemory_operand" "")))]
11922 "TARGET_QIMODE_MATH"
11923 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11925 ;; %%% Potential partial reg stall on alternative 2. What to do?
11927 (define_insn "*ashlqi3_1_lea"
11928 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11929 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11930 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11931 (clobber (reg:CC FLAGS_REG))]
11932 "!TARGET_PARTIAL_REG_STALL
11933 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11935 switch (get_attr_type (insn))
11940 gcc_assert (operands[2] == const1_rtx);
11941 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11942 return "add{l}\t%k0, %k0";
11944 return "add{b}\t%0, %0";
11947 if (REG_P (operands[2]))
11949 if (get_attr_mode (insn) == MODE_SI)
11950 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11952 return "sal{b}\t{%b2, %0|%0, %b2}";
11954 else if (operands[2] == const1_rtx
11955 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11957 if (get_attr_mode (insn) == MODE_SI)
11958 return "sal{l}\t%0";
11960 return "sal{b}\t%0";
11964 if (get_attr_mode (insn) == MODE_SI)
11965 return "sal{l}\t{%2, %k0|%k0, %2}";
11967 return "sal{b}\t{%2, %0|%0, %2}";
11971 [(set (attr "type")
11972 (cond [(eq_attr "alternative" "2")
11973 (const_string "lea")
11974 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11976 (match_operand 0 "register_operand" ""))
11977 (match_operand 2 "const1_operand" ""))
11978 (const_string "alu")
11980 (const_string "ishift")))
11981 (set_attr "mode" "QI,SI,SI")])
11983 (define_insn "*ashlqi3_1"
11984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11985 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11986 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11987 (clobber (reg:CC FLAGS_REG))]
11988 "TARGET_PARTIAL_REG_STALL
11989 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11991 switch (get_attr_type (insn))
11994 gcc_assert (operands[2] == const1_rtx);
11995 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11996 return "add{l}\t%k0, %k0";
11998 return "add{b}\t%0, %0";
12001 if (REG_P (operands[2]))
12003 if (get_attr_mode (insn) == MODE_SI)
12004 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12006 return "sal{b}\t{%b2, %0|%0, %b2}";
12008 else if (operands[2] == const1_rtx
12009 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12011 if (get_attr_mode (insn) == MODE_SI)
12012 return "sal{l}\t%0";
12014 return "sal{b}\t%0";
12018 if (get_attr_mode (insn) == MODE_SI)
12019 return "sal{l}\t{%2, %k0|%k0, %2}";
12021 return "sal{b}\t{%2, %0|%0, %2}";
12025 [(set (attr "type")
12026 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12028 (match_operand 0 "register_operand" ""))
12029 (match_operand 2 "const1_operand" ""))
12030 (const_string "alu")
12032 (const_string "ishift")))
12033 (set_attr "mode" "QI,SI")])
12035 ;; This pattern can't accept a variable shift count, since shifts by
12036 ;; zero don't affect the flags. We assume that shifts by constant
12037 ;; zero are optimized away.
12038 (define_insn "*ashlqi3_cmp"
12039 [(set (reg FLAGS_REG)
12041 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12042 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12044 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12045 (ashift:QI (match_dup 1) (match_dup 2)))]
12046 "(optimize_function_for_size_p (cfun)
12047 || !TARGET_PARTIAL_FLAG_REG_STALL
12048 || (operands[2] == const1_rtx
12050 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12051 && ix86_match_ccmode (insn, CCGOCmode)
12052 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12054 switch (get_attr_type (insn))
12057 gcc_assert (operands[2] == const1_rtx);
12058 return "add{b}\t%0, %0";
12061 if (REG_P (operands[2]))
12062 return "sal{b}\t{%b2, %0|%0, %b2}";
12063 else if (operands[2] == const1_rtx
12064 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12065 return "sal{b}\t%0";
12067 return "sal{b}\t{%2, %0|%0, %2}";
12070 [(set (attr "type")
12071 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12073 (match_operand 0 "register_operand" ""))
12074 (match_operand 2 "const1_operand" ""))
12075 (const_string "alu")
12077 (const_string "ishift")))
12078 (set_attr "mode" "QI")])
12080 (define_insn "*ashlqi3_cconly"
12081 [(set (reg FLAGS_REG)
12083 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12084 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12086 (clobber (match_scratch:QI 0 "=q"))]
12087 "(optimize_function_for_size_p (cfun)
12088 || !TARGET_PARTIAL_FLAG_REG_STALL
12089 || (operands[2] == const1_rtx
12091 || TARGET_DOUBLE_WITH_ADD)))
12092 && ix86_match_ccmode (insn, CCGOCmode)
12093 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12095 switch (get_attr_type (insn))
12098 gcc_assert (operands[2] == const1_rtx);
12099 return "add{b}\t%0, %0";
12102 if (REG_P (operands[2]))
12103 return "sal{b}\t{%b2, %0|%0, %b2}";
12104 else if (operands[2] == const1_rtx
12105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12106 return "sal{b}\t%0";
12108 return "sal{b}\t{%2, %0|%0, %2}";
12111 [(set (attr "type")
12112 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12114 (match_operand 0 "register_operand" ""))
12115 (match_operand 2 "const1_operand" ""))
12116 (const_string "alu")
12118 (const_string "ishift")))
12119 (set_attr "mode" "QI")])
12121 ;; See comment above `ashldi3' about how this works.
12123 (define_expand "ashrti3"
12124 [(set (match_operand:TI 0 "register_operand" "")
12125 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12126 (match_operand:QI 2 "nonmemory_operand" "")))]
12128 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12130 (define_insn "*ashrti3_1"
12131 [(set (match_operand:TI 0 "register_operand" "=r")
12132 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12133 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12134 (clobber (reg:CC FLAGS_REG))]
12137 [(set_attr "type" "multi")])
12140 [(match_scratch:DI 3 "r")
12141 (parallel [(set (match_operand:TI 0 "register_operand" "")
12142 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12143 (match_operand:QI 2 "nonmemory_operand" "")))
12144 (clobber (reg:CC FLAGS_REG))])
12148 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12151 [(set (match_operand:TI 0 "register_operand" "")
12152 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12153 (match_operand:QI 2 "nonmemory_operand" "")))
12154 (clobber (reg:CC FLAGS_REG))]
12155 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12156 ? epilogue_completed : reload_completed)"
12158 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12160 (define_insn "x86_64_shrd"
12161 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12162 (ior:DI (ashiftrt:DI (match_dup 0)
12163 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12164 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12165 (minus:QI (const_int 64) (match_dup 2)))))
12166 (clobber (reg:CC FLAGS_REG))]
12168 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12169 [(set_attr "type" "ishift")
12170 (set_attr "prefix_0f" "1")
12171 (set_attr "mode" "DI")
12172 (set_attr "athlon_decode" "vector")
12173 (set_attr "amdfam10_decode" "vector")])
12175 (define_expand "ashrdi3"
12176 [(set (match_operand:DI 0 "shiftdi_operand" "")
12177 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12178 (match_operand:QI 2 "nonmemory_operand" "")))]
12180 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12182 (define_expand "x86_64_shift_adj_3"
12183 [(use (match_operand:DI 0 "register_operand" ""))
12184 (use (match_operand:DI 1 "register_operand" ""))
12185 (use (match_operand:QI 2 "register_operand" ""))]
12188 rtx label = gen_label_rtx ();
12191 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12193 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12194 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12195 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12196 gen_rtx_LABEL_REF (VOIDmode, label),
12198 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12199 JUMP_LABEL (tmp) = label;
12201 emit_move_insn (operands[0], operands[1]);
12202 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12204 emit_label (label);
12205 LABEL_NUSES (label) = 1;
12210 (define_insn "ashrdi3_63_rex64"
12211 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12212 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12213 (match_operand:DI 2 "const_int_operand" "i,i")))
12214 (clobber (reg:CC FLAGS_REG))]
12215 "TARGET_64BIT && INTVAL (operands[2]) == 63
12216 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12217 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12220 sar{q}\t{%2, %0|%0, %2}"
12221 [(set_attr "type" "imovx,ishift")
12222 (set_attr "prefix_0f" "0,*")
12223 (set_attr "length_immediate" "0,*")
12224 (set_attr "modrm" "0,1")
12225 (set_attr "mode" "DI")])
12227 (define_insn "*ashrdi3_1_one_bit_rex64"
12228 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12229 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12230 (match_operand:QI 2 "const1_operand" "")))
12231 (clobber (reg:CC FLAGS_REG))]
12233 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12234 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12236 [(set_attr "type" "ishift")
12237 (set (attr "length")
12238 (if_then_else (match_operand:DI 0 "register_operand" "")
12240 (const_string "*")))])
12242 (define_insn "*ashrdi3_1_rex64"
12243 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12244 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12245 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12246 (clobber (reg:CC FLAGS_REG))]
12247 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12249 sar{q}\t{%2, %0|%0, %2}
12250 sar{q}\t{%b2, %0|%0, %b2}"
12251 [(set_attr "type" "ishift")
12252 (set_attr "mode" "DI")])
12254 ;; This pattern can't accept a variable shift count, since shifts by
12255 ;; zero don't affect the flags. We assume that shifts by constant
12256 ;; zero are optimized away.
12257 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12258 [(set (reg FLAGS_REG)
12260 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12261 (match_operand:QI 2 "const1_operand" ""))
12263 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12264 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12266 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12267 && ix86_match_ccmode (insn, CCGOCmode)
12268 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12270 [(set_attr "type" "ishift")
12271 (set (attr "length")
12272 (if_then_else (match_operand:DI 0 "register_operand" "")
12274 (const_string "*")))])
12276 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12277 [(set (reg FLAGS_REG)
12279 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12280 (match_operand:QI 2 "const1_operand" ""))
12282 (clobber (match_scratch:DI 0 "=r"))]
12284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12285 && ix86_match_ccmode (insn, CCGOCmode)
12286 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12288 [(set_attr "type" "ishift")
12289 (set_attr "length" "2")])
12291 ;; This pattern can't accept a variable shift count, since shifts by
12292 ;; zero don't affect the flags. We assume that shifts by constant
12293 ;; zero are optimized away.
12294 (define_insn "*ashrdi3_cmp_rex64"
12295 [(set (reg FLAGS_REG)
12297 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12298 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12300 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12301 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12303 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12304 && ix86_match_ccmode (insn, CCGOCmode)
12305 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12306 "sar{q}\t{%2, %0|%0, %2}"
12307 [(set_attr "type" "ishift")
12308 (set_attr "mode" "DI")])
12310 (define_insn "*ashrdi3_cconly_rex64"
12311 [(set (reg FLAGS_REG)
12313 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12316 (clobber (match_scratch:DI 0 "=r"))]
12318 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12319 && ix86_match_ccmode (insn, CCGOCmode)
12320 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12321 "sar{q}\t{%2, %0|%0, %2}"
12322 [(set_attr "type" "ishift")
12323 (set_attr "mode" "DI")])
12325 (define_insn "*ashrdi3_1"
12326 [(set (match_operand:DI 0 "register_operand" "=r")
12327 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12328 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12329 (clobber (reg:CC FLAGS_REG))]
12332 [(set_attr "type" "multi")])
12334 ;; By default we don't ask for a scratch register, because when DImode
12335 ;; values are manipulated, registers are already at a premium. But if
12336 ;; we have one handy, we won't turn it away.
12338 [(match_scratch:SI 3 "r")
12339 (parallel [(set (match_operand:DI 0 "register_operand" "")
12340 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12341 (match_operand:QI 2 "nonmemory_operand" "")))
12342 (clobber (reg:CC FLAGS_REG))])
12344 "!TARGET_64BIT && TARGET_CMOVE"
12346 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12349 [(set (match_operand:DI 0 "register_operand" "")
12350 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12351 (match_operand:QI 2 "nonmemory_operand" "")))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12354 ? epilogue_completed : reload_completed)"
12356 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12358 (define_insn "x86_shrd"
12359 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12360 (ior:SI (ashiftrt:SI (match_dup 0)
12361 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12362 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12363 (minus:QI (const_int 32) (match_dup 2)))))
12364 (clobber (reg:CC FLAGS_REG))]
12366 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12367 [(set_attr "type" "ishift")
12368 (set_attr "prefix_0f" "1")
12369 (set_attr "pent_pair" "np")
12370 (set_attr "mode" "SI")])
12372 (define_expand "x86_shift_adj_3"
12373 [(use (match_operand:SI 0 "register_operand" ""))
12374 (use (match_operand:SI 1 "register_operand" ""))
12375 (use (match_operand:QI 2 "register_operand" ""))]
12378 rtx label = gen_label_rtx ();
12381 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12383 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12384 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12385 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12386 gen_rtx_LABEL_REF (VOIDmode, label),
12388 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12389 JUMP_LABEL (tmp) = label;
12391 emit_move_insn (operands[0], operands[1]);
12392 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12394 emit_label (label);
12395 LABEL_NUSES (label) = 1;
12400 (define_expand "ashrsi3_31"
12401 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12402 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12403 (match_operand:SI 2 "const_int_operand" "i,i")))
12404 (clobber (reg:CC FLAGS_REG))])]
12407 (define_insn "*ashrsi3_31"
12408 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12409 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12410 (match_operand:SI 2 "const_int_operand" "i,i")))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "INTVAL (operands[2]) == 31
12413 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12414 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12417 sar{l}\t{%2, %0|%0, %2}"
12418 [(set_attr "type" "imovx,ishift")
12419 (set_attr "prefix_0f" "0,*")
12420 (set_attr "length_immediate" "0,*")
12421 (set_attr "modrm" "0,1")
12422 (set_attr "mode" "SI")])
12424 (define_insn "*ashrsi3_31_zext"
12425 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12426 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12427 (match_operand:SI 2 "const_int_operand" "i,i"))))
12428 (clobber (reg:CC FLAGS_REG))]
12429 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12430 && INTVAL (operands[2]) == 31
12431 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12434 sar{l}\t{%2, %k0|%k0, %2}"
12435 [(set_attr "type" "imovx,ishift")
12436 (set_attr "prefix_0f" "0,*")
12437 (set_attr "length_immediate" "0,*")
12438 (set_attr "modrm" "0,1")
12439 (set_attr "mode" "SI")])
12441 (define_expand "ashrsi3"
12442 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12443 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12444 (match_operand:QI 2 "nonmemory_operand" "")))]
12446 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12448 (define_insn "*ashrsi3_1_one_bit"
12449 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12450 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12451 (match_operand:QI 2 "const1_operand" "")))
12452 (clobber (reg:CC FLAGS_REG))]
12453 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12454 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12456 [(set_attr "type" "ishift")
12457 (set (attr "length")
12458 (if_then_else (match_operand:SI 0 "register_operand" "")
12460 (const_string "*")))])
12462 (define_insn "*ashrsi3_1_one_bit_zext"
12463 [(set (match_operand:DI 0 "register_operand" "=r")
12464 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12465 (match_operand:QI 2 "const1_operand" ""))))
12466 (clobber (reg:CC FLAGS_REG))]
12468 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12469 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12471 [(set_attr "type" "ishift")
12472 (set_attr "length" "2")])
12474 (define_insn "*ashrsi3_1"
12475 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12476 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12477 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478 (clobber (reg:CC FLAGS_REG))]
12479 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12481 sar{l}\t{%2, %0|%0, %2}
12482 sar{l}\t{%b2, %0|%0, %b2}"
12483 [(set_attr "type" "ishift")
12484 (set_attr "mode" "SI")])
12486 (define_insn "*ashrsi3_1_zext"
12487 [(set (match_operand:DI 0 "register_operand" "=r,r")
12488 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12489 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12490 (clobber (reg:CC FLAGS_REG))]
12491 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12493 sar{l}\t{%2, %k0|%k0, %2}
12494 sar{l}\t{%b2, %k0|%k0, %b2}"
12495 [(set_attr "type" "ishift")
12496 (set_attr "mode" "SI")])
12498 ;; This pattern can't accept a variable shift count, since shifts by
12499 ;; zero don't affect the flags. We assume that shifts by constant
12500 ;; zero are optimized away.
12501 (define_insn "*ashrsi3_one_bit_cmp"
12502 [(set (reg FLAGS_REG)
12504 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12505 (match_operand:QI 2 "const1_operand" ""))
12507 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12508 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12509 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12510 && ix86_match_ccmode (insn, CCGOCmode)
12511 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12513 [(set_attr "type" "ishift")
12514 (set (attr "length")
12515 (if_then_else (match_operand:SI 0 "register_operand" "")
12517 (const_string "*")))])
12519 (define_insn "*ashrsi3_one_bit_cconly"
12520 [(set (reg FLAGS_REG)
12522 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12523 (match_operand:QI 2 "const1_operand" ""))
12525 (clobber (match_scratch:SI 0 "=r"))]
12526 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12527 && ix86_match_ccmode (insn, CCGOCmode)
12528 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12530 [(set_attr "type" "ishift")
12531 (set_attr "length" "2")])
12533 (define_insn "*ashrsi3_one_bit_cmp_zext"
12534 [(set (reg FLAGS_REG)
12536 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12537 (match_operand:QI 2 "const1_operand" ""))
12539 (set (match_operand:DI 0 "register_operand" "=r")
12540 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12542 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12543 && ix86_match_ccmode (insn, CCmode)
12544 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12546 [(set_attr "type" "ishift")
12547 (set_attr "length" "2")])
12549 ;; This pattern can't accept a variable shift count, since shifts by
12550 ;; zero don't affect the flags. We assume that shifts by constant
12551 ;; zero are optimized away.
12552 (define_insn "*ashrsi3_cmp"
12553 [(set (reg FLAGS_REG)
12555 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12556 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12558 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12559 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12560 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12561 && ix86_match_ccmode (insn, CCGOCmode)
12562 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12563 "sar{l}\t{%2, %0|%0, %2}"
12564 [(set_attr "type" "ishift")
12565 (set_attr "mode" "SI")])
12567 (define_insn "*ashrsi3_cconly"
12568 [(set (reg FLAGS_REG)
12570 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12571 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12573 (clobber (match_scratch:SI 0 "=r"))]
12574 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12575 && ix86_match_ccmode (insn, CCGOCmode)
12576 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12577 "sar{l}\t{%2, %0|%0, %2}"
12578 [(set_attr "type" "ishift")
12579 (set_attr "mode" "SI")])
12581 (define_insn "*ashrsi3_cmp_zext"
12582 [(set (reg FLAGS_REG)
12584 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12585 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12587 (set (match_operand:DI 0 "register_operand" "=r")
12588 (zero_extend:DI (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, %k0|%k0, %2}"
12594 [(set_attr "type" "ishift")
12595 (set_attr "mode" "SI")])
12597 (define_expand "ashrhi3"
12598 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12599 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12600 (match_operand:QI 2 "nonmemory_operand" "")))]
12601 "TARGET_HIMODE_MATH"
12602 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12604 (define_insn "*ashrhi3_1_one_bit"
12605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12606 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12607 (match_operand:QI 2 "const1_operand" "")))
12608 (clobber (reg:CC FLAGS_REG))]
12609 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12610 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12612 [(set_attr "type" "ishift")
12613 (set (attr "length")
12614 (if_then_else (match_operand 0 "register_operand" "")
12616 (const_string "*")))])
12618 (define_insn "*ashrhi3_1"
12619 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12620 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12621 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12622 (clobber (reg:CC FLAGS_REG))]
12623 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12625 sar{w}\t{%2, %0|%0, %2}
12626 sar{w}\t{%b2, %0|%0, %b2}"
12627 [(set_attr "type" "ishift")
12628 (set_attr "mode" "HI")])
12630 ;; This pattern can't accept a variable shift count, since shifts by
12631 ;; zero don't affect the flags. We assume that shifts by constant
12632 ;; zero are optimized away.
12633 (define_insn "*ashrhi3_one_bit_cmp"
12634 [(set (reg FLAGS_REG)
12636 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12637 (match_operand:QI 2 "const1_operand" ""))
12639 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12640 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12641 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12642 && ix86_match_ccmode (insn, CCGOCmode)
12643 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12645 [(set_attr "type" "ishift")
12646 (set (attr "length")
12647 (if_then_else (match_operand 0 "register_operand" "")
12649 (const_string "*")))])
12651 (define_insn "*ashrhi3_one_bit_cconly"
12652 [(set (reg FLAGS_REG)
12654 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12655 (match_operand:QI 2 "const1_operand" ""))
12657 (clobber (match_scratch:HI 0 "=r"))]
12658 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12659 && ix86_match_ccmode (insn, CCGOCmode)
12660 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12662 [(set_attr "type" "ishift")
12663 (set_attr "length" "2")])
12665 ;; This pattern can't accept a variable shift count, since shifts by
12666 ;; zero don't affect the flags. We assume that shifts by constant
12667 ;; zero are optimized away.
12668 (define_insn "*ashrhi3_cmp"
12669 [(set (reg FLAGS_REG)
12671 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12672 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12674 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12675 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12676 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12677 && ix86_match_ccmode (insn, CCGOCmode)
12678 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12679 "sar{w}\t{%2, %0|%0, %2}"
12680 [(set_attr "type" "ishift")
12681 (set_attr "mode" "HI")])
12683 (define_insn "*ashrhi3_cconly"
12684 [(set (reg FLAGS_REG)
12686 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12687 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12689 (clobber (match_scratch:HI 0 "=r"))]
12690 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12691 && ix86_match_ccmode (insn, CCGOCmode)
12692 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12693 "sar{w}\t{%2, %0|%0, %2}"
12694 [(set_attr "type" "ishift")
12695 (set_attr "mode" "HI")])
12697 (define_expand "ashrqi3"
12698 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12699 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12700 (match_operand:QI 2 "nonmemory_operand" "")))]
12701 "TARGET_QIMODE_MATH"
12702 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12704 (define_insn "*ashrqi3_1_one_bit"
12705 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12706 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12707 (match_operand:QI 2 "const1_operand" "")))
12708 (clobber (reg:CC FLAGS_REG))]
12709 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12710 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12712 [(set_attr "type" "ishift")
12713 (set (attr "length")
12714 (if_then_else (match_operand 0 "register_operand" "")
12716 (const_string "*")))])
12718 (define_insn "*ashrqi3_1_one_bit_slp"
12719 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12720 (ashiftrt:QI (match_dup 0)
12721 (match_operand:QI 1 "const1_operand" "")))
12722 (clobber (reg:CC FLAGS_REG))]
12723 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12724 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12725 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12727 [(set_attr "type" "ishift1")
12728 (set (attr "length")
12729 (if_then_else (match_operand 0 "register_operand" "")
12731 (const_string "*")))])
12733 (define_insn "*ashrqi3_1"
12734 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12735 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12736 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12737 (clobber (reg:CC FLAGS_REG))]
12738 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12740 sar{b}\t{%2, %0|%0, %2}
12741 sar{b}\t{%b2, %0|%0, %b2}"
12742 [(set_attr "type" "ishift")
12743 (set_attr "mode" "QI")])
12745 (define_insn "*ashrqi3_1_slp"
12746 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12747 (ashiftrt:QI (match_dup 0)
12748 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12749 (clobber (reg:CC FLAGS_REG))]
12750 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12751 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12753 sar{b}\t{%1, %0|%0, %1}
12754 sar{b}\t{%b1, %0|%0, %b1}"
12755 [(set_attr "type" "ishift1")
12756 (set_attr "mode" "QI")])
12758 ;; This pattern can't accept a variable shift count, since shifts by
12759 ;; zero don't affect the flags. We assume that shifts by constant
12760 ;; zero are optimized away.
12761 (define_insn "*ashrqi3_one_bit_cmp"
12762 [(set (reg FLAGS_REG)
12764 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12765 (match_operand:QI 2 "const1_operand" "I"))
12767 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12768 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12769 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12770 && ix86_match_ccmode (insn, CCGOCmode)
12771 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12773 [(set_attr "type" "ishift")
12774 (set (attr "length")
12775 (if_then_else (match_operand 0 "register_operand" "")
12777 (const_string "*")))])
12779 (define_insn "*ashrqi3_one_bit_cconly"
12780 [(set (reg FLAGS_REG)
12782 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12783 (match_operand:QI 2 "const1_operand" ""))
12785 (clobber (match_scratch:QI 0 "=q"))]
12786 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12787 && ix86_match_ccmode (insn, CCGOCmode)
12788 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12790 [(set_attr "type" "ishift")
12791 (set_attr "length" "2")])
12793 ;; This pattern can't accept a variable shift count, since shifts by
12794 ;; zero don't affect the flags. We assume that shifts by constant
12795 ;; zero are optimized away.
12796 (define_insn "*ashrqi3_cmp"
12797 [(set (reg FLAGS_REG)
12799 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12800 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12802 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12803 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12804 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12805 && ix86_match_ccmode (insn, CCGOCmode)
12806 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12807 "sar{b}\t{%2, %0|%0, %2}"
12808 [(set_attr "type" "ishift")
12809 (set_attr "mode" "QI")])
12811 (define_insn "*ashrqi3_cconly"
12812 [(set (reg FLAGS_REG)
12814 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12815 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12817 (clobber (match_scratch:QI 0 "=q"))]
12818 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12819 && ix86_match_ccmode (insn, CCGOCmode)
12820 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12821 "sar{b}\t{%2, %0|%0, %2}"
12822 [(set_attr "type" "ishift")
12823 (set_attr "mode" "QI")])
12826 ;; Logical shift instructions
12828 ;; See comment above `ashldi3' about how this works.
12830 (define_expand "lshrti3"
12831 [(set (match_operand:TI 0 "register_operand" "")
12832 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12833 (match_operand:QI 2 "nonmemory_operand" "")))]
12835 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12837 ;; This pattern must be defined before *lshrti3_1 to prevent
12838 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12840 (define_insn "*avx_lshrti3"
12841 [(set (match_operand:TI 0 "register_operand" "=x")
12842 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12843 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12846 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12847 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12849 [(set_attr "type" "sseishft")
12850 (set_attr "prefix" "vex")
12851 (set_attr "mode" "TI")])
12853 (define_insn "sse2_lshrti3"
12854 [(set (match_operand:TI 0 "register_operand" "=x")
12855 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12856 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12859 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12860 return "psrldq\t{%2, %0|%0, %2}";
12862 [(set_attr "type" "sseishft")
12863 (set_attr "prefix_data16" "1")
12864 (set_attr "mode" "TI")])
12866 (define_insn "*lshrti3_1"
12867 [(set (match_operand:TI 0 "register_operand" "=r")
12868 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12869 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12870 (clobber (reg:CC FLAGS_REG))]
12873 [(set_attr "type" "multi")])
12876 [(match_scratch:DI 3 "r")
12877 (parallel [(set (match_operand:TI 0 "register_operand" "")
12878 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12879 (match_operand:QI 2 "nonmemory_operand" "")))
12880 (clobber (reg:CC FLAGS_REG))])
12884 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12887 [(set (match_operand:TI 0 "register_operand" "")
12888 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12889 (match_operand:QI 2 "nonmemory_operand" "")))
12890 (clobber (reg:CC FLAGS_REG))]
12891 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12892 ? epilogue_completed : reload_completed)"
12894 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12896 (define_expand "lshrdi3"
12897 [(set (match_operand:DI 0 "shiftdi_operand" "")
12898 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12899 (match_operand:QI 2 "nonmemory_operand" "")))]
12901 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12903 (define_insn "*lshrdi3_1_one_bit_rex64"
12904 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12905 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12906 (match_operand:QI 2 "const1_operand" "")))
12907 (clobber (reg:CC FLAGS_REG))]
12909 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12910 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12912 [(set_attr "type" "ishift")
12913 (set (attr "length")
12914 (if_then_else (match_operand:DI 0 "register_operand" "")
12916 (const_string "*")))])
12918 (define_insn "*lshrdi3_1_rex64"
12919 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12920 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12921 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12922 (clobber (reg:CC FLAGS_REG))]
12923 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12925 shr{q}\t{%2, %0|%0, %2}
12926 shr{q}\t{%b2, %0|%0, %b2}"
12927 [(set_attr "type" "ishift")
12928 (set_attr "mode" "DI")])
12930 ;; This pattern can't accept a variable shift count, since shifts by
12931 ;; zero don't affect the flags. We assume that shifts by constant
12932 ;; zero are optimized away.
12933 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12934 [(set (reg FLAGS_REG)
12936 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12937 (match_operand:QI 2 "const1_operand" ""))
12939 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12940 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12942 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12943 && ix86_match_ccmode (insn, CCGOCmode)
12944 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12946 [(set_attr "type" "ishift")
12947 (set (attr "length")
12948 (if_then_else (match_operand:DI 0 "register_operand" "")
12950 (const_string "*")))])
12952 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12953 [(set (reg FLAGS_REG)
12955 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12956 (match_operand:QI 2 "const1_operand" ""))
12958 (clobber (match_scratch:DI 0 "=r"))]
12960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12961 && ix86_match_ccmode (insn, CCGOCmode)
12962 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12964 [(set_attr "type" "ishift")
12965 (set_attr "length" "2")])
12967 ;; This pattern can't accept a variable shift count, since shifts by
12968 ;; zero don't affect the flags. We assume that shifts by constant
12969 ;; zero are optimized away.
12970 (define_insn "*lshrdi3_cmp_rex64"
12971 [(set (reg FLAGS_REG)
12973 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12974 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12976 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12977 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12979 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12980 && ix86_match_ccmode (insn, CCGOCmode)
12981 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12982 "shr{q}\t{%2, %0|%0, %2}"
12983 [(set_attr "type" "ishift")
12984 (set_attr "mode" "DI")])
12986 (define_insn "*lshrdi3_cconly_rex64"
12987 [(set (reg FLAGS_REG)
12989 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12990 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12992 (clobber (match_scratch:DI 0 "=r"))]
12994 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12995 && ix86_match_ccmode (insn, CCGOCmode)
12996 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12997 "shr{q}\t{%2, %0|%0, %2}"
12998 [(set_attr "type" "ishift")
12999 (set_attr "mode" "DI")])
13001 (define_insn "*lshrdi3_1"
13002 [(set (match_operand:DI 0 "register_operand" "=r")
13003 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13004 (match_operand:QI 2 "nonmemory_operand" "Jc")))
13005 (clobber (reg:CC FLAGS_REG))]
13008 [(set_attr "type" "multi")])
13010 ;; By default we don't ask for a scratch register, because when DImode
13011 ;; values are manipulated, registers are already at a premium. But if
13012 ;; we have one handy, we won't turn it away.
13014 [(match_scratch:SI 3 "r")
13015 (parallel [(set (match_operand:DI 0 "register_operand" "")
13016 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13017 (match_operand:QI 2 "nonmemory_operand" "")))
13018 (clobber (reg:CC FLAGS_REG))])
13020 "!TARGET_64BIT && TARGET_CMOVE"
13022 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13025 [(set (match_operand:DI 0 "register_operand" "")
13026 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13027 (match_operand:QI 2 "nonmemory_operand" "")))
13028 (clobber (reg:CC FLAGS_REG))]
13029 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13030 ? epilogue_completed : reload_completed)"
13032 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13034 (define_expand "lshrsi3"
13035 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13036 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13037 (match_operand:QI 2 "nonmemory_operand" "")))]
13039 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13041 (define_insn "*lshrsi3_1_one_bit"
13042 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13043 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13044 (match_operand:QI 2 "const1_operand" "")))
13045 (clobber (reg:CC FLAGS_REG))]
13046 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13047 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13049 [(set_attr "type" "ishift")
13050 (set (attr "length")
13051 (if_then_else (match_operand:SI 0 "register_operand" "")
13053 (const_string "*")))])
13055 (define_insn "*lshrsi3_1_one_bit_zext"
13056 [(set (match_operand:DI 0 "register_operand" "=r")
13057 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13058 (match_operand:QI 2 "const1_operand" "")))
13059 (clobber (reg:CC FLAGS_REG))]
13061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13062 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13064 [(set_attr "type" "ishift")
13065 (set_attr "length" "2")])
13067 (define_insn "*lshrsi3_1"
13068 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13069 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13070 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13071 (clobber (reg:CC FLAGS_REG))]
13072 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13074 shr{l}\t{%2, %0|%0, %2}
13075 shr{l}\t{%b2, %0|%0, %b2}"
13076 [(set_attr "type" "ishift")
13077 (set_attr "mode" "SI")])
13079 (define_insn "*lshrsi3_1_zext"
13080 [(set (match_operand:DI 0 "register_operand" "=r,r")
13082 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13083 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13084 (clobber (reg:CC FLAGS_REG))]
13085 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13087 shr{l}\t{%2, %k0|%k0, %2}
13088 shr{l}\t{%b2, %k0|%k0, %b2}"
13089 [(set_attr "type" "ishift")
13090 (set_attr "mode" "SI")])
13092 ;; This pattern can't accept a variable shift count, since shifts by
13093 ;; zero don't affect the flags. We assume that shifts by constant
13094 ;; zero are optimized away.
13095 (define_insn "*lshrsi3_one_bit_cmp"
13096 [(set (reg FLAGS_REG)
13098 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13099 (match_operand:QI 2 "const1_operand" ""))
13101 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13102 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13103 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13104 && ix86_match_ccmode (insn, CCGOCmode)
13105 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13107 [(set_attr "type" "ishift")
13108 (set (attr "length")
13109 (if_then_else (match_operand:SI 0 "register_operand" "")
13111 (const_string "*")))])
13113 (define_insn "*lshrsi3_one_bit_cconly"
13114 [(set (reg FLAGS_REG)
13116 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13117 (match_operand:QI 2 "const1_operand" ""))
13119 (clobber (match_scratch:SI 0 "=r"))]
13120 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13121 && ix86_match_ccmode (insn, CCGOCmode)
13122 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13124 [(set_attr "type" "ishift")
13125 (set_attr "length" "2")])
13127 (define_insn "*lshrsi3_cmp_one_bit_zext"
13128 [(set (reg FLAGS_REG)
13130 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13131 (match_operand:QI 2 "const1_operand" ""))
13133 (set (match_operand:DI 0 "register_operand" "=r")
13134 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13137 && ix86_match_ccmode (insn, CCGOCmode)
13138 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13140 [(set_attr "type" "ishift")
13141 (set_attr "length" "2")])
13143 ;; This pattern can't accept a variable shift count, since shifts by
13144 ;; zero don't affect the flags. We assume that shifts by constant
13145 ;; zero are optimized away.
13146 (define_insn "*lshrsi3_cmp"
13147 [(set (reg FLAGS_REG)
13149 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13150 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13152 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13153 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13154 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13155 && ix86_match_ccmode (insn, CCGOCmode)
13156 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13157 "shr{l}\t{%2, %0|%0, %2}"
13158 [(set_attr "type" "ishift")
13159 (set_attr "mode" "SI")])
13161 (define_insn "*lshrsi3_cconly"
13162 [(set (reg FLAGS_REG)
13164 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13165 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13167 (clobber (match_scratch:SI 0 "=r"))]
13168 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13169 && ix86_match_ccmode (insn, CCGOCmode)
13170 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13171 "shr{l}\t{%2, %0|%0, %2}"
13172 [(set_attr "type" "ishift")
13173 (set_attr "mode" "SI")])
13175 (define_insn "*lshrsi3_cmp_zext"
13176 [(set (reg FLAGS_REG)
13178 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13179 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13181 (set (match_operand:DI 0 "register_operand" "=r")
13182 (lshiftrt:DI (zero_extend:DI (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, %k0|%k0, %2}"
13188 [(set_attr "type" "ishift")
13189 (set_attr "mode" "SI")])
13191 (define_expand "lshrhi3"
13192 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13193 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13194 (match_operand:QI 2 "nonmemory_operand" "")))]
13195 "TARGET_HIMODE_MATH"
13196 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13198 (define_insn "*lshrhi3_1_one_bit"
13199 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13200 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13201 (match_operand:QI 2 "const1_operand" "")))
13202 (clobber (reg:CC FLAGS_REG))]
13203 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13204 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13206 [(set_attr "type" "ishift")
13207 (set (attr "length")
13208 (if_then_else (match_operand 0 "register_operand" "")
13210 (const_string "*")))])
13212 (define_insn "*lshrhi3_1"
13213 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13214 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13215 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13216 (clobber (reg:CC FLAGS_REG))]
13217 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13219 shr{w}\t{%2, %0|%0, %2}
13220 shr{w}\t{%b2, %0|%0, %b2}"
13221 [(set_attr "type" "ishift")
13222 (set_attr "mode" "HI")])
13224 ;; This pattern can't accept a variable shift count, since shifts by
13225 ;; zero don't affect the flags. We assume that shifts by constant
13226 ;; zero are optimized away.
13227 (define_insn "*lshrhi3_one_bit_cmp"
13228 [(set (reg FLAGS_REG)
13230 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13231 (match_operand:QI 2 "const1_operand" ""))
13233 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13234 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13235 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13236 && ix86_match_ccmode (insn, CCGOCmode)
13237 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13239 [(set_attr "type" "ishift")
13240 (set (attr "length")
13241 (if_then_else (match_operand:SI 0 "register_operand" "")
13243 (const_string "*")))])
13245 (define_insn "*lshrhi3_one_bit_cconly"
13246 [(set (reg FLAGS_REG)
13248 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13249 (match_operand:QI 2 "const1_operand" ""))
13251 (clobber (match_scratch:HI 0 "=r"))]
13252 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13253 && ix86_match_ccmode (insn, CCGOCmode)
13254 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13256 [(set_attr "type" "ishift")
13257 (set_attr "length" "2")])
13259 ;; This pattern can't accept a variable shift count, since shifts by
13260 ;; zero don't affect the flags. We assume that shifts by constant
13261 ;; zero are optimized away.
13262 (define_insn "*lshrhi3_cmp"
13263 [(set (reg FLAGS_REG)
13265 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13266 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13268 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13269 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13270 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13271 && ix86_match_ccmode (insn, CCGOCmode)
13272 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13273 "shr{w}\t{%2, %0|%0, %2}"
13274 [(set_attr "type" "ishift")
13275 (set_attr "mode" "HI")])
13277 (define_insn "*lshrhi3_cconly"
13278 [(set (reg FLAGS_REG)
13280 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13281 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13283 (clobber (match_scratch:HI 0 "=r"))]
13284 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13285 && ix86_match_ccmode (insn, CCGOCmode)
13286 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13287 "shr{w}\t{%2, %0|%0, %2}"
13288 [(set_attr "type" "ishift")
13289 (set_attr "mode" "HI")])
13291 (define_expand "lshrqi3"
13292 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13293 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13294 (match_operand:QI 2 "nonmemory_operand" "")))]
13295 "TARGET_QIMODE_MATH"
13296 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13298 (define_insn "*lshrqi3_1_one_bit"
13299 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13300 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13301 (match_operand:QI 2 "const1_operand" "")))
13302 (clobber (reg:CC FLAGS_REG))]
13303 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13304 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13306 [(set_attr "type" "ishift")
13307 (set (attr "length")
13308 (if_then_else (match_operand 0 "register_operand" "")
13310 (const_string "*")))])
13312 (define_insn "*lshrqi3_1_one_bit_slp"
13313 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13314 (lshiftrt:QI (match_dup 0)
13315 (match_operand:QI 1 "const1_operand" "")))
13316 (clobber (reg:CC FLAGS_REG))]
13317 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13318 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13320 [(set_attr "type" "ishift1")
13321 (set (attr "length")
13322 (if_then_else (match_operand 0 "register_operand" "")
13324 (const_string "*")))])
13326 (define_insn "*lshrqi3_1"
13327 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13328 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13329 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13330 (clobber (reg:CC FLAGS_REG))]
13331 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13333 shr{b}\t{%2, %0|%0, %2}
13334 shr{b}\t{%b2, %0|%0, %b2}"
13335 [(set_attr "type" "ishift")
13336 (set_attr "mode" "QI")])
13338 (define_insn "*lshrqi3_1_slp"
13339 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13340 (lshiftrt:QI (match_dup 0)
13341 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13342 (clobber (reg:CC FLAGS_REG))]
13343 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13344 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13346 shr{b}\t{%1, %0|%0, %1}
13347 shr{b}\t{%b1, %0|%0, %b1}"
13348 [(set_attr "type" "ishift1")
13349 (set_attr "mode" "QI")])
13351 ;; This pattern can't accept a variable shift count, since shifts by
13352 ;; zero don't affect the flags. We assume that shifts by constant
13353 ;; zero are optimized away.
13354 (define_insn "*lshrqi2_one_bit_cmp"
13355 [(set (reg FLAGS_REG)
13357 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13358 (match_operand:QI 2 "const1_operand" ""))
13360 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13361 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13362 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13363 && ix86_match_ccmode (insn, CCGOCmode)
13364 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13366 [(set_attr "type" "ishift")
13367 (set (attr "length")
13368 (if_then_else (match_operand:SI 0 "register_operand" "")
13370 (const_string "*")))])
13372 (define_insn "*lshrqi2_one_bit_cconly"
13373 [(set (reg FLAGS_REG)
13375 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13376 (match_operand:QI 2 "const1_operand" ""))
13378 (clobber (match_scratch:QI 0 "=q"))]
13379 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13380 && ix86_match_ccmode (insn, CCGOCmode)
13381 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13383 [(set_attr "type" "ishift")
13384 (set_attr "length" "2")])
13386 ;; This pattern can't accept a variable shift count, since shifts by
13387 ;; zero don't affect the flags. We assume that shifts by constant
13388 ;; zero are optimized away.
13389 (define_insn "*lshrqi2_cmp"
13390 [(set (reg FLAGS_REG)
13392 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13393 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13395 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13396 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13397 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13398 && ix86_match_ccmode (insn, CCGOCmode)
13399 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13400 "shr{b}\t{%2, %0|%0, %2}"
13401 [(set_attr "type" "ishift")
13402 (set_attr "mode" "QI")])
13404 (define_insn "*lshrqi2_cconly"
13405 [(set (reg FLAGS_REG)
13407 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13408 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13410 (clobber (match_scratch:QI 0 "=q"))]
13411 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13412 && ix86_match_ccmode (insn, CCGOCmode)
13413 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13414 "shr{b}\t{%2, %0|%0, %2}"
13415 [(set_attr "type" "ishift")
13416 (set_attr "mode" "QI")])
13418 ;; Rotate instructions
13420 (define_expand "rotldi3"
13421 [(set (match_operand:DI 0 "shiftdi_operand" "")
13422 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13423 (match_operand:QI 2 "nonmemory_operand" "")))]
13428 ix86_expand_binary_operator (ROTATE, DImode, operands);
13431 if (!const_1_to_31_operand (operands[2], VOIDmode))
13433 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13437 ;; Implement rotation using two double-precision shift instructions
13438 ;; and a scratch register.
13439 (define_insn_and_split "ix86_rotldi3"
13440 [(set (match_operand:DI 0 "register_operand" "=r")
13441 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13442 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13443 (clobber (reg:CC FLAGS_REG))
13444 (clobber (match_scratch:SI 3 "=&r"))]
13447 "&& reload_completed"
13448 [(set (match_dup 3) (match_dup 4))
13450 [(set (match_dup 4)
13451 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13452 (lshiftrt:SI (match_dup 5)
13453 (minus:QI (const_int 32) (match_dup 2)))))
13454 (clobber (reg:CC FLAGS_REG))])
13456 [(set (match_dup 5)
13457 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13458 (lshiftrt:SI (match_dup 3)
13459 (minus:QI (const_int 32) (match_dup 2)))))
13460 (clobber (reg:CC FLAGS_REG))])]
13461 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13463 (define_insn "*rotlsi3_1_one_bit_rex64"
13464 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13465 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13466 (match_operand:QI 2 "const1_operand" "")))
13467 (clobber (reg:CC FLAGS_REG))]
13469 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13470 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13472 [(set_attr "type" "rotate")
13473 (set (attr "length")
13474 (if_then_else (match_operand:DI 0 "register_operand" "")
13476 (const_string "*")))])
13478 (define_insn "*rotldi3_1_rex64"
13479 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13480 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13481 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13482 (clobber (reg:CC FLAGS_REG))]
13483 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13485 rol{q}\t{%2, %0|%0, %2}
13486 rol{q}\t{%b2, %0|%0, %b2}"
13487 [(set_attr "type" "rotate")
13488 (set_attr "mode" "DI")])
13490 (define_expand "rotlsi3"
13491 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13492 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13493 (match_operand:QI 2 "nonmemory_operand" "")))]
13495 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13497 (define_insn "*rotlsi3_1_one_bit"
13498 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13499 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13500 (match_operand:QI 2 "const1_operand" "")))
13501 (clobber (reg:CC FLAGS_REG))]
13502 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13503 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13505 [(set_attr "type" "rotate")
13506 (set (attr "length")
13507 (if_then_else (match_operand:SI 0 "register_operand" "")
13509 (const_string "*")))])
13511 (define_insn "*rotlsi3_1_one_bit_zext"
13512 [(set (match_operand:DI 0 "register_operand" "=r")
13514 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13515 (match_operand:QI 2 "const1_operand" ""))))
13516 (clobber (reg:CC FLAGS_REG))]
13518 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13519 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13521 [(set_attr "type" "rotate")
13522 (set_attr "length" "2")])
13524 (define_insn "*rotlsi3_1"
13525 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13526 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13527 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13528 (clobber (reg:CC FLAGS_REG))]
13529 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13531 rol{l}\t{%2, %0|%0, %2}
13532 rol{l}\t{%b2, %0|%0, %b2}"
13533 [(set_attr "type" "rotate")
13534 (set_attr "mode" "SI")])
13536 (define_insn "*rotlsi3_1_zext"
13537 [(set (match_operand:DI 0 "register_operand" "=r,r")
13539 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13540 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13541 (clobber (reg:CC FLAGS_REG))]
13542 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13544 rol{l}\t{%2, %k0|%k0, %2}
13545 rol{l}\t{%b2, %k0|%k0, %b2}"
13546 [(set_attr "type" "rotate")
13547 (set_attr "mode" "SI")])
13549 (define_expand "rotlhi3"
13550 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13551 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13552 (match_operand:QI 2 "nonmemory_operand" "")))]
13553 "TARGET_HIMODE_MATH"
13554 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13556 (define_insn "*rotlhi3_1_one_bit"
13557 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13558 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13559 (match_operand:QI 2 "const1_operand" "")))
13560 (clobber (reg:CC FLAGS_REG))]
13561 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13562 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13564 [(set_attr "type" "rotate")
13565 (set (attr "length")
13566 (if_then_else (match_operand 0 "register_operand" "")
13568 (const_string "*")))])
13570 (define_insn "*rotlhi3_1"
13571 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13572 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13573 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13574 (clobber (reg:CC FLAGS_REG))]
13575 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13577 rol{w}\t{%2, %0|%0, %2}
13578 rol{w}\t{%b2, %0|%0, %b2}"
13579 [(set_attr "type" "rotate")
13580 (set_attr "mode" "HI")])
13583 [(set (match_operand:HI 0 "register_operand" "")
13584 (rotate:HI (match_dup 0) (const_int 8)))
13585 (clobber (reg:CC FLAGS_REG))]
13587 [(parallel [(set (strict_low_part (match_dup 0))
13588 (bswap:HI (match_dup 0)))
13589 (clobber (reg:CC FLAGS_REG))])]
13592 (define_expand "rotlqi3"
13593 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13594 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13595 (match_operand:QI 2 "nonmemory_operand" "")))]
13596 "TARGET_QIMODE_MATH"
13597 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13599 (define_insn "*rotlqi3_1_one_bit_slp"
13600 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13601 (rotate:QI (match_dup 0)
13602 (match_operand:QI 1 "const1_operand" "")))
13603 (clobber (reg:CC FLAGS_REG))]
13604 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13605 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13607 [(set_attr "type" "rotate1")
13608 (set (attr "length")
13609 (if_then_else (match_operand 0 "register_operand" "")
13611 (const_string "*")))])
13613 (define_insn "*rotlqi3_1_one_bit"
13614 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13615 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13616 (match_operand:QI 2 "const1_operand" "")))
13617 (clobber (reg:CC FLAGS_REG))]
13618 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13619 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13621 [(set_attr "type" "rotate")
13622 (set (attr "length")
13623 (if_then_else (match_operand 0 "register_operand" "")
13625 (const_string "*")))])
13627 (define_insn "*rotlqi3_1_slp"
13628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13629 (rotate:QI (match_dup 0)
13630 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13631 (clobber (reg:CC FLAGS_REG))]
13632 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13633 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13635 rol{b}\t{%1, %0|%0, %1}
13636 rol{b}\t{%b1, %0|%0, %b1}"
13637 [(set_attr "type" "rotate1")
13638 (set_attr "mode" "QI")])
13640 (define_insn "*rotlqi3_1"
13641 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13642 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13643 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13644 (clobber (reg:CC FLAGS_REG))]
13645 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13647 rol{b}\t{%2, %0|%0, %2}
13648 rol{b}\t{%b2, %0|%0, %b2}"
13649 [(set_attr "type" "rotate")
13650 (set_attr "mode" "QI")])
13652 (define_expand "rotrdi3"
13653 [(set (match_operand:DI 0 "shiftdi_operand" "")
13654 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13655 (match_operand:QI 2 "nonmemory_operand" "")))]
13660 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13663 if (!const_1_to_31_operand (operands[2], VOIDmode))
13665 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13669 ;; Implement rotation using two double-precision shift instructions
13670 ;; and a scratch register.
13671 (define_insn_and_split "ix86_rotrdi3"
13672 [(set (match_operand:DI 0 "register_operand" "=r")
13673 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13674 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13675 (clobber (reg:CC FLAGS_REG))
13676 (clobber (match_scratch:SI 3 "=&r"))]
13679 "&& reload_completed"
13680 [(set (match_dup 3) (match_dup 4))
13682 [(set (match_dup 4)
13683 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13684 (ashift:SI (match_dup 5)
13685 (minus:QI (const_int 32) (match_dup 2)))))
13686 (clobber (reg:CC FLAGS_REG))])
13688 [(set (match_dup 5)
13689 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13690 (ashift:SI (match_dup 3)
13691 (minus:QI (const_int 32) (match_dup 2)))))
13692 (clobber (reg:CC FLAGS_REG))])]
13693 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13695 (define_insn "*rotrdi3_1_one_bit_rex64"
13696 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13697 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13698 (match_operand:QI 2 "const1_operand" "")))
13699 (clobber (reg:CC FLAGS_REG))]
13701 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13702 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13704 [(set_attr "type" "rotate")
13705 (set (attr "length")
13706 (if_then_else (match_operand:DI 0 "register_operand" "")
13708 (const_string "*")))])
13710 (define_insn "*rotrdi3_1_rex64"
13711 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13712 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13713 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13714 (clobber (reg:CC FLAGS_REG))]
13715 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13717 ror{q}\t{%2, %0|%0, %2}
13718 ror{q}\t{%b2, %0|%0, %b2}"
13719 [(set_attr "type" "rotate")
13720 (set_attr "mode" "DI")])
13722 (define_expand "rotrsi3"
13723 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13724 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13725 (match_operand:QI 2 "nonmemory_operand" "")))]
13727 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13729 (define_insn "*rotrsi3_1_one_bit"
13730 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13731 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13732 (match_operand:QI 2 "const1_operand" "")))
13733 (clobber (reg:CC FLAGS_REG))]
13734 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13735 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13737 [(set_attr "type" "rotate")
13738 (set (attr "length")
13739 (if_then_else (match_operand:SI 0 "register_operand" "")
13741 (const_string "*")))])
13743 (define_insn "*rotrsi3_1_one_bit_zext"
13744 [(set (match_operand:DI 0 "register_operand" "=r")
13746 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13747 (match_operand:QI 2 "const1_operand" ""))))
13748 (clobber (reg:CC FLAGS_REG))]
13750 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13751 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13753 [(set_attr "type" "rotate")
13754 (set (attr "length")
13755 (if_then_else (match_operand:SI 0 "register_operand" "")
13757 (const_string "*")))])
13759 (define_insn "*rotrsi3_1"
13760 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13761 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13762 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13763 (clobber (reg:CC FLAGS_REG))]
13764 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13766 ror{l}\t{%2, %0|%0, %2}
13767 ror{l}\t{%b2, %0|%0, %b2}"
13768 [(set_attr "type" "rotate")
13769 (set_attr "mode" "SI")])
13771 (define_insn "*rotrsi3_1_zext"
13772 [(set (match_operand:DI 0 "register_operand" "=r,r")
13774 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13775 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13776 (clobber (reg:CC FLAGS_REG))]
13777 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13779 ror{l}\t{%2, %k0|%k0, %2}
13780 ror{l}\t{%b2, %k0|%k0, %b2}"
13781 [(set_attr "type" "rotate")
13782 (set_attr "mode" "SI")])
13784 (define_expand "rotrhi3"
13785 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13786 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13787 (match_operand:QI 2 "nonmemory_operand" "")))]
13788 "TARGET_HIMODE_MATH"
13789 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13791 (define_insn "*rotrhi3_one_bit"
13792 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13793 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13794 (match_operand:QI 2 "const1_operand" "")))
13795 (clobber (reg:CC FLAGS_REG))]
13796 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13797 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13799 [(set_attr "type" "rotate")
13800 (set (attr "length")
13801 (if_then_else (match_operand 0 "register_operand" "")
13803 (const_string "*")))])
13805 (define_insn "*rotrhi3_1"
13806 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13807 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13808 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13809 (clobber (reg:CC FLAGS_REG))]
13810 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13812 ror{w}\t{%2, %0|%0, %2}
13813 ror{w}\t{%b2, %0|%0, %b2}"
13814 [(set_attr "type" "rotate")
13815 (set_attr "mode" "HI")])
13818 [(set (match_operand:HI 0 "register_operand" "")
13819 (rotatert:HI (match_dup 0) (const_int 8)))
13820 (clobber (reg:CC FLAGS_REG))]
13822 [(parallel [(set (strict_low_part (match_dup 0))
13823 (bswap:HI (match_dup 0)))
13824 (clobber (reg:CC FLAGS_REG))])]
13827 (define_expand "rotrqi3"
13828 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13829 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13830 (match_operand:QI 2 "nonmemory_operand" "")))]
13831 "TARGET_QIMODE_MATH"
13832 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13834 (define_insn "*rotrqi3_1_one_bit"
13835 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13836 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13837 (match_operand:QI 2 "const1_operand" "")))
13838 (clobber (reg:CC FLAGS_REG))]
13839 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13840 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13842 [(set_attr "type" "rotate")
13843 (set (attr "length")
13844 (if_then_else (match_operand 0 "register_operand" "")
13846 (const_string "*")))])
13848 (define_insn "*rotrqi3_1_one_bit_slp"
13849 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13850 (rotatert:QI (match_dup 0)
13851 (match_operand:QI 1 "const1_operand" "")))
13852 (clobber (reg:CC FLAGS_REG))]
13853 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13854 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13856 [(set_attr "type" "rotate1")
13857 (set (attr "length")
13858 (if_then_else (match_operand 0 "register_operand" "")
13860 (const_string "*")))])
13862 (define_insn "*rotrqi3_1"
13863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13864 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13865 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13866 (clobber (reg:CC FLAGS_REG))]
13867 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13869 ror{b}\t{%2, %0|%0, %2}
13870 ror{b}\t{%b2, %0|%0, %b2}"
13871 [(set_attr "type" "rotate")
13872 (set_attr "mode" "QI")])
13874 (define_insn "*rotrqi3_1_slp"
13875 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13876 (rotatert:QI (match_dup 0)
13877 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13878 (clobber (reg:CC FLAGS_REG))]
13879 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13882 ror{b}\t{%1, %0|%0, %1}
13883 ror{b}\t{%b1, %0|%0, %b1}"
13884 [(set_attr "type" "rotate1")
13885 (set_attr "mode" "QI")])
13887 ;; Bit set / bit test instructions
13889 (define_expand "extv"
13890 [(set (match_operand:SI 0 "register_operand" "")
13891 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13892 (match_operand:SI 2 "const8_operand" "")
13893 (match_operand:SI 3 "const8_operand" "")))]
13896 /* Handle extractions from %ah et al. */
13897 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13900 /* From mips.md: extract_bit_field doesn't verify that our source
13901 matches the predicate, so check it again here. */
13902 if (! ext_register_operand (operands[1], VOIDmode))
13906 (define_expand "extzv"
13907 [(set (match_operand:SI 0 "register_operand" "")
13908 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13909 (match_operand:SI 2 "const8_operand" "")
13910 (match_operand:SI 3 "const8_operand" "")))]
13913 /* Handle extractions from %ah et al. */
13914 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13917 /* From mips.md: extract_bit_field doesn't verify that our source
13918 matches the predicate, so check it again here. */
13919 if (! ext_register_operand (operands[1], VOIDmode))
13923 (define_expand "insv"
13924 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13925 (match_operand 1 "const8_operand" "")
13926 (match_operand 2 "const8_operand" ""))
13927 (match_operand 3 "register_operand" ""))]
13930 /* Handle insertions to %ah et al. */
13931 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13934 /* From mips.md: insert_bit_field doesn't verify that our source
13935 matches the predicate, so check it again here. */
13936 if (! ext_register_operand (operands[0], VOIDmode))
13940 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13942 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13947 ;; %%% bts, btr, btc, bt.
13948 ;; In general these instructions are *slow* when applied to memory,
13949 ;; since they enforce atomic operation. When applied to registers,
13950 ;; it depends on the cpu implementation. They're never faster than
13951 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13952 ;; no point. But in 64-bit, we can't hold the relevant immediates
13953 ;; within the instruction itself, so operating on bits in the high
13954 ;; 32-bits of a register becomes easier.
13956 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13957 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13958 ;; negdf respectively, so they can never be disabled entirely.
13960 (define_insn "*btsq"
13961 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13963 (match_operand:DI 1 "const_0_to_63_operand" ""))
13965 (clobber (reg:CC FLAGS_REG))]
13966 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13967 "bts{q}\t{%1, %0|%0, %1}"
13968 [(set_attr "type" "alu1")])
13970 (define_insn "*btrq"
13971 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13973 (match_operand:DI 1 "const_0_to_63_operand" ""))
13975 (clobber (reg:CC FLAGS_REG))]
13976 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13977 "btr{q}\t{%1, %0|%0, %1}"
13978 [(set_attr "type" "alu1")])
13980 (define_insn "*btcq"
13981 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13983 (match_operand:DI 1 "const_0_to_63_operand" ""))
13984 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13985 (clobber (reg:CC FLAGS_REG))]
13986 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13987 "btc{q}\t{%1, %0|%0, %1}"
13988 [(set_attr "type" "alu1")])
13990 ;; Allow Nocona to avoid these instructions if a register is available.
13993 [(match_scratch:DI 2 "r")
13994 (parallel [(set (zero_extract:DI
13995 (match_operand:DI 0 "register_operand" "")
13997 (match_operand:DI 1 "const_0_to_63_operand" ""))
13999 (clobber (reg:CC FLAGS_REG))])]
14000 "TARGET_64BIT && !TARGET_USE_BT"
14003 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14006 if (HOST_BITS_PER_WIDE_INT >= 64)
14007 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14008 else if (i < HOST_BITS_PER_WIDE_INT)
14009 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14011 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14013 op1 = immed_double_const (lo, hi, DImode);
14016 emit_move_insn (operands[2], op1);
14020 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14025 [(match_scratch:DI 2 "r")
14026 (parallel [(set (zero_extract:DI
14027 (match_operand:DI 0 "register_operand" "")
14029 (match_operand:DI 1 "const_0_to_63_operand" ""))
14031 (clobber (reg:CC FLAGS_REG))])]
14032 "TARGET_64BIT && !TARGET_USE_BT"
14035 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14038 if (HOST_BITS_PER_WIDE_INT >= 64)
14039 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14040 else if (i < HOST_BITS_PER_WIDE_INT)
14041 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14043 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14045 op1 = immed_double_const (~lo, ~hi, DImode);
14048 emit_move_insn (operands[2], op1);
14052 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14057 [(match_scratch:DI 2 "r")
14058 (parallel [(set (zero_extract:DI
14059 (match_operand:DI 0 "register_operand" "")
14061 (match_operand:DI 1 "const_0_to_63_operand" ""))
14062 (not:DI (zero_extract:DI
14063 (match_dup 0) (const_int 1) (match_dup 1))))
14064 (clobber (reg:CC FLAGS_REG))])]
14065 "TARGET_64BIT && !TARGET_USE_BT"
14068 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14071 if (HOST_BITS_PER_WIDE_INT >= 64)
14072 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14073 else if (i < HOST_BITS_PER_WIDE_INT)
14074 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14076 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14078 op1 = immed_double_const (lo, hi, DImode);
14081 emit_move_insn (operands[2], op1);
14085 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14089 (define_insn "*btdi_rex64"
14090 [(set (reg:CCC FLAGS_REG)
14093 (match_operand:DI 0 "register_operand" "r")
14095 (match_operand:DI 1 "nonmemory_operand" "rN"))
14097 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14098 "bt{q}\t{%1, %0|%0, %1}"
14099 [(set_attr "type" "alu1")])
14101 (define_insn "*btsi"
14102 [(set (reg:CCC FLAGS_REG)
14105 (match_operand:SI 0 "register_operand" "r")
14107 (match_operand:SI 1 "nonmemory_operand" "rN"))
14109 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14110 "bt{l}\t{%1, %0|%0, %1}"
14111 [(set_attr "type" "alu1")])
14113 ;; Store-flag instructions.
14115 ;; For all sCOND expanders, also expand the compare or test insn that
14116 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14118 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14119 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14120 ;; way, which can later delete the movzx if only QImode is needed.
14122 (define_expand "s<code>"
14123 [(set (match_operand:QI 0 "register_operand" "")
14124 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14126 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14128 (define_expand "s<code>"
14129 [(set (match_operand:QI 0 "register_operand" "")
14130 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14131 "TARGET_80387 || TARGET_SSE"
14132 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14134 (define_insn "*setcc_1"
14135 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14136 (match_operator:QI 1 "ix86_comparison_operator"
14137 [(reg FLAGS_REG) (const_int 0)]))]
14140 [(set_attr "type" "setcc")
14141 (set_attr "mode" "QI")])
14143 (define_insn "*setcc_2"
14144 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14145 (match_operator:QI 1 "ix86_comparison_operator"
14146 [(reg FLAGS_REG) (const_int 0)]))]
14149 [(set_attr "type" "setcc")
14150 (set_attr "mode" "QI")])
14152 ;; In general it is not safe to assume too much about CCmode registers,
14153 ;; so simplify-rtx stops when it sees a second one. Under certain
14154 ;; conditions this is safe on x86, so help combine not create
14161 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14162 (ne:QI (match_operator 1 "ix86_comparison_operator"
14163 [(reg FLAGS_REG) (const_int 0)])
14166 [(set (match_dup 0) (match_dup 1))]
14168 PUT_MODE (operands[1], QImode);
14172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14173 (ne:QI (match_operator 1 "ix86_comparison_operator"
14174 [(reg FLAGS_REG) (const_int 0)])
14177 [(set (match_dup 0) (match_dup 1))]
14179 PUT_MODE (operands[1], QImode);
14183 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14184 (eq:QI (match_operator 1 "ix86_comparison_operator"
14185 [(reg FLAGS_REG) (const_int 0)])
14188 [(set (match_dup 0) (match_dup 1))]
14190 rtx new_op1 = copy_rtx (operands[1]);
14191 operands[1] = new_op1;
14192 PUT_MODE (new_op1, QImode);
14193 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14194 GET_MODE (XEXP (new_op1, 0))));
14196 /* Make sure that (a) the CCmode we have for the flags is strong
14197 enough for the reversed compare or (b) we have a valid FP compare. */
14198 if (! ix86_comparison_operator (new_op1, VOIDmode))
14203 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14204 (eq:QI (match_operator 1 "ix86_comparison_operator"
14205 [(reg FLAGS_REG) (const_int 0)])
14208 [(set (match_dup 0) (match_dup 1))]
14210 rtx new_op1 = copy_rtx (operands[1]);
14211 operands[1] = new_op1;
14212 PUT_MODE (new_op1, QImode);
14213 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14214 GET_MODE (XEXP (new_op1, 0))));
14216 /* Make sure that (a) the CCmode we have for the flags is strong
14217 enough for the reversed compare or (b) we have a valid FP compare. */
14218 if (! ix86_comparison_operator (new_op1, VOIDmode))
14222 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14223 ;; subsequent logical operations are used to imitate conditional moves.
14224 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14227 (define_insn "*avx_setcc<mode>"
14228 [(set (match_operand:MODEF 0 "register_operand" "=x")
14229 (match_operator:MODEF 1 "avx_comparison_float_operator"
14230 [(match_operand:MODEF 2 "register_operand" "x")
14231 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14233 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14234 [(set_attr "type" "ssecmp")
14235 (set_attr "prefix" "vex")
14236 (set_attr "mode" "<MODE>")])
14238 (define_insn "*sse_setcc<mode>"
14239 [(set (match_operand:MODEF 0 "register_operand" "=x")
14240 (match_operator:MODEF 1 "sse_comparison_operator"
14241 [(match_operand:MODEF 2 "register_operand" "0")
14242 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14243 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14244 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14245 [(set_attr "type" "ssecmp")
14246 (set_attr "mode" "<MODE>")])
14248 (define_insn "*sse5_setcc<mode>"
14249 [(set (match_operand:MODEF 0 "register_operand" "=x")
14250 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14251 [(match_operand:MODEF 2 "register_operand" "x")
14252 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14254 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14255 [(set_attr "type" "sse4arg")
14256 (set_attr "mode" "<MODE>")])
14259 ;; Basic conditional jump instructions.
14260 ;; We ignore the overflow flag for signed branch instructions.
14262 ;; For all bCOND expanders, also expand the compare or test insn that
14263 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14265 (define_expand "b<code>"
14267 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14269 (label_ref (match_operand 0 ""))
14272 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14274 (define_expand "b<code>"
14276 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14278 (label_ref (match_operand 0 ""))
14280 "TARGET_80387 || TARGET_SSE_MATH"
14281 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14283 (define_insn "*jcc_1"
14285 (if_then_else (match_operator 1 "ix86_comparison_operator"
14286 [(reg FLAGS_REG) (const_int 0)])
14287 (label_ref (match_operand 0 "" ""))
14291 [(set_attr "type" "ibr")
14292 (set_attr "modrm" "0")
14293 (set (attr "length")
14294 (if_then_else (and (ge (minus (match_dup 0) (pc))
14296 (lt (minus (match_dup 0) (pc))
14301 (define_insn "*jcc_2"
14303 (if_then_else (match_operator 1 "ix86_comparison_operator"
14304 [(reg FLAGS_REG) (const_int 0)])
14306 (label_ref (match_operand 0 "" ""))))]
14309 [(set_attr "type" "ibr")
14310 (set_attr "modrm" "0")
14311 (set (attr "length")
14312 (if_then_else (and (ge (minus (match_dup 0) (pc))
14314 (lt (minus (match_dup 0) (pc))
14319 ;; In general it is not safe to assume too much about CCmode registers,
14320 ;; so simplify-rtx stops when it sees a second one. Under certain
14321 ;; conditions this is safe on x86, so help combine not create
14329 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14330 [(reg FLAGS_REG) (const_int 0)])
14332 (label_ref (match_operand 1 "" ""))
14336 (if_then_else (match_dup 0)
14337 (label_ref (match_dup 1))
14340 PUT_MODE (operands[0], VOIDmode);
14345 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14346 [(reg FLAGS_REG) (const_int 0)])
14348 (label_ref (match_operand 1 "" ""))
14352 (if_then_else (match_dup 0)
14353 (label_ref (match_dup 1))
14356 rtx new_op0 = copy_rtx (operands[0]);
14357 operands[0] = new_op0;
14358 PUT_MODE (new_op0, VOIDmode);
14359 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14360 GET_MODE (XEXP (new_op0, 0))));
14362 /* Make sure that (a) the CCmode we have for the flags is strong
14363 enough for the reversed compare or (b) we have a valid FP compare. */
14364 if (! ix86_comparison_operator (new_op0, VOIDmode))
14368 ;; zero_extend in SImode is correct, since this is what combine pass
14369 ;; generates from shift insn with QImode operand. Actually, the mode of
14370 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14371 ;; appropriate modulo of the bit offset value.
14373 (define_insn_and_split "*jcc_btdi_rex64"
14375 (if_then_else (match_operator 0 "bt_comparison_operator"
14377 (match_operand:DI 1 "register_operand" "r")
14380 (match_operand:QI 2 "register_operand" "r")))
14382 (label_ref (match_operand 3 "" ""))
14384 (clobber (reg:CC FLAGS_REG))]
14385 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14388 [(set (reg:CCC FLAGS_REG)
14396 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14397 (label_ref (match_dup 3))
14400 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14402 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14405 ;; avoid useless masking of bit offset operand
14406 (define_insn_and_split "*jcc_btdi_mask_rex64"
14408 (if_then_else (match_operator 0 "bt_comparison_operator"
14410 (match_operand:DI 1 "register_operand" "r")
14413 (match_operand:SI 2 "register_operand" "r")
14414 (match_operand:SI 3 "const_int_operand" "n")))])
14415 (label_ref (match_operand 4 "" ""))
14417 (clobber (reg:CC FLAGS_REG))]
14418 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14419 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14422 [(set (reg:CCC FLAGS_REG)
14430 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14431 (label_ref (match_dup 4))
14434 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14436 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14439 (define_insn_and_split "*jcc_btsi"
14441 (if_then_else (match_operator 0 "bt_comparison_operator"
14443 (match_operand:SI 1 "register_operand" "r")
14446 (match_operand:QI 2 "register_operand" "r")))
14448 (label_ref (match_operand 3 "" ""))
14450 (clobber (reg:CC FLAGS_REG))]
14451 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14454 [(set (reg:CCC FLAGS_REG)
14462 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14463 (label_ref (match_dup 3))
14466 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14468 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14471 ;; avoid useless masking of bit offset operand
14472 (define_insn_and_split "*jcc_btsi_mask"
14474 (if_then_else (match_operator 0 "bt_comparison_operator"
14476 (match_operand:SI 1 "register_operand" "r")
14479 (match_operand:SI 2 "register_operand" "r")
14480 (match_operand:SI 3 "const_int_operand" "n")))])
14481 (label_ref (match_operand 4 "" ""))
14483 (clobber (reg:CC FLAGS_REG))]
14484 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14485 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14488 [(set (reg:CCC FLAGS_REG)
14496 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14497 (label_ref (match_dup 4))
14499 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14501 (define_insn_and_split "*jcc_btsi_1"
14503 (if_then_else (match_operator 0 "bt_comparison_operator"
14506 (match_operand:SI 1 "register_operand" "r")
14507 (match_operand:QI 2 "register_operand" "r"))
14510 (label_ref (match_operand 3 "" ""))
14512 (clobber (reg:CC FLAGS_REG))]
14513 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14516 [(set (reg:CCC FLAGS_REG)
14524 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14525 (label_ref (match_dup 3))
14528 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14530 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14533 ;; avoid useless masking of bit offset operand
14534 (define_insn_and_split "*jcc_btsi_mask_1"
14537 (match_operator 0 "bt_comparison_operator"
14540 (match_operand:SI 1 "register_operand" "r")
14543 (match_operand:SI 2 "register_operand" "r")
14544 (match_operand:SI 3 "const_int_operand" "n")) 0))
14547 (label_ref (match_operand 4 "" ""))
14549 (clobber (reg:CC FLAGS_REG))]
14550 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14551 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14554 [(set (reg:CCC FLAGS_REG)
14562 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14563 (label_ref (match_dup 4))
14565 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14567 ;; Define combination compare-and-branch fp compare instructions to use
14568 ;; during early optimization. Splitting the operation apart early makes
14569 ;; for bad code when we want to reverse the operation.
14571 (define_insn "*fp_jcc_1_mixed"
14573 (if_then_else (match_operator 0 "comparison_operator"
14574 [(match_operand 1 "register_operand" "f,x")
14575 (match_operand 2 "nonimmediate_operand" "f,xm")])
14576 (label_ref (match_operand 3 "" ""))
14578 (clobber (reg:CCFP FPSR_REG))
14579 (clobber (reg:CCFP FLAGS_REG))]
14580 "TARGET_MIX_SSE_I387
14581 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14582 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14583 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14586 (define_insn "*fp_jcc_1_sse"
14588 (if_then_else (match_operator 0 "comparison_operator"
14589 [(match_operand 1 "register_operand" "x")
14590 (match_operand 2 "nonimmediate_operand" "xm")])
14591 (label_ref (match_operand 3 "" ""))
14593 (clobber (reg:CCFP FPSR_REG))
14594 (clobber (reg:CCFP FLAGS_REG))]
14596 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14597 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14598 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14601 (define_insn "*fp_jcc_1_387"
14603 (if_then_else (match_operator 0 "comparison_operator"
14604 [(match_operand 1 "register_operand" "f")
14605 (match_operand 2 "register_operand" "f")])
14606 (label_ref (match_operand 3 "" ""))
14608 (clobber (reg:CCFP FPSR_REG))
14609 (clobber (reg:CCFP FLAGS_REG))]
14610 "X87_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_2_mixed"
14618 (if_then_else (match_operator 0 "comparison_operator"
14619 [(match_operand 1 "register_operand" "f,x")
14620 (match_operand 2 "nonimmediate_operand" "f,xm")])
14622 (label_ref (match_operand 3 "" ""))))
14623 (clobber (reg:CCFP FPSR_REG))
14624 (clobber (reg:CCFP FLAGS_REG))]
14625 "TARGET_MIX_SSE_I387
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_2_sse"
14633 (if_then_else (match_operator 0 "comparison_operator"
14634 [(match_operand 1 "register_operand" "x")
14635 (match_operand 2 "nonimmediate_operand" "xm")])
14637 (label_ref (match_operand 3 "" ""))))
14638 (clobber (reg:CCFP FPSR_REG))
14639 (clobber (reg:CCFP FLAGS_REG))]
14641 && SSE_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_387"
14648 (if_then_else (match_operator 0 "comparison_operator"
14649 [(match_operand 1 "register_operand" "f")
14650 (match_operand 2 "register_operand" "f")])
14652 (label_ref (match_operand 3 "" ""))))
14653 (clobber (reg:CCFP FPSR_REG))
14654 (clobber (reg:CCFP FLAGS_REG))]
14655 "X87_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_3_387"
14663 (if_then_else (match_operator 0 "comparison_operator"
14664 [(match_operand 1 "register_operand" "f")
14665 (match_operand 2 "nonimmediate_operand" "fm")])
14666 (label_ref (match_operand 3 "" ""))
14668 (clobber (reg:CCFP FPSR_REG))
14669 (clobber (reg:CCFP FLAGS_REG))
14670 (clobber (match_scratch:HI 4 "=a"))]
14672 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14673 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14674 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14675 && SELECT_CC_MODE (GET_CODE (operands[0]),
14676 operands[1], operands[2]) == CCFPmode
14677 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14680 (define_insn "*fp_jcc_4_387"
14682 (if_then_else (match_operator 0 "comparison_operator"
14683 [(match_operand 1 "register_operand" "f")
14684 (match_operand 2 "nonimmediate_operand" "fm")])
14686 (label_ref (match_operand 3 "" ""))))
14687 (clobber (reg:CCFP FPSR_REG))
14688 (clobber (reg:CCFP FLAGS_REG))
14689 (clobber (match_scratch:HI 4 "=a"))]
14691 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14692 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14693 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14694 && SELECT_CC_MODE (GET_CODE (operands[0]),
14695 operands[1], operands[2]) == CCFPmode
14696 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14699 (define_insn "*fp_jcc_5_387"
14701 (if_then_else (match_operator 0 "comparison_operator"
14702 [(match_operand 1 "register_operand" "f")
14703 (match_operand 2 "register_operand" "f")])
14704 (label_ref (match_operand 3 "" ""))
14706 (clobber (reg:CCFP FPSR_REG))
14707 (clobber (reg:CCFP FLAGS_REG))
14708 (clobber (match_scratch:HI 4 "=a"))]
14709 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14710 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14711 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14714 (define_insn "*fp_jcc_6_387"
14716 (if_then_else (match_operator 0 "comparison_operator"
14717 [(match_operand 1 "register_operand" "f")
14718 (match_operand 2 "register_operand" "f")])
14720 (label_ref (match_operand 3 "" ""))))
14721 (clobber (reg:CCFP FPSR_REG))
14722 (clobber (reg:CCFP FLAGS_REG))
14723 (clobber (match_scratch:HI 4 "=a"))]
14724 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14725 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14726 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14729 (define_insn "*fp_jcc_7_387"
14731 (if_then_else (match_operator 0 "comparison_operator"
14732 [(match_operand 1 "register_operand" "f")
14733 (match_operand 2 "const0_operand" "")])
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_use_fcomi_compare (GET_CODE (operands[0]))
14742 && SELECT_CC_MODE (GET_CODE (operands[0]),
14743 operands[1], operands[2]) == CCFPmode
14744 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14747 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14748 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14749 ;; with a precedence over other operators and is always put in the first
14750 ;; place. Swap condition and operands to match ficom instruction.
14752 (define_insn "*fp_jcc_8<mode>_387"
14754 (if_then_else (match_operator 0 "comparison_operator"
14755 [(match_operator 1 "float_operator"
14756 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14757 (match_operand 3 "register_operand" "f,f")])
14758 (label_ref (match_operand 4 "" ""))
14760 (clobber (reg:CCFP FPSR_REG))
14761 (clobber (reg:CCFP FLAGS_REG))
14762 (clobber (match_scratch:HI 5 "=a,a"))]
14763 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14764 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14765 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14766 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14767 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14768 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14773 (if_then_else (match_operator 0 "comparison_operator"
14774 [(match_operand 1 "register_operand" "")
14775 (match_operand 2 "nonimmediate_operand" "")])
14776 (match_operand 3 "" "")
14777 (match_operand 4 "" "")))
14778 (clobber (reg:CCFP FPSR_REG))
14779 (clobber (reg:CCFP FLAGS_REG))]
14783 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14784 operands[3], operands[4], NULL_RTX, NULL_RTX);
14790 (if_then_else (match_operator 0 "comparison_operator"
14791 [(match_operand 1 "register_operand" "")
14792 (match_operand 2 "general_operand" "")])
14793 (match_operand 3 "" "")
14794 (match_operand 4 "" "")))
14795 (clobber (reg:CCFP FPSR_REG))
14796 (clobber (reg:CCFP FLAGS_REG))
14797 (clobber (match_scratch:HI 5 "=a"))]
14801 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14802 operands[3], operands[4], operands[5], NULL_RTX);
14808 (if_then_else (match_operator 0 "comparison_operator"
14809 [(match_operator 1 "float_operator"
14810 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14811 (match_operand 3 "register_operand" "")])
14812 (match_operand 4 "" "")
14813 (match_operand 5 "" "")))
14814 (clobber (reg:CCFP FPSR_REG))
14815 (clobber (reg:CCFP FLAGS_REG))
14816 (clobber (match_scratch:HI 6 "=a"))]
14820 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14821 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14822 operands[3], operands[7],
14823 operands[4], operands[5], operands[6], NULL_RTX);
14827 ;; %%% Kill this when reload knows how to do it.
14830 (if_then_else (match_operator 0 "comparison_operator"
14831 [(match_operator 1 "float_operator"
14832 [(match_operand:X87MODEI12 2 "register_operand" "")])
14833 (match_operand 3 "register_operand" "")])
14834 (match_operand 4 "" "")
14835 (match_operand 5 "" "")))
14836 (clobber (reg:CCFP FPSR_REG))
14837 (clobber (reg:CCFP FLAGS_REG))
14838 (clobber (match_scratch:HI 6 "=a"))]
14842 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14843 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14844 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14845 operands[3], operands[7],
14846 operands[4], operands[5], operands[6], operands[2]);
14850 ;; Unconditional and other jump instructions
14852 (define_insn "jump"
14854 (label_ref (match_operand 0 "" "")))]
14857 [(set_attr "type" "ibr")
14858 (set (attr "length")
14859 (if_then_else (and (ge (minus (match_dup 0) (pc))
14861 (lt (minus (match_dup 0) (pc))
14865 (set_attr "modrm" "0")])
14867 (define_expand "indirect_jump"
14868 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14872 (define_insn "*indirect_jump"
14873 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14876 [(set_attr "type" "ibr")
14877 (set_attr "length_immediate" "0")])
14879 (define_expand "tablejump"
14880 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14881 (use (label_ref (match_operand 1 "" "")))])]
14884 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14885 relative. Convert the relative address to an absolute address. */
14889 enum rtx_code code;
14891 /* We can't use @GOTOFF for text labels on VxWorks;
14892 see gotoff_operand. */
14893 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14897 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14899 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14903 op1 = pic_offset_table_rtx;
14908 op0 = pic_offset_table_rtx;
14912 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14917 (define_insn "*tablejump_1"
14918 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14919 (use (label_ref (match_operand 1 "" "")))]
14922 [(set_attr "type" "ibr")
14923 (set_attr "length_immediate" "0")])
14925 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14928 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14929 (set (match_operand:QI 1 "register_operand" "")
14930 (match_operator:QI 2 "ix86_comparison_operator"
14931 [(reg FLAGS_REG) (const_int 0)]))
14932 (set (match_operand 3 "q_regs_operand" "")
14933 (zero_extend (match_dup 1)))]
14934 "(peep2_reg_dead_p (3, operands[1])
14935 || operands_match_p (operands[1], operands[3]))
14936 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14937 [(set (match_dup 4) (match_dup 0))
14938 (set (strict_low_part (match_dup 5))
14941 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14942 operands[5] = gen_lowpart (QImode, operands[3]);
14943 ix86_expand_clear (operands[3]);
14946 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14949 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14950 (set (match_operand:QI 1 "register_operand" "")
14951 (match_operator:QI 2 "ix86_comparison_operator"
14952 [(reg FLAGS_REG) (const_int 0)]))
14953 (parallel [(set (match_operand 3 "q_regs_operand" "")
14954 (zero_extend (match_dup 1)))
14955 (clobber (reg:CC FLAGS_REG))])]
14956 "(peep2_reg_dead_p (3, operands[1])
14957 || operands_match_p (operands[1], operands[3]))
14958 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14959 [(set (match_dup 4) (match_dup 0))
14960 (set (strict_low_part (match_dup 5))
14963 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14964 operands[5] = gen_lowpart (QImode, operands[3]);
14965 ix86_expand_clear (operands[3]);
14968 ;; Call instructions.
14970 ;; The predicates normally associated with named expanders are not properly
14971 ;; checked for calls. This is a bug in the generic code, but it isn't that
14972 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14974 ;; Call subroutine returning no value.
14976 (define_expand "call_pop"
14977 [(parallel [(call (match_operand:QI 0 "" "")
14978 (match_operand:SI 1 "" ""))
14979 (set (reg:SI SP_REG)
14980 (plus:SI (reg:SI SP_REG)
14981 (match_operand:SI 3 "" "")))])]
14984 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14988 (define_insn "*call_pop_0"
14989 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14990 (match_operand:SI 1 "" ""))
14991 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14992 (match_operand:SI 2 "immediate_operand" "")))]
14995 if (SIBLING_CALL_P (insn))
14998 return "call\t%P0";
15000 [(set_attr "type" "call")])
15002 (define_insn "*call_pop_1"
15003 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15004 (match_operand:SI 1 "" ""))
15005 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15006 (match_operand:SI 2 "immediate_operand" "i")))]
15009 if (constant_call_address_operand (operands[0], Pmode))
15011 if (SIBLING_CALL_P (insn))
15014 return "call\t%P0";
15016 if (SIBLING_CALL_P (insn))
15019 return "call\t%A0";
15021 [(set_attr "type" "call")])
15023 (define_expand "call"
15024 [(call (match_operand:QI 0 "" "")
15025 (match_operand 1 "" ""))
15026 (use (match_operand 2 "" ""))]
15029 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15033 (define_expand "sibcall"
15034 [(call (match_operand:QI 0 "" "")
15035 (match_operand 1 "" ""))
15036 (use (match_operand 2 "" ""))]
15039 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15043 (define_insn "*call_0"
15044 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15045 (match_operand 1 "" ""))]
15048 if (SIBLING_CALL_P (insn))
15051 return "call\t%P0";
15053 [(set_attr "type" "call")])
15055 (define_insn "*call_1"
15056 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15057 (match_operand 1 "" ""))]
15058 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15060 if (constant_call_address_operand (operands[0], Pmode))
15061 return "call\t%P0";
15062 return "call\t%A0";
15064 [(set_attr "type" "call")])
15066 (define_insn "*sibcall_1"
15067 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15068 (match_operand 1 "" ""))]
15069 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15071 if (constant_call_address_operand (operands[0], Pmode))
15075 [(set_attr "type" "call")])
15077 (define_insn "*call_1_rex64"
15078 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15079 (match_operand 1 "" ""))]
15080 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15081 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15083 if (constant_call_address_operand (operands[0], Pmode))
15084 return "call\t%P0";
15085 return "call\t%A0";
15087 [(set_attr "type" "call")])
15089 (define_insn "*call_1_rex64_ms_sysv"
15090 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15091 (match_operand 1 "" ""))
15092 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15093 (clobber (reg:TI XMM6_REG))
15094 (clobber (reg:TI XMM7_REG))
15095 (clobber (reg:TI XMM8_REG))
15096 (clobber (reg:TI XMM9_REG))
15097 (clobber (reg:TI XMM10_REG))
15098 (clobber (reg:TI XMM11_REG))
15099 (clobber (reg:TI XMM12_REG))
15100 (clobber (reg:TI XMM13_REG))
15101 (clobber (reg:TI XMM14_REG))
15102 (clobber (reg:TI XMM15_REG))
15103 (clobber (reg:DI SI_REG))
15104 (clobber (reg:DI DI_REG))]
15105 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15107 if (constant_call_address_operand (operands[0], Pmode))
15108 return "call\t%P0";
15109 return "call\t%A0";
15111 [(set_attr "type" "call")])
15113 (define_insn "*call_1_rex64_large"
15114 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15115 (match_operand 1 "" ""))]
15116 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15118 [(set_attr "type" "call")])
15120 (define_insn "*sibcall_1_rex64"
15121 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15122 (match_operand 1 "" ""))]
15123 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15125 [(set_attr "type" "call")])
15127 (define_insn "*sibcall_1_rex64_v"
15128 [(call (mem:QI (reg:DI R11_REG))
15129 (match_operand 0 "" ""))]
15130 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15132 [(set_attr "type" "call")])
15135 ;; Call subroutine, returning value in operand 0
15137 (define_expand "call_value_pop"
15138 [(parallel [(set (match_operand 0 "" "")
15139 (call (match_operand:QI 1 "" "")
15140 (match_operand:SI 2 "" "")))
15141 (set (reg:SI SP_REG)
15142 (plus:SI (reg:SI SP_REG)
15143 (match_operand:SI 4 "" "")))])]
15146 ix86_expand_call (operands[0], operands[1], operands[2],
15147 operands[3], operands[4], 0);
15151 (define_expand "call_value"
15152 [(set (match_operand 0 "" "")
15153 (call (match_operand:QI 1 "" "")
15154 (match_operand:SI 2 "" "")))
15155 (use (match_operand:SI 3 "" ""))]
15156 ;; Operand 2 not used on the i386.
15159 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15163 (define_expand "sibcall_value"
15164 [(set (match_operand 0 "" "")
15165 (call (match_operand:QI 1 "" "")
15166 (match_operand:SI 2 "" "")))
15167 (use (match_operand:SI 3 "" ""))]
15168 ;; Operand 2 not used on the i386.
15171 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15175 ;; Call subroutine returning any type.
15177 (define_expand "untyped_call"
15178 [(parallel [(call (match_operand 0 "" "")
15180 (match_operand 1 "" "")
15181 (match_operand 2 "" "")])]
15186 /* In order to give reg-stack an easier job in validating two
15187 coprocessor registers as containing a possible return value,
15188 simply pretend the untyped call returns a complex long double
15191 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15192 and should have the default ABI. */
15194 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15195 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15196 operands[0], const0_rtx,
15197 GEN_INT ((TARGET_64BIT
15198 ? (ix86_abi == SYSV_ABI
15199 ? X86_64_SSE_REGPARM_MAX
15200 : X64_SSE_REGPARM_MAX)
15201 : X86_32_SSE_REGPARM_MAX)
15205 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15207 rtx set = XVECEXP (operands[2], 0, i);
15208 emit_move_insn (SET_DEST (set), SET_SRC (set));
15211 /* The optimizer does not know that the call sets the function value
15212 registers we stored in the result block. We avoid problems by
15213 claiming that all hard registers are used and clobbered at this
15215 emit_insn (gen_blockage ());
15220 ;; Prologue and epilogue instructions
15222 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15223 ;; all of memory. This blocks insns from being moved across this point.
15225 (define_insn "blockage"
15226 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15229 [(set_attr "length" "0")])
15231 ;; Do not schedule instructions accessing memory across this point.
15233 (define_expand "memory_blockage"
15234 [(set (match_dup 0)
15235 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15238 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15239 MEM_VOLATILE_P (operands[0]) = 1;
15242 (define_insn "*memory_blockage"
15243 [(set (match_operand:BLK 0 "" "")
15244 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15247 [(set_attr "length" "0")])
15249 ;; As USE insns aren't meaningful after reload, this is used instead
15250 ;; to prevent deleting instructions setting registers for PIC code
15251 (define_insn "prologue_use"
15252 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15255 [(set_attr "length" "0")])
15257 ;; Insn emitted into the body of a function to return from a function.
15258 ;; This is only done if the function's epilogue is known to be simple.
15259 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15261 (define_expand "return"
15263 "ix86_can_use_return_insn_p ()"
15265 if (crtl->args.pops_args)
15267 rtx popc = GEN_INT (crtl->args.pops_args);
15268 emit_jump_insn (gen_return_pop_internal (popc));
15273 (define_insn "return_internal"
15277 [(set_attr "length" "1")
15278 (set_attr "length_immediate" "0")
15279 (set_attr "modrm" "0")])
15281 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15282 ;; instruction Athlon and K8 have.
15284 (define_insn "return_internal_long"
15286 (unspec [(const_int 0)] UNSPEC_REP)]
15289 [(set_attr "length" "1")
15290 (set_attr "length_immediate" "0")
15291 (set_attr "prefix_rep" "1")
15292 (set_attr "modrm" "0")])
15294 (define_insn "return_pop_internal"
15296 (use (match_operand:SI 0 "const_int_operand" ""))]
15299 [(set_attr "length" "3")
15300 (set_attr "length_immediate" "2")
15301 (set_attr "modrm" "0")])
15303 (define_insn "return_indirect_internal"
15305 (use (match_operand:SI 0 "register_operand" "r"))]
15308 [(set_attr "type" "ibr")
15309 (set_attr "length_immediate" "0")])
15315 [(set_attr "length" "1")
15316 (set_attr "length_immediate" "0")
15317 (set_attr "modrm" "0")])
15319 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15320 ;; branch prediction penalty for the third jump in a 16-byte
15323 (define_insn "align"
15324 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15327 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15328 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15330 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15331 The align insn is used to avoid 3 jump instructions in the row to improve
15332 branch prediction and the benefits hardly outweigh the cost of extra 8
15333 nops on the average inserted by full alignment pseudo operation. */
15337 [(set_attr "length" "16")])
15339 (define_expand "prologue"
15342 "ix86_expand_prologue (); DONE;")
15344 (define_insn "set_got"
15345 [(set (match_operand:SI 0 "register_operand" "=r")
15346 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15347 (clobber (reg:CC FLAGS_REG))]
15349 { return output_set_got (operands[0], NULL_RTX); }
15350 [(set_attr "type" "multi")
15351 (set_attr "length" "12")])
15353 (define_insn "set_got_labelled"
15354 [(set (match_operand:SI 0 "register_operand" "=r")
15355 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15357 (clobber (reg:CC FLAGS_REG))]
15359 { return output_set_got (operands[0], operands[1]); }
15360 [(set_attr "type" "multi")
15361 (set_attr "length" "12")])
15363 (define_insn "set_got_rex64"
15364 [(set (match_operand:DI 0 "register_operand" "=r")
15365 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15367 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15368 [(set_attr "type" "lea")
15369 (set_attr "length" "6")])
15371 (define_insn "set_rip_rex64"
15372 [(set (match_operand:DI 0 "register_operand" "=r")
15373 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15375 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15376 [(set_attr "type" "lea")
15377 (set_attr "length" "6")])
15379 (define_insn "set_got_offset_rex64"
15380 [(set (match_operand:DI 0 "register_operand" "=r")
15382 [(label_ref (match_operand 1 "" ""))]
15383 UNSPEC_SET_GOT_OFFSET))]
15385 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15386 [(set_attr "type" "imov")
15387 (set_attr "length" "11")])
15389 (define_expand "epilogue"
15392 "ix86_expand_epilogue (1); DONE;")
15394 (define_expand "sibcall_epilogue"
15397 "ix86_expand_epilogue (0); DONE;")
15399 (define_expand "eh_return"
15400 [(use (match_operand 0 "register_operand" ""))]
15403 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15405 /* Tricky bit: we write the address of the handler to which we will
15406 be returning into someone else's stack frame, one word below the
15407 stack address we wish to restore. */
15408 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15409 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15410 tmp = gen_rtx_MEM (Pmode, tmp);
15411 emit_move_insn (tmp, ra);
15413 if (Pmode == SImode)
15414 emit_jump_insn (gen_eh_return_si (sa));
15416 emit_jump_insn (gen_eh_return_di (sa));
15421 (define_insn_and_split "eh_return_<mode>"
15423 (unspec [(match_operand:P 0 "register_operand" "c")]
15424 UNSPEC_EH_RETURN))]
15429 "ix86_expand_epilogue (2); DONE;")
15431 (define_insn "leave"
15432 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15433 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15434 (clobber (mem:BLK (scratch)))]
15437 [(set_attr "type" "leave")])
15439 (define_insn "leave_rex64"
15440 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15441 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15442 (clobber (mem:BLK (scratch)))]
15445 [(set_attr "type" "leave")])
15447 (define_expand "ffssi2"
15449 [(set (match_operand:SI 0 "register_operand" "")
15450 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15451 (clobber (match_scratch:SI 2 ""))
15452 (clobber (reg:CC FLAGS_REG))])]
15457 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15462 (define_expand "ffs_cmove"
15463 [(set (match_dup 2) (const_int -1))
15464 (parallel [(set (reg:CCZ FLAGS_REG)
15465 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15467 (set (match_operand:SI 0 "register_operand" "")
15468 (ctz:SI (match_dup 1)))])
15469 (set (match_dup 0) (if_then_else:SI
15470 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15473 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15474 (clobber (reg:CC FLAGS_REG))])]
15476 "operands[2] = gen_reg_rtx (SImode);")
15478 (define_insn_and_split "*ffs_no_cmove"
15479 [(set (match_operand:SI 0 "register_operand" "=r")
15480 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15481 (clobber (match_scratch:SI 2 "=&q"))
15482 (clobber (reg:CC FLAGS_REG))]
15485 "&& reload_completed"
15486 [(parallel [(set (reg:CCZ FLAGS_REG)
15487 (compare:CCZ (match_dup 1) (const_int 0)))
15488 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15489 (set (strict_low_part (match_dup 3))
15490 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15491 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15492 (clobber (reg:CC FLAGS_REG))])
15493 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15494 (clobber (reg:CC FLAGS_REG))])
15495 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15496 (clobber (reg:CC FLAGS_REG))])]
15498 operands[3] = gen_lowpart (QImode, operands[2]);
15499 ix86_expand_clear (operands[2]);
15502 (define_insn "*ffssi_1"
15503 [(set (reg:CCZ FLAGS_REG)
15504 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15506 (set (match_operand:SI 0 "register_operand" "=r")
15507 (ctz:SI (match_dup 1)))]
15509 "bsf{l}\t{%1, %0|%0, %1}"
15510 [(set_attr "prefix_0f" "1")])
15512 (define_expand "ffsdi2"
15513 [(set (match_dup 2) (const_int -1))
15514 (parallel [(set (reg:CCZ FLAGS_REG)
15515 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15517 (set (match_operand:DI 0 "register_operand" "")
15518 (ctz:DI (match_dup 1)))])
15519 (set (match_dup 0) (if_then_else:DI
15520 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15523 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15524 (clobber (reg:CC FLAGS_REG))])]
15526 "operands[2] = gen_reg_rtx (DImode);")
15528 (define_insn "*ffsdi_1"
15529 [(set (reg:CCZ FLAGS_REG)
15530 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15532 (set (match_operand:DI 0 "register_operand" "=r")
15533 (ctz:DI (match_dup 1)))]
15535 "bsf{q}\t{%1, %0|%0, %1}"
15536 [(set_attr "prefix_0f" "1")])
15538 (define_insn "ctzsi2"
15539 [(set (match_operand:SI 0 "register_operand" "=r")
15540 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15541 (clobber (reg:CC FLAGS_REG))]
15543 "bsf{l}\t{%1, %0|%0, %1}"
15544 [(set_attr "prefix_0f" "1")])
15546 (define_insn "ctzdi2"
15547 [(set (match_operand:DI 0 "register_operand" "=r")
15548 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15549 (clobber (reg:CC FLAGS_REG))]
15551 "bsf{q}\t{%1, %0|%0, %1}"
15552 [(set_attr "prefix_0f" "1")])
15554 (define_expand "clzsi2"
15556 [(set (match_operand:SI 0 "register_operand" "")
15557 (minus:SI (const_int 31)
15558 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15559 (clobber (reg:CC FLAGS_REG))])
15561 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15562 (clobber (reg:CC FLAGS_REG))])]
15567 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15572 (define_insn "clzsi2_abm"
15573 [(set (match_operand:SI 0 "register_operand" "=r")
15574 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15575 (clobber (reg:CC FLAGS_REG))]
15577 "lzcnt{l}\t{%1, %0|%0, %1}"
15578 [(set_attr "prefix_rep" "1")
15579 (set_attr "type" "bitmanip")
15580 (set_attr "mode" "SI")])
15582 (define_insn "*bsr"
15583 [(set (match_operand:SI 0 "register_operand" "=r")
15584 (minus:SI (const_int 31)
15585 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15586 (clobber (reg:CC FLAGS_REG))]
15588 "bsr{l}\t{%1, %0|%0, %1}"
15589 [(set_attr "prefix_0f" "1")
15590 (set_attr "mode" "SI")])
15592 (define_insn "popcount<mode>2"
15593 [(set (match_operand:SWI248 0 "register_operand" "=r")
15595 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15596 (clobber (reg:CC FLAGS_REG))]
15600 return "popcnt\t{%1, %0|%0, %1}";
15602 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15605 [(set_attr "prefix_rep" "1")
15606 (set_attr "type" "bitmanip")
15607 (set_attr "mode" "<MODE>")])
15609 (define_insn "*popcount<mode>2_cmp"
15610 [(set (reg FLAGS_REG)
15613 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15615 (set (match_operand:SWI248 0 "register_operand" "=r")
15616 (popcount:SWI248 (match_dup 1)))]
15617 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15620 return "popcnt\t{%1, %0|%0, %1}";
15622 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15625 [(set_attr "prefix_rep" "1")
15626 (set_attr "type" "bitmanip")
15627 (set_attr "mode" "<MODE>")])
15629 (define_insn "*popcountsi2_cmp_zext"
15630 [(set (reg FLAGS_REG)
15632 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15634 (set (match_operand:DI 0 "register_operand" "=r")
15635 (zero_extend:DI(popcount:SI (match_dup 1))))]
15636 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15639 return "popcnt\t{%1, %0|%0, %1}";
15641 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15644 [(set_attr "prefix_rep" "1")
15645 (set_attr "type" "bitmanip")
15646 (set_attr "mode" "SI")])
15648 (define_expand "bswapsi2"
15649 [(set (match_operand:SI 0 "register_operand" "")
15650 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15655 rtx x = operands[0];
15657 emit_move_insn (x, operands[1]);
15658 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15659 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15660 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15665 (define_insn "*bswapsi_1"
15666 [(set (match_operand:SI 0 "register_operand" "=r")
15667 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15670 [(set_attr "prefix_0f" "1")
15671 (set_attr "length" "2")])
15673 (define_insn "*bswaphi_lowpart_1"
15674 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15675 (bswap:HI (match_dup 0)))
15676 (clobber (reg:CC FLAGS_REG))]
15677 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15679 xchg{b}\t{%h0, %b0|%b0, %h0}
15680 rol{w}\t{$8, %0|%0, 8}"
15681 [(set_attr "length" "2,4")
15682 (set_attr "mode" "QI,HI")])
15684 (define_insn "bswaphi_lowpart"
15685 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15686 (bswap:HI (match_dup 0)))
15687 (clobber (reg:CC FLAGS_REG))]
15689 "rol{w}\t{$8, %0|%0, 8}"
15690 [(set_attr "length" "4")
15691 (set_attr "mode" "HI")])
15693 (define_insn "bswapdi2"
15694 [(set (match_operand:DI 0 "register_operand" "=r")
15695 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15698 [(set_attr "prefix_0f" "1")
15699 (set_attr "length" "3")])
15701 (define_expand "clzdi2"
15703 [(set (match_operand:DI 0 "register_operand" "")
15704 (minus:DI (const_int 63)
15705 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15706 (clobber (reg:CC FLAGS_REG))])
15708 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15709 (clobber (reg:CC FLAGS_REG))])]
15714 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15719 (define_insn "clzdi2_abm"
15720 [(set (match_operand:DI 0 "register_operand" "=r")
15721 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15722 (clobber (reg:CC FLAGS_REG))]
15723 "TARGET_64BIT && TARGET_ABM"
15724 "lzcnt{q}\t{%1, %0|%0, %1}"
15725 [(set_attr "prefix_rep" "1")
15726 (set_attr "type" "bitmanip")
15727 (set_attr "mode" "DI")])
15729 (define_insn "*bsr_rex64"
15730 [(set (match_operand:DI 0 "register_operand" "=r")
15731 (minus:DI (const_int 63)
15732 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15733 (clobber (reg:CC FLAGS_REG))]
15735 "bsr{q}\t{%1, %0|%0, %1}"
15736 [(set_attr "prefix_0f" "1")
15737 (set_attr "mode" "DI")])
15739 (define_expand "clzhi2"
15741 [(set (match_operand:HI 0 "register_operand" "")
15742 (minus:HI (const_int 15)
15743 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15744 (clobber (reg:CC FLAGS_REG))])
15746 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15747 (clobber (reg:CC FLAGS_REG))])]
15752 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15757 (define_insn "clzhi2_abm"
15758 [(set (match_operand:HI 0 "register_operand" "=r")
15759 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15760 (clobber (reg:CC FLAGS_REG))]
15762 "lzcnt{w}\t{%1, %0|%0, %1}"
15763 [(set_attr "prefix_rep" "1")
15764 (set_attr "type" "bitmanip")
15765 (set_attr "mode" "HI")])
15767 (define_insn "*bsrhi"
15768 [(set (match_operand:HI 0 "register_operand" "=r")
15769 (minus:HI (const_int 15)
15770 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15771 (clobber (reg:CC FLAGS_REG))]
15773 "bsr{w}\t{%1, %0|%0, %1}"
15774 [(set_attr "prefix_0f" "1")
15775 (set_attr "mode" "HI")])
15777 (define_expand "paritydi2"
15778 [(set (match_operand:DI 0 "register_operand" "")
15779 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15782 rtx scratch = gen_reg_rtx (QImode);
15785 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15786 NULL_RTX, operands[1]));
15788 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15789 gen_rtx_REG (CCmode, FLAGS_REG),
15791 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15794 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15797 rtx tmp = gen_reg_rtx (SImode);
15799 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15800 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15805 (define_insn_and_split "paritydi2_cmp"
15806 [(set (reg:CC FLAGS_REG)
15807 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15808 (clobber (match_scratch:DI 0 "=r"))
15809 (clobber (match_scratch:SI 1 "=&r"))
15810 (clobber (match_scratch:HI 2 "=Q"))]
15813 "&& reload_completed"
15815 [(set (match_dup 1)
15816 (xor:SI (match_dup 1) (match_dup 4)))
15817 (clobber (reg:CC FLAGS_REG))])
15819 [(set (reg:CC FLAGS_REG)
15820 (parity:CC (match_dup 1)))
15821 (clobber (match_dup 1))
15822 (clobber (match_dup 2))])]
15824 operands[4] = gen_lowpart (SImode, operands[3]);
15828 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15829 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15832 operands[1] = gen_highpart (SImode, operands[3]);
15835 (define_expand "paritysi2"
15836 [(set (match_operand:SI 0 "register_operand" "")
15837 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15840 rtx scratch = gen_reg_rtx (QImode);
15843 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15845 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15846 gen_rtx_REG (CCmode, FLAGS_REG),
15848 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15850 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15854 (define_insn_and_split "paritysi2_cmp"
15855 [(set (reg:CC FLAGS_REG)
15856 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15857 (clobber (match_scratch:SI 0 "=r"))
15858 (clobber (match_scratch:HI 1 "=&Q"))]
15861 "&& reload_completed"
15863 [(set (match_dup 1)
15864 (xor:HI (match_dup 1) (match_dup 3)))
15865 (clobber (reg:CC FLAGS_REG))])
15867 [(set (reg:CC FLAGS_REG)
15868 (parity:CC (match_dup 1)))
15869 (clobber (match_dup 1))])]
15871 operands[3] = gen_lowpart (HImode, operands[2]);
15873 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15874 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15877 (define_insn "*parityhi2_cmp"
15878 [(set (reg:CC FLAGS_REG)
15879 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15880 (clobber (match_scratch:HI 0 "=Q"))]
15882 "xor{b}\t{%h0, %b0|%b0, %h0}"
15883 [(set_attr "length" "2")
15884 (set_attr "mode" "HI")])
15886 (define_insn "*parityqi2_cmp"
15887 [(set (reg:CC FLAGS_REG)
15888 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15891 [(set_attr "length" "2")
15892 (set_attr "mode" "QI")])
15894 ;; Thread-local storage patterns for ELF.
15896 ;; Note that these code sequences must appear exactly as shown
15897 ;; in order to allow linker relaxation.
15899 (define_insn "*tls_global_dynamic_32_gnu"
15900 [(set (match_operand:SI 0 "register_operand" "=a")
15901 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15902 (match_operand:SI 2 "tls_symbolic_operand" "")
15903 (match_operand:SI 3 "call_insn_operand" "")]
15905 (clobber (match_scratch:SI 4 "=d"))
15906 (clobber (match_scratch:SI 5 "=c"))
15907 (clobber (reg:CC FLAGS_REG))]
15908 "!TARGET_64BIT && TARGET_GNU_TLS"
15909 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15910 [(set_attr "type" "multi")
15911 (set_attr "length" "12")])
15913 (define_insn "*tls_global_dynamic_32_sun"
15914 [(set (match_operand:SI 0 "register_operand" "=a")
15915 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15916 (match_operand:SI 2 "tls_symbolic_operand" "")
15917 (match_operand:SI 3 "call_insn_operand" "")]
15919 (clobber (match_scratch:SI 4 "=d"))
15920 (clobber (match_scratch:SI 5 "=c"))
15921 (clobber (reg:CC FLAGS_REG))]
15922 "!TARGET_64BIT && TARGET_SUN_TLS"
15923 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15924 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15925 [(set_attr "type" "multi")
15926 (set_attr "length" "14")])
15928 (define_expand "tls_global_dynamic_32"
15929 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15932 (match_operand:SI 1 "tls_symbolic_operand" "")
15935 (clobber (match_scratch:SI 4 ""))
15936 (clobber (match_scratch:SI 5 ""))
15937 (clobber (reg:CC FLAGS_REG))])]
15941 operands[2] = pic_offset_table_rtx;
15944 operands[2] = gen_reg_rtx (Pmode);
15945 emit_insn (gen_set_got (operands[2]));
15947 if (TARGET_GNU2_TLS)
15949 emit_insn (gen_tls_dynamic_gnu2_32
15950 (operands[0], operands[1], operands[2]));
15953 operands[3] = ix86_tls_get_addr ();
15956 (define_insn "*tls_global_dynamic_64"
15957 [(set (match_operand:DI 0 "register_operand" "=a")
15958 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15959 (match_operand:DI 3 "" "")))
15960 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15963 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15964 [(set_attr "type" "multi")
15965 (set_attr "length" "16")])
15967 (define_expand "tls_global_dynamic_64"
15968 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15969 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15970 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15974 if (TARGET_GNU2_TLS)
15976 emit_insn (gen_tls_dynamic_gnu2_64
15977 (operands[0], operands[1]));
15980 operands[2] = ix86_tls_get_addr ();
15983 (define_insn "*tls_local_dynamic_base_32_gnu"
15984 [(set (match_operand:SI 0 "register_operand" "=a")
15985 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15986 (match_operand:SI 2 "call_insn_operand" "")]
15987 UNSPEC_TLS_LD_BASE))
15988 (clobber (match_scratch:SI 3 "=d"))
15989 (clobber (match_scratch:SI 4 "=c"))
15990 (clobber (reg:CC FLAGS_REG))]
15991 "!TARGET_64BIT && TARGET_GNU_TLS"
15992 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15993 [(set_attr "type" "multi")
15994 (set_attr "length" "11")])
15996 (define_insn "*tls_local_dynamic_base_32_sun"
15997 [(set (match_operand:SI 0 "register_operand" "=a")
15998 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15999 (match_operand:SI 2 "call_insn_operand" "")]
16000 UNSPEC_TLS_LD_BASE))
16001 (clobber (match_scratch:SI 3 "=d"))
16002 (clobber (match_scratch:SI 4 "=c"))
16003 (clobber (reg:CC FLAGS_REG))]
16004 "!TARGET_64BIT && TARGET_SUN_TLS"
16005 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16006 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16007 [(set_attr "type" "multi")
16008 (set_attr "length" "13")])
16010 (define_expand "tls_local_dynamic_base_32"
16011 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16012 (unspec:SI [(match_dup 1) (match_dup 2)]
16013 UNSPEC_TLS_LD_BASE))
16014 (clobber (match_scratch:SI 3 ""))
16015 (clobber (match_scratch:SI 4 ""))
16016 (clobber (reg:CC FLAGS_REG))])]
16020 operands[1] = pic_offset_table_rtx;
16023 operands[1] = gen_reg_rtx (Pmode);
16024 emit_insn (gen_set_got (operands[1]));
16026 if (TARGET_GNU2_TLS)
16028 emit_insn (gen_tls_dynamic_gnu2_32
16029 (operands[0], ix86_tls_module_base (), operands[1]));
16032 operands[2] = ix86_tls_get_addr ();
16035 (define_insn "*tls_local_dynamic_base_64"
16036 [(set (match_operand:DI 0 "register_operand" "=a")
16037 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16038 (match_operand:DI 2 "" "")))
16039 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16041 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16042 [(set_attr "type" "multi")
16043 (set_attr "length" "12")])
16045 (define_expand "tls_local_dynamic_base_64"
16046 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16047 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16048 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16051 if (TARGET_GNU2_TLS)
16053 emit_insn (gen_tls_dynamic_gnu2_64
16054 (operands[0], ix86_tls_module_base ()));
16057 operands[1] = ix86_tls_get_addr ();
16060 ;; Local dynamic of a single variable is a lose. Show combine how
16061 ;; to convert that back to global dynamic.
16063 (define_insn_and_split "*tls_local_dynamic_32_once"
16064 [(set (match_operand:SI 0 "register_operand" "=a")
16065 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16066 (match_operand:SI 2 "call_insn_operand" "")]
16067 UNSPEC_TLS_LD_BASE)
16068 (const:SI (unspec:SI
16069 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16071 (clobber (match_scratch:SI 4 "=d"))
16072 (clobber (match_scratch:SI 5 "=c"))
16073 (clobber (reg:CC FLAGS_REG))]
16077 [(parallel [(set (match_dup 0)
16078 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16080 (clobber (match_dup 4))
16081 (clobber (match_dup 5))
16082 (clobber (reg:CC FLAGS_REG))])]
16085 ;; Load and add the thread base pointer from %gs:0.
16087 (define_insn "*load_tp_si"
16088 [(set (match_operand:SI 0 "register_operand" "=r")
16089 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16091 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16092 [(set_attr "type" "imov")
16093 (set_attr "modrm" "0")
16094 (set_attr "length" "7")
16095 (set_attr "memory" "load")
16096 (set_attr "imm_disp" "false")])
16098 (define_insn "*add_tp_si"
16099 [(set (match_operand:SI 0 "register_operand" "=r")
16100 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16101 (match_operand:SI 1 "register_operand" "0")))
16102 (clobber (reg:CC FLAGS_REG))]
16104 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16105 [(set_attr "type" "alu")
16106 (set_attr "modrm" "0")
16107 (set_attr "length" "7")
16108 (set_attr "memory" "load")
16109 (set_attr "imm_disp" "false")])
16111 (define_insn "*load_tp_di"
16112 [(set (match_operand:DI 0 "register_operand" "=r")
16113 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16115 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16116 [(set_attr "type" "imov")
16117 (set_attr "modrm" "0")
16118 (set_attr "length" "7")
16119 (set_attr "memory" "load")
16120 (set_attr "imm_disp" "false")])
16122 (define_insn "*add_tp_di"
16123 [(set (match_operand:DI 0 "register_operand" "=r")
16124 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16125 (match_operand:DI 1 "register_operand" "0")))
16126 (clobber (reg:CC FLAGS_REG))]
16128 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16129 [(set_attr "type" "alu")
16130 (set_attr "modrm" "0")
16131 (set_attr "length" "7")
16132 (set_attr "memory" "load")
16133 (set_attr "imm_disp" "false")])
16135 ;; GNU2 TLS patterns can be split.
16137 (define_expand "tls_dynamic_gnu2_32"
16138 [(set (match_dup 3)
16139 (plus:SI (match_operand:SI 2 "register_operand" "")
16141 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16144 [(set (match_operand:SI 0 "register_operand" "")
16145 (unspec:SI [(match_dup 1) (match_dup 3)
16146 (match_dup 2) (reg:SI SP_REG)]
16148 (clobber (reg:CC FLAGS_REG))])]
16149 "!TARGET_64BIT && TARGET_GNU2_TLS"
16151 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16152 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16155 (define_insn "*tls_dynamic_lea_32"
16156 [(set (match_operand:SI 0 "register_operand" "=r")
16157 (plus:SI (match_operand:SI 1 "register_operand" "b")
16159 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16160 UNSPEC_TLSDESC))))]
16161 "!TARGET_64BIT && TARGET_GNU2_TLS"
16162 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16163 [(set_attr "type" "lea")
16164 (set_attr "mode" "SI")
16165 (set_attr "length" "6")
16166 (set_attr "length_address" "4")])
16168 (define_insn "*tls_dynamic_call_32"
16169 [(set (match_operand:SI 0 "register_operand" "=a")
16170 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16171 (match_operand:SI 2 "register_operand" "0")
16172 ;; we have to make sure %ebx still points to the GOT
16173 (match_operand:SI 3 "register_operand" "b")
16176 (clobber (reg:CC FLAGS_REG))]
16177 "!TARGET_64BIT && TARGET_GNU2_TLS"
16178 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16179 [(set_attr "type" "call")
16180 (set_attr "length" "2")
16181 (set_attr "length_address" "0")])
16183 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16184 [(set (match_operand:SI 0 "register_operand" "=&a")
16186 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16187 (match_operand:SI 4 "" "")
16188 (match_operand:SI 2 "register_operand" "b")
16191 (const:SI (unspec:SI
16192 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16194 (clobber (reg:CC FLAGS_REG))]
16195 "!TARGET_64BIT && TARGET_GNU2_TLS"
16198 [(set (match_dup 0) (match_dup 5))]
16200 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16201 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16204 (define_expand "tls_dynamic_gnu2_64"
16205 [(set (match_dup 2)
16206 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16209 [(set (match_operand:DI 0 "register_operand" "")
16210 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16212 (clobber (reg:CC FLAGS_REG))])]
16213 "TARGET_64BIT && TARGET_GNU2_TLS"
16215 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16216 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16219 (define_insn "*tls_dynamic_lea_64"
16220 [(set (match_operand:DI 0 "register_operand" "=r")
16221 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16223 "TARGET_64BIT && TARGET_GNU2_TLS"
16224 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16225 [(set_attr "type" "lea")
16226 (set_attr "mode" "DI")
16227 (set_attr "length" "7")
16228 (set_attr "length_address" "4")])
16230 (define_insn "*tls_dynamic_call_64"
16231 [(set (match_operand:DI 0 "register_operand" "=a")
16232 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16233 (match_operand:DI 2 "register_operand" "0")
16236 (clobber (reg:CC FLAGS_REG))]
16237 "TARGET_64BIT && TARGET_GNU2_TLS"
16238 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16239 [(set_attr "type" "call")
16240 (set_attr "length" "2")
16241 (set_attr "length_address" "0")])
16243 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16244 [(set (match_operand:DI 0 "register_operand" "=&a")
16246 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16247 (match_operand:DI 3 "" "")
16250 (const:DI (unspec:DI
16251 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16253 (clobber (reg:CC FLAGS_REG))]
16254 "TARGET_64BIT && TARGET_GNU2_TLS"
16257 [(set (match_dup 0) (match_dup 4))]
16259 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16260 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16265 ;; These patterns match the binary 387 instructions for addM3, subM3,
16266 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16267 ;; SFmode. The first is the normal insn, the second the same insn but
16268 ;; with one operand a conversion, and the third the same insn but with
16269 ;; the other operand a conversion. The conversion may be SFmode or
16270 ;; SImode if the target mode DFmode, but only SImode if the target mode
16273 ;; Gcc is slightly more smart about handling normal two address instructions
16274 ;; so use special patterns for add and mull.
16276 (define_insn "*fop_<mode>_comm_mixed_avx"
16277 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16278 (match_operator:MODEF 3 "binary_fp_operator"
16279 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16280 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16281 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16282 && COMMUTATIVE_ARITH_P (operands[3])
16283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16284 "* return output_387_binary_op (insn, operands);"
16285 [(set (attr "type")
16286 (if_then_else (eq_attr "alternative" "1")
16287 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16288 (const_string "ssemul")
16289 (const_string "sseadd"))
16290 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16291 (const_string "fmul")
16292 (const_string "fop"))))
16293 (set_attr "prefix" "orig,maybe_vex")
16294 (set_attr "mode" "<MODE>")])
16296 (define_insn "*fop_<mode>_comm_mixed"
16297 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16298 (match_operator:MODEF 3 "binary_fp_operator"
16299 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16300 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16301 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16302 && COMMUTATIVE_ARITH_P (operands[3])
16303 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16304 "* return output_387_binary_op (insn, operands);"
16305 [(set (attr "type")
16306 (if_then_else (eq_attr "alternative" "1")
16307 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16308 (const_string "ssemul")
16309 (const_string "sseadd"))
16310 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16311 (const_string "fmul")
16312 (const_string "fop"))))
16313 (set_attr "mode" "<MODE>")])
16315 (define_insn "*fop_<mode>_comm_avx"
16316 [(set (match_operand:MODEF 0 "register_operand" "=x")
16317 (match_operator:MODEF 3 "binary_fp_operator"
16318 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16319 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16320 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16321 && COMMUTATIVE_ARITH_P (operands[3])
16322 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16323 "* return output_387_binary_op (insn, operands);"
16324 [(set (attr "type")
16325 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16326 (const_string "ssemul")
16327 (const_string "sseadd")))
16328 (set_attr "prefix" "vex")
16329 (set_attr "mode" "<MODE>")])
16331 (define_insn "*fop_<mode>_comm_sse"
16332 [(set (match_operand:MODEF 0 "register_operand" "=x")
16333 (match_operator:MODEF 3 "binary_fp_operator"
16334 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16335 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16336 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16337 && COMMUTATIVE_ARITH_P (operands[3])
16338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16339 "* return output_387_binary_op (insn, operands);"
16340 [(set (attr "type")
16341 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16342 (const_string "ssemul")
16343 (const_string "sseadd")))
16344 (set_attr "mode" "<MODE>")])
16346 (define_insn "*fop_<mode>_comm_i387"
16347 [(set (match_operand:MODEF 0 "register_operand" "=f")
16348 (match_operator:MODEF 3 "binary_fp_operator"
16349 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16350 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16351 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16352 && COMMUTATIVE_ARITH_P (operands[3])
16353 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16354 "* return output_387_binary_op (insn, operands);"
16355 [(set (attr "type")
16356 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16357 (const_string "fmul")
16358 (const_string "fop")))
16359 (set_attr "mode" "<MODE>")])
16361 (define_insn "*fop_<mode>_1_mixed_avx"
16362 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16363 (match_operator:MODEF 3 "binary_fp_operator"
16364 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16365 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16366 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16367 && !COMMUTATIVE_ARITH_P (operands[3])
16368 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16369 "* return output_387_binary_op (insn, operands);"
16370 [(set (attr "type")
16371 (cond [(and (eq_attr "alternative" "2")
16372 (match_operand:MODEF 3 "mult_operator" ""))
16373 (const_string "ssemul")
16374 (and (eq_attr "alternative" "2")
16375 (match_operand:MODEF 3 "div_operator" ""))
16376 (const_string "ssediv")
16377 (eq_attr "alternative" "2")
16378 (const_string "sseadd")
16379 (match_operand:MODEF 3 "mult_operator" "")
16380 (const_string "fmul")
16381 (match_operand:MODEF 3 "div_operator" "")
16382 (const_string "fdiv")
16384 (const_string "fop")))
16385 (set_attr "prefix" "orig,orig,maybe_vex")
16386 (set_attr "mode" "<MODE>")])
16388 (define_insn "*fop_<mode>_1_mixed"
16389 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16390 (match_operator:MODEF 3 "binary_fp_operator"
16391 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16392 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16393 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16394 && !COMMUTATIVE_ARITH_P (operands[3])
16395 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16396 "* return output_387_binary_op (insn, operands);"
16397 [(set (attr "type")
16398 (cond [(and (eq_attr "alternative" "2")
16399 (match_operand:MODEF 3 "mult_operator" ""))
16400 (const_string "ssemul")
16401 (and (eq_attr "alternative" "2")
16402 (match_operand:MODEF 3 "div_operator" ""))
16403 (const_string "ssediv")
16404 (eq_attr "alternative" "2")
16405 (const_string "sseadd")
16406 (match_operand:MODEF 3 "mult_operator" "")
16407 (const_string "fmul")
16408 (match_operand:MODEF 3 "div_operator" "")
16409 (const_string "fdiv")
16411 (const_string "fop")))
16412 (set_attr "mode" "<MODE>")])
16414 (define_insn "*rcpsf2_sse"
16415 [(set (match_operand:SF 0 "register_operand" "=x")
16416 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16419 "%vrcpss\t{%1, %d0|%d0, %1}"
16420 [(set_attr "type" "sse")
16421 (set_attr "prefix" "maybe_vex")
16422 (set_attr "mode" "SF")])
16424 (define_insn "*fop_<mode>_1_avx"
16425 [(set (match_operand:MODEF 0 "register_operand" "=x")
16426 (match_operator:MODEF 3 "binary_fp_operator"
16427 [(match_operand:MODEF 1 "register_operand" "x")
16428 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16429 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16430 && !COMMUTATIVE_ARITH_P (operands[3])"
16431 "* return output_387_binary_op (insn, operands);"
16432 [(set (attr "type")
16433 (cond [(match_operand:MODEF 3 "mult_operator" "")
16434 (const_string "ssemul")
16435 (match_operand:MODEF 3 "div_operator" "")
16436 (const_string "ssediv")
16438 (const_string "sseadd")))
16439 (set_attr "prefix" "vex")
16440 (set_attr "mode" "<MODE>")])
16442 (define_insn "*fop_<mode>_1_sse"
16443 [(set (match_operand:MODEF 0 "register_operand" "=x")
16444 (match_operator:MODEF 3 "binary_fp_operator"
16445 [(match_operand:MODEF 1 "register_operand" "0")
16446 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16447 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16448 && !COMMUTATIVE_ARITH_P (operands[3])"
16449 "* return output_387_binary_op (insn, operands);"
16450 [(set (attr "type")
16451 (cond [(match_operand:MODEF 3 "mult_operator" "")
16452 (const_string "ssemul")
16453 (match_operand:MODEF 3 "div_operator" "")
16454 (const_string "ssediv")
16456 (const_string "sseadd")))
16457 (set_attr "mode" "<MODE>")])
16459 ;; This pattern is not fully shadowed by the pattern above.
16460 (define_insn "*fop_<mode>_1_i387"
16461 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16462 (match_operator:MODEF 3 "binary_fp_operator"
16463 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16464 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16465 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16466 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16467 && !COMMUTATIVE_ARITH_P (operands[3])
16468 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16469 "* return output_387_binary_op (insn, operands);"
16470 [(set (attr "type")
16471 (cond [(match_operand:MODEF 3 "mult_operator" "")
16472 (const_string "fmul")
16473 (match_operand:MODEF 3 "div_operator" "")
16474 (const_string "fdiv")
16476 (const_string "fop")))
16477 (set_attr "mode" "<MODE>")])
16479 ;; ??? Add SSE splitters for these!
16480 (define_insn "*fop_<MODEF:mode>_2_i387"
16481 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16482 (match_operator:MODEF 3 "binary_fp_operator"
16484 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16485 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16486 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16487 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16488 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16489 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16490 [(set (attr "type")
16491 (cond [(match_operand:MODEF 3 "mult_operator" "")
16492 (const_string "fmul")
16493 (match_operand:MODEF 3 "div_operator" "")
16494 (const_string "fdiv")
16496 (const_string "fop")))
16497 (set_attr "fp_int_src" "true")
16498 (set_attr "mode" "<X87MODEI12:MODE>")])
16500 (define_insn "*fop_<MODEF:mode>_3_i387"
16501 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16502 (match_operator:MODEF 3 "binary_fp_operator"
16503 [(match_operand:MODEF 1 "register_operand" "0,0")
16505 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16506 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
16507 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16508 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16509 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16510 [(set (attr "type")
16511 (cond [(match_operand:MODEF 3 "mult_operator" "")
16512 (const_string "fmul")
16513 (match_operand:MODEF 3 "div_operator" "")
16514 (const_string "fdiv")
16516 (const_string "fop")))
16517 (set_attr "fp_int_src" "true")
16518 (set_attr "mode" "<MODE>")])
16520 (define_insn "*fop_df_4_i387"
16521 [(set (match_operand:DF 0 "register_operand" "=f,f")
16522 (match_operator:DF 3 "binary_fp_operator"
16524 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16525 (match_operand:DF 2 "register_operand" "0,f")]))]
16526 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16527 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16528 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16529 "* return output_387_binary_op (insn, operands);"
16530 [(set (attr "type")
16531 (cond [(match_operand:DF 3 "mult_operator" "")
16532 (const_string "fmul")
16533 (match_operand:DF 3 "div_operator" "")
16534 (const_string "fdiv")
16536 (const_string "fop")))
16537 (set_attr "mode" "SF")])
16539 (define_insn "*fop_df_5_i387"
16540 [(set (match_operand:DF 0 "register_operand" "=f,f")
16541 (match_operator:DF 3 "binary_fp_operator"
16542 [(match_operand:DF 1 "register_operand" "0,f")
16544 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16545 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16546 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16547 "* return output_387_binary_op (insn, operands);"
16548 [(set (attr "type")
16549 (cond [(match_operand:DF 3 "mult_operator" "")
16550 (const_string "fmul")
16551 (match_operand:DF 3 "div_operator" "")
16552 (const_string "fdiv")
16554 (const_string "fop")))
16555 (set_attr "mode" "SF")])
16557 (define_insn "*fop_df_6_i387"
16558 [(set (match_operand:DF 0 "register_operand" "=f,f")
16559 (match_operator:DF 3 "binary_fp_operator"
16561 (match_operand:SF 1 "register_operand" "0,f"))
16563 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16564 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16565 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16566 "* return output_387_binary_op (insn, operands);"
16567 [(set (attr "type")
16568 (cond [(match_operand:DF 3 "mult_operator" "")
16569 (const_string "fmul")
16570 (match_operand:DF 3 "div_operator" "")
16571 (const_string "fdiv")
16573 (const_string "fop")))
16574 (set_attr "mode" "SF")])
16576 (define_insn "*fop_xf_comm_i387"
16577 [(set (match_operand:XF 0 "register_operand" "=f")
16578 (match_operator:XF 3 "binary_fp_operator"
16579 [(match_operand:XF 1 "register_operand" "%0")
16580 (match_operand:XF 2 "register_operand" "f")]))]
16582 && COMMUTATIVE_ARITH_P (operands[3])"
16583 "* return output_387_binary_op (insn, operands);"
16584 [(set (attr "type")
16585 (if_then_else (match_operand:XF 3 "mult_operator" "")
16586 (const_string "fmul")
16587 (const_string "fop")))
16588 (set_attr "mode" "XF")])
16590 (define_insn "*fop_xf_1_i387"
16591 [(set (match_operand:XF 0 "register_operand" "=f,f")
16592 (match_operator:XF 3 "binary_fp_operator"
16593 [(match_operand:XF 1 "register_operand" "0,f")
16594 (match_operand:XF 2 "register_operand" "f,0")]))]
16596 && !COMMUTATIVE_ARITH_P (operands[3])"
16597 "* return output_387_binary_op (insn, operands);"
16598 [(set (attr "type")
16599 (cond [(match_operand:XF 3 "mult_operator" "")
16600 (const_string "fmul")
16601 (match_operand:XF 3 "div_operator" "")
16602 (const_string "fdiv")
16604 (const_string "fop")))
16605 (set_attr "mode" "XF")])
16607 (define_insn "*fop_xf_2_i387"
16608 [(set (match_operand:XF 0 "register_operand" "=f,f")
16609 (match_operator:XF 3 "binary_fp_operator"
16611 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16612 (match_operand:XF 2 "register_operand" "0,0")]))]
16613 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16614 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16615 [(set (attr "type")
16616 (cond [(match_operand:XF 3 "mult_operator" "")
16617 (const_string "fmul")
16618 (match_operand:XF 3 "div_operator" "")
16619 (const_string "fdiv")
16621 (const_string "fop")))
16622 (set_attr "fp_int_src" "true")
16623 (set_attr "mode" "<MODE>")])
16625 (define_insn "*fop_xf_3_i387"
16626 [(set (match_operand:XF 0 "register_operand" "=f,f")
16627 (match_operator:XF 3 "binary_fp_operator"
16628 [(match_operand:XF 1 "register_operand" "0,0")
16630 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16631 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16632 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16633 [(set (attr "type")
16634 (cond [(match_operand:XF 3 "mult_operator" "")
16635 (const_string "fmul")
16636 (match_operand:XF 3 "div_operator" "")
16637 (const_string "fdiv")
16639 (const_string "fop")))
16640 (set_attr "fp_int_src" "true")
16641 (set_attr "mode" "<MODE>")])
16643 (define_insn "*fop_xf_4_i387"
16644 [(set (match_operand:XF 0 "register_operand" "=f,f")
16645 (match_operator:XF 3 "binary_fp_operator"
16647 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16648 (match_operand:XF 2 "register_operand" "0,f")]))]
16650 "* return output_387_binary_op (insn, operands);"
16651 [(set (attr "type")
16652 (cond [(match_operand:XF 3 "mult_operator" "")
16653 (const_string "fmul")
16654 (match_operand:XF 3 "div_operator" "")
16655 (const_string "fdiv")
16657 (const_string "fop")))
16658 (set_attr "mode" "<MODE>")])
16660 (define_insn "*fop_xf_5_i387"
16661 [(set (match_operand:XF 0 "register_operand" "=f,f")
16662 (match_operator:XF 3 "binary_fp_operator"
16663 [(match_operand:XF 1 "register_operand" "0,f")
16665 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16667 "* return output_387_binary_op (insn, operands);"
16668 [(set (attr "type")
16669 (cond [(match_operand:XF 3 "mult_operator" "")
16670 (const_string "fmul")
16671 (match_operand:XF 3 "div_operator" "")
16672 (const_string "fdiv")
16674 (const_string "fop")))
16675 (set_attr "mode" "<MODE>")])
16677 (define_insn "*fop_xf_6_i387"
16678 [(set (match_operand:XF 0 "register_operand" "=f,f")
16679 (match_operator:XF 3 "binary_fp_operator"
16681 (match_operand:MODEF 1 "register_operand" "0,f"))
16683 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16685 "* return output_387_binary_op (insn, operands);"
16686 [(set (attr "type")
16687 (cond [(match_operand:XF 3 "mult_operator" "")
16688 (const_string "fmul")
16689 (match_operand:XF 3 "div_operator" "")
16690 (const_string "fdiv")
16692 (const_string "fop")))
16693 (set_attr "mode" "<MODE>")])
16696 [(set (match_operand 0 "register_operand" "")
16697 (match_operator 3 "binary_fp_operator"
16698 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16699 (match_operand 2 "register_operand" "")]))]
16701 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16702 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16705 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16706 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16707 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16708 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16709 GET_MODE (operands[3]),
16712 ix86_free_from_memory (GET_MODE (operands[1]));
16717 [(set (match_operand 0 "register_operand" "")
16718 (match_operator 3 "binary_fp_operator"
16719 [(match_operand 1 "register_operand" "")
16720 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16722 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16723 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16726 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16727 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16728 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16729 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16730 GET_MODE (operands[3]),
16733 ix86_free_from_memory (GET_MODE (operands[2]));
16737 ;; FPU special functions.
16739 ;; This pattern implements a no-op XFmode truncation for
16740 ;; all fancy i386 XFmode math functions.
16742 (define_insn "truncxf<mode>2_i387_noop_unspec"
16743 [(set (match_operand:MODEF 0 "register_operand" "=f")
16744 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16745 UNSPEC_TRUNC_NOOP))]
16746 "TARGET_USE_FANCY_MATH_387"
16747 "* return output_387_reg_move (insn, operands);"
16748 [(set_attr "type" "fmov")
16749 (set_attr "mode" "<MODE>")])
16751 (define_insn "sqrtxf2"
16752 [(set (match_operand:XF 0 "register_operand" "=f")
16753 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16754 "TARGET_USE_FANCY_MATH_387"
16756 [(set_attr "type" "fpspc")
16757 (set_attr "mode" "XF")
16758 (set_attr "athlon_decode" "direct")
16759 (set_attr "amdfam10_decode" "direct")])
16761 (define_insn "sqrt_extend<mode>xf2_i387"
16762 [(set (match_operand:XF 0 "register_operand" "=f")
16765 (match_operand:MODEF 1 "register_operand" "0"))))]
16766 "TARGET_USE_FANCY_MATH_387"
16768 [(set_attr "type" "fpspc")
16769 (set_attr "mode" "XF")
16770 (set_attr "athlon_decode" "direct")
16771 (set_attr "amdfam10_decode" "direct")])
16773 (define_insn "*rsqrtsf2_sse"
16774 [(set (match_operand:SF 0 "register_operand" "=x")
16775 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16778 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16779 [(set_attr "type" "sse")
16780 (set_attr "prefix" "maybe_vex")
16781 (set_attr "mode" "SF")])
16783 (define_expand "rsqrtsf2"
16784 [(set (match_operand:SF 0 "register_operand" "")
16785 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16789 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16793 (define_insn "*sqrt<mode>2_sse"
16794 [(set (match_operand:MODEF 0 "register_operand" "=x")
16796 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16797 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16798 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16799 [(set_attr "type" "sse")
16800 (set_attr "prefix" "maybe_vex")
16801 (set_attr "mode" "<MODE>")
16802 (set_attr "athlon_decode" "*")
16803 (set_attr "amdfam10_decode" "*")])
16805 (define_expand "sqrt<mode>2"
16806 [(set (match_operand:MODEF 0 "register_operand" "")
16808 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16809 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16810 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16812 if (<MODE>mode == SFmode
16813 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16814 && flag_finite_math_only && !flag_trapping_math
16815 && flag_unsafe_math_optimizations)
16817 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16821 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16823 rtx op0 = gen_reg_rtx (XFmode);
16824 rtx op1 = force_reg (<MODE>mode, operands[1]);
16826 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16827 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16832 (define_insn "fpremxf4_i387"
16833 [(set (match_operand:XF 0 "register_operand" "=f")
16834 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16835 (match_operand:XF 3 "register_operand" "1")]
16837 (set (match_operand:XF 1 "register_operand" "=u")
16838 (unspec:XF [(match_dup 2) (match_dup 3)]
16840 (set (reg:CCFP FPSR_REG)
16841 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16843 "TARGET_USE_FANCY_MATH_387"
16845 [(set_attr "type" "fpspc")
16846 (set_attr "mode" "XF")])
16848 (define_expand "fmodxf3"
16849 [(use (match_operand:XF 0 "register_operand" ""))
16850 (use (match_operand:XF 1 "general_operand" ""))
16851 (use (match_operand:XF 2 "general_operand" ""))]
16852 "TARGET_USE_FANCY_MATH_387"
16854 rtx label = gen_label_rtx ();
16856 rtx op1 = gen_reg_rtx (XFmode);
16857 rtx op2 = gen_reg_rtx (XFmode);
16859 emit_move_insn (op2, operands[2]);
16860 emit_move_insn (op1, operands[1]);
16862 emit_label (label);
16863 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16864 ix86_emit_fp_unordered_jump (label);
16865 LABEL_NUSES (label) = 1;
16867 emit_move_insn (operands[0], op1);
16871 (define_expand "fmod<mode>3"
16872 [(use (match_operand:MODEF 0 "register_operand" ""))
16873 (use (match_operand:MODEF 1 "general_operand" ""))
16874 (use (match_operand:MODEF 2 "general_operand" ""))]
16875 "TARGET_USE_FANCY_MATH_387"
16877 rtx label = gen_label_rtx ();
16879 rtx op1 = gen_reg_rtx (XFmode);
16880 rtx op2 = gen_reg_rtx (XFmode);
16882 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16883 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16885 emit_label (label);
16886 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16887 ix86_emit_fp_unordered_jump (label);
16888 LABEL_NUSES (label) = 1;
16890 /* Truncate the result properly for strict SSE math. */
16891 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16892 && !TARGET_MIX_SSE_I387)
16893 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16895 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16900 (define_insn "fprem1xf4_i387"
16901 [(set (match_operand:XF 0 "register_operand" "=f")
16902 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16903 (match_operand:XF 3 "register_operand" "1")]
16905 (set (match_operand:XF 1 "register_operand" "=u")
16906 (unspec:XF [(match_dup 2) (match_dup 3)]
16908 (set (reg:CCFP FPSR_REG)
16909 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16911 "TARGET_USE_FANCY_MATH_387"
16913 [(set_attr "type" "fpspc")
16914 (set_attr "mode" "XF")])
16916 (define_expand "remainderxf3"
16917 [(use (match_operand:XF 0 "register_operand" ""))
16918 (use (match_operand:XF 1 "general_operand" ""))
16919 (use (match_operand:XF 2 "general_operand" ""))]
16920 "TARGET_USE_FANCY_MATH_387"
16922 rtx label = gen_label_rtx ();
16924 rtx op1 = gen_reg_rtx (XFmode);
16925 rtx op2 = gen_reg_rtx (XFmode);
16927 emit_move_insn (op2, operands[2]);
16928 emit_move_insn (op1, operands[1]);
16930 emit_label (label);
16931 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16932 ix86_emit_fp_unordered_jump (label);
16933 LABEL_NUSES (label) = 1;
16935 emit_move_insn (operands[0], op1);
16939 (define_expand "remainder<mode>3"
16940 [(use (match_operand:MODEF 0 "register_operand" ""))
16941 (use (match_operand:MODEF 1 "general_operand" ""))
16942 (use (match_operand:MODEF 2 "general_operand" ""))]
16943 "TARGET_USE_FANCY_MATH_387"
16945 rtx label = gen_label_rtx ();
16947 rtx op1 = gen_reg_rtx (XFmode);
16948 rtx op2 = gen_reg_rtx (XFmode);
16950 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16951 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16953 emit_label (label);
16955 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16956 ix86_emit_fp_unordered_jump (label);
16957 LABEL_NUSES (label) = 1;
16959 /* Truncate the result properly for strict SSE math. */
16960 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16961 && !TARGET_MIX_SSE_I387)
16962 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16964 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16969 (define_insn "*sinxf2_i387"
16970 [(set (match_operand:XF 0 "register_operand" "=f")
16971 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16972 "TARGET_USE_FANCY_MATH_387
16973 && flag_unsafe_math_optimizations"
16975 [(set_attr "type" "fpspc")
16976 (set_attr "mode" "XF")])
16978 (define_insn "*sin_extend<mode>xf2_i387"
16979 [(set (match_operand:XF 0 "register_operand" "=f")
16980 (unspec:XF [(float_extend:XF
16981 (match_operand:MODEF 1 "register_operand" "0"))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16985 || TARGET_MIX_SSE_I387)
16986 && flag_unsafe_math_optimizations"
16988 [(set_attr "type" "fpspc")
16989 (set_attr "mode" "XF")])
16991 (define_insn "*cosxf2_i387"
16992 [(set (match_operand:XF 0 "register_operand" "=f")
16993 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16994 "TARGET_USE_FANCY_MATH_387
16995 && flag_unsafe_math_optimizations"
16997 [(set_attr "type" "fpspc")
16998 (set_attr "mode" "XF")])
17000 (define_insn "*cos_extend<mode>xf2_i387"
17001 [(set (match_operand:XF 0 "register_operand" "=f")
17002 (unspec:XF [(float_extend:XF
17003 (match_operand:MODEF 1 "register_operand" "0"))]
17005 "TARGET_USE_FANCY_MATH_387
17006 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17007 || TARGET_MIX_SSE_I387)
17008 && flag_unsafe_math_optimizations"
17010 [(set_attr "type" "fpspc")
17011 (set_attr "mode" "XF")])
17013 ;; When sincos pattern is defined, sin and cos builtin functions will be
17014 ;; expanded to sincos pattern with one of its outputs left unused.
17015 ;; CSE pass will figure out if two sincos patterns can be combined,
17016 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17017 ;; depending on the unused output.
17019 (define_insn "sincosxf3"
17020 [(set (match_operand:XF 0 "register_operand" "=f")
17021 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17022 UNSPEC_SINCOS_COS))
17023 (set (match_operand:XF 1 "register_operand" "=u")
17024 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17025 "TARGET_USE_FANCY_MATH_387
17026 && flag_unsafe_math_optimizations"
17028 [(set_attr "type" "fpspc")
17029 (set_attr "mode" "XF")])
17032 [(set (match_operand:XF 0 "register_operand" "")
17033 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17034 UNSPEC_SINCOS_COS))
17035 (set (match_operand:XF 1 "register_operand" "")
17036 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17037 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17038 && !(reload_completed || reload_in_progress)"
17039 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17043 [(set (match_operand:XF 0 "register_operand" "")
17044 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17045 UNSPEC_SINCOS_COS))
17046 (set (match_operand:XF 1 "register_operand" "")
17047 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17048 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17049 && !(reload_completed || reload_in_progress)"
17050 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17053 (define_insn "sincos_extend<mode>xf3_i387"
17054 [(set (match_operand:XF 0 "register_operand" "=f")
17055 (unspec:XF [(float_extend:XF
17056 (match_operand:MODEF 2 "register_operand" "0"))]
17057 UNSPEC_SINCOS_COS))
17058 (set (match_operand:XF 1 "register_operand" "=u")
17059 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17060 "TARGET_USE_FANCY_MATH_387
17061 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17062 || TARGET_MIX_SSE_I387)
17063 && flag_unsafe_math_optimizations"
17065 [(set_attr "type" "fpspc")
17066 (set_attr "mode" "XF")])
17069 [(set (match_operand:XF 0 "register_operand" "")
17070 (unspec:XF [(float_extend:XF
17071 (match_operand:MODEF 2 "register_operand" ""))]
17072 UNSPEC_SINCOS_COS))
17073 (set (match_operand:XF 1 "register_operand" "")
17074 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17075 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17076 && !(reload_completed || reload_in_progress)"
17077 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17081 [(set (match_operand:XF 0 "register_operand" "")
17082 (unspec:XF [(float_extend:XF
17083 (match_operand:MODEF 2 "register_operand" ""))]
17084 UNSPEC_SINCOS_COS))
17085 (set (match_operand:XF 1 "register_operand" "")
17086 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17087 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17088 && !(reload_completed || reload_in_progress)"
17089 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17092 (define_expand "sincos<mode>3"
17093 [(use (match_operand:MODEF 0 "register_operand" ""))
17094 (use (match_operand:MODEF 1 "register_operand" ""))
17095 (use (match_operand:MODEF 2 "register_operand" ""))]
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 rtx op0 = gen_reg_rtx (XFmode);
17102 rtx op1 = gen_reg_rtx (XFmode);
17104 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17105 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17106 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17110 (define_insn "fptanxf4_i387"
17111 [(set (match_operand:XF 0 "register_operand" "=f")
17112 (match_operand:XF 3 "const_double_operand" "F"))
17113 (set (match_operand:XF 1 "register_operand" "=u")
17114 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17116 "TARGET_USE_FANCY_MATH_387
17117 && flag_unsafe_math_optimizations
17118 && standard_80387_constant_p (operands[3]) == 2"
17120 [(set_attr "type" "fpspc")
17121 (set_attr "mode" "XF")])
17123 (define_insn "fptan_extend<mode>xf4_i387"
17124 [(set (match_operand:MODEF 0 "register_operand" "=f")
17125 (match_operand:MODEF 3 "const_double_operand" "F"))
17126 (set (match_operand:XF 1 "register_operand" "=u")
17127 (unspec:XF [(float_extend:XF
17128 (match_operand:MODEF 2 "register_operand" "0"))]
17130 "TARGET_USE_FANCY_MATH_387
17131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17132 || TARGET_MIX_SSE_I387)
17133 && flag_unsafe_math_optimizations
17134 && standard_80387_constant_p (operands[3]) == 2"
17136 [(set_attr "type" "fpspc")
17137 (set_attr "mode" "XF")])
17139 (define_expand "tanxf2"
17140 [(use (match_operand:XF 0 "register_operand" ""))
17141 (use (match_operand:XF 1 "register_operand" ""))]
17142 "TARGET_USE_FANCY_MATH_387
17143 && flag_unsafe_math_optimizations"
17145 rtx one = gen_reg_rtx (XFmode);
17146 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17148 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17152 (define_expand "tan<mode>2"
17153 [(use (match_operand:MODEF 0 "register_operand" ""))
17154 (use (match_operand:MODEF 1 "register_operand" ""))]
17155 "TARGET_USE_FANCY_MATH_387
17156 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17157 || TARGET_MIX_SSE_I387)
17158 && flag_unsafe_math_optimizations"
17160 rtx op0 = gen_reg_rtx (XFmode);
17162 rtx one = gen_reg_rtx (<MODE>mode);
17163 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17165 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17166 operands[1], op2));
17167 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17171 (define_insn "*fpatanxf3_i387"
17172 [(set (match_operand:XF 0 "register_operand" "=f")
17173 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17174 (match_operand:XF 2 "register_operand" "u")]
17176 (clobber (match_scratch:XF 3 "=2"))]
17177 "TARGET_USE_FANCY_MATH_387
17178 && flag_unsafe_math_optimizations"
17180 [(set_attr "type" "fpspc")
17181 (set_attr "mode" "XF")])
17183 (define_insn "fpatan_extend<mode>xf3_i387"
17184 [(set (match_operand:XF 0 "register_operand" "=f")
17185 (unspec:XF [(float_extend:XF
17186 (match_operand:MODEF 1 "register_operand" "0"))
17188 (match_operand:MODEF 2 "register_operand" "u"))]
17190 (clobber (match_scratch:XF 3 "=2"))]
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 [(set_attr "type" "fpspc")
17197 (set_attr "mode" "XF")])
17199 (define_expand "atan2xf3"
17200 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17201 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17202 (match_operand:XF 1 "register_operand" "")]
17204 (clobber (match_scratch:XF 3 ""))])]
17205 "TARGET_USE_FANCY_MATH_387
17206 && flag_unsafe_math_optimizations"
17209 (define_expand "atan2<mode>3"
17210 [(use (match_operand:MODEF 0 "register_operand" ""))
17211 (use (match_operand:MODEF 1 "register_operand" ""))
17212 (use (match_operand:MODEF 2 "register_operand" ""))]
17213 "TARGET_USE_FANCY_MATH_387
17214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17215 || TARGET_MIX_SSE_I387)
17216 && flag_unsafe_math_optimizations"
17218 rtx op0 = gen_reg_rtx (XFmode);
17220 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17221 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17225 (define_expand "atanxf2"
17226 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17227 (unspec:XF [(match_dup 2)
17228 (match_operand:XF 1 "register_operand" "")]
17230 (clobber (match_scratch:XF 3 ""))])]
17231 "TARGET_USE_FANCY_MATH_387
17232 && flag_unsafe_math_optimizations"
17234 operands[2] = gen_reg_rtx (XFmode);
17235 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17238 (define_expand "atan<mode>2"
17239 [(use (match_operand:MODEF 0 "register_operand" ""))
17240 (use (match_operand:MODEF 1 "register_operand" ""))]
17241 "TARGET_USE_FANCY_MATH_387
17242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17243 || TARGET_MIX_SSE_I387)
17244 && flag_unsafe_math_optimizations"
17246 rtx op0 = gen_reg_rtx (XFmode);
17248 rtx op2 = gen_reg_rtx (<MODE>mode);
17249 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17251 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17252 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17256 (define_expand "asinxf2"
17257 [(set (match_dup 2)
17258 (mult:XF (match_operand:XF 1 "register_operand" "")
17260 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17261 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17262 (parallel [(set (match_operand:XF 0 "register_operand" "")
17263 (unspec:XF [(match_dup 5) (match_dup 1)]
17265 (clobber (match_scratch:XF 6 ""))])]
17266 "TARGET_USE_FANCY_MATH_387
17267 && flag_unsafe_math_optimizations"
17271 if (optimize_insn_for_size_p ())
17274 for (i = 2; i < 6; i++)
17275 operands[i] = gen_reg_rtx (XFmode);
17277 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17280 (define_expand "asin<mode>2"
17281 [(use (match_operand:MODEF 0 "register_operand" ""))
17282 (use (match_operand:MODEF 1 "general_operand" ""))]
17283 "TARGET_USE_FANCY_MATH_387
17284 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17285 || TARGET_MIX_SSE_I387)
17286 && flag_unsafe_math_optimizations"
17288 rtx op0 = gen_reg_rtx (XFmode);
17289 rtx op1 = gen_reg_rtx (XFmode);
17291 if (optimize_insn_for_size_p ())
17294 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17295 emit_insn (gen_asinxf2 (op0, op1));
17296 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17300 (define_expand "acosxf2"
17301 [(set (match_dup 2)
17302 (mult:XF (match_operand:XF 1 "register_operand" "")
17304 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17305 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17306 (parallel [(set (match_operand:XF 0 "register_operand" "")
17307 (unspec:XF [(match_dup 1) (match_dup 5)]
17309 (clobber (match_scratch:XF 6 ""))])]
17310 "TARGET_USE_FANCY_MATH_387
17311 && flag_unsafe_math_optimizations"
17315 if (optimize_insn_for_size_p ())
17318 for (i = 2; i < 6; i++)
17319 operands[i] = gen_reg_rtx (XFmode);
17321 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17324 (define_expand "acos<mode>2"
17325 [(use (match_operand:MODEF 0 "register_operand" ""))
17326 (use (match_operand:MODEF 1 "general_operand" ""))]
17327 "TARGET_USE_FANCY_MATH_387
17328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17329 || TARGET_MIX_SSE_I387)
17330 && flag_unsafe_math_optimizations"
17332 rtx op0 = gen_reg_rtx (XFmode);
17333 rtx op1 = gen_reg_rtx (XFmode);
17335 if (optimize_insn_for_size_p ())
17338 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17339 emit_insn (gen_acosxf2 (op0, op1));
17340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17344 (define_insn "fyl2xxf3_i387"
17345 [(set (match_operand:XF 0 "register_operand" "=f")
17346 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17347 (match_operand:XF 2 "register_operand" "u")]
17349 (clobber (match_scratch:XF 3 "=2"))]
17350 "TARGET_USE_FANCY_MATH_387
17351 && flag_unsafe_math_optimizations"
17353 [(set_attr "type" "fpspc")
17354 (set_attr "mode" "XF")])
17356 (define_insn "fyl2x_extend<mode>xf3_i387"
17357 [(set (match_operand:XF 0 "register_operand" "=f")
17358 (unspec:XF [(float_extend:XF
17359 (match_operand:MODEF 1 "register_operand" "0"))
17360 (match_operand:XF 2 "register_operand" "u")]
17362 (clobber (match_scratch:XF 3 "=2"))]
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 [(set_attr "type" "fpspc")
17369 (set_attr "mode" "XF")])
17371 (define_expand "logxf2"
17372 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17373 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17374 (match_dup 2)] UNSPEC_FYL2X))
17375 (clobber (match_scratch:XF 3 ""))])]
17376 "TARGET_USE_FANCY_MATH_387
17377 && flag_unsafe_math_optimizations"
17379 operands[2] = gen_reg_rtx (XFmode);
17380 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17383 (define_expand "log<mode>2"
17384 [(use (match_operand:MODEF 0 "register_operand" ""))
17385 (use (match_operand:MODEF 1 "register_operand" ""))]
17386 "TARGET_USE_FANCY_MATH_387
17387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17388 || TARGET_MIX_SSE_I387)
17389 && flag_unsafe_math_optimizations"
17391 rtx op0 = gen_reg_rtx (XFmode);
17393 rtx op2 = gen_reg_rtx (XFmode);
17394 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17396 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17397 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17401 (define_expand "log10xf2"
17402 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17403 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17404 (match_dup 2)] UNSPEC_FYL2X))
17405 (clobber (match_scratch:XF 3 ""))])]
17406 "TARGET_USE_FANCY_MATH_387
17407 && flag_unsafe_math_optimizations"
17409 operands[2] = gen_reg_rtx (XFmode);
17410 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17413 (define_expand "log10<mode>2"
17414 [(use (match_operand:MODEF 0 "register_operand" ""))
17415 (use (match_operand:MODEF 1 "register_operand" ""))]
17416 "TARGET_USE_FANCY_MATH_387
17417 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17418 || TARGET_MIX_SSE_I387)
17419 && flag_unsafe_math_optimizations"
17421 rtx op0 = gen_reg_rtx (XFmode);
17423 rtx op2 = gen_reg_rtx (XFmode);
17424 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17426 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17427 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17431 (define_expand "log2xf2"
17432 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17433 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17434 (match_dup 2)] UNSPEC_FYL2X))
17435 (clobber (match_scratch:XF 3 ""))])]
17436 "TARGET_USE_FANCY_MATH_387
17437 && flag_unsafe_math_optimizations"
17439 operands[2] = gen_reg_rtx (XFmode);
17440 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17443 (define_expand "log2<mode>2"
17444 [(use (match_operand:MODEF 0 "register_operand" ""))
17445 (use (match_operand:MODEF 1 "register_operand" ""))]
17446 "TARGET_USE_FANCY_MATH_387
17447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17448 || TARGET_MIX_SSE_I387)
17449 && flag_unsafe_math_optimizations"
17451 rtx op0 = gen_reg_rtx (XFmode);
17453 rtx op2 = gen_reg_rtx (XFmode);
17454 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17456 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17457 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17461 (define_insn "fyl2xp1xf3_i387"
17462 [(set (match_operand:XF 0 "register_operand" "=f")
17463 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17464 (match_operand:XF 2 "register_operand" "u")]
17466 (clobber (match_scratch:XF 3 "=2"))]
17467 "TARGET_USE_FANCY_MATH_387
17468 && flag_unsafe_math_optimizations"
17470 [(set_attr "type" "fpspc")
17471 (set_attr "mode" "XF")])
17473 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17474 [(set (match_operand:XF 0 "register_operand" "=f")
17475 (unspec:XF [(float_extend:XF
17476 (match_operand:MODEF 1 "register_operand" "0"))
17477 (match_operand:XF 2 "register_operand" "u")]
17479 (clobber (match_scratch:XF 3 "=2"))]
17480 "TARGET_USE_FANCY_MATH_387
17481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17482 || TARGET_MIX_SSE_I387)
17483 && flag_unsafe_math_optimizations"
17485 [(set_attr "type" "fpspc")
17486 (set_attr "mode" "XF")])
17488 (define_expand "log1pxf2"
17489 [(use (match_operand:XF 0 "register_operand" ""))
17490 (use (match_operand:XF 1 "register_operand" ""))]
17491 "TARGET_USE_FANCY_MATH_387
17492 && flag_unsafe_math_optimizations"
17494 if (optimize_insn_for_size_p ())
17497 ix86_emit_i387_log1p (operands[0], operands[1]);
17501 (define_expand "log1p<mode>2"
17502 [(use (match_operand:MODEF 0 "register_operand" ""))
17503 (use (match_operand:MODEF 1 "register_operand" ""))]
17504 "TARGET_USE_FANCY_MATH_387
17505 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17506 || TARGET_MIX_SSE_I387)
17507 && flag_unsafe_math_optimizations"
17511 if (optimize_insn_for_size_p ())
17514 op0 = gen_reg_rtx (XFmode);
17516 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17518 ix86_emit_i387_log1p (op0, operands[1]);
17519 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17523 (define_insn "fxtractxf3_i387"
17524 [(set (match_operand:XF 0 "register_operand" "=f")
17525 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17526 UNSPEC_XTRACT_FRACT))
17527 (set (match_operand:XF 1 "register_operand" "=u")
17528 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17529 "TARGET_USE_FANCY_MATH_387
17530 && flag_unsafe_math_optimizations"
17532 [(set_attr "type" "fpspc")
17533 (set_attr "mode" "XF")])
17535 (define_insn "fxtract_extend<mode>xf3_i387"
17536 [(set (match_operand:XF 0 "register_operand" "=f")
17537 (unspec:XF [(float_extend:XF
17538 (match_operand:MODEF 2 "register_operand" "0"))]
17539 UNSPEC_XTRACT_FRACT))
17540 (set (match_operand:XF 1 "register_operand" "=u")
17541 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17542 "TARGET_USE_FANCY_MATH_387
17543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17544 || TARGET_MIX_SSE_I387)
17545 && flag_unsafe_math_optimizations"
17547 [(set_attr "type" "fpspc")
17548 (set_attr "mode" "XF")])
17550 (define_expand "logbxf2"
17551 [(parallel [(set (match_dup 2)
17552 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17553 UNSPEC_XTRACT_FRACT))
17554 (set (match_operand:XF 0 "register_operand" "")
17555 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17556 "TARGET_USE_FANCY_MATH_387
17557 && flag_unsafe_math_optimizations"
17559 operands[2] = gen_reg_rtx (XFmode);
17562 (define_expand "logb<mode>2"
17563 [(use (match_operand:MODEF 0 "register_operand" ""))
17564 (use (match_operand:MODEF 1 "register_operand" ""))]
17565 "TARGET_USE_FANCY_MATH_387
17566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17567 || TARGET_MIX_SSE_I387)
17568 && flag_unsafe_math_optimizations"
17570 rtx op0 = gen_reg_rtx (XFmode);
17571 rtx op1 = gen_reg_rtx (XFmode);
17573 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17574 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17578 (define_expand "ilogbxf2"
17579 [(use (match_operand:SI 0 "register_operand" ""))
17580 (use (match_operand:XF 1 "register_operand" ""))]
17581 "TARGET_USE_FANCY_MATH_387
17582 && flag_unsafe_math_optimizations"
17586 if (optimize_insn_for_size_p ())
17589 op0 = gen_reg_rtx (XFmode);
17590 op1 = gen_reg_rtx (XFmode);
17592 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17593 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17597 (define_expand "ilogb<mode>2"
17598 [(use (match_operand:SI 0 "register_operand" ""))
17599 (use (match_operand:MODEF 1 "register_operand" ""))]
17600 "TARGET_USE_FANCY_MATH_387
17601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17602 || TARGET_MIX_SSE_I387)
17603 && flag_unsafe_math_optimizations"
17607 if (optimize_insn_for_size_p ())
17610 op0 = gen_reg_rtx (XFmode);
17611 op1 = gen_reg_rtx (XFmode);
17613 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17614 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17618 (define_insn "*f2xm1xf2_i387"
17619 [(set (match_operand:XF 0 "register_operand" "=f")
17620 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17622 "TARGET_USE_FANCY_MATH_387
17623 && flag_unsafe_math_optimizations"
17625 [(set_attr "type" "fpspc")
17626 (set_attr "mode" "XF")])
17628 (define_insn "*fscalexf4_i387"
17629 [(set (match_operand:XF 0 "register_operand" "=f")
17630 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17631 (match_operand:XF 3 "register_operand" "1")]
17632 UNSPEC_FSCALE_FRACT))
17633 (set (match_operand:XF 1 "register_operand" "=u")
17634 (unspec:XF [(match_dup 2) (match_dup 3)]
17635 UNSPEC_FSCALE_EXP))]
17636 "TARGET_USE_FANCY_MATH_387
17637 && flag_unsafe_math_optimizations"
17639 [(set_attr "type" "fpspc")
17640 (set_attr "mode" "XF")])
17642 (define_expand "expNcorexf3"
17643 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17644 (match_operand:XF 2 "register_operand" "")))
17645 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17646 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17647 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17648 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17649 (parallel [(set (match_operand:XF 0 "register_operand" "")
17650 (unspec:XF [(match_dup 8) (match_dup 4)]
17651 UNSPEC_FSCALE_FRACT))
17653 (unspec:XF [(match_dup 8) (match_dup 4)]
17654 UNSPEC_FSCALE_EXP))])]
17655 "TARGET_USE_FANCY_MATH_387
17656 && flag_unsafe_math_optimizations"
17660 if (optimize_insn_for_size_p ())
17663 for (i = 3; i < 10; i++)
17664 operands[i] = gen_reg_rtx (XFmode);
17666 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17669 (define_expand "expxf2"
17670 [(use (match_operand:XF 0 "register_operand" ""))
17671 (use (match_operand:XF 1 "register_operand" ""))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && flag_unsafe_math_optimizations"
17677 if (optimize_insn_for_size_p ())
17680 op2 = gen_reg_rtx (XFmode);
17681 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17683 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17687 (define_expand "exp<mode>2"
17688 [(use (match_operand:MODEF 0 "register_operand" ""))
17689 (use (match_operand:MODEF 1 "general_operand" ""))]
17690 "TARGET_USE_FANCY_MATH_387
17691 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17692 || TARGET_MIX_SSE_I387)
17693 && flag_unsafe_math_optimizations"
17697 if (optimize_insn_for_size_p ())
17700 op0 = gen_reg_rtx (XFmode);
17701 op1 = gen_reg_rtx (XFmode);
17703 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17704 emit_insn (gen_expxf2 (op0, op1));
17705 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17709 (define_expand "exp10xf2"
17710 [(use (match_operand:XF 0 "register_operand" ""))
17711 (use (match_operand:XF 1 "register_operand" ""))]
17712 "TARGET_USE_FANCY_MATH_387
17713 && flag_unsafe_math_optimizations"
17717 if (optimize_insn_for_size_p ())
17720 op2 = gen_reg_rtx (XFmode);
17721 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17723 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17727 (define_expand "exp10<mode>2"
17728 [(use (match_operand:MODEF 0 "register_operand" ""))
17729 (use (match_operand:MODEF 1 "general_operand" ""))]
17730 "TARGET_USE_FANCY_MATH_387
17731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17732 || TARGET_MIX_SSE_I387)
17733 && flag_unsafe_math_optimizations"
17737 if (optimize_insn_for_size_p ())
17740 op0 = gen_reg_rtx (XFmode);
17741 op1 = gen_reg_rtx (XFmode);
17743 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17744 emit_insn (gen_exp10xf2 (op0, op1));
17745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17749 (define_expand "exp2xf2"
17750 [(use (match_operand:XF 0 "register_operand" ""))
17751 (use (match_operand:XF 1 "register_operand" ""))]
17752 "TARGET_USE_FANCY_MATH_387
17753 && flag_unsafe_math_optimizations"
17757 if (optimize_insn_for_size_p ())
17760 op2 = gen_reg_rtx (XFmode);
17761 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17763 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17767 (define_expand "exp2<mode>2"
17768 [(use (match_operand:MODEF 0 "register_operand" ""))
17769 (use (match_operand:MODEF 1 "general_operand" ""))]
17770 "TARGET_USE_FANCY_MATH_387
17771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17772 || TARGET_MIX_SSE_I387)
17773 && flag_unsafe_math_optimizations"
17777 if (optimize_insn_for_size_p ())
17780 op0 = gen_reg_rtx (XFmode);
17781 op1 = gen_reg_rtx (XFmode);
17783 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17784 emit_insn (gen_exp2xf2 (op0, op1));
17785 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17789 (define_expand "expm1xf2"
17790 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17792 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17793 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17794 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17795 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17796 (parallel [(set (match_dup 7)
17797 (unspec:XF [(match_dup 6) (match_dup 4)]
17798 UNSPEC_FSCALE_FRACT))
17800 (unspec:XF [(match_dup 6) (match_dup 4)]
17801 UNSPEC_FSCALE_EXP))])
17802 (parallel [(set (match_dup 10)
17803 (unspec:XF [(match_dup 9) (match_dup 8)]
17804 UNSPEC_FSCALE_FRACT))
17805 (set (match_dup 11)
17806 (unspec:XF [(match_dup 9) (match_dup 8)]
17807 UNSPEC_FSCALE_EXP))])
17808 (set (match_dup 12) (minus:XF (match_dup 10)
17809 (float_extend:XF (match_dup 13))))
17810 (set (match_operand:XF 0 "register_operand" "")
17811 (plus:XF (match_dup 12) (match_dup 7)))]
17812 "TARGET_USE_FANCY_MATH_387
17813 && flag_unsafe_math_optimizations"
17817 if (optimize_insn_for_size_p ())
17820 for (i = 2; i < 13; i++)
17821 operands[i] = gen_reg_rtx (XFmode);
17824 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17826 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17829 (define_expand "expm1<mode>2"
17830 [(use (match_operand:MODEF 0 "register_operand" ""))
17831 (use (match_operand:MODEF 1 "general_operand" ""))]
17832 "TARGET_USE_FANCY_MATH_387
17833 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17834 || TARGET_MIX_SSE_I387)
17835 && flag_unsafe_math_optimizations"
17839 if (optimize_insn_for_size_p ())
17842 op0 = gen_reg_rtx (XFmode);
17843 op1 = gen_reg_rtx (XFmode);
17845 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17846 emit_insn (gen_expm1xf2 (op0, op1));
17847 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17851 (define_expand "ldexpxf3"
17852 [(set (match_dup 3)
17853 (float:XF (match_operand:SI 2 "register_operand" "")))
17854 (parallel [(set (match_operand:XF 0 " register_operand" "")
17855 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17857 UNSPEC_FSCALE_FRACT))
17859 (unspec:XF [(match_dup 1) (match_dup 3)]
17860 UNSPEC_FSCALE_EXP))])]
17861 "TARGET_USE_FANCY_MATH_387
17862 && flag_unsafe_math_optimizations"
17864 if (optimize_insn_for_size_p ())
17867 operands[3] = gen_reg_rtx (XFmode);
17868 operands[4] = gen_reg_rtx (XFmode);
17871 (define_expand "ldexp<mode>3"
17872 [(use (match_operand:MODEF 0 "register_operand" ""))
17873 (use (match_operand:MODEF 1 "general_operand" ""))
17874 (use (match_operand:SI 2 "register_operand" ""))]
17875 "TARGET_USE_FANCY_MATH_387
17876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17877 || TARGET_MIX_SSE_I387)
17878 && flag_unsafe_math_optimizations"
17882 if (optimize_insn_for_size_p ())
17885 op0 = gen_reg_rtx (XFmode);
17886 op1 = gen_reg_rtx (XFmode);
17888 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17889 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17890 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17894 (define_expand "scalbxf3"
17895 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17896 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17897 (match_operand:XF 2 "register_operand" "")]
17898 UNSPEC_FSCALE_FRACT))
17900 (unspec:XF [(match_dup 1) (match_dup 2)]
17901 UNSPEC_FSCALE_EXP))])]
17902 "TARGET_USE_FANCY_MATH_387
17903 && flag_unsafe_math_optimizations"
17905 if (optimize_insn_for_size_p ())
17908 operands[3] = gen_reg_rtx (XFmode);
17911 (define_expand "scalb<mode>3"
17912 [(use (match_operand:MODEF 0 "register_operand" ""))
17913 (use (match_operand:MODEF 1 "general_operand" ""))
17914 (use (match_operand:MODEF 2 "register_operand" ""))]
17915 "TARGET_USE_FANCY_MATH_387
17916 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17917 || TARGET_MIX_SSE_I387)
17918 && flag_unsafe_math_optimizations"
17922 if (optimize_insn_for_size_p ())
17925 op0 = gen_reg_rtx (XFmode);
17926 op1 = gen_reg_rtx (XFmode);
17927 op2 = gen_reg_rtx (XFmode);
17929 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17930 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17931 emit_insn (gen_scalbxf3 (op0, op1, op2));
17932 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17937 (define_insn "sse4_1_round<mode>2"
17938 [(set (match_operand:MODEF 0 "register_operand" "=x")
17939 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17940 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17943 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17944 [(set_attr "type" "ssecvt")
17945 (set_attr "prefix_extra" "1")
17946 (set_attr "prefix" "maybe_vex")
17947 (set_attr "mode" "<MODE>")])
17949 (define_insn "rintxf2"
17950 [(set (match_operand:XF 0 "register_operand" "=f")
17951 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17953 "TARGET_USE_FANCY_MATH_387
17954 && flag_unsafe_math_optimizations"
17956 [(set_attr "type" "fpspc")
17957 (set_attr "mode" "XF")])
17959 (define_expand "rint<mode>2"
17960 [(use (match_operand:MODEF 0 "register_operand" ""))
17961 (use (match_operand:MODEF 1 "register_operand" ""))]
17962 "(TARGET_USE_FANCY_MATH_387
17963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17964 || TARGET_MIX_SSE_I387)
17965 && flag_unsafe_math_optimizations)
17966 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17967 && !flag_trapping_math)"
17969 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17970 && !flag_trapping_math)
17972 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17975 emit_insn (gen_sse4_1_round<mode>2
17976 (operands[0], operands[1], GEN_INT (0x04)));
17978 ix86_expand_rint (operand0, operand1);
17982 rtx op0 = gen_reg_rtx (XFmode);
17983 rtx op1 = gen_reg_rtx (XFmode);
17985 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17986 emit_insn (gen_rintxf2 (op0, op1));
17988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17993 (define_expand "round<mode>2"
17994 [(match_operand:MODEF 0 "register_operand" "")
17995 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17996 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17997 && !flag_trapping_math && !flag_rounding_math"
17999 if (optimize_insn_for_size_p ())
18001 if (TARGET_64BIT || (<MODE>mode != DFmode))
18002 ix86_expand_round (operand0, operand1);
18004 ix86_expand_rounddf_32 (operand0, operand1);
18008 (define_insn_and_split "*fistdi2_1"
18009 [(set (match_operand:DI 0 "nonimmediate_operand" "")
18010 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18012 "TARGET_USE_FANCY_MATH_387
18013 && !(reload_completed || reload_in_progress)"
18018 if (memory_operand (operands[0], VOIDmode))
18019 emit_insn (gen_fistdi2 (operands[0], operands[1]));
18022 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18023 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18028 [(set_attr "type" "fpspc")
18029 (set_attr "mode" "DI")])
18031 (define_insn "fistdi2"
18032 [(set (match_operand:DI 0 "memory_operand" "=m")
18033 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18035 (clobber (match_scratch:XF 2 "=&1f"))]
18036 "TARGET_USE_FANCY_MATH_387"
18037 "* return output_fix_trunc (insn, operands, 0);"
18038 [(set_attr "type" "fpspc")
18039 (set_attr "mode" "DI")])
18041 (define_insn "fistdi2_with_temp"
18042 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18043 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18045 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18046 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18047 "TARGET_USE_FANCY_MATH_387"
18049 [(set_attr "type" "fpspc")
18050 (set_attr "mode" "DI")])
18053 [(set (match_operand:DI 0 "register_operand" "")
18054 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18056 (clobber (match_operand:DI 2 "memory_operand" ""))
18057 (clobber (match_scratch 3 ""))]
18059 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18060 (clobber (match_dup 3))])
18061 (set (match_dup 0) (match_dup 2))]
18065 [(set (match_operand:DI 0 "memory_operand" "")
18066 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18068 (clobber (match_operand:DI 2 "memory_operand" ""))
18069 (clobber (match_scratch 3 ""))]
18071 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18072 (clobber (match_dup 3))])]
18075 (define_insn_and_split "*fist<mode>2_1"
18076 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18077 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18079 "TARGET_USE_FANCY_MATH_387
18080 && !(reload_completed || reload_in_progress)"
18085 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18086 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18090 [(set_attr "type" "fpspc")
18091 (set_attr "mode" "<MODE>")])
18093 (define_insn "fist<mode>2"
18094 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18095 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18097 "TARGET_USE_FANCY_MATH_387"
18098 "* return output_fix_trunc (insn, operands, 0);"
18099 [(set_attr "type" "fpspc")
18100 (set_attr "mode" "<MODE>")])
18102 (define_insn "fist<mode>2_with_temp"
18103 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18104 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18106 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18107 "TARGET_USE_FANCY_MATH_387"
18109 [(set_attr "type" "fpspc")
18110 (set_attr "mode" "<MODE>")])
18113 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18114 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18116 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18118 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18119 (set (match_dup 0) (match_dup 2))]
18123 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18124 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18126 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18128 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18131 (define_expand "lrintxf<mode>2"
18132 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18133 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18135 "TARGET_USE_FANCY_MATH_387"
18138 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18139 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18140 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18141 UNSPEC_FIX_NOTRUNC))]
18142 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18143 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18146 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18147 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18148 (match_operand:MODEF 1 "register_operand" "")]
18149 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18150 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18151 && !flag_trapping_math && !flag_rounding_math"
18153 if (optimize_insn_for_size_p ())
18155 ix86_expand_lround (operand0, operand1);
18159 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18160 (define_insn_and_split "frndintxf2_floor"
18161 [(set (match_operand:XF 0 "register_operand" "")
18162 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18163 UNSPEC_FRNDINT_FLOOR))
18164 (clobber (reg:CC FLAGS_REG))]
18165 "TARGET_USE_FANCY_MATH_387
18166 && flag_unsafe_math_optimizations
18167 && !(reload_completed || reload_in_progress)"
18172 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18174 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18175 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18177 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18178 operands[2], operands[3]));
18181 [(set_attr "type" "frndint")
18182 (set_attr "i387_cw" "floor")
18183 (set_attr "mode" "XF")])
18185 (define_insn "frndintxf2_floor_i387"
18186 [(set (match_operand:XF 0 "register_operand" "=f")
18187 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18188 UNSPEC_FRNDINT_FLOOR))
18189 (use (match_operand:HI 2 "memory_operand" "m"))
18190 (use (match_operand:HI 3 "memory_operand" "m"))]
18191 "TARGET_USE_FANCY_MATH_387
18192 && flag_unsafe_math_optimizations"
18193 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18194 [(set_attr "type" "frndint")
18195 (set_attr "i387_cw" "floor")
18196 (set_attr "mode" "XF")])
18198 (define_expand "floorxf2"
18199 [(use (match_operand:XF 0 "register_operand" ""))
18200 (use (match_operand:XF 1 "register_operand" ""))]
18201 "TARGET_USE_FANCY_MATH_387
18202 && flag_unsafe_math_optimizations"
18204 if (optimize_insn_for_size_p ())
18206 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18210 (define_expand "floor<mode>2"
18211 [(use (match_operand:MODEF 0 "register_operand" ""))
18212 (use (match_operand:MODEF 1 "register_operand" ""))]
18213 "(TARGET_USE_FANCY_MATH_387
18214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18215 || TARGET_MIX_SSE_I387)
18216 && flag_unsafe_math_optimizations)
18217 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18218 && !flag_trapping_math)"
18220 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18221 && !flag_trapping_math
18222 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18224 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18227 emit_insn (gen_sse4_1_round<mode>2
18228 (operands[0], operands[1], GEN_INT (0x01)));
18229 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18230 ix86_expand_floorceil (operand0, operand1, true);
18232 ix86_expand_floorceildf_32 (operand0, operand1, true);
18238 if (optimize_insn_for_size_p ())
18241 op0 = gen_reg_rtx (XFmode);
18242 op1 = gen_reg_rtx (XFmode);
18243 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18244 emit_insn (gen_frndintxf2_floor (op0, op1));
18246 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18251 (define_insn_and_split "*fist<mode>2_floor_1"
18252 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18253 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18254 UNSPEC_FIST_FLOOR))
18255 (clobber (reg:CC FLAGS_REG))]
18256 "TARGET_USE_FANCY_MATH_387
18257 && flag_unsafe_math_optimizations
18258 && !(reload_completed || reload_in_progress)"
18263 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18265 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18266 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18267 if (memory_operand (operands[0], VOIDmode))
18268 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18269 operands[2], operands[3]));
18272 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18273 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18274 operands[2], operands[3],
18279 [(set_attr "type" "fistp")
18280 (set_attr "i387_cw" "floor")
18281 (set_attr "mode" "<MODE>")])
18283 (define_insn "fistdi2_floor"
18284 [(set (match_operand:DI 0 "memory_operand" "=m")
18285 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18286 UNSPEC_FIST_FLOOR))
18287 (use (match_operand:HI 2 "memory_operand" "m"))
18288 (use (match_operand:HI 3 "memory_operand" "m"))
18289 (clobber (match_scratch:XF 4 "=&1f"))]
18290 "TARGET_USE_FANCY_MATH_387
18291 && flag_unsafe_math_optimizations"
18292 "* return output_fix_trunc (insn, operands, 0);"
18293 [(set_attr "type" "fistp")
18294 (set_attr "i387_cw" "floor")
18295 (set_attr "mode" "DI")])
18297 (define_insn "fistdi2_floor_with_temp"
18298 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18299 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18300 UNSPEC_FIST_FLOOR))
18301 (use (match_operand:HI 2 "memory_operand" "m,m"))
18302 (use (match_operand:HI 3 "memory_operand" "m,m"))
18303 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18304 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18305 "TARGET_USE_FANCY_MATH_387
18306 && flag_unsafe_math_optimizations"
18308 [(set_attr "type" "fistp")
18309 (set_attr "i387_cw" "floor")
18310 (set_attr "mode" "DI")])
18313 [(set (match_operand:DI 0 "register_operand" "")
18314 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18315 UNSPEC_FIST_FLOOR))
18316 (use (match_operand:HI 2 "memory_operand" ""))
18317 (use (match_operand:HI 3 "memory_operand" ""))
18318 (clobber (match_operand:DI 4 "memory_operand" ""))
18319 (clobber (match_scratch 5 ""))]
18321 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18322 (use (match_dup 2))
18323 (use (match_dup 3))
18324 (clobber (match_dup 5))])
18325 (set (match_dup 0) (match_dup 4))]
18329 [(set (match_operand:DI 0 "memory_operand" "")
18330 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18331 UNSPEC_FIST_FLOOR))
18332 (use (match_operand:HI 2 "memory_operand" ""))
18333 (use (match_operand:HI 3 "memory_operand" ""))
18334 (clobber (match_operand:DI 4 "memory_operand" ""))
18335 (clobber (match_scratch 5 ""))]
18337 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18338 (use (match_dup 2))
18339 (use (match_dup 3))
18340 (clobber (match_dup 5))])]
18343 (define_insn "fist<mode>2_floor"
18344 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18345 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18346 UNSPEC_FIST_FLOOR))
18347 (use (match_operand:HI 2 "memory_operand" "m"))
18348 (use (match_operand:HI 3 "memory_operand" "m"))]
18349 "TARGET_USE_FANCY_MATH_387
18350 && flag_unsafe_math_optimizations"
18351 "* return output_fix_trunc (insn, operands, 0);"
18352 [(set_attr "type" "fistp")
18353 (set_attr "i387_cw" "floor")
18354 (set_attr "mode" "<MODE>")])
18356 (define_insn "fist<mode>2_floor_with_temp"
18357 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18358 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18359 UNSPEC_FIST_FLOOR))
18360 (use (match_operand:HI 2 "memory_operand" "m,m"))
18361 (use (match_operand:HI 3 "memory_operand" "m,m"))
18362 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18363 "TARGET_USE_FANCY_MATH_387
18364 && flag_unsafe_math_optimizations"
18366 [(set_attr "type" "fistp")
18367 (set_attr "i387_cw" "floor")
18368 (set_attr "mode" "<MODE>")])
18371 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18372 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18373 UNSPEC_FIST_FLOOR))
18374 (use (match_operand:HI 2 "memory_operand" ""))
18375 (use (match_operand:HI 3 "memory_operand" ""))
18376 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18378 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18379 UNSPEC_FIST_FLOOR))
18380 (use (match_dup 2))
18381 (use (match_dup 3))])
18382 (set (match_dup 0) (match_dup 4))]
18386 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18387 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18388 UNSPEC_FIST_FLOOR))
18389 (use (match_operand:HI 2 "memory_operand" ""))
18390 (use (match_operand:HI 3 "memory_operand" ""))
18391 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18393 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18394 UNSPEC_FIST_FLOOR))
18395 (use (match_dup 2))
18396 (use (match_dup 3))])]
18399 (define_expand "lfloorxf<mode>2"
18400 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18401 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18402 UNSPEC_FIST_FLOOR))
18403 (clobber (reg:CC FLAGS_REG))])]
18404 "TARGET_USE_FANCY_MATH_387
18405 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18406 && flag_unsafe_math_optimizations"
18409 (define_expand "lfloor<mode>di2"
18410 [(match_operand:DI 0 "nonimmediate_operand" "")
18411 (match_operand:MODEF 1 "register_operand" "")]
18412 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18413 && !flag_trapping_math"
18415 if (optimize_insn_for_size_p ())
18417 ix86_expand_lfloorceil (operand0, operand1, true);
18421 (define_expand "lfloor<mode>si2"
18422 [(match_operand:SI 0 "nonimmediate_operand" "")
18423 (match_operand:MODEF 1 "register_operand" "")]
18424 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18425 && !flag_trapping_math"
18427 if (optimize_insn_for_size_p () && TARGET_64BIT)
18429 ix86_expand_lfloorceil (operand0, operand1, true);
18433 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18434 (define_insn_and_split "frndintxf2_ceil"
18435 [(set (match_operand:XF 0 "register_operand" "")
18436 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18437 UNSPEC_FRNDINT_CEIL))
18438 (clobber (reg:CC FLAGS_REG))]
18439 "TARGET_USE_FANCY_MATH_387
18440 && flag_unsafe_math_optimizations
18441 && !(reload_completed || reload_in_progress)"
18446 ix86_optimize_mode_switching[I387_CEIL] = 1;
18448 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18449 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18451 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18452 operands[2], operands[3]));
18455 [(set_attr "type" "frndint")
18456 (set_attr "i387_cw" "ceil")
18457 (set_attr "mode" "XF")])
18459 (define_insn "frndintxf2_ceil_i387"
18460 [(set (match_operand:XF 0 "register_operand" "=f")
18461 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18462 UNSPEC_FRNDINT_CEIL))
18463 (use (match_operand:HI 2 "memory_operand" "m"))
18464 (use (match_operand:HI 3 "memory_operand" "m"))]
18465 "TARGET_USE_FANCY_MATH_387
18466 && flag_unsafe_math_optimizations"
18467 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18468 [(set_attr "type" "frndint")
18469 (set_attr "i387_cw" "ceil")
18470 (set_attr "mode" "XF")])
18472 (define_expand "ceilxf2"
18473 [(use (match_operand:XF 0 "register_operand" ""))
18474 (use (match_operand:XF 1 "register_operand" ""))]
18475 "TARGET_USE_FANCY_MATH_387
18476 && flag_unsafe_math_optimizations"
18478 if (optimize_insn_for_size_p ())
18480 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18484 (define_expand "ceil<mode>2"
18485 [(use (match_operand:MODEF 0 "register_operand" ""))
18486 (use (match_operand:MODEF 1 "register_operand" ""))]
18487 "(TARGET_USE_FANCY_MATH_387
18488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18489 || TARGET_MIX_SSE_I387)
18490 && flag_unsafe_math_optimizations)
18491 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18492 && !flag_trapping_math)"
18494 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18495 && !flag_trapping_math
18496 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18499 emit_insn (gen_sse4_1_round<mode>2
18500 (operands[0], operands[1], GEN_INT (0x02)));
18501 else if (optimize_insn_for_size_p ())
18503 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18504 ix86_expand_floorceil (operand0, operand1, false);
18506 ix86_expand_floorceildf_32 (operand0, operand1, false);
18512 if (optimize_insn_for_size_p ())
18515 op0 = gen_reg_rtx (XFmode);
18516 op1 = gen_reg_rtx (XFmode);
18517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18518 emit_insn (gen_frndintxf2_ceil (op0, op1));
18520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18525 (define_insn_and_split "*fist<mode>2_ceil_1"
18526 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18527 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18529 (clobber (reg:CC FLAGS_REG))]
18530 "TARGET_USE_FANCY_MATH_387
18531 && flag_unsafe_math_optimizations
18532 && !(reload_completed || reload_in_progress)"
18537 ix86_optimize_mode_switching[I387_CEIL] = 1;
18539 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18540 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18541 if (memory_operand (operands[0], VOIDmode))
18542 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18543 operands[2], operands[3]));
18546 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18547 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18548 operands[2], operands[3],
18553 [(set_attr "type" "fistp")
18554 (set_attr "i387_cw" "ceil")
18555 (set_attr "mode" "<MODE>")])
18557 (define_insn "fistdi2_ceil"
18558 [(set (match_operand:DI 0 "memory_operand" "=m")
18559 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18561 (use (match_operand:HI 2 "memory_operand" "m"))
18562 (use (match_operand:HI 3 "memory_operand" "m"))
18563 (clobber (match_scratch:XF 4 "=&1f"))]
18564 "TARGET_USE_FANCY_MATH_387
18565 && flag_unsafe_math_optimizations"
18566 "* return output_fix_trunc (insn, operands, 0);"
18567 [(set_attr "type" "fistp")
18568 (set_attr "i387_cw" "ceil")
18569 (set_attr "mode" "DI")])
18571 (define_insn "fistdi2_ceil_with_temp"
18572 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18573 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18575 (use (match_operand:HI 2 "memory_operand" "m,m"))
18576 (use (match_operand:HI 3 "memory_operand" "m,m"))
18577 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18578 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18579 "TARGET_USE_FANCY_MATH_387
18580 && flag_unsafe_math_optimizations"
18582 [(set_attr "type" "fistp")
18583 (set_attr "i387_cw" "ceil")
18584 (set_attr "mode" "DI")])
18587 [(set (match_operand:DI 0 "register_operand" "")
18588 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18590 (use (match_operand:HI 2 "memory_operand" ""))
18591 (use (match_operand:HI 3 "memory_operand" ""))
18592 (clobber (match_operand:DI 4 "memory_operand" ""))
18593 (clobber (match_scratch 5 ""))]
18595 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18596 (use (match_dup 2))
18597 (use (match_dup 3))
18598 (clobber (match_dup 5))])
18599 (set (match_dup 0) (match_dup 4))]
18603 [(set (match_operand:DI 0 "memory_operand" "")
18604 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18606 (use (match_operand:HI 2 "memory_operand" ""))
18607 (use (match_operand:HI 3 "memory_operand" ""))
18608 (clobber (match_operand:DI 4 "memory_operand" ""))
18609 (clobber (match_scratch 5 ""))]
18611 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18612 (use (match_dup 2))
18613 (use (match_dup 3))
18614 (clobber (match_dup 5))])]
18617 (define_insn "fist<mode>2_ceil"
18618 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18619 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18621 (use (match_operand:HI 2 "memory_operand" "m"))
18622 (use (match_operand:HI 3 "memory_operand" "m"))]
18623 "TARGET_USE_FANCY_MATH_387
18624 && flag_unsafe_math_optimizations"
18625 "* return output_fix_trunc (insn, operands, 0);"
18626 [(set_attr "type" "fistp")
18627 (set_attr "i387_cw" "ceil")
18628 (set_attr "mode" "<MODE>")])
18630 (define_insn "fist<mode>2_ceil_with_temp"
18631 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18632 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18634 (use (match_operand:HI 2 "memory_operand" "m,m"))
18635 (use (match_operand:HI 3 "memory_operand" "m,m"))
18636 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18637 "TARGET_USE_FANCY_MATH_387
18638 && flag_unsafe_math_optimizations"
18640 [(set_attr "type" "fistp")
18641 (set_attr "i387_cw" "ceil")
18642 (set_attr "mode" "<MODE>")])
18645 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18646 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18648 (use (match_operand:HI 2 "memory_operand" ""))
18649 (use (match_operand:HI 3 "memory_operand" ""))
18650 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18652 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18654 (use (match_dup 2))
18655 (use (match_dup 3))])
18656 (set (match_dup 0) (match_dup 4))]
18660 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18661 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18663 (use (match_operand:HI 2 "memory_operand" ""))
18664 (use (match_operand:HI 3 "memory_operand" ""))
18665 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18667 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18669 (use (match_dup 2))
18670 (use (match_dup 3))])]
18673 (define_expand "lceilxf<mode>2"
18674 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18675 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18677 (clobber (reg:CC FLAGS_REG))])]
18678 "TARGET_USE_FANCY_MATH_387
18679 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18680 && flag_unsafe_math_optimizations"
18683 (define_expand "lceil<mode>di2"
18684 [(match_operand:DI 0 "nonimmediate_operand" "")
18685 (match_operand:MODEF 1 "register_operand" "")]
18686 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18687 && !flag_trapping_math"
18689 ix86_expand_lfloorceil (operand0, operand1, false);
18693 (define_expand "lceil<mode>si2"
18694 [(match_operand:SI 0 "nonimmediate_operand" "")
18695 (match_operand:MODEF 1 "register_operand" "")]
18696 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18697 && !flag_trapping_math"
18699 ix86_expand_lfloorceil (operand0, operand1, false);
18703 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18704 (define_insn_and_split "frndintxf2_trunc"
18705 [(set (match_operand:XF 0 "register_operand" "")
18706 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18707 UNSPEC_FRNDINT_TRUNC))
18708 (clobber (reg:CC FLAGS_REG))]
18709 "TARGET_USE_FANCY_MATH_387
18710 && flag_unsafe_math_optimizations
18711 && !(reload_completed || reload_in_progress)"
18716 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18718 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18719 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18721 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18722 operands[2], operands[3]));
18725 [(set_attr "type" "frndint")
18726 (set_attr "i387_cw" "trunc")
18727 (set_attr "mode" "XF")])
18729 (define_insn "frndintxf2_trunc_i387"
18730 [(set (match_operand:XF 0 "register_operand" "=f")
18731 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18732 UNSPEC_FRNDINT_TRUNC))
18733 (use (match_operand:HI 2 "memory_operand" "m"))
18734 (use (match_operand:HI 3 "memory_operand" "m"))]
18735 "TARGET_USE_FANCY_MATH_387
18736 && flag_unsafe_math_optimizations"
18737 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18738 [(set_attr "type" "frndint")
18739 (set_attr "i387_cw" "trunc")
18740 (set_attr "mode" "XF")])
18742 (define_expand "btruncxf2"
18743 [(use (match_operand:XF 0 "register_operand" ""))
18744 (use (match_operand:XF 1 "register_operand" ""))]
18745 "TARGET_USE_FANCY_MATH_387
18746 && flag_unsafe_math_optimizations"
18748 if (optimize_insn_for_size_p ())
18750 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18754 (define_expand "btrunc<mode>2"
18755 [(use (match_operand:MODEF 0 "register_operand" ""))
18756 (use (match_operand:MODEF 1 "register_operand" ""))]
18757 "(TARGET_USE_FANCY_MATH_387
18758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18759 || TARGET_MIX_SSE_I387)
18760 && flag_unsafe_math_optimizations)
18761 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18762 && !flag_trapping_math)"
18764 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18765 && !flag_trapping_math
18766 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18769 emit_insn (gen_sse4_1_round<mode>2
18770 (operands[0], operands[1], GEN_INT (0x03)));
18771 else if (optimize_insn_for_size_p ())
18773 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18774 ix86_expand_trunc (operand0, operand1);
18776 ix86_expand_truncdf_32 (operand0, operand1);
18782 if (optimize_insn_for_size_p ())
18785 op0 = gen_reg_rtx (XFmode);
18786 op1 = gen_reg_rtx (XFmode);
18787 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18788 emit_insn (gen_frndintxf2_trunc (op0, op1));
18790 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18795 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18796 (define_insn_and_split "frndintxf2_mask_pm"
18797 [(set (match_operand:XF 0 "register_operand" "")
18798 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18799 UNSPEC_FRNDINT_MASK_PM))
18800 (clobber (reg:CC FLAGS_REG))]
18801 "TARGET_USE_FANCY_MATH_387
18802 && flag_unsafe_math_optimizations
18803 && !(reload_completed || reload_in_progress)"
18808 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18810 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18811 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18813 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18814 operands[2], operands[3]));
18817 [(set_attr "type" "frndint")
18818 (set_attr "i387_cw" "mask_pm")
18819 (set_attr "mode" "XF")])
18821 (define_insn "frndintxf2_mask_pm_i387"
18822 [(set (match_operand:XF 0 "register_operand" "=f")
18823 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18824 UNSPEC_FRNDINT_MASK_PM))
18825 (use (match_operand:HI 2 "memory_operand" "m"))
18826 (use (match_operand:HI 3 "memory_operand" "m"))]
18827 "TARGET_USE_FANCY_MATH_387
18828 && flag_unsafe_math_optimizations"
18829 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18830 [(set_attr "type" "frndint")
18831 (set_attr "i387_cw" "mask_pm")
18832 (set_attr "mode" "XF")])
18834 (define_expand "nearbyintxf2"
18835 [(use (match_operand:XF 0 "register_operand" ""))
18836 (use (match_operand:XF 1 "register_operand" ""))]
18837 "TARGET_USE_FANCY_MATH_387
18838 && flag_unsafe_math_optimizations"
18840 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18845 (define_expand "nearbyint<mode>2"
18846 [(use (match_operand:MODEF 0 "register_operand" ""))
18847 (use (match_operand:MODEF 1 "register_operand" ""))]
18848 "TARGET_USE_FANCY_MATH_387
18849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18850 || TARGET_MIX_SSE_I387)
18851 && flag_unsafe_math_optimizations"
18853 rtx op0 = gen_reg_rtx (XFmode);
18854 rtx op1 = gen_reg_rtx (XFmode);
18856 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18857 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18859 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18863 (define_insn "fxam<mode>2_i387"
18864 [(set (match_operand:HI 0 "register_operand" "=a")
18866 [(match_operand:X87MODEF 1 "register_operand" "f")]
18868 "TARGET_USE_FANCY_MATH_387"
18869 "fxam\n\tfnstsw\t%0"
18870 [(set_attr "type" "multi")
18871 (set_attr "unit" "i387")
18872 (set_attr "mode" "<MODE>")])
18874 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18875 [(set (match_operand:HI 0 "register_operand" "")
18877 [(match_operand:MODEF 1 "memory_operand" "")]
18879 "TARGET_USE_FANCY_MATH_387
18880 && !(reload_completed || reload_in_progress)"
18883 [(set (match_dup 2)(match_dup 1))
18885 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18887 operands[2] = gen_reg_rtx (<MODE>mode);
18889 MEM_VOLATILE_P (operands[1]) = 1;
18891 [(set_attr "type" "multi")
18892 (set_attr "unit" "i387")
18893 (set_attr "mode" "<MODE>")])
18895 (define_expand "isinfxf2"
18896 [(use (match_operand:SI 0 "register_operand" ""))
18897 (use (match_operand:XF 1 "register_operand" ""))]
18898 "TARGET_USE_FANCY_MATH_387
18899 && TARGET_C99_FUNCTIONS"
18901 rtx mask = GEN_INT (0x45);
18902 rtx val = GEN_INT (0x05);
18906 rtx scratch = gen_reg_rtx (HImode);
18907 rtx res = gen_reg_rtx (QImode);
18909 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18911 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18912 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18913 cond = gen_rtx_fmt_ee (EQ, QImode,
18914 gen_rtx_REG (CCmode, FLAGS_REG),
18916 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18917 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18921 (define_expand "isinf<mode>2"
18922 [(use (match_operand:SI 0 "register_operand" ""))
18923 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18924 "TARGET_USE_FANCY_MATH_387
18925 && TARGET_C99_FUNCTIONS
18926 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18928 rtx mask = GEN_INT (0x45);
18929 rtx val = GEN_INT (0x05);
18933 rtx scratch = gen_reg_rtx (HImode);
18934 rtx res = gen_reg_rtx (QImode);
18936 /* Remove excess precision by forcing value through memory. */
18937 if (memory_operand (operands[1], VOIDmode))
18938 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18941 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18942 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18944 emit_move_insn (temp, operands[1]);
18945 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18948 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18949 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18950 cond = gen_rtx_fmt_ee (EQ, QImode,
18951 gen_rtx_REG (CCmode, FLAGS_REG),
18953 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18954 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18958 (define_expand "signbit<mode>2"
18959 [(use (match_operand:SI 0 "register_operand" ""))
18960 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18961 "TARGET_USE_FANCY_MATH_387
18962 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18964 rtx mask = GEN_INT (0x0200);
18966 rtx scratch = gen_reg_rtx (HImode);
18968 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18969 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18973 ;; Block operation instructions
18976 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18979 [(set_attr "length" "1")
18980 (set_attr "length_immediate" "0")
18981 (set_attr "modrm" "0")])
18983 (define_expand "movmemsi"
18984 [(use (match_operand:BLK 0 "memory_operand" ""))
18985 (use (match_operand:BLK 1 "memory_operand" ""))
18986 (use (match_operand:SI 2 "nonmemory_operand" ""))
18987 (use (match_operand:SI 3 "const_int_operand" ""))
18988 (use (match_operand:SI 4 "const_int_operand" ""))
18989 (use (match_operand:SI 5 "const_int_operand" ""))]
18992 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18993 operands[4], operands[5]))
18999 (define_expand "movmemdi"
19000 [(use (match_operand:BLK 0 "memory_operand" ""))
19001 (use (match_operand:BLK 1 "memory_operand" ""))
19002 (use (match_operand:DI 2 "nonmemory_operand" ""))
19003 (use (match_operand:DI 3 "const_int_operand" ""))
19004 (use (match_operand:SI 4 "const_int_operand" ""))
19005 (use (match_operand:SI 5 "const_int_operand" ""))]
19008 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19009 operands[4], operands[5]))
19015 ;; Most CPUs don't like single string operations
19016 ;; Handle this case here to simplify previous expander.
19018 (define_expand "strmov"
19019 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19020 (set (match_operand 1 "memory_operand" "") (match_dup 4))
19021 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19022 (clobber (reg:CC FLAGS_REG))])
19023 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19024 (clobber (reg:CC FLAGS_REG))])]
19027 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19029 /* If .md ever supports :P for Pmode, these can be directly
19030 in the pattern above. */
19031 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19032 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19034 /* Can't use this if the user has appropriated esi or edi. */
19035 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19036 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19038 emit_insn (gen_strmov_singleop (operands[0], operands[1],
19039 operands[2], operands[3],
19040 operands[5], operands[6]));
19044 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19047 (define_expand "strmov_singleop"
19048 [(parallel [(set (match_operand 1 "memory_operand" "")
19049 (match_operand 3 "memory_operand" ""))
19050 (set (match_operand 0 "register_operand" "")
19051 (match_operand 4 "" ""))
19052 (set (match_operand 2 "register_operand" "")
19053 (match_operand 5 "" ""))])]
19055 "ix86_current_function_needs_cld = 1;")
19057 (define_insn "*strmovdi_rex_1"
19058 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19059 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19060 (set (match_operand:DI 0 "register_operand" "=D")
19061 (plus:DI (match_dup 2)
19063 (set (match_operand:DI 1 "register_operand" "=S")
19064 (plus:DI (match_dup 3)
19068 [(set_attr "type" "str")
19069 (set_attr "mode" "DI")
19070 (set_attr "memory" "both")])
19072 (define_insn "*strmovsi_1"
19073 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19074 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19075 (set (match_operand:SI 0 "register_operand" "=D")
19076 (plus:SI (match_dup 2)
19078 (set (match_operand:SI 1 "register_operand" "=S")
19079 (plus:SI (match_dup 3)
19083 [(set_attr "type" "str")
19084 (set_attr "mode" "SI")
19085 (set_attr "memory" "both")])
19087 (define_insn "*strmovsi_rex_1"
19088 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19089 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19090 (set (match_operand:DI 0 "register_operand" "=D")
19091 (plus:DI (match_dup 2)
19093 (set (match_operand:DI 1 "register_operand" "=S")
19094 (plus:DI (match_dup 3)
19098 [(set_attr "type" "str")
19099 (set_attr "mode" "SI")
19100 (set_attr "memory" "both")])
19102 (define_insn "*strmovhi_1"
19103 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19104 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19105 (set (match_operand:SI 0 "register_operand" "=D")
19106 (plus:SI (match_dup 2)
19108 (set (match_operand:SI 1 "register_operand" "=S")
19109 (plus:SI (match_dup 3)
19113 [(set_attr "type" "str")
19114 (set_attr "memory" "both")
19115 (set_attr "mode" "HI")])
19117 (define_insn "*strmovhi_rex_1"
19118 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19119 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19120 (set (match_operand:DI 0 "register_operand" "=D")
19121 (plus:DI (match_dup 2)
19123 (set (match_operand:DI 1 "register_operand" "=S")
19124 (plus:DI (match_dup 3)
19128 [(set_attr "type" "str")
19129 (set_attr "memory" "both")
19130 (set_attr "mode" "HI")])
19132 (define_insn "*strmovqi_1"
19133 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19134 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19135 (set (match_operand:SI 0 "register_operand" "=D")
19136 (plus:SI (match_dup 2)
19138 (set (match_operand:SI 1 "register_operand" "=S")
19139 (plus:SI (match_dup 3)
19143 [(set_attr "type" "str")
19144 (set_attr "memory" "both")
19145 (set_attr "mode" "QI")])
19147 (define_insn "*strmovqi_rex_1"
19148 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19149 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19150 (set (match_operand:DI 0 "register_operand" "=D")
19151 (plus:DI (match_dup 2)
19153 (set (match_operand:DI 1 "register_operand" "=S")
19154 (plus:DI (match_dup 3)
19158 [(set_attr "type" "str")
19159 (set_attr "memory" "both")
19160 (set_attr "mode" "QI")])
19162 (define_expand "rep_mov"
19163 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19164 (set (match_operand 0 "register_operand" "")
19165 (match_operand 5 "" ""))
19166 (set (match_operand 2 "register_operand" "")
19167 (match_operand 6 "" ""))
19168 (set (match_operand 1 "memory_operand" "")
19169 (match_operand 3 "memory_operand" ""))
19170 (use (match_dup 4))])]
19172 "ix86_current_function_needs_cld = 1;")
19174 (define_insn "*rep_movdi_rex64"
19175 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19176 (set (match_operand:DI 0 "register_operand" "=D")
19177 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19179 (match_operand:DI 3 "register_operand" "0")))
19180 (set (match_operand:DI 1 "register_operand" "=S")
19181 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19182 (match_operand:DI 4 "register_operand" "1")))
19183 (set (mem:BLK (match_dup 3))
19184 (mem:BLK (match_dup 4)))
19185 (use (match_dup 5))]
19188 [(set_attr "type" "str")
19189 (set_attr "prefix_rep" "1")
19190 (set_attr "memory" "both")
19191 (set_attr "mode" "DI")])
19193 (define_insn "*rep_movsi"
19194 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19195 (set (match_operand:SI 0 "register_operand" "=D")
19196 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19198 (match_operand:SI 3 "register_operand" "0")))
19199 (set (match_operand:SI 1 "register_operand" "=S")
19200 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19201 (match_operand:SI 4 "register_operand" "1")))
19202 (set (mem:BLK (match_dup 3))
19203 (mem:BLK (match_dup 4)))
19204 (use (match_dup 5))]
19207 [(set_attr "type" "str")
19208 (set_attr "prefix_rep" "1")
19209 (set_attr "memory" "both")
19210 (set_attr "mode" "SI")])
19212 (define_insn "*rep_movsi_rex64"
19213 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19214 (set (match_operand:DI 0 "register_operand" "=D")
19215 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19217 (match_operand:DI 3 "register_operand" "0")))
19218 (set (match_operand:DI 1 "register_operand" "=S")
19219 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19220 (match_operand:DI 4 "register_operand" "1")))
19221 (set (mem:BLK (match_dup 3))
19222 (mem:BLK (match_dup 4)))
19223 (use (match_dup 5))]
19226 [(set_attr "type" "str")
19227 (set_attr "prefix_rep" "1")
19228 (set_attr "memory" "both")
19229 (set_attr "mode" "SI")])
19231 (define_insn "*rep_movqi"
19232 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19233 (set (match_operand:SI 0 "register_operand" "=D")
19234 (plus:SI (match_operand:SI 3 "register_operand" "0")
19235 (match_operand:SI 5 "register_operand" "2")))
19236 (set (match_operand:SI 1 "register_operand" "=S")
19237 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
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_movqi_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 (match_operand:DI 3 "register_operand" "0")
19252 (match_operand:DI 5 "register_operand" "2")))
19253 (set (match_operand:DI 1 "register_operand" "=S")
19254 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19255 (set (mem:BLK (match_dup 3))
19256 (mem:BLK (match_dup 4)))
19257 (use (match_dup 5))]
19260 [(set_attr "type" "str")
19261 (set_attr "prefix_rep" "1")
19262 (set_attr "memory" "both")
19263 (set_attr "mode" "SI")])
19265 (define_expand "setmemsi"
19266 [(use (match_operand:BLK 0 "memory_operand" ""))
19267 (use (match_operand:SI 1 "nonmemory_operand" ""))
19268 (use (match_operand 2 "const_int_operand" ""))
19269 (use (match_operand 3 "const_int_operand" ""))
19270 (use (match_operand:SI 4 "const_int_operand" ""))
19271 (use (match_operand:SI 5 "const_int_operand" ""))]
19274 if (ix86_expand_setmem (operands[0], operands[1],
19275 operands[2], operands[3],
19276 operands[4], operands[5]))
19282 (define_expand "setmemdi"
19283 [(use (match_operand:BLK 0 "memory_operand" ""))
19284 (use (match_operand:DI 1 "nonmemory_operand" ""))
19285 (use (match_operand 2 "const_int_operand" ""))
19286 (use (match_operand 3 "const_int_operand" ""))
19287 (use (match_operand 4 "const_int_operand" ""))
19288 (use (match_operand 5 "const_int_operand" ""))]
19291 if (ix86_expand_setmem (operands[0], operands[1],
19292 operands[2], operands[3],
19293 operands[4], operands[5]))
19299 ;; Most CPUs don't like single string operations
19300 ;; Handle this case here to simplify previous expander.
19302 (define_expand "strset"
19303 [(set (match_operand 1 "memory_operand" "")
19304 (match_operand 2 "register_operand" ""))
19305 (parallel [(set (match_operand 0 "register_operand" "")
19307 (clobber (reg:CC FLAGS_REG))])]
19310 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19311 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19313 /* If .md ever supports :P for Pmode, this can be directly
19314 in the pattern above. */
19315 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19316 GEN_INT (GET_MODE_SIZE (GET_MODE
19318 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19320 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19326 (define_expand "strset_singleop"
19327 [(parallel [(set (match_operand 1 "memory_operand" "")
19328 (match_operand 2 "register_operand" ""))
19329 (set (match_operand 0 "register_operand" "")
19330 (match_operand 3 "" ""))])]
19332 "ix86_current_function_needs_cld = 1;")
19334 (define_insn "*strsetdi_rex_1"
19335 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19336 (match_operand:DI 2 "register_operand" "a"))
19337 (set (match_operand:DI 0 "register_operand" "=D")
19338 (plus:DI (match_dup 1)
19342 [(set_attr "type" "str")
19343 (set_attr "memory" "store")
19344 (set_attr "mode" "DI")])
19346 (define_insn "*strsetsi_1"
19347 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19348 (match_operand:SI 2 "register_operand" "a"))
19349 (set (match_operand:SI 0 "register_operand" "=D")
19350 (plus:SI (match_dup 1)
19354 [(set_attr "type" "str")
19355 (set_attr "memory" "store")
19356 (set_attr "mode" "SI")])
19358 (define_insn "*strsetsi_rex_1"
19359 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19360 (match_operand:SI 2 "register_operand" "a"))
19361 (set (match_operand:DI 0 "register_operand" "=D")
19362 (plus:DI (match_dup 1)
19366 [(set_attr "type" "str")
19367 (set_attr "memory" "store")
19368 (set_attr "mode" "SI")])
19370 (define_insn "*strsethi_1"
19371 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19372 (match_operand:HI 2 "register_operand" "a"))
19373 (set (match_operand:SI 0 "register_operand" "=D")
19374 (plus:SI (match_dup 1)
19378 [(set_attr "type" "str")
19379 (set_attr "memory" "store")
19380 (set_attr "mode" "HI")])
19382 (define_insn "*strsethi_rex_1"
19383 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19384 (match_operand:HI 2 "register_operand" "a"))
19385 (set (match_operand:DI 0 "register_operand" "=D")
19386 (plus:DI (match_dup 1)
19390 [(set_attr "type" "str")
19391 (set_attr "memory" "store")
19392 (set_attr "mode" "HI")])
19394 (define_insn "*strsetqi_1"
19395 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19396 (match_operand:QI 2 "register_operand" "a"))
19397 (set (match_operand:SI 0 "register_operand" "=D")
19398 (plus:SI (match_dup 1)
19402 [(set_attr "type" "str")
19403 (set_attr "memory" "store")
19404 (set_attr "mode" "QI")])
19406 (define_insn "*strsetqi_rex_1"
19407 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19408 (match_operand:QI 2 "register_operand" "a"))
19409 (set (match_operand:DI 0 "register_operand" "=D")
19410 (plus:DI (match_dup 1)
19414 [(set_attr "type" "str")
19415 (set_attr "memory" "store")
19416 (set_attr "mode" "QI")])
19418 (define_expand "rep_stos"
19419 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19420 (set (match_operand 0 "register_operand" "")
19421 (match_operand 4 "" ""))
19422 (set (match_operand 2 "memory_operand" "") (const_int 0))
19423 (use (match_operand 3 "register_operand" ""))
19424 (use (match_dup 1))])]
19426 "ix86_current_function_needs_cld = 1;")
19428 (define_insn "*rep_stosdi_rex64"
19429 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19430 (set (match_operand:DI 0 "register_operand" "=D")
19431 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19433 (match_operand:DI 3 "register_operand" "0")))
19434 (set (mem:BLK (match_dup 3))
19436 (use (match_operand:DI 2 "register_operand" "a"))
19437 (use (match_dup 4))]
19440 [(set_attr "type" "str")
19441 (set_attr "prefix_rep" "1")
19442 (set_attr "memory" "store")
19443 (set_attr "mode" "DI")])
19445 (define_insn "*rep_stossi"
19446 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19447 (set (match_operand:SI 0 "register_operand" "=D")
19448 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19450 (match_operand:SI 3 "register_operand" "0")))
19451 (set (mem:BLK (match_dup 3))
19453 (use (match_operand:SI 2 "register_operand" "a"))
19454 (use (match_dup 4))]
19457 [(set_attr "type" "str")
19458 (set_attr "prefix_rep" "1")
19459 (set_attr "memory" "store")
19460 (set_attr "mode" "SI")])
19462 (define_insn "*rep_stossi_rex64"
19463 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19464 (set (match_operand:DI 0 "register_operand" "=D")
19465 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19467 (match_operand:DI 3 "register_operand" "0")))
19468 (set (mem:BLK (match_dup 3))
19470 (use (match_operand:SI 2 "register_operand" "a"))
19471 (use (match_dup 4))]
19474 [(set_attr "type" "str")
19475 (set_attr "prefix_rep" "1")
19476 (set_attr "memory" "store")
19477 (set_attr "mode" "SI")])
19479 (define_insn "*rep_stosqi"
19480 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19481 (set (match_operand:SI 0 "register_operand" "=D")
19482 (plus:SI (match_operand:SI 3 "register_operand" "0")
19483 (match_operand:SI 4 "register_operand" "1")))
19484 (set (mem:BLK (match_dup 3))
19486 (use (match_operand:QI 2 "register_operand" "a"))
19487 (use (match_dup 4))]
19490 [(set_attr "type" "str")
19491 (set_attr "prefix_rep" "1")
19492 (set_attr "memory" "store")
19493 (set_attr "mode" "QI")])
19495 (define_insn "*rep_stosqi_rex64"
19496 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19497 (set (match_operand:DI 0 "register_operand" "=D")
19498 (plus:DI (match_operand:DI 3 "register_operand" "0")
19499 (match_operand:DI 4 "register_operand" "1")))
19500 (set (mem:BLK (match_dup 3))
19502 (use (match_operand:QI 2 "register_operand" "a"))
19503 (use (match_dup 4))]
19506 [(set_attr "type" "str")
19507 (set_attr "prefix_rep" "1")
19508 (set_attr "memory" "store")
19509 (set_attr "mode" "QI")])
19511 (define_expand "cmpstrnsi"
19512 [(set (match_operand:SI 0 "register_operand" "")
19513 (compare:SI (match_operand:BLK 1 "general_operand" "")
19514 (match_operand:BLK 2 "general_operand" "")))
19515 (use (match_operand 3 "general_operand" ""))
19516 (use (match_operand 4 "immediate_operand" ""))]
19519 rtx addr1, addr2, out, outlow, count, countreg, align;
19521 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19524 /* Can't use this if the user has appropriated esi or edi. */
19525 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19530 out = gen_reg_rtx (SImode);
19532 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19533 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19534 if (addr1 != XEXP (operands[1], 0))
19535 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19536 if (addr2 != XEXP (operands[2], 0))
19537 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19539 count = operands[3];
19540 countreg = ix86_zero_extend_to_Pmode (count);
19542 /* %%% Iff we are testing strict equality, we can use known alignment
19543 to good advantage. This may be possible with combine, particularly
19544 once cc0 is dead. */
19545 align = operands[4];
19547 if (CONST_INT_P (count))
19549 if (INTVAL (count) == 0)
19551 emit_move_insn (operands[0], const0_rtx);
19554 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19555 operands[1], operands[2]));
19560 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19562 emit_insn (gen_cmpsi_1 (countreg, countreg));
19563 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19564 operands[1], operands[2]));
19567 outlow = gen_lowpart (QImode, out);
19568 emit_insn (gen_cmpintqi (outlow));
19569 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19571 if (operands[0] != out)
19572 emit_move_insn (operands[0], out);
19577 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19579 (define_expand "cmpintqi"
19580 [(set (match_dup 1)
19581 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19583 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19584 (parallel [(set (match_operand:QI 0 "register_operand" "")
19585 (minus:QI (match_dup 1)
19587 (clobber (reg:CC FLAGS_REG))])]
19589 "operands[1] = gen_reg_rtx (QImode);
19590 operands[2] = gen_reg_rtx (QImode);")
19592 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19593 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19595 (define_expand "cmpstrnqi_nz_1"
19596 [(parallel [(set (reg:CC FLAGS_REG)
19597 (compare:CC (match_operand 4 "memory_operand" "")
19598 (match_operand 5 "memory_operand" "")))
19599 (use (match_operand 2 "register_operand" ""))
19600 (use (match_operand:SI 3 "immediate_operand" ""))
19601 (clobber (match_operand 0 "register_operand" ""))
19602 (clobber (match_operand 1 "register_operand" ""))
19603 (clobber (match_dup 2))])]
19605 "ix86_current_function_needs_cld = 1;")
19607 (define_insn "*cmpstrnqi_nz_1"
19608 [(set (reg:CC FLAGS_REG)
19609 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19610 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19611 (use (match_operand:SI 6 "register_operand" "2"))
19612 (use (match_operand:SI 3 "immediate_operand" "i"))
19613 (clobber (match_operand:SI 0 "register_operand" "=S"))
19614 (clobber (match_operand:SI 1 "register_operand" "=D"))
19615 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19618 [(set_attr "type" "str")
19619 (set_attr "mode" "QI")
19620 (set_attr "prefix_rep" "1")])
19622 (define_insn "*cmpstrnqi_nz_rex_1"
19623 [(set (reg:CC FLAGS_REG)
19624 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19625 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19626 (use (match_operand:DI 6 "register_operand" "2"))
19627 (use (match_operand:SI 3 "immediate_operand" "i"))
19628 (clobber (match_operand:DI 0 "register_operand" "=S"))
19629 (clobber (match_operand:DI 1 "register_operand" "=D"))
19630 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19633 [(set_attr "type" "str")
19634 (set_attr "mode" "QI")
19635 (set_attr "prefix_rep" "1")])
19637 ;; The same, but the count is not known to not be zero.
19639 (define_expand "cmpstrnqi_1"
19640 [(parallel [(set (reg:CC FLAGS_REG)
19641 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19643 (compare:CC (match_operand 4 "memory_operand" "")
19644 (match_operand 5 "memory_operand" ""))
19646 (use (match_operand:SI 3 "immediate_operand" ""))
19647 (use (reg:CC FLAGS_REG))
19648 (clobber (match_operand 0 "register_operand" ""))
19649 (clobber (match_operand 1 "register_operand" ""))
19650 (clobber (match_dup 2))])]
19652 "ix86_current_function_needs_cld = 1;")
19654 (define_insn "*cmpstrnqi_1"
19655 [(set (reg:CC FLAGS_REG)
19656 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19658 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19659 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19661 (use (match_operand:SI 3 "immediate_operand" "i"))
19662 (use (reg:CC FLAGS_REG))
19663 (clobber (match_operand:SI 0 "register_operand" "=S"))
19664 (clobber (match_operand:SI 1 "register_operand" "=D"))
19665 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19668 [(set_attr "type" "str")
19669 (set_attr "mode" "QI")
19670 (set_attr "prefix_rep" "1")])
19672 (define_insn "*cmpstrnqi_rex_1"
19673 [(set (reg:CC FLAGS_REG)
19674 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19676 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19677 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19679 (use (match_operand:SI 3 "immediate_operand" "i"))
19680 (use (reg:CC FLAGS_REG))
19681 (clobber (match_operand:DI 0 "register_operand" "=S"))
19682 (clobber (match_operand:DI 1 "register_operand" "=D"))
19683 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19686 [(set_attr "type" "str")
19687 (set_attr "mode" "QI")
19688 (set_attr "prefix_rep" "1")])
19690 (define_expand "strlensi"
19691 [(set (match_operand:SI 0 "register_operand" "")
19692 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19693 (match_operand:QI 2 "immediate_operand" "")
19694 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19697 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19703 (define_expand "strlendi"
19704 [(set (match_operand:DI 0 "register_operand" "")
19705 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19706 (match_operand:QI 2 "immediate_operand" "")
19707 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19710 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19716 (define_expand "strlenqi_1"
19717 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19718 (clobber (match_operand 1 "register_operand" ""))
19719 (clobber (reg:CC FLAGS_REG))])]
19721 "ix86_current_function_needs_cld = 1;")
19723 (define_insn "*strlenqi_1"
19724 [(set (match_operand:SI 0 "register_operand" "=&c")
19725 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19726 (match_operand:QI 2 "register_operand" "a")
19727 (match_operand:SI 3 "immediate_operand" "i")
19728 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19729 (clobber (match_operand:SI 1 "register_operand" "=D"))
19730 (clobber (reg:CC FLAGS_REG))]
19733 [(set_attr "type" "str")
19734 (set_attr "mode" "QI")
19735 (set_attr "prefix_rep" "1")])
19737 (define_insn "*strlenqi_rex_1"
19738 [(set (match_operand:DI 0 "register_operand" "=&c")
19739 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19740 (match_operand:QI 2 "register_operand" "a")
19741 (match_operand:DI 3 "immediate_operand" "i")
19742 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19743 (clobber (match_operand:DI 1 "register_operand" "=D"))
19744 (clobber (reg:CC FLAGS_REG))]
19747 [(set_attr "type" "str")
19748 (set_attr "mode" "QI")
19749 (set_attr "prefix_rep" "1")])
19751 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19752 ;; handled in combine, but it is not currently up to the task.
19753 ;; When used for their truth value, the cmpstrn* expanders generate
19762 ;; The intermediate three instructions are unnecessary.
19764 ;; This one handles cmpstrn*_nz_1...
19767 (set (reg:CC FLAGS_REG)
19768 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19769 (mem:BLK (match_operand 5 "register_operand" ""))))
19770 (use (match_operand 6 "register_operand" ""))
19771 (use (match_operand:SI 3 "immediate_operand" ""))
19772 (clobber (match_operand 0 "register_operand" ""))
19773 (clobber (match_operand 1 "register_operand" ""))
19774 (clobber (match_operand 2 "register_operand" ""))])
19775 (set (match_operand:QI 7 "register_operand" "")
19776 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19777 (set (match_operand:QI 8 "register_operand" "")
19778 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19779 (set (reg FLAGS_REG)
19780 (compare (match_dup 7) (match_dup 8)))
19782 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19784 (set (reg:CC FLAGS_REG)
19785 (compare:CC (mem:BLK (match_dup 4))
19786 (mem:BLK (match_dup 5))))
19787 (use (match_dup 6))
19788 (use (match_dup 3))
19789 (clobber (match_dup 0))
19790 (clobber (match_dup 1))
19791 (clobber (match_dup 2))])]
19794 ;; ...and this one handles cmpstrn*_1.
19797 (set (reg:CC FLAGS_REG)
19798 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19800 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19801 (mem:BLK (match_operand 5 "register_operand" "")))
19803 (use (match_operand:SI 3 "immediate_operand" ""))
19804 (use (reg:CC FLAGS_REG))
19805 (clobber (match_operand 0 "register_operand" ""))
19806 (clobber (match_operand 1 "register_operand" ""))
19807 (clobber (match_operand 2 "register_operand" ""))])
19808 (set (match_operand:QI 7 "register_operand" "")
19809 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19810 (set (match_operand:QI 8 "register_operand" "")
19811 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19812 (set (reg FLAGS_REG)
19813 (compare (match_dup 7) (match_dup 8)))
19815 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19817 (set (reg:CC FLAGS_REG)
19818 (if_then_else:CC (ne (match_dup 6)
19820 (compare:CC (mem:BLK (match_dup 4))
19821 (mem:BLK (match_dup 5)))
19823 (use (match_dup 3))
19824 (use (reg:CC FLAGS_REG))
19825 (clobber (match_dup 0))
19826 (clobber (match_dup 1))
19827 (clobber (match_dup 2))])]
19832 ;; Conditional move instructions.
19834 (define_expand "movdicc"
19835 [(set (match_operand:DI 0 "register_operand" "")
19836 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19837 (match_operand:DI 2 "general_operand" "")
19838 (match_operand:DI 3 "general_operand" "")))]
19840 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19842 (define_insn "x86_movdicc_0_m1_rex64"
19843 [(set (match_operand:DI 0 "register_operand" "=r")
19844 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19847 (clobber (reg:CC FLAGS_REG))]
19850 ; Since we don't have the proper number of operands for an alu insn,
19851 ; fill in all the blanks.
19852 [(set_attr "type" "alu")
19853 (set_attr "pent_pair" "pu")
19854 (set_attr "memory" "none")
19855 (set_attr "imm_disp" "false")
19856 (set_attr "mode" "DI")
19857 (set_attr "length_immediate" "0")])
19859 (define_insn "*x86_movdicc_0_m1_se"
19860 [(set (match_operand:DI 0 "register_operand" "=r")
19861 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19864 (clobber (reg:CC FLAGS_REG))]
19867 [(set_attr "type" "alu")
19868 (set_attr "pent_pair" "pu")
19869 (set_attr "memory" "none")
19870 (set_attr "imm_disp" "false")
19871 (set_attr "mode" "DI")
19872 (set_attr "length_immediate" "0")])
19874 (define_insn "*movdicc_c_rex64"
19875 [(set (match_operand:DI 0 "register_operand" "=r,r")
19876 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19877 [(reg FLAGS_REG) (const_int 0)])
19878 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19879 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19880 "TARGET_64BIT && TARGET_CMOVE
19881 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19883 cmov%O2%C1\t{%2, %0|%0, %2}
19884 cmov%O2%c1\t{%3, %0|%0, %3}"
19885 [(set_attr "type" "icmov")
19886 (set_attr "mode" "DI")])
19888 (define_expand "movsicc"
19889 [(set (match_operand:SI 0 "register_operand" "")
19890 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19891 (match_operand:SI 2 "general_operand" "")
19892 (match_operand:SI 3 "general_operand" "")))]
19894 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19896 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19897 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19898 ;; So just document what we're doing explicitly.
19900 (define_insn "x86_movsicc_0_m1"
19901 [(set (match_operand:SI 0 "register_operand" "=r")
19902 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19905 (clobber (reg:CC FLAGS_REG))]
19908 ; Since we don't have the proper number of operands for an alu insn,
19909 ; fill in all the blanks.
19910 [(set_attr "type" "alu")
19911 (set_attr "pent_pair" "pu")
19912 (set_attr "memory" "none")
19913 (set_attr "imm_disp" "false")
19914 (set_attr "mode" "SI")
19915 (set_attr "length_immediate" "0")])
19917 (define_insn "*x86_movsicc_0_m1_se"
19918 [(set (match_operand:SI 0 "register_operand" "=r")
19919 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19922 (clobber (reg:CC FLAGS_REG))]
19925 [(set_attr "type" "alu")
19926 (set_attr "pent_pair" "pu")
19927 (set_attr "memory" "none")
19928 (set_attr "imm_disp" "false")
19929 (set_attr "mode" "SI")
19930 (set_attr "length_immediate" "0")])
19932 (define_insn "*movsicc_noc"
19933 [(set (match_operand:SI 0 "register_operand" "=r,r")
19934 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19935 [(reg FLAGS_REG) (const_int 0)])
19936 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19937 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19939 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19941 cmov%O2%C1\t{%2, %0|%0, %2}
19942 cmov%O2%c1\t{%3, %0|%0, %3}"
19943 [(set_attr "type" "icmov")
19944 (set_attr "mode" "SI")])
19946 (define_expand "movhicc"
19947 [(set (match_operand:HI 0 "register_operand" "")
19948 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19949 (match_operand:HI 2 "general_operand" "")
19950 (match_operand:HI 3 "general_operand" "")))]
19951 "TARGET_HIMODE_MATH"
19952 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19954 (define_insn "*movhicc_noc"
19955 [(set (match_operand:HI 0 "register_operand" "=r,r")
19956 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19957 [(reg FLAGS_REG) (const_int 0)])
19958 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19959 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19961 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19963 cmov%O2%C1\t{%2, %0|%0, %2}
19964 cmov%O2%c1\t{%3, %0|%0, %3}"
19965 [(set_attr "type" "icmov")
19966 (set_attr "mode" "HI")])
19968 (define_expand "movqicc"
19969 [(set (match_operand:QI 0 "register_operand" "")
19970 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19971 (match_operand:QI 2 "general_operand" "")
19972 (match_operand:QI 3 "general_operand" "")))]
19973 "TARGET_QIMODE_MATH"
19974 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19976 (define_insn_and_split "*movqicc_noc"
19977 [(set (match_operand:QI 0 "register_operand" "=r,r")
19978 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19979 [(match_operand 4 "flags_reg_operand" "")
19981 (match_operand:QI 2 "register_operand" "r,0")
19982 (match_operand:QI 3 "register_operand" "0,r")))]
19983 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19985 "&& reload_completed"
19986 [(set (match_dup 0)
19987 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19990 "operands[0] = gen_lowpart (SImode, operands[0]);
19991 operands[2] = gen_lowpart (SImode, operands[2]);
19992 operands[3] = gen_lowpart (SImode, operands[3]);"
19993 [(set_attr "type" "icmov")
19994 (set_attr "mode" "SI")])
19996 (define_expand "mov<mode>cc"
19997 [(set (match_operand:X87MODEF 0 "register_operand" "")
19998 (if_then_else:X87MODEF
19999 (match_operand 1 "comparison_operator" "")
20000 (match_operand:X87MODEF 2 "register_operand" "")
20001 (match_operand:X87MODEF 3 "register_operand" "")))]
20002 "(TARGET_80387 && TARGET_CMOVE)
20003 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20004 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20006 (define_insn "*movsfcc_1_387"
20007 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20008 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20009 [(reg FLAGS_REG) (const_int 0)])
20010 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20011 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20012 "TARGET_80387 && TARGET_CMOVE
20013 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20015 fcmov%F1\t{%2, %0|%0, %2}
20016 fcmov%f1\t{%3, %0|%0, %3}
20017 cmov%O2%C1\t{%2, %0|%0, %2}
20018 cmov%O2%c1\t{%3, %0|%0, %3}"
20019 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20020 (set_attr "mode" "SF,SF,SI,SI")])
20022 (define_insn "*movdfcc_1"
20023 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20024 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20025 [(reg FLAGS_REG) (const_int 0)])
20026 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20027 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20028 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20029 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20031 fcmov%F1\t{%2, %0|%0, %2}
20032 fcmov%f1\t{%3, %0|%0, %3}
20035 [(set_attr "type" "fcmov,fcmov,multi,multi")
20036 (set_attr "mode" "DF")])
20038 (define_insn "*movdfcc_1_rex64"
20039 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20040 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20041 [(reg FLAGS_REG) (const_int 0)])
20042 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20043 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20044 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20045 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20047 fcmov%F1\t{%2, %0|%0, %2}
20048 fcmov%f1\t{%3, %0|%0, %3}
20049 cmov%O2%C1\t{%2, %0|%0, %2}
20050 cmov%O2%c1\t{%3, %0|%0, %3}"
20051 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20052 (set_attr "mode" "DF")])
20055 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20056 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20057 [(match_operand 4 "flags_reg_operand" "")
20059 (match_operand:DF 2 "nonimmediate_operand" "")
20060 (match_operand:DF 3 "nonimmediate_operand" "")))]
20061 "!TARGET_64BIT && reload_completed"
20062 [(set (match_dup 2)
20063 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20067 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20070 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20071 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20073 (define_insn "*movxfcc_1"
20074 [(set (match_operand:XF 0 "register_operand" "=f,f")
20075 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20076 [(reg FLAGS_REG) (const_int 0)])
20077 (match_operand:XF 2 "register_operand" "f,0")
20078 (match_operand:XF 3 "register_operand" "0,f")))]
20079 "TARGET_80387 && TARGET_CMOVE"
20081 fcmov%F1\t{%2, %0|%0, %2}
20082 fcmov%f1\t{%3, %0|%0, %3}"
20083 [(set_attr "type" "fcmov")
20084 (set_attr "mode" "XF")])
20086 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20087 ;; the scalar versions to have only XMM registers as operands.
20089 ;; SSE5 conditional move
20090 (define_insn "*sse5_pcmov_<mode>"
20091 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20092 (if_then_else:MODEF
20093 (match_operand:MODEF 1 "register_operand" "x,0")
20094 (match_operand:MODEF 2 "register_operand" "0,x")
20095 (match_operand:MODEF 3 "register_operand" "x,x")))]
20096 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20097 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20098 [(set_attr "type" "sse4arg")])
20100 ;; These versions of the min/max patterns are intentionally ignorant of
20101 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20102 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20103 ;; are undefined in this condition, we're certain this is correct.
20105 (define_insn "*avx_<code><mode>3"
20106 [(set (match_operand:MODEF 0 "register_operand" "=x")
20108 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20109 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20110 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20111 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20112 [(set_attr "type" "sseadd")
20113 (set_attr "prefix" "vex")
20114 (set_attr "mode" "<MODE>")])
20116 (define_insn "<code><mode>3"
20117 [(set (match_operand:MODEF 0 "register_operand" "=x")
20119 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20120 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20121 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20122 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20123 [(set_attr "type" "sseadd")
20124 (set_attr "mode" "<MODE>")])
20126 ;; These versions of the min/max patterns implement exactly the operations
20127 ;; min = (op1 < op2 ? op1 : op2)
20128 ;; max = (!(op1 < op2) ? op1 : op2)
20129 ;; Their operands are not commutative, and thus they may be used in the
20130 ;; presence of -0.0 and NaN.
20132 (define_insn "*avx_ieee_smin<mode>3"
20133 [(set (match_operand:MODEF 0 "register_operand" "=x")
20135 [(match_operand:MODEF 1 "register_operand" "x")
20136 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20138 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20139 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20140 [(set_attr "type" "sseadd")
20141 (set_attr "prefix" "vex")
20142 (set_attr "mode" "<MODE>")])
20144 (define_insn "*ieee_smin<mode>3"
20145 [(set (match_operand:MODEF 0 "register_operand" "=x")
20147 [(match_operand:MODEF 1 "register_operand" "0")
20148 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20150 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20151 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20152 [(set_attr "type" "sseadd")
20153 (set_attr "mode" "<MODE>")])
20155 (define_insn "*avx_ieee_smax<mode>3"
20156 [(set (match_operand:MODEF 0 "register_operand" "=x")
20158 [(match_operand:MODEF 1 "register_operand" "0")
20159 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20161 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20162 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20163 [(set_attr "type" "sseadd")
20164 (set_attr "prefix" "vex")
20165 (set_attr "mode" "<MODE>")])
20167 (define_insn "*ieee_smax<mode>3"
20168 [(set (match_operand:MODEF 0 "register_operand" "=x")
20170 [(match_operand:MODEF 1 "register_operand" "0")
20171 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20173 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20174 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20175 [(set_attr "type" "sseadd")
20176 (set_attr "mode" "<MODE>")])
20178 ;; Make two stack loads independent:
20180 ;; fld %st(0) -> fld bb
20181 ;; fmul bb fmul %st(1), %st
20183 ;; Actually we only match the last two instructions for simplicity.
20185 [(set (match_operand 0 "fp_register_operand" "")
20186 (match_operand 1 "fp_register_operand" ""))
20188 (match_operator 2 "binary_fp_operator"
20190 (match_operand 3 "memory_operand" "")]))]
20191 "REGNO (operands[0]) != REGNO (operands[1])"
20192 [(set (match_dup 0) (match_dup 3))
20193 (set (match_dup 0) (match_dup 4))]
20195 ;; The % modifier is not operational anymore in peephole2's, so we have to
20196 ;; swap the operands manually in the case of addition and multiplication.
20197 "if (COMMUTATIVE_ARITH_P (operands[2]))
20198 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20199 operands[0], operands[1]);
20201 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20202 operands[1], operands[0]);")
20204 ;; Conditional addition patterns
20205 (define_expand "add<mode>cc"
20206 [(match_operand:SWI 0 "register_operand" "")
20207 (match_operand 1 "comparison_operator" "")
20208 (match_operand:SWI 2 "register_operand" "")
20209 (match_operand:SWI 3 "const_int_operand" "")]
20211 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20214 ;; Misc patterns (?)
20216 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20217 ;; Otherwise there will be nothing to keep
20219 ;; [(set (reg ebp) (reg esp))]
20220 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20221 ;; (clobber (eflags)]
20222 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20224 ;; in proper program order.
20225 (define_insn "pro_epilogue_adjust_stack_1"
20226 [(set (match_operand:SI 0 "register_operand" "=r,r")
20227 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20228 (match_operand:SI 2 "immediate_operand" "i,i")))
20229 (clobber (reg:CC FLAGS_REG))
20230 (clobber (mem:BLK (scratch)))]
20233 switch (get_attr_type (insn))
20236 return "mov{l}\t{%1, %0|%0, %1}";
20239 if (CONST_INT_P (operands[2])
20240 && (INTVAL (operands[2]) == 128
20241 || (INTVAL (operands[2]) < 0
20242 && INTVAL (operands[2]) != -128)))
20244 operands[2] = GEN_INT (-INTVAL (operands[2]));
20245 return "sub{l}\t{%2, %0|%0, %2}";
20247 return "add{l}\t{%2, %0|%0, %2}";
20250 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20251 return "lea{l}\t{%a2, %0|%0, %a2}";
20254 gcc_unreachable ();
20257 [(set (attr "type")
20258 (cond [(eq_attr "alternative" "0")
20259 (const_string "alu")
20260 (match_operand:SI 2 "const0_operand" "")
20261 (const_string "imov")
20263 (const_string "lea")))
20264 (set_attr "mode" "SI")])
20266 (define_insn "pro_epilogue_adjust_stack_rex64"
20267 [(set (match_operand:DI 0 "register_operand" "=r,r")
20268 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20269 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20270 (clobber (reg:CC FLAGS_REG))
20271 (clobber (mem:BLK (scratch)))]
20274 switch (get_attr_type (insn))
20277 return "mov{q}\t{%1, %0|%0, %1}";
20280 if (CONST_INT_P (operands[2])
20281 /* Avoid overflows. */
20282 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20283 && (INTVAL (operands[2]) == 128
20284 || (INTVAL (operands[2]) < 0
20285 && INTVAL (operands[2]) != -128)))
20287 operands[2] = GEN_INT (-INTVAL (operands[2]));
20288 return "sub{q}\t{%2, %0|%0, %2}";
20290 return "add{q}\t{%2, %0|%0, %2}";
20293 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20294 return "lea{q}\t{%a2, %0|%0, %a2}";
20297 gcc_unreachable ();
20300 [(set (attr "type")
20301 (cond [(eq_attr "alternative" "0")
20302 (const_string "alu")
20303 (match_operand:DI 2 "const0_operand" "")
20304 (const_string "imov")
20306 (const_string "lea")))
20307 (set_attr "mode" "DI")])
20309 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20310 [(set (match_operand:DI 0 "register_operand" "=r,r")
20311 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20312 (match_operand:DI 3 "immediate_operand" "i,i")))
20313 (use (match_operand:DI 2 "register_operand" "r,r"))
20314 (clobber (reg:CC FLAGS_REG))
20315 (clobber (mem:BLK (scratch)))]
20318 switch (get_attr_type (insn))
20321 return "add{q}\t{%2, %0|%0, %2}";
20324 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20325 return "lea{q}\t{%a2, %0|%0, %a2}";
20328 gcc_unreachable ();
20331 [(set_attr "type" "alu,lea")
20332 (set_attr "mode" "DI")])
20334 (define_insn "allocate_stack_worker_32"
20335 [(set (match_operand:SI 0 "register_operand" "=a")
20336 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20337 UNSPECV_STACK_PROBE))
20338 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20339 (clobber (reg:CC FLAGS_REG))]
20340 "!TARGET_64BIT && TARGET_STACK_PROBE"
20342 [(set_attr "type" "multi")
20343 (set_attr "length" "5")])
20345 (define_insn "allocate_stack_worker_64"
20346 [(set (match_operand:DI 0 "register_operand" "=a")
20347 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20348 UNSPECV_STACK_PROBE))
20349 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20350 (clobber (reg:DI R10_REG))
20351 (clobber (reg:DI R11_REG))
20352 (clobber (reg:CC FLAGS_REG))]
20353 "TARGET_64BIT && TARGET_STACK_PROBE"
20355 [(set_attr "type" "multi")
20356 (set_attr "length" "5")])
20358 (define_expand "allocate_stack"
20359 [(match_operand 0 "register_operand" "")
20360 (match_operand 1 "general_operand" "")]
20361 "TARGET_STACK_PROBE"
20365 #ifndef CHECK_STACK_LIMIT
20366 #define CHECK_STACK_LIMIT 0
20369 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20370 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20372 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20373 stack_pointer_rtx, 0, OPTAB_DIRECT);
20374 if (x != stack_pointer_rtx)
20375 emit_move_insn (stack_pointer_rtx, x);
20379 x = copy_to_mode_reg (Pmode, operands[1]);
20381 x = gen_allocate_stack_worker_64 (x, x);
20383 x = gen_allocate_stack_worker_32 (x, x);
20387 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20391 (define_expand "builtin_setjmp_receiver"
20392 [(label_ref (match_operand 0 "" ""))]
20393 "!TARGET_64BIT && flag_pic"
20399 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20400 rtx label_rtx = gen_label_rtx ();
20401 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20402 xops[0] = xops[1] = picreg;
20403 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20404 ix86_expand_binary_operator (MINUS, SImode, xops);
20408 emit_insn (gen_set_got (pic_offset_table_rtx));
20412 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20415 [(set (match_operand 0 "register_operand" "")
20416 (match_operator 3 "promotable_binary_operator"
20417 [(match_operand 1 "register_operand" "")
20418 (match_operand 2 "aligned_operand" "")]))
20419 (clobber (reg:CC FLAGS_REG))]
20420 "! TARGET_PARTIAL_REG_STALL && reload_completed
20421 && ((GET_MODE (operands[0]) == HImode
20422 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20423 /* ??? next two lines just !satisfies_constraint_K (...) */
20424 || !CONST_INT_P (operands[2])
20425 || satisfies_constraint_K (operands[2])))
20426 || (GET_MODE (operands[0]) == QImode
20427 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20428 [(parallel [(set (match_dup 0)
20429 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20430 (clobber (reg:CC FLAGS_REG))])]
20431 "operands[0] = gen_lowpart (SImode, operands[0]);
20432 operands[1] = gen_lowpart (SImode, operands[1]);
20433 if (GET_CODE (operands[3]) != ASHIFT)
20434 operands[2] = gen_lowpart (SImode, operands[2]);
20435 PUT_MODE (operands[3], SImode);")
20437 ; Promote the QImode tests, as i386 has encoding of the AND
20438 ; instruction with 32-bit sign-extended immediate and thus the
20439 ; instruction size is unchanged, except in the %eax case for
20440 ; which it is increased by one byte, hence the ! optimize_size.
20442 [(set (match_operand 0 "flags_reg_operand" "")
20443 (match_operator 2 "compare_operator"
20444 [(and (match_operand 3 "aligned_operand" "")
20445 (match_operand 4 "const_int_operand" ""))
20447 (set (match_operand 1 "register_operand" "")
20448 (and (match_dup 3) (match_dup 4)))]
20449 "! TARGET_PARTIAL_REG_STALL && reload_completed
20450 && optimize_insn_for_speed_p ()
20451 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20452 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20453 /* Ensure that the operand will remain sign-extended immediate. */
20454 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20455 [(parallel [(set (match_dup 0)
20456 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20459 (and:SI (match_dup 3) (match_dup 4)))])]
20462 = gen_int_mode (INTVAL (operands[4])
20463 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20464 operands[1] = gen_lowpart (SImode, operands[1]);
20465 operands[3] = gen_lowpart (SImode, operands[3]);
20468 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20469 ; the TEST instruction with 32-bit sign-extended immediate and thus
20470 ; the instruction size would at least double, which is not what we
20471 ; want even with ! optimize_size.
20473 [(set (match_operand 0 "flags_reg_operand" "")
20474 (match_operator 1 "compare_operator"
20475 [(and (match_operand:HI 2 "aligned_operand" "")
20476 (match_operand:HI 3 "const_int_operand" ""))
20478 "! TARGET_PARTIAL_REG_STALL && reload_completed
20479 && ! TARGET_FAST_PREFIX
20480 && optimize_insn_for_speed_p ()
20481 /* Ensure that the operand will remain sign-extended immediate. */
20482 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20483 [(set (match_dup 0)
20484 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20488 = gen_int_mode (INTVAL (operands[3])
20489 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20490 operands[2] = gen_lowpart (SImode, operands[2]);
20494 [(set (match_operand 0 "register_operand" "")
20495 (neg (match_operand 1 "register_operand" "")))
20496 (clobber (reg:CC FLAGS_REG))]
20497 "! TARGET_PARTIAL_REG_STALL && reload_completed
20498 && (GET_MODE (operands[0]) == HImode
20499 || (GET_MODE (operands[0]) == QImode
20500 && (TARGET_PROMOTE_QImode
20501 || optimize_insn_for_size_p ())))"
20502 [(parallel [(set (match_dup 0)
20503 (neg:SI (match_dup 1)))
20504 (clobber (reg:CC FLAGS_REG))])]
20505 "operands[0] = gen_lowpart (SImode, operands[0]);
20506 operands[1] = gen_lowpart (SImode, operands[1]);")
20509 [(set (match_operand 0 "register_operand" "")
20510 (not (match_operand 1 "register_operand" "")))]
20511 "! TARGET_PARTIAL_REG_STALL && reload_completed
20512 && (GET_MODE (operands[0]) == HImode
20513 || (GET_MODE (operands[0]) == QImode
20514 && (TARGET_PROMOTE_QImode
20515 || optimize_insn_for_size_p ())))"
20516 [(set (match_dup 0)
20517 (not:SI (match_dup 1)))]
20518 "operands[0] = gen_lowpart (SImode, operands[0]);
20519 operands[1] = gen_lowpart (SImode, operands[1]);")
20522 [(set (match_operand 0 "register_operand" "")
20523 (if_then_else (match_operator 1 "comparison_operator"
20524 [(reg FLAGS_REG) (const_int 0)])
20525 (match_operand 2 "register_operand" "")
20526 (match_operand 3 "register_operand" "")))]
20527 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20528 && (GET_MODE (operands[0]) == HImode
20529 || (GET_MODE (operands[0]) == QImode
20530 && (TARGET_PROMOTE_QImode
20531 || optimize_insn_for_size_p ())))"
20532 [(set (match_dup 0)
20533 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20534 "operands[0] = gen_lowpart (SImode, operands[0]);
20535 operands[2] = gen_lowpart (SImode, operands[2]);
20536 operands[3] = gen_lowpart (SImode, operands[3]);")
20539 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20540 ;; transform a complex memory operation into two memory to register operations.
20542 ;; Don't push memory operands
20544 [(set (match_operand:SI 0 "push_operand" "")
20545 (match_operand:SI 1 "memory_operand" ""))
20546 (match_scratch:SI 2 "r")]
20547 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20548 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20549 [(set (match_dup 2) (match_dup 1))
20550 (set (match_dup 0) (match_dup 2))]
20554 [(set (match_operand:DI 0 "push_operand" "")
20555 (match_operand:DI 1 "memory_operand" ""))
20556 (match_scratch:DI 2 "r")]
20557 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20558 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20559 [(set (match_dup 2) (match_dup 1))
20560 (set (match_dup 0) (match_dup 2))]
20563 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20566 [(set (match_operand:SF 0 "push_operand" "")
20567 (match_operand:SF 1 "memory_operand" ""))
20568 (match_scratch:SF 2 "r")]
20569 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20570 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20571 [(set (match_dup 2) (match_dup 1))
20572 (set (match_dup 0) (match_dup 2))]
20576 [(set (match_operand:HI 0 "push_operand" "")
20577 (match_operand:HI 1 "memory_operand" ""))
20578 (match_scratch:HI 2 "r")]
20579 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20580 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20581 [(set (match_dup 2) (match_dup 1))
20582 (set (match_dup 0) (match_dup 2))]
20586 [(set (match_operand:QI 0 "push_operand" "")
20587 (match_operand:QI 1 "memory_operand" ""))
20588 (match_scratch:QI 2 "q")]
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))]
20595 ;; Don't move an immediate directly to memory when the instruction
20598 [(match_scratch:SI 1 "r")
20599 (set (match_operand:SI 0 "memory_operand" "")
20601 "optimize_insn_for_speed_p ()
20602 && ! TARGET_USE_MOV0
20603 && TARGET_SPLIT_LONG_MOVES
20604 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20605 && peep2_regno_dead_p (0, FLAGS_REG)"
20606 [(parallel [(set (match_dup 1) (const_int 0))
20607 (clobber (reg:CC FLAGS_REG))])
20608 (set (match_dup 0) (match_dup 1))]
20612 [(match_scratch:HI 1 "r")
20613 (set (match_operand:HI 0 "memory_operand" "")
20615 "optimize_insn_for_speed_p ()
20616 && ! TARGET_USE_MOV0
20617 && TARGET_SPLIT_LONG_MOVES
20618 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20619 && peep2_regno_dead_p (0, FLAGS_REG)"
20620 [(parallel [(set (match_dup 2) (const_int 0))
20621 (clobber (reg:CC FLAGS_REG))])
20622 (set (match_dup 0) (match_dup 1))]
20623 "operands[2] = gen_lowpart (SImode, operands[1]);")
20626 [(match_scratch:QI 1 "q")
20627 (set (match_operand:QI 0 "memory_operand" "")
20629 "optimize_insn_for_speed_p ()
20630 && ! TARGET_USE_MOV0
20631 && TARGET_SPLIT_LONG_MOVES
20632 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20633 && peep2_regno_dead_p (0, FLAGS_REG)"
20634 [(parallel [(set (match_dup 2) (const_int 0))
20635 (clobber (reg:CC FLAGS_REG))])
20636 (set (match_dup 0) (match_dup 1))]
20637 "operands[2] = gen_lowpart (SImode, operands[1]);")
20640 [(match_scratch:SI 2 "r")
20641 (set (match_operand:SI 0 "memory_operand" "")
20642 (match_operand:SI 1 "immediate_operand" ""))]
20643 "optimize_insn_for_speed_p ()
20644 && TARGET_SPLIT_LONG_MOVES
20645 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20646 [(set (match_dup 2) (match_dup 1))
20647 (set (match_dup 0) (match_dup 2))]
20651 [(match_scratch:HI 2 "r")
20652 (set (match_operand:HI 0 "memory_operand" "")
20653 (match_operand:HI 1 "immediate_operand" ""))]
20654 "optimize_insn_for_speed_p ()
20655 && TARGET_SPLIT_LONG_MOVES
20656 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20657 [(set (match_dup 2) (match_dup 1))
20658 (set (match_dup 0) (match_dup 2))]
20662 [(match_scratch:QI 2 "q")
20663 (set (match_operand:QI 0 "memory_operand" "")
20664 (match_operand:QI 1 "immediate_operand" ""))]
20665 "optimize_insn_for_speed_p ()
20666 && TARGET_SPLIT_LONG_MOVES
20667 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20668 [(set (match_dup 2) (match_dup 1))
20669 (set (match_dup 0) (match_dup 2))]
20672 ;; Don't compare memory with zero, load and use a test instead.
20674 [(set (match_operand 0 "flags_reg_operand" "")
20675 (match_operator 1 "compare_operator"
20676 [(match_operand:SI 2 "memory_operand" "")
20678 (match_scratch:SI 3 "r")]
20679 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20680 [(set (match_dup 3) (match_dup 2))
20681 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20684 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20685 ;; Don't split NOTs with a displacement operand, because resulting XOR
20686 ;; will not be pairable anyway.
20688 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20689 ;; represented using a modRM byte. The XOR replacement is long decoded,
20690 ;; so this split helps here as well.
20692 ;; Note: Can't do this as a regular split because we can't get proper
20693 ;; lifetime information then.
20696 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20697 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20698 "optimize_insn_for_speed_p ()
20699 && ((TARGET_NOT_UNPAIRABLE
20700 && (!MEM_P (operands[0])
20701 || !memory_displacement_operand (operands[0], SImode)))
20702 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20703 && peep2_regno_dead_p (0, FLAGS_REG)"
20704 [(parallel [(set (match_dup 0)
20705 (xor:SI (match_dup 1) (const_int -1)))
20706 (clobber (reg:CC FLAGS_REG))])]
20710 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20711 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20712 "optimize_insn_for_speed_p ()
20713 && ((TARGET_NOT_UNPAIRABLE
20714 && (!MEM_P (operands[0])
20715 || !memory_displacement_operand (operands[0], HImode)))
20716 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20717 && peep2_regno_dead_p (0, FLAGS_REG)"
20718 [(parallel [(set (match_dup 0)
20719 (xor:HI (match_dup 1) (const_int -1)))
20720 (clobber (reg:CC FLAGS_REG))])]
20724 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20725 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20726 "optimize_insn_for_speed_p ()
20727 && ((TARGET_NOT_UNPAIRABLE
20728 && (!MEM_P (operands[0])
20729 || !memory_displacement_operand (operands[0], QImode)))
20730 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20731 && peep2_regno_dead_p (0, FLAGS_REG)"
20732 [(parallel [(set (match_dup 0)
20733 (xor:QI (match_dup 1) (const_int -1)))
20734 (clobber (reg:CC FLAGS_REG))])]
20737 ;; Non pairable "test imm, reg" instructions can be translated to
20738 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20739 ;; byte opcode instead of two, have a short form for byte operands),
20740 ;; so do it for other CPUs as well. Given that the value was dead,
20741 ;; this should not create any new dependencies. Pass on the sub-word
20742 ;; versions if we're concerned about partial register stalls.
20745 [(set (match_operand 0 "flags_reg_operand" "")
20746 (match_operator 1 "compare_operator"
20747 [(and:SI (match_operand:SI 2 "register_operand" "")
20748 (match_operand:SI 3 "immediate_operand" ""))
20750 "ix86_match_ccmode (insn, CCNOmode)
20751 && (true_regnum (operands[2]) != AX_REG
20752 || satisfies_constraint_K (operands[3]))
20753 && peep2_reg_dead_p (1, operands[2])"
20755 [(set (match_dup 0)
20756 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20759 (and:SI (match_dup 2) (match_dup 3)))])]
20762 ;; We don't need to handle HImode case, because it will be promoted to SImode
20763 ;; on ! TARGET_PARTIAL_REG_STALL
20766 [(set (match_operand 0 "flags_reg_operand" "")
20767 (match_operator 1 "compare_operator"
20768 [(and:QI (match_operand:QI 2 "register_operand" "")
20769 (match_operand:QI 3 "immediate_operand" ""))
20771 "! TARGET_PARTIAL_REG_STALL
20772 && ix86_match_ccmode (insn, CCNOmode)
20773 && true_regnum (operands[2]) != AX_REG
20774 && peep2_reg_dead_p (1, operands[2])"
20776 [(set (match_dup 0)
20777 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20780 (and:QI (match_dup 2) (match_dup 3)))])]
20784 [(set (match_operand 0 "flags_reg_operand" "")
20785 (match_operator 1 "compare_operator"
20788 (match_operand 2 "ext_register_operand" "")
20791 (match_operand 3 "const_int_operand" ""))
20793 "! TARGET_PARTIAL_REG_STALL
20794 && ix86_match_ccmode (insn, CCNOmode)
20795 && true_regnum (operands[2]) != AX_REG
20796 && peep2_reg_dead_p (1, operands[2])"
20797 [(parallel [(set (match_dup 0)
20806 (set (zero_extract:SI (match_dup 2)
20817 ;; Don't do logical operations with memory inputs.
20819 [(match_scratch:SI 2 "r")
20820 (parallel [(set (match_operand:SI 0 "register_operand" "")
20821 (match_operator:SI 3 "arith_or_logical_operator"
20823 (match_operand:SI 1 "memory_operand" "")]))
20824 (clobber (reg:CC FLAGS_REG))])]
20825 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20826 [(set (match_dup 2) (match_dup 1))
20827 (parallel [(set (match_dup 0)
20828 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20829 (clobber (reg:CC FLAGS_REG))])]
20833 [(match_scratch:SI 2 "r")
20834 (parallel [(set (match_operand:SI 0 "register_operand" "")
20835 (match_operator:SI 3 "arith_or_logical_operator"
20836 [(match_operand:SI 1 "memory_operand" "")
20838 (clobber (reg:CC FLAGS_REG))])]
20839 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20840 [(set (match_dup 2) (match_dup 1))
20841 (parallel [(set (match_dup 0)
20842 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20843 (clobber (reg:CC FLAGS_REG))])]
20846 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20847 ;; refers to the destination of the load!
20850 [(set (match_operand:SI 0 "register_operand" "")
20851 (match_operand:SI 1 "register_operand" ""))
20852 (parallel [(set (match_dup 0)
20853 (match_operator:SI 3 "commutative_operator"
20855 (match_operand:SI 2 "memory_operand" "")]))
20856 (clobber (reg:CC FLAGS_REG))])]
20857 "REGNO (operands[0]) != REGNO (operands[1])
20858 && GENERAL_REGNO_P (REGNO (operands[0]))
20859 && GENERAL_REGNO_P (REGNO (operands[1]))"
20860 [(set (match_dup 0) (match_dup 4))
20861 (parallel [(set (match_dup 0)
20862 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20863 (clobber (reg:CC FLAGS_REG))])]
20864 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20867 [(set (match_operand 0 "register_operand" "")
20868 (match_operand 1 "register_operand" ""))
20870 (match_operator 3 "commutative_operator"
20872 (match_operand 2 "memory_operand" "")]))]
20873 "REGNO (operands[0]) != REGNO (operands[1])
20874 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20875 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20876 [(set (match_dup 0) (match_dup 2))
20878 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20881 ; Don't do logical operations with memory outputs
20883 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20884 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20885 ; the same decoder scheduling characteristics as the original.
20888 [(match_scratch:SI 2 "r")
20889 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20890 (match_operator:SI 3 "arith_or_logical_operator"
20892 (match_operand:SI 1 "nonmemory_operand" "")]))
20893 (clobber (reg:CC FLAGS_REG))])]
20894 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20895 [(set (match_dup 2) (match_dup 0))
20896 (parallel [(set (match_dup 2)
20897 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20898 (clobber (reg:CC FLAGS_REG))])
20899 (set (match_dup 0) (match_dup 2))]
20903 [(match_scratch:SI 2 "r")
20904 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20905 (match_operator:SI 3 "arith_or_logical_operator"
20906 [(match_operand:SI 1 "nonmemory_operand" "")
20908 (clobber (reg:CC FLAGS_REG))])]
20909 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20910 [(set (match_dup 2) (match_dup 0))
20911 (parallel [(set (match_dup 2)
20912 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20913 (clobber (reg:CC FLAGS_REG))])
20914 (set (match_dup 0) (match_dup 2))]
20917 ;; Attempt to always use XOR for zeroing registers.
20919 [(set (match_operand 0 "register_operand" "")
20920 (match_operand 1 "const0_operand" ""))]
20921 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20922 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20923 && GENERAL_REG_P (operands[0])
20924 && peep2_regno_dead_p (0, FLAGS_REG)"
20925 [(parallel [(set (match_dup 0) (const_int 0))
20926 (clobber (reg:CC FLAGS_REG))])]
20928 operands[0] = gen_lowpart (word_mode, operands[0]);
20932 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20934 "(GET_MODE (operands[0]) == QImode
20935 || GET_MODE (operands[0]) == HImode)
20936 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20937 && peep2_regno_dead_p (0, FLAGS_REG)"
20938 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20939 (clobber (reg:CC FLAGS_REG))])])
20941 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20943 [(set (match_operand 0 "register_operand" "")
20945 "(GET_MODE (operands[0]) == HImode
20946 || GET_MODE (operands[0]) == SImode
20947 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20948 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20949 && peep2_regno_dead_p (0, FLAGS_REG)"
20950 [(parallel [(set (match_dup 0) (const_int -1))
20951 (clobber (reg:CC FLAGS_REG))])]
20952 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20955 ;; Attempt to convert simple leas to adds. These can be created by
20958 [(set (match_operand:SI 0 "register_operand" "")
20959 (plus:SI (match_dup 0)
20960 (match_operand:SI 1 "nonmemory_operand" "")))]
20961 "peep2_regno_dead_p (0, FLAGS_REG)"
20962 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20963 (clobber (reg:CC FLAGS_REG))])]
20967 [(set (match_operand:SI 0 "register_operand" "")
20968 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20969 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20970 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20971 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20972 (clobber (reg:CC FLAGS_REG))])]
20973 "operands[2] = gen_lowpart (SImode, operands[2]);")
20976 [(set (match_operand:DI 0 "register_operand" "")
20977 (plus:DI (match_dup 0)
20978 (match_operand:DI 1 "x86_64_general_operand" "")))]
20979 "peep2_regno_dead_p (0, FLAGS_REG)"
20980 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20981 (clobber (reg:CC FLAGS_REG))])]
20985 [(set (match_operand:SI 0 "register_operand" "")
20986 (mult:SI (match_dup 0)
20987 (match_operand:SI 1 "const_int_operand" "")))]
20988 "exact_log2 (INTVAL (operands[1])) >= 0
20989 && peep2_regno_dead_p (0, FLAGS_REG)"
20990 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20991 (clobber (reg:CC FLAGS_REG))])]
20992 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20995 [(set (match_operand:DI 0 "register_operand" "")
20996 (mult:DI (match_dup 0)
20997 (match_operand:DI 1 "const_int_operand" "")))]
20998 "exact_log2 (INTVAL (operands[1])) >= 0
20999 && peep2_regno_dead_p (0, FLAGS_REG)"
21000 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21001 (clobber (reg:CC FLAGS_REG))])]
21002 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21005 [(set (match_operand:SI 0 "register_operand" "")
21006 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21007 (match_operand:DI 2 "const_int_operand" "")) 0))]
21008 "exact_log2 (INTVAL (operands[2])) >= 0
21009 && REGNO (operands[0]) == REGNO (operands[1])
21010 && peep2_regno_dead_p (0, FLAGS_REG)"
21011 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21012 (clobber (reg:CC FLAGS_REG))])]
21013 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21015 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
21016 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
21017 ;; many CPUs it is also faster, since special hardware to avoid esp
21018 ;; dependencies is present.
21020 ;; While some of these conversions may be done using splitters, we use peepholes
21021 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21023 ;; Convert prologue esp subtractions to push.
21024 ;; We need register to push. In order to keep verify_flow_info happy we have
21026 ;; - use scratch and clobber it in order to avoid dependencies
21027 ;; - use already live register
21028 ;; We can't use the second way right now, since there is no reliable way how to
21029 ;; verify that given register is live. First choice will also most likely in
21030 ;; fewer dependencies. On the place of esp adjustments it is very likely that
21031 ;; call clobbered registers are dead. We may want to use base pointer as an
21032 ;; alternative when no register is available later.
21035 [(match_scratch:SI 0 "r")
21036 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21037 (clobber (reg:CC FLAGS_REG))
21038 (clobber (mem:BLK (scratch)))])]
21039 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21040 [(clobber (match_dup 0))
21041 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21042 (clobber (mem:BLK (scratch)))])])
21045 [(match_scratch:SI 0 "r")
21046 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21047 (clobber (reg:CC FLAGS_REG))
21048 (clobber (mem:BLK (scratch)))])]
21049 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21050 [(clobber (match_dup 0))
21051 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21052 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21053 (clobber (mem:BLK (scratch)))])])
21055 ;; Convert esp subtractions to push.
21057 [(match_scratch:SI 0 "r")
21058 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21059 (clobber (reg:CC FLAGS_REG))])]
21060 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21061 [(clobber (match_dup 0))
21062 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21065 [(match_scratch:SI 0 "r")
21066 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21067 (clobber (reg:CC FLAGS_REG))])]
21068 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21069 [(clobber (match_dup 0))
21070 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21071 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21073 ;; Convert epilogue deallocator to pop.
21075 [(match_scratch:SI 0 "r")
21076 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21077 (clobber (reg:CC FLAGS_REG))
21078 (clobber (mem:BLK (scratch)))])]
21079 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21080 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21081 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21082 (clobber (mem:BLK (scratch)))])]
21085 ;; Two pops case is tricky, since pop causes dependency on destination register.
21086 ;; We use two registers if available.
21088 [(match_scratch:SI 0 "r")
21089 (match_scratch:SI 1 "r")
21090 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21091 (clobber (reg:CC FLAGS_REG))
21092 (clobber (mem:BLK (scratch)))])]
21093 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21094 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21095 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21096 (clobber (mem:BLK (scratch)))])
21097 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21098 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21102 [(match_scratch:SI 0 "r")
21103 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21104 (clobber (reg:CC FLAGS_REG))
21105 (clobber (mem:BLK (scratch)))])]
21106 "optimize_insn_for_size_p ()"
21107 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21108 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21109 (clobber (mem:BLK (scratch)))])
21110 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21111 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21114 ;; Convert esp additions to pop.
21116 [(match_scratch:SI 0 "r")
21117 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21118 (clobber (reg:CC FLAGS_REG))])]
21120 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21121 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21124 ;; Two pops case is tricky, since pop causes dependency on destination register.
21125 ;; We use two registers if available.
21127 [(match_scratch:SI 0 "r")
21128 (match_scratch:SI 1 "r")
21129 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21130 (clobber (reg:CC FLAGS_REG))])]
21132 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21133 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21134 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21135 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21139 [(match_scratch:SI 0 "r")
21140 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21141 (clobber (reg:CC FLAGS_REG))])]
21142 "optimize_insn_for_size_p ()"
21143 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21144 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21145 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21146 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21149 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21150 ;; required and register dies. Similarly for 128 to -128.
21152 [(set (match_operand 0 "flags_reg_operand" "")
21153 (match_operator 1 "compare_operator"
21154 [(match_operand 2 "register_operand" "")
21155 (match_operand 3 "const_int_operand" "")]))]
21156 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21157 && incdec_operand (operands[3], GET_MODE (operands[3])))
21158 || (!TARGET_FUSE_CMP_AND_BRANCH
21159 && INTVAL (operands[3]) == 128))
21160 && ix86_match_ccmode (insn, CCGCmode)
21161 && peep2_reg_dead_p (1, operands[2])"
21162 [(parallel [(set (match_dup 0)
21163 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21164 (clobber (match_dup 2))])]
21168 [(match_scratch:DI 0 "r")
21169 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21170 (clobber (reg:CC FLAGS_REG))
21171 (clobber (mem:BLK (scratch)))])]
21172 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21173 [(clobber (match_dup 0))
21174 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21175 (clobber (mem:BLK (scratch)))])])
21178 [(match_scratch:DI 0 "r")
21179 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21180 (clobber (reg:CC FLAGS_REG))
21181 (clobber (mem:BLK (scratch)))])]
21182 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21183 [(clobber (match_dup 0))
21184 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21185 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21186 (clobber (mem:BLK (scratch)))])])
21188 ;; Convert esp subtractions to push.
21190 [(match_scratch:DI 0 "r")
21191 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21192 (clobber (reg:CC FLAGS_REG))])]
21193 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21194 [(clobber (match_dup 0))
21195 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21198 [(match_scratch:DI 0 "r")
21199 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21200 (clobber (reg:CC FLAGS_REG))])]
21201 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21202 [(clobber (match_dup 0))
21203 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21204 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21206 ;; Convert epilogue deallocator to pop.
21208 [(match_scratch:DI 0 "r")
21209 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21210 (clobber (reg:CC FLAGS_REG))
21211 (clobber (mem:BLK (scratch)))])]
21212 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21213 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21214 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21215 (clobber (mem:BLK (scratch)))])]
21218 ;; Two pops case is tricky, since pop causes dependency on destination register.
21219 ;; We use two registers if available.
21221 [(match_scratch:DI 0 "r")
21222 (match_scratch:DI 1 "r")
21223 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21224 (clobber (reg:CC FLAGS_REG))
21225 (clobber (mem:BLK (scratch)))])]
21226 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21227 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21228 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21229 (clobber (mem:BLK (scratch)))])
21230 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21231 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21235 [(match_scratch:DI 0 "r")
21236 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21237 (clobber (reg:CC FLAGS_REG))
21238 (clobber (mem:BLK (scratch)))])]
21239 "optimize_insn_for_size_p ()"
21240 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21241 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21242 (clobber (mem:BLK (scratch)))])
21243 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21244 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21247 ;; Convert esp additions to pop.
21249 [(match_scratch:DI 0 "r")
21250 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21251 (clobber (reg:CC FLAGS_REG))])]
21253 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21254 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21257 ;; Two pops case is tricky, since pop causes dependency on destination register.
21258 ;; We use two registers if available.
21260 [(match_scratch:DI 0 "r")
21261 (match_scratch:DI 1 "r")
21262 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21263 (clobber (reg:CC FLAGS_REG))])]
21265 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21266 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21267 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21268 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21272 [(match_scratch:DI 0 "r")
21273 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21274 (clobber (reg:CC FLAGS_REG))])]
21275 "optimize_insn_for_size_p ()"
21276 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21277 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21278 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21279 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21282 ;; Convert imul by three, five and nine into lea
21285 [(set (match_operand:SI 0 "register_operand" "")
21286 (mult:SI (match_operand:SI 1 "register_operand" "")
21287 (match_operand:SI 2 "const_int_operand" "")))
21288 (clobber (reg:CC FLAGS_REG))])]
21289 "INTVAL (operands[2]) == 3
21290 || INTVAL (operands[2]) == 5
21291 || INTVAL (operands[2]) == 9"
21292 [(set (match_dup 0)
21293 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21295 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21299 [(set (match_operand:SI 0 "register_operand" "")
21300 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21301 (match_operand:SI 2 "const_int_operand" "")))
21302 (clobber (reg:CC FLAGS_REG))])]
21303 "optimize_insn_for_speed_p ()
21304 && (INTVAL (operands[2]) == 3
21305 || INTVAL (operands[2]) == 5
21306 || INTVAL (operands[2]) == 9)"
21307 [(set (match_dup 0) (match_dup 1))
21309 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21311 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21315 [(set (match_operand:DI 0 "register_operand" "")
21316 (mult:DI (match_operand:DI 1 "register_operand" "")
21317 (match_operand:DI 2 "const_int_operand" "")))
21318 (clobber (reg:CC FLAGS_REG))])]
21320 && (INTVAL (operands[2]) == 3
21321 || INTVAL (operands[2]) == 5
21322 || INTVAL (operands[2]) == 9)"
21323 [(set (match_dup 0)
21324 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21326 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21330 [(set (match_operand:DI 0 "register_operand" "")
21331 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21332 (match_operand:DI 2 "const_int_operand" "")))
21333 (clobber (reg:CC FLAGS_REG))])]
21335 && optimize_insn_for_speed_p ()
21336 && (INTVAL (operands[2]) == 3
21337 || INTVAL (operands[2]) == 5
21338 || INTVAL (operands[2]) == 9)"
21339 [(set (match_dup 0) (match_dup 1))
21341 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21343 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21345 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21346 ;; imul $32bit_imm, reg, reg is direct decoded.
21348 [(match_scratch:DI 3 "r")
21349 (parallel [(set (match_operand:DI 0 "register_operand" "")
21350 (mult:DI (match_operand:DI 1 "memory_operand" "")
21351 (match_operand:DI 2 "immediate_operand" "")))
21352 (clobber (reg:CC FLAGS_REG))])]
21353 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21354 && !satisfies_constraint_K (operands[2])"
21355 [(set (match_dup 3) (match_dup 1))
21356 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21357 (clobber (reg:CC FLAGS_REG))])]
21361 [(match_scratch:SI 3 "r")
21362 (parallel [(set (match_operand:SI 0 "register_operand" "")
21363 (mult:SI (match_operand:SI 1 "memory_operand" "")
21364 (match_operand:SI 2 "immediate_operand" "")))
21365 (clobber (reg:CC FLAGS_REG))])]
21366 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21367 && !satisfies_constraint_K (operands[2])"
21368 [(set (match_dup 3) (match_dup 1))
21369 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21370 (clobber (reg:CC FLAGS_REG))])]
21374 [(match_scratch:SI 3 "r")
21375 (parallel [(set (match_operand:DI 0 "register_operand" "")
21377 (mult:SI (match_operand:SI 1 "memory_operand" "")
21378 (match_operand:SI 2 "immediate_operand" ""))))
21379 (clobber (reg:CC FLAGS_REG))])]
21380 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21381 && !satisfies_constraint_K (operands[2])"
21382 [(set (match_dup 3) (match_dup 1))
21383 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21384 (clobber (reg:CC FLAGS_REG))])]
21387 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21388 ;; Convert it into imul reg, reg
21389 ;; It would be better to force assembler to encode instruction using long
21390 ;; immediate, but there is apparently no way to do so.
21392 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21393 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21394 (match_operand:DI 2 "const_int_operand" "")))
21395 (clobber (reg:CC FLAGS_REG))])
21396 (match_scratch:DI 3 "r")]
21397 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21398 && satisfies_constraint_K (operands[2])"
21399 [(set (match_dup 3) (match_dup 2))
21400 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21401 (clobber (reg:CC FLAGS_REG))])]
21403 if (!rtx_equal_p (operands[0], operands[1]))
21404 emit_move_insn (operands[0], operands[1]);
21408 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21409 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21410 (match_operand:SI 2 "const_int_operand" "")))
21411 (clobber (reg:CC FLAGS_REG))])
21412 (match_scratch:SI 3 "r")]
21413 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21414 && satisfies_constraint_K (operands[2])"
21415 [(set (match_dup 3) (match_dup 2))
21416 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21417 (clobber (reg:CC FLAGS_REG))])]
21419 if (!rtx_equal_p (operands[0], operands[1]))
21420 emit_move_insn (operands[0], operands[1]);
21424 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21425 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21426 (match_operand:HI 2 "immediate_operand" "")))
21427 (clobber (reg:CC FLAGS_REG))])
21428 (match_scratch:HI 3 "r")]
21429 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21430 [(set (match_dup 3) (match_dup 2))
21431 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21432 (clobber (reg:CC FLAGS_REG))])]
21434 if (!rtx_equal_p (operands[0], operands[1]))
21435 emit_move_insn (operands[0], operands[1]);
21438 ;; After splitting up read-modify operations, array accesses with memory
21439 ;; operands might end up in form:
21441 ;; movl 4(%esp), %edx
21443 ;; instead of pre-splitting:
21445 ;; addl 4(%esp), %eax
21447 ;; movl 4(%esp), %edx
21448 ;; leal (%edx,%eax,4), %eax
21451 [(parallel [(set (match_operand 0 "register_operand" "")
21452 (ashift (match_operand 1 "register_operand" "")
21453 (match_operand 2 "const_int_operand" "")))
21454 (clobber (reg:CC FLAGS_REG))])
21455 (set (match_operand 3 "register_operand")
21456 (match_operand 4 "x86_64_general_operand" ""))
21457 (parallel [(set (match_operand 5 "register_operand" "")
21458 (plus (match_operand 6 "register_operand" "")
21459 (match_operand 7 "register_operand" "")))
21460 (clobber (reg:CC FLAGS_REG))])]
21461 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21462 /* Validate MODE for lea. */
21463 && ((!TARGET_PARTIAL_REG_STALL
21464 && (GET_MODE (operands[0]) == QImode
21465 || GET_MODE (operands[0]) == HImode))
21466 || GET_MODE (operands[0]) == SImode
21467 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21468 /* We reorder load and the shift. */
21469 && !rtx_equal_p (operands[1], operands[3])
21470 && !reg_overlap_mentioned_p (operands[0], operands[4])
21471 /* Last PLUS must consist of operand 0 and 3. */
21472 && !rtx_equal_p (operands[0], operands[3])
21473 && (rtx_equal_p (operands[3], operands[6])
21474 || rtx_equal_p (operands[3], operands[7]))
21475 && (rtx_equal_p (operands[0], operands[6])
21476 || rtx_equal_p (operands[0], operands[7]))
21477 /* The intermediate operand 0 must die or be same as output. */
21478 && (rtx_equal_p (operands[0], operands[5])
21479 || peep2_reg_dead_p (3, operands[0]))"
21480 [(set (match_dup 3) (match_dup 4))
21481 (set (match_dup 0) (match_dup 1))]
21483 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21484 int scale = 1 << INTVAL (operands[2]);
21485 rtx index = gen_lowpart (Pmode, operands[1]);
21486 rtx base = gen_lowpart (Pmode, operands[3]);
21487 rtx dest = gen_lowpart (mode, operands[5]);
21489 operands[1] = gen_rtx_PLUS (Pmode, base,
21490 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21492 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21493 operands[0] = dest;
21496 ;; Call-value patterns last so that the wildcard operand does not
21497 ;; disrupt insn-recog's switch tables.
21499 (define_insn "*call_value_pop_0"
21500 [(set (match_operand 0 "" "")
21501 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21502 (match_operand:SI 2 "" "")))
21503 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21504 (match_operand:SI 3 "immediate_operand" "")))]
21507 if (SIBLING_CALL_P (insn))
21510 return "call\t%P1";
21512 [(set_attr "type" "callv")])
21514 (define_insn "*call_value_pop_1"
21515 [(set (match_operand 0 "" "")
21516 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21517 (match_operand:SI 2 "" "")))
21518 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21519 (match_operand:SI 3 "immediate_operand" "i")))]
21522 if (constant_call_address_operand (operands[1], Pmode))
21524 if (SIBLING_CALL_P (insn))
21527 return "call\t%P1";
21529 if (SIBLING_CALL_P (insn))
21532 return "call\t%A1";
21534 [(set_attr "type" "callv")])
21536 (define_insn "*call_value_0"
21537 [(set (match_operand 0 "" "")
21538 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21539 (match_operand:SI 2 "" "")))]
21542 if (SIBLING_CALL_P (insn))
21545 return "call\t%P1";
21547 [(set_attr "type" "callv")])
21549 (define_insn "*call_value_0_rex64"
21550 [(set (match_operand 0 "" "")
21551 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21552 (match_operand:DI 2 "const_int_operand" "")))]
21555 if (SIBLING_CALL_P (insn))
21558 return "call\t%P1";
21560 [(set_attr "type" "callv")])
21562 (define_insn "*call_value_0_rex64_ms_sysv"
21563 [(set (match_operand 0 "" "")
21564 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21565 (match_operand:DI 2 "const_int_operand" "")))
21566 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21567 (clobber (reg:TI XMM6_REG))
21568 (clobber (reg:TI XMM7_REG))
21569 (clobber (reg:TI XMM8_REG))
21570 (clobber (reg:TI XMM9_REG))
21571 (clobber (reg:TI XMM10_REG))
21572 (clobber (reg:TI XMM11_REG))
21573 (clobber (reg:TI XMM12_REG))
21574 (clobber (reg:TI XMM13_REG))
21575 (clobber (reg:TI XMM14_REG))
21576 (clobber (reg:TI XMM15_REG))
21577 (clobber (reg:DI SI_REG))
21578 (clobber (reg:DI DI_REG))]
21579 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21581 if (SIBLING_CALL_P (insn))
21584 return "call\t%P1";
21586 [(set_attr "type" "callv")])
21588 (define_insn "*call_value_1"
21589 [(set (match_operand 0 "" "")
21590 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21591 (match_operand:SI 2 "" "")))]
21592 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21594 if (constant_call_address_operand (operands[1], Pmode))
21595 return "call\t%P1";
21596 return "call\t%A1";
21598 [(set_attr "type" "callv")])
21600 (define_insn "*sibcall_value_1"
21601 [(set (match_operand 0 "" "")
21602 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21603 (match_operand:SI 2 "" "")))]
21604 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21606 if (constant_call_address_operand (operands[1], Pmode))
21610 [(set_attr "type" "callv")])
21612 (define_insn "*call_value_1_rex64"
21613 [(set (match_operand 0 "" "")
21614 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21615 (match_operand:DI 2 "" "")))]
21616 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21617 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21619 if (constant_call_address_operand (operands[1], Pmode))
21620 return "call\t%P1";
21621 return "call\t%A1";
21623 [(set_attr "type" "callv")])
21625 (define_insn "*call_value_1_rex64_ms_sysv"
21626 [(set (match_operand 0 "" "")
21627 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21628 (match_operand:DI 2 "" "")))
21629 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21630 (clobber (reg:TI 27))
21631 (clobber (reg:TI 28))
21632 (clobber (reg:TI 45))
21633 (clobber (reg:TI 46))
21634 (clobber (reg:TI 47))
21635 (clobber (reg:TI 48))
21636 (clobber (reg:TI 49))
21637 (clobber (reg:TI 50))
21638 (clobber (reg:TI 51))
21639 (clobber (reg:TI 52))
21640 (clobber (reg:DI SI_REG))
21641 (clobber (reg:DI DI_REG))]
21642 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21644 if (constant_call_address_operand (operands[1], Pmode))
21645 return "call\t%P1";
21646 return "call\t%A1";
21648 [(set_attr "type" "callv")])
21650 (define_insn "*call_value_1_rex64_large"
21651 [(set (match_operand 0 "" "")
21652 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21653 (match_operand:DI 2 "" "")))]
21654 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21656 [(set_attr "type" "callv")])
21658 (define_insn "*sibcall_value_1_rex64"
21659 [(set (match_operand 0 "" "")
21660 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21661 (match_operand:DI 2 "" "")))]
21662 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21664 [(set_attr "type" "callv")])
21666 (define_insn "*sibcall_value_1_rex64_v"
21667 [(set (match_operand 0 "" "")
21668 (call (mem:QI (reg:DI R11_REG))
21669 (match_operand:DI 1 "" "")))]
21670 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21672 [(set_attr "type" "callv")])
21674 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21675 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21676 ;; caught for use by garbage collectors and the like. Using an insn that
21677 ;; maps to SIGILL makes it more likely the program will rightfully die.
21678 ;; Keeping with tradition, "6" is in honor of #UD.
21679 (define_insn "trap"
21680 [(trap_if (const_int 1) (const_int 6))]
21682 { return ASM_SHORT "0x0b0f"; }
21683 [(set_attr "length" "2")])
21685 (define_expand "sse_prologue_save"
21686 [(parallel [(set (match_operand:BLK 0 "" "")
21687 (unspec:BLK [(reg:DI 21)
21694 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21695 (use (match_operand:DI 1 "register_operand" ""))
21696 (use (match_operand:DI 2 "immediate_operand" ""))
21697 (use (label_ref:DI (match_operand 3 "" "")))])]
21701 (define_insn "*sse_prologue_save_insn"
21702 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21703 (match_operand:DI 4 "const_int_operand" "n")))
21704 (unspec:BLK [(reg:DI 21)
21711 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21712 (use (match_operand:DI 1 "register_operand" "r"))
21713 (use (match_operand:DI 2 "const_int_operand" "i"))
21714 (use (label_ref:DI (match_operand 3 "" "X")))]
21716 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21717 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21720 operands[0] = gen_rtx_MEM (Pmode,
21721 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21722 /* VEX instruction with a REX prefix will #UD. */
21723 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21724 gcc_unreachable ();
21726 output_asm_insn ("jmp\t%A1", operands);
21727 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21729 operands[4] = adjust_address (operands[0], DImode, i*16);
21730 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21731 PUT_MODE (operands[4], TImode);
21732 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21733 output_asm_insn ("rex", operands);
21734 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21736 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21737 CODE_LABEL_NUMBER (operands[3]));
21740 [(set_attr "type" "other")
21741 (set_attr "length_immediate" "0")
21742 (set_attr "length_address" "0")
21743 (set (attr "length")
21745 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21746 (const_string "34")
21747 (const_string "42")))
21748 (set_attr "memory" "store")
21749 (set_attr "modrm" "0")
21750 (set_attr "prefix" "maybe_vex")
21751 (set_attr "mode" "DI")])
21753 (define_expand "prefetch"
21754 [(prefetch (match_operand 0 "address_operand" "")
21755 (match_operand:SI 1 "const_int_operand" "")
21756 (match_operand:SI 2 "const_int_operand" ""))]
21757 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21759 int rw = INTVAL (operands[1]);
21760 int locality = INTVAL (operands[2]);
21762 gcc_assert (rw == 0 || rw == 1);
21763 gcc_assert (locality >= 0 && locality <= 3);
21764 gcc_assert (GET_MODE (operands[0]) == Pmode
21765 || GET_MODE (operands[0]) == VOIDmode);
21767 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21768 supported by SSE counterpart or the SSE prefetch is not available
21769 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21771 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21772 operands[2] = GEN_INT (3);
21774 operands[1] = const0_rtx;
21777 (define_insn "*prefetch_sse"
21778 [(prefetch (match_operand:SI 0 "address_operand" "p")
21780 (match_operand:SI 1 "const_int_operand" ""))]
21781 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21783 static const char * const patterns[4] = {
21784 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21787 int locality = INTVAL (operands[1]);
21788 gcc_assert (locality >= 0 && locality <= 3);
21790 return patterns[locality];
21792 [(set_attr "type" "sse")
21793 (set_attr "memory" "none")])
21795 (define_insn "*prefetch_sse_rex"
21796 [(prefetch (match_operand:DI 0 "address_operand" "p")
21798 (match_operand:SI 1 "const_int_operand" ""))]
21799 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21801 static const char * const patterns[4] = {
21802 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21805 int locality = INTVAL (operands[1]);
21806 gcc_assert (locality >= 0 && locality <= 3);
21808 return patterns[locality];
21810 [(set_attr "type" "sse")
21811 (set_attr "memory" "none")])
21813 (define_insn "*prefetch_3dnow"
21814 [(prefetch (match_operand:SI 0 "address_operand" "p")
21815 (match_operand:SI 1 "const_int_operand" "n")
21817 "TARGET_3DNOW && !TARGET_64BIT"
21819 if (INTVAL (operands[1]) == 0)
21820 return "prefetch\t%a0";
21822 return "prefetchw\t%a0";
21824 [(set_attr "type" "mmx")
21825 (set_attr "memory" "none")])
21827 (define_insn "*prefetch_3dnow_rex"
21828 [(prefetch (match_operand:DI 0 "address_operand" "p")
21829 (match_operand:SI 1 "const_int_operand" "n")
21831 "TARGET_3DNOW && TARGET_64BIT"
21833 if (INTVAL (operands[1]) == 0)
21834 return "prefetch\t%a0";
21836 return "prefetchw\t%a0";
21838 [(set_attr "type" "mmx")
21839 (set_attr "memory" "none")])
21841 (define_expand "stack_protect_set"
21842 [(match_operand 0 "memory_operand" "")
21843 (match_operand 1 "memory_operand" "")]
21846 #ifdef TARGET_THREAD_SSP_OFFSET
21848 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21849 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21851 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21852 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21855 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21857 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21862 (define_insn "stack_protect_set_si"
21863 [(set (match_operand:SI 0 "memory_operand" "=m")
21864 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21865 (set (match_scratch:SI 2 "=&r") (const_int 0))
21866 (clobber (reg:CC FLAGS_REG))]
21868 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21869 [(set_attr "type" "multi")])
21871 (define_insn "stack_protect_set_di"
21872 [(set (match_operand:DI 0 "memory_operand" "=m")
21873 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21874 (set (match_scratch:DI 2 "=&r") (const_int 0))
21875 (clobber (reg:CC FLAGS_REG))]
21877 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21878 [(set_attr "type" "multi")])
21880 (define_insn "stack_tls_protect_set_si"
21881 [(set (match_operand:SI 0 "memory_operand" "=m")
21882 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21883 (set (match_scratch:SI 2 "=&r") (const_int 0))
21884 (clobber (reg:CC FLAGS_REG))]
21886 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21887 [(set_attr "type" "multi")])
21889 (define_insn "stack_tls_protect_set_di"
21890 [(set (match_operand:DI 0 "memory_operand" "=m")
21891 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21892 (set (match_scratch:DI 2 "=&r") (const_int 0))
21893 (clobber (reg:CC FLAGS_REG))]
21896 /* The kernel uses a different segment register for performance reasons; a
21897 system call would not have to trash the userspace segment register,
21898 which would be expensive */
21899 if (ix86_cmodel != CM_KERNEL)
21900 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21902 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21904 [(set_attr "type" "multi")])
21906 (define_expand "stack_protect_test"
21907 [(match_operand 0 "memory_operand" "")
21908 (match_operand 1 "memory_operand" "")
21909 (match_operand 2 "" "")]
21912 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21913 ix86_compare_op0 = operands[0];
21914 ix86_compare_op1 = operands[1];
21915 ix86_compare_emitted = flags;
21917 #ifdef TARGET_THREAD_SSP_OFFSET
21919 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21920 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21922 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21923 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21926 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21928 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21930 emit_jump_insn (gen_beq (operands[2]));
21934 (define_insn "stack_protect_test_si"
21935 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21936 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21937 (match_operand:SI 2 "memory_operand" "m")]
21939 (clobber (match_scratch:SI 3 "=&r"))]
21941 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21942 [(set_attr "type" "multi")])
21944 (define_insn "stack_protect_test_di"
21945 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21946 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21947 (match_operand:DI 2 "memory_operand" "m")]
21949 (clobber (match_scratch:DI 3 "=&r"))]
21951 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21952 [(set_attr "type" "multi")])
21954 (define_insn "stack_tls_protect_test_si"
21955 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21956 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21957 (match_operand:SI 2 "const_int_operand" "i")]
21958 UNSPEC_SP_TLS_TEST))
21959 (clobber (match_scratch:SI 3 "=r"))]
21961 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21962 [(set_attr "type" "multi")])
21964 (define_insn "stack_tls_protect_test_di"
21965 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21966 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21967 (match_operand:DI 2 "const_int_operand" "i")]
21968 UNSPEC_SP_TLS_TEST))
21969 (clobber (match_scratch:DI 3 "=r"))]
21972 /* The kernel uses a different segment register for performance reasons; a
21973 system call would not have to trash the userspace segment register,
21974 which would be expensive */
21975 if (ix86_cmodel != CM_KERNEL)
21976 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21978 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21980 [(set_attr "type" "multi")])
21982 (define_mode_iterator CRC32MODE [QI HI SI])
21983 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21984 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21986 (define_insn "sse4_2_crc32<mode>"
21987 [(set (match_operand:SI 0 "register_operand" "=r")
21989 [(match_operand:SI 1 "register_operand" "0")
21990 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21993 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21994 [(set_attr "type" "sselog1")
21995 (set_attr "prefix_rep" "1")
21996 (set_attr "prefix_extra" "1")
21997 (set_attr "mode" "SI")])
21999 (define_insn "sse4_2_crc32di"
22000 [(set (match_operand:DI 0 "register_operand" "=r")
22002 [(match_operand:DI 1 "register_operand" "0")
22003 (match_operand:DI 2 "nonimmediate_operand" "rm")]
22005 "TARGET_SSE4_2 && TARGET_64BIT"
22006 "crc32q\t{%2, %0|%0, %2}"
22007 [(set_attr "type" "sselog1")
22008 (set_attr "prefix_rep" "1")
22009 (set_attr "prefix_extra" "1")
22010 (set_attr "mode" "DI")])
22014 (include "sync.md")