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,?fx*r,Y2")
4463 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4464 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4465 "TARGET_MIX_SSE_I387"
4467 switch (which_alternative)
4470 return output_387_reg_move (insn, operands);
4475 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4480 [(set_attr "type" "fmov,multi,ssecvt")
4481 (set_attr "unit" "*,i387,*")
4482 (set_attr "prefix" "orig,orig,maybe_vex")
4483 (set_attr "mode" "SF")])
4485 (define_insn "*truncdfsf_i387"
4486 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4488 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4489 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4492 switch (which_alternative)
4495 return output_387_reg_move (insn, operands);
4503 [(set_attr "type" "fmov,multi")
4504 (set_attr "unit" "*,i387")
4505 (set_attr "mode" "SF")])
4507 (define_insn "*truncdfsf2_i387_1"
4508 [(set (match_operand:SF 0 "memory_operand" "=m")
4510 (match_operand:DF 1 "register_operand" "f")))]
4512 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4513 && !TARGET_MIX_SSE_I387"
4514 "* return output_387_reg_move (insn, operands);"
4515 [(set_attr "type" "fmov")
4516 (set_attr "mode" "SF")])
4519 [(set (match_operand:SF 0 "register_operand" "")
4521 (match_operand:DF 1 "fp_register_operand" "")))
4522 (clobber (match_operand 2 "" ""))]
4524 [(set (match_dup 2) (match_dup 1))
4525 (set (match_dup 0) (match_dup 2))]
4527 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4530 ;; Conversion from XFmode to {SF,DF}mode
4532 (define_expand "truncxf<mode>2"
4533 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4534 (float_truncate:MODEF
4535 (match_operand:XF 1 "register_operand" "")))
4536 (clobber (match_dup 2))])]
4539 if (flag_unsafe_math_optimizations)
4541 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4542 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4543 if (reg != operands[0])
4544 emit_move_insn (operands[0], reg);
4549 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4550 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4554 (define_insn "*truncxfsf2_mixed"
4555 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4557 (match_operand:XF 1 "register_operand" "f,f")))
4558 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4561 gcc_assert (!which_alternative);
4562 return output_387_reg_move (insn, operands);
4564 [(set_attr "type" "fmov,multi")
4565 (set_attr "unit" "*,i387")
4566 (set_attr "mode" "SF")])
4568 (define_insn "*truncxfdf2_mixed"
4569 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4571 (match_operand:XF 1 "register_operand" "f,f")))
4572 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4575 gcc_assert (!which_alternative);
4576 return output_387_reg_move (insn, operands);
4578 [(set_attr "type" "fmov,multi")
4579 (set_attr "unit" "*,i387")
4580 (set_attr "mode" "DF")])
4582 (define_insn "truncxf<mode>2_i387_noop"
4583 [(set (match_operand:MODEF 0 "register_operand" "=f")
4584 (float_truncate:MODEF
4585 (match_operand:XF 1 "register_operand" "f")))]
4586 "TARGET_80387 && flag_unsafe_math_optimizations"
4587 "* return output_387_reg_move (insn, operands);"
4588 [(set_attr "type" "fmov")
4589 (set_attr "mode" "<MODE>")])
4591 (define_insn "*truncxf<mode>2_i387"
4592 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4593 (float_truncate:MODEF
4594 (match_operand:XF 1 "register_operand" "f")))]
4596 "* return output_387_reg_move (insn, operands);"
4597 [(set_attr "type" "fmov")
4598 (set_attr "mode" "<MODE>")])
4601 [(set (match_operand:MODEF 0 "register_operand" "")
4602 (float_truncate:MODEF
4603 (match_operand:XF 1 "register_operand" "")))
4604 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4605 "TARGET_80387 && reload_completed"
4606 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4607 (set (match_dup 0) (match_dup 2))]
4611 [(set (match_operand:MODEF 0 "memory_operand" "")
4612 (float_truncate:MODEF
4613 (match_operand:XF 1 "register_operand" "")))
4614 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4616 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4619 ;; Signed conversion to DImode.
4621 (define_expand "fix_truncxfdi2"
4622 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4623 (fix:DI (match_operand:XF 1 "register_operand" "")))
4624 (clobber (reg:CC FLAGS_REG))])]
4629 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4634 (define_expand "fix_trunc<mode>di2"
4635 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4636 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4637 (clobber (reg:CC FLAGS_REG))])]
4638 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4641 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4643 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4646 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4648 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4649 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4650 if (out != operands[0])
4651 emit_move_insn (operands[0], out);
4656 ;; Signed conversion to SImode.
4658 (define_expand "fix_truncxfsi2"
4659 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4660 (fix:SI (match_operand:XF 1 "register_operand" "")))
4661 (clobber (reg:CC FLAGS_REG))])]
4666 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4671 (define_expand "fix_trunc<mode>si2"
4672 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4673 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4674 (clobber (reg:CC FLAGS_REG))])]
4675 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4678 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4680 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4683 if (SSE_FLOAT_MODE_P (<MODE>mode))
4685 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4686 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4687 if (out != operands[0])
4688 emit_move_insn (operands[0], out);
4693 ;; Signed conversion to HImode.
4695 (define_expand "fix_trunc<mode>hi2"
4696 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4697 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4698 (clobber (reg:CC FLAGS_REG))])]
4700 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4704 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4709 ;; Unsigned conversion to SImode.
4711 (define_expand "fixuns_trunc<mode>si2"
4713 [(set (match_operand:SI 0 "register_operand" "")
4715 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4717 (clobber (match_scratch:<ssevecmode> 3 ""))
4718 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4719 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4721 enum machine_mode mode = <MODE>mode;
4722 enum machine_mode vecmode = <ssevecmode>mode;
4723 REAL_VALUE_TYPE TWO31r;
4726 if (optimize_insn_for_size_p ())
4729 real_ldexp (&TWO31r, &dconst1, 31);
4730 two31 = const_double_from_real_value (TWO31r, mode);
4731 two31 = ix86_build_const_vector (mode, true, two31);
4732 operands[2] = force_reg (vecmode, two31);
4735 (define_insn_and_split "*fixuns_trunc<mode>_1"
4736 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4738 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4739 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4740 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4741 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4742 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4743 && optimize_function_for_speed_p (cfun)"
4745 "&& reload_completed"
4748 ix86_split_convert_uns_si_sse (operands);
4752 ;; Unsigned conversion to HImode.
4753 ;; Without these patterns, we'll try the unsigned SI conversion which
4754 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4756 (define_expand "fixuns_trunc<mode>hi2"
4758 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4759 (set (match_operand:HI 0 "nonimmediate_operand" "")
4760 (subreg:HI (match_dup 2) 0))]
4761 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4762 "operands[2] = gen_reg_rtx (SImode);")
4764 ;; When SSE is available, it is always faster to use it!
4765 (define_insn "fix_trunc<mode>di_sse"
4766 [(set (match_operand:DI 0 "register_operand" "=r,r")
4767 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4768 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4769 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4770 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4771 [(set_attr "type" "sseicvt")
4772 (set_attr "prefix" "maybe_vex")
4773 (set_attr "mode" "<MODE>")
4774 (set_attr "athlon_decode" "double,vector")
4775 (set_attr "amdfam10_decode" "double,double")])
4777 (define_insn "fix_trunc<mode>si_sse"
4778 [(set (match_operand:SI 0 "register_operand" "=r,r")
4779 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4780 "SSE_FLOAT_MODE_P (<MODE>mode)
4781 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4782 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4783 [(set_attr "type" "sseicvt")
4784 (set_attr "prefix" "maybe_vex")
4785 (set_attr "mode" "<MODE>")
4786 (set_attr "athlon_decode" "double,vector")
4787 (set_attr "amdfam10_decode" "double,double")])
4789 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4791 [(set (match_operand:MODEF 0 "register_operand" "")
4792 (match_operand:MODEF 1 "memory_operand" ""))
4793 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4794 (fix:SSEMODEI24 (match_dup 0)))]
4795 "TARGET_SHORTEN_X87_SSE
4796 && peep2_reg_dead_p (2, operands[0])"
4797 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4800 ;; Avoid vector decoded forms of the instruction.
4802 [(match_scratch:DF 2 "Y2")
4803 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4804 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4805 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4806 [(set (match_dup 2) (match_dup 1))
4807 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4811 [(match_scratch:SF 2 "x")
4812 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4813 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4814 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4815 [(set (match_dup 2) (match_dup 1))
4816 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4819 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4820 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4821 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4822 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4824 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4825 && (TARGET_64BIT || <MODE>mode != DImode))
4827 && !(reload_completed || reload_in_progress)"
4832 if (memory_operand (operands[0], VOIDmode))
4833 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4836 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4837 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4843 [(set_attr "type" "fisttp")
4844 (set_attr "mode" "<MODE>")])
4846 (define_insn "fix_trunc<mode>_i387_fisttp"
4847 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4848 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4849 (clobber (match_scratch:XF 2 "=&1f"))]
4850 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4852 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4853 && (TARGET_64BIT || <MODE>mode != DImode))
4854 && TARGET_SSE_MATH)"
4855 "* return output_fix_trunc (insn, operands, 1);"
4856 [(set_attr "type" "fisttp")
4857 (set_attr "mode" "<MODE>")])
4859 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4860 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4861 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4862 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4863 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4864 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4866 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4867 && (TARGET_64BIT || <MODE>mode != DImode))
4868 && TARGET_SSE_MATH)"
4870 [(set_attr "type" "fisttp")
4871 (set_attr "mode" "<MODE>")])
4874 [(set (match_operand:X87MODEI 0 "register_operand" "")
4875 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4876 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4877 (clobber (match_scratch 3 ""))]
4879 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4880 (clobber (match_dup 3))])
4881 (set (match_dup 0) (match_dup 2))]
4885 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4886 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4887 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4888 (clobber (match_scratch 3 ""))]
4890 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4891 (clobber (match_dup 3))])]
4894 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4895 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4896 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4897 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4898 ;; function in i386.c.
4899 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4900 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4901 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4902 (clobber (reg:CC FLAGS_REG))]
4903 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4905 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4906 && (TARGET_64BIT || <MODE>mode != DImode))
4907 && !(reload_completed || reload_in_progress)"
4912 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4914 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4915 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4916 if (memory_operand (operands[0], VOIDmode))
4917 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4918 operands[2], operands[3]));
4921 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4922 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4923 operands[2], operands[3],
4928 [(set_attr "type" "fistp")
4929 (set_attr "i387_cw" "trunc")
4930 (set_attr "mode" "<MODE>")])
4932 (define_insn "fix_truncdi_i387"
4933 [(set (match_operand:DI 0 "memory_operand" "=m")
4934 (fix:DI (match_operand 1 "register_operand" "f")))
4935 (use (match_operand:HI 2 "memory_operand" "m"))
4936 (use (match_operand:HI 3 "memory_operand" "m"))
4937 (clobber (match_scratch:XF 4 "=&1f"))]
4938 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4940 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4941 "* return output_fix_trunc (insn, operands, 0);"
4942 [(set_attr "type" "fistp")
4943 (set_attr "i387_cw" "trunc")
4944 (set_attr "mode" "DI")])
4946 (define_insn "fix_truncdi_i387_with_temp"
4947 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4948 (fix:DI (match_operand 1 "register_operand" "f,f")))
4949 (use (match_operand:HI 2 "memory_operand" "m,m"))
4950 (use (match_operand:HI 3 "memory_operand" "m,m"))
4951 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4952 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4953 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4955 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4957 [(set_attr "type" "fistp")
4958 (set_attr "i387_cw" "trunc")
4959 (set_attr "mode" "DI")])
4962 [(set (match_operand:DI 0 "register_operand" "")
4963 (fix:DI (match_operand 1 "register_operand" "")))
4964 (use (match_operand:HI 2 "memory_operand" ""))
4965 (use (match_operand:HI 3 "memory_operand" ""))
4966 (clobber (match_operand:DI 4 "memory_operand" ""))
4967 (clobber (match_scratch 5 ""))]
4969 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4972 (clobber (match_dup 5))])
4973 (set (match_dup 0) (match_dup 4))]
4977 [(set (match_operand:DI 0 "memory_operand" "")
4978 (fix:DI (match_operand 1 "register_operand" "")))
4979 (use (match_operand:HI 2 "memory_operand" ""))
4980 (use (match_operand:HI 3 "memory_operand" ""))
4981 (clobber (match_operand:DI 4 "memory_operand" ""))
4982 (clobber (match_scratch 5 ""))]
4984 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4987 (clobber (match_dup 5))])]
4990 (define_insn "fix_trunc<mode>_i387"
4991 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4992 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4993 (use (match_operand:HI 2 "memory_operand" "m"))
4994 (use (match_operand:HI 3 "memory_operand" "m"))]
4995 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4997 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4998 "* return output_fix_trunc (insn, operands, 0);"
4999 [(set_attr "type" "fistp")
5000 (set_attr "i387_cw" "trunc")
5001 (set_attr "mode" "<MODE>")])
5003 (define_insn "fix_trunc<mode>_i387_with_temp"
5004 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5005 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5006 (use (match_operand:HI 2 "memory_operand" "m,m"))
5007 (use (match_operand:HI 3 "memory_operand" "m,m"))
5008 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5009 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5011 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5013 [(set_attr "type" "fistp")
5014 (set_attr "i387_cw" "trunc")
5015 (set_attr "mode" "<MODE>")])
5018 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5019 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5020 (use (match_operand:HI 2 "memory_operand" ""))
5021 (use (match_operand:HI 3 "memory_operand" ""))
5022 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5024 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5026 (use (match_dup 3))])
5027 (set (match_dup 0) (match_dup 4))]
5031 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5032 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5033 (use (match_operand:HI 2 "memory_operand" ""))
5034 (use (match_operand:HI 3 "memory_operand" ""))
5035 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5037 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5039 (use (match_dup 3))])]
5042 (define_insn "x86_fnstcw_1"
5043 [(set (match_operand:HI 0 "memory_operand" "=m")
5044 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5047 [(set_attr "length" "2")
5048 (set_attr "mode" "HI")
5049 (set_attr "unit" "i387")])
5051 (define_insn "x86_fldcw_1"
5052 [(set (reg:HI FPCR_REG)
5053 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5056 [(set_attr "length" "2")
5057 (set_attr "mode" "HI")
5058 (set_attr "unit" "i387")
5059 (set_attr "athlon_decode" "vector")
5060 (set_attr "amdfam10_decode" "vector")])
5062 ;; Conversion between fixed point and floating point.
5064 ;; Even though we only accept memory inputs, the backend _really_
5065 ;; wants to be able to do this between registers.
5067 (define_expand "floathi<mode>2"
5068 [(set (match_operand:X87MODEF 0 "register_operand" "")
5069 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5071 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5072 || TARGET_MIX_SSE_I387)"
5075 ;; Pre-reload splitter to add memory clobber to the pattern.
5076 (define_insn_and_split "*floathi<mode>2_1"
5077 [(set (match_operand:X87MODEF 0 "register_operand" "")
5078 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5081 || TARGET_MIX_SSE_I387)
5082 && !(reload_completed || reload_in_progress)"
5085 [(parallel [(set (match_dup 0)
5086 (float:X87MODEF (match_dup 1)))
5087 (clobber (match_dup 2))])]
5088 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5090 (define_insn "*floathi<mode>2_i387_with_temp"
5091 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5092 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5093 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5096 || TARGET_MIX_SSE_I387)"
5098 [(set_attr "type" "fmov,multi")
5099 (set_attr "mode" "<MODE>")
5100 (set_attr "unit" "*,i387")
5101 (set_attr "fp_int_src" "true")])
5103 (define_insn "*floathi<mode>2_i387"
5104 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5105 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5108 || TARGET_MIX_SSE_I387)"
5110 [(set_attr "type" "fmov")
5111 (set_attr "mode" "<MODE>")
5112 (set_attr "fp_int_src" "true")])
5115 [(set (match_operand:X87MODEF 0 "register_operand" "")
5116 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5117 (clobber (match_operand:HI 2 "memory_operand" ""))]
5119 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5120 || TARGET_MIX_SSE_I387)
5121 && reload_completed"
5122 [(set (match_dup 2) (match_dup 1))
5123 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5127 [(set (match_operand:X87MODEF 0 "register_operand" "")
5128 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5129 (clobber (match_operand:HI 2 "memory_operand" ""))]
5131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5132 || TARGET_MIX_SSE_I387)
5133 && reload_completed"
5134 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5137 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5138 [(set (match_operand:X87MODEF 0 "register_operand" "")
5140 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5142 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5143 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5146 ;; Pre-reload splitter to add memory clobber to the pattern.
5147 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5148 [(set (match_operand:X87MODEF 0 "register_operand" "")
5149 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5151 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5152 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5153 || TARGET_MIX_SSE_I387))
5154 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5155 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5156 && ((<SSEMODEI24:MODE>mode == SImode
5157 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5158 && optimize_function_for_speed_p (cfun)
5159 && flag_trapping_math)
5160 || !(TARGET_INTER_UNIT_CONVERSIONS
5161 || optimize_function_for_size_p (cfun)))))
5162 && !(reload_completed || reload_in_progress)"
5165 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5166 (clobber (match_dup 2))])]
5168 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5170 /* Avoid store forwarding (partial memory) stall penalty
5171 by passing DImode value through XMM registers. */
5172 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5173 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5174 && optimize_function_for_speed_p (cfun))
5176 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5183 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5184 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5186 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5187 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5188 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5189 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5191 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5192 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5193 (set_attr "unit" "*,i387,*,*,*")
5194 (set_attr "athlon_decode" "*,*,double,direct,double")
5195 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5196 (set_attr "fp_int_src" "true")])
5198 (define_insn "*floatsi<mode>2_vector_mixed"
5199 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5200 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5201 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5202 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5206 [(set_attr "type" "fmov,sseicvt")
5207 (set_attr "mode" "<MODE>,<ssevecmode>")
5208 (set_attr "unit" "i387,*")
5209 (set_attr "athlon_decode" "*,direct")
5210 (set_attr "amdfam10_decode" "*,double")
5211 (set_attr "fp_int_src" "true")])
5213 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5214 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5216 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5217 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5218 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5221 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5222 (set_attr "mode" "<MODEF:MODE>")
5223 (set_attr "unit" "*,i387,*,*")
5224 (set_attr "athlon_decode" "*,*,double,direct")
5225 (set_attr "amdfam10_decode" "*,*,vector,double")
5226 (set_attr "fp_int_src" "true")])
5229 [(set (match_operand:MODEF 0 "register_operand" "")
5230 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5231 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5232 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5233 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5234 && TARGET_INTER_UNIT_CONVERSIONS
5236 && (SSE_REG_P (operands[0])
5237 || (GET_CODE (operands[0]) == SUBREG
5238 && SSE_REG_P (operands[0])))"
5239 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5243 [(set (match_operand:MODEF 0 "register_operand" "")
5244 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5245 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5246 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5247 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5248 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5250 && (SSE_REG_P (operands[0])
5251 || (GET_CODE (operands[0]) == SUBREG
5252 && SSE_REG_P (operands[0])))"
5253 [(set (match_dup 2) (match_dup 1))
5254 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5257 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5258 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5260 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5261 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5262 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5263 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5266 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5267 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5268 [(set_attr "type" "fmov,sseicvt,sseicvt")
5269 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5270 (set_attr "mode" "<MODEF:MODE>")
5271 (set_attr "unit" "i387,*,*")
5272 (set_attr "athlon_decode" "*,double,direct")
5273 (set_attr "amdfam10_decode" "*,vector,double")
5274 (set_attr "fp_int_src" "true")])
5276 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5277 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5279 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5280 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5281 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5282 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5285 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5286 [(set_attr "type" "fmov,sseicvt")
5287 (set_attr "prefix" "orig,maybe_vex")
5288 (set_attr "mode" "<MODEF:MODE>")
5289 (set_attr "athlon_decode" "*,direct")
5290 (set_attr "amdfam10_decode" "*,double")
5291 (set_attr "fp_int_src" "true")])
5293 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5294 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5296 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5297 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5298 "TARGET_SSE2 && TARGET_SSE_MATH
5299 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5301 [(set_attr "type" "sseicvt")
5302 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5303 (set_attr "athlon_decode" "double,direct,double")
5304 (set_attr "amdfam10_decode" "vector,double,double")
5305 (set_attr "fp_int_src" "true")])
5307 (define_insn "*floatsi<mode>2_vector_sse"
5308 [(set (match_operand:MODEF 0 "register_operand" "=x")
5309 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5310 "TARGET_SSE2 && TARGET_SSE_MATH
5311 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5313 [(set_attr "type" "sseicvt")
5314 (set_attr "mode" "<MODE>")
5315 (set_attr "athlon_decode" "direct")
5316 (set_attr "amdfam10_decode" "double")
5317 (set_attr "fp_int_src" "true")])
5320 [(set (match_operand:MODEF 0 "register_operand" "")
5321 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5322 (clobber (match_operand:SI 2 "memory_operand" ""))]
5323 "TARGET_SSE2 && TARGET_SSE_MATH
5324 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5326 && (SSE_REG_P (operands[0])
5327 || (GET_CODE (operands[0]) == SUBREG
5328 && SSE_REG_P (operands[0])))"
5331 rtx op1 = operands[1];
5333 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5335 if (GET_CODE (op1) == SUBREG)
5336 op1 = SUBREG_REG (op1);
5338 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5340 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5341 emit_insn (gen_sse2_loadld (operands[4],
5342 CONST0_RTX (V4SImode), operands[1]));
5344 /* We can ignore possible trapping value in the
5345 high part of SSE register for non-trapping math. */
5346 else if (SSE_REG_P (op1) && !flag_trapping_math)
5347 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5350 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5351 emit_move_insn (operands[2], operands[1]);
5352 emit_insn (gen_sse2_loadld (operands[4],
5353 CONST0_RTX (V4SImode), operands[2]));
5356 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5361 [(set (match_operand:MODEF 0 "register_operand" "")
5362 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5363 (clobber (match_operand:SI 2 "memory_operand" ""))]
5364 "TARGET_SSE2 && TARGET_SSE_MATH
5365 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5367 && (SSE_REG_P (operands[0])
5368 || (GET_CODE (operands[0]) == SUBREG
5369 && SSE_REG_P (operands[0])))"
5372 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5374 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5376 emit_insn (gen_sse2_loadld (operands[4],
5377 CONST0_RTX (V4SImode), operands[1]));
5379 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5384 [(set (match_operand:MODEF 0 "register_operand" "")
5385 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5386 "TARGET_SSE2 && TARGET_SSE_MATH
5387 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5389 && (SSE_REG_P (operands[0])
5390 || (GET_CODE (operands[0]) == SUBREG
5391 && SSE_REG_P (operands[0])))"
5394 rtx op1 = operands[1];
5396 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5398 if (GET_CODE (op1) == SUBREG)
5399 op1 = SUBREG_REG (op1);
5401 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5403 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5404 emit_insn (gen_sse2_loadld (operands[4],
5405 CONST0_RTX (V4SImode), operands[1]));
5407 /* We can ignore possible trapping value in the
5408 high part of SSE register for non-trapping math. */
5409 else if (SSE_REG_P (op1) && !flag_trapping_math)
5410 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5414 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5419 [(set (match_operand:MODEF 0 "register_operand" "")
5420 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5421 "TARGET_SSE2 && TARGET_SSE_MATH
5422 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5424 && (SSE_REG_P (operands[0])
5425 || (GET_CODE (operands[0]) == SUBREG
5426 && SSE_REG_P (operands[0])))"
5429 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5431 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5433 emit_insn (gen_sse2_loadld (operands[4],
5434 CONST0_RTX (V4SImode), operands[1]));
5436 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5440 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5441 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5443 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5444 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5445 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5446 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5448 [(set_attr "type" "sseicvt")
5449 (set_attr "mode" "<MODEF:MODE>")
5450 (set_attr "athlon_decode" "double,direct")
5451 (set_attr "amdfam10_decode" "vector,double")
5452 (set_attr "fp_int_src" "true")])
5454 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5455 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5457 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5458 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5459 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5460 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5461 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5462 [(set_attr "type" "sseicvt")
5463 (set_attr "prefix" "maybe_vex")
5464 (set_attr "mode" "<MODEF:MODE>")
5465 (set_attr "athlon_decode" "double,direct")
5466 (set_attr "amdfam10_decode" "vector,double")
5467 (set_attr "fp_int_src" "true")])
5470 [(set (match_operand:MODEF 0 "register_operand" "")
5471 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5472 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5473 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5474 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5475 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5477 && (SSE_REG_P (operands[0])
5478 || (GET_CODE (operands[0]) == SUBREG
5479 && SSE_REG_P (operands[0])))"
5480 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5483 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5484 [(set (match_operand:MODEF 0 "register_operand" "=x")
5486 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5487 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5488 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5489 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5490 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5491 [(set_attr "type" "sseicvt")
5492 (set_attr "prefix" "maybe_vex")
5493 (set_attr "mode" "<MODEF:MODE>")
5494 (set_attr "athlon_decode" "direct")
5495 (set_attr "amdfam10_decode" "double")
5496 (set_attr "fp_int_src" "true")])
5499 [(set (match_operand:MODEF 0 "register_operand" "")
5500 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5501 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5502 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5503 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5504 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5506 && (SSE_REG_P (operands[0])
5507 || (GET_CODE (operands[0]) == SUBREG
5508 && SSE_REG_P (operands[0])))"
5509 [(set (match_dup 2) (match_dup 1))
5510 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5514 [(set (match_operand:MODEF 0 "register_operand" "")
5515 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5516 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5517 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5518 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5520 && (SSE_REG_P (operands[0])
5521 || (GET_CODE (operands[0]) == SUBREG
5522 && SSE_REG_P (operands[0])))"
5523 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5526 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5527 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5529 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5530 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5535 [(set_attr "type" "fmov,multi")
5536 (set_attr "mode" "<X87MODEF:MODE>")
5537 (set_attr "unit" "*,i387")
5538 (set_attr "fp_int_src" "true")])
5540 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5541 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5543 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5546 [(set_attr "type" "fmov")
5547 (set_attr "mode" "<X87MODEF:MODE>")
5548 (set_attr "fp_int_src" "true")])
5551 [(set (match_operand:X87MODEF 0 "register_operand" "")
5552 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5553 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5556 && FP_REG_P (operands[0])"
5557 [(set (match_dup 2) (match_dup 1))
5558 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5562 [(set (match_operand:X87MODEF 0 "register_operand" "")
5563 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5564 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5567 && FP_REG_P (operands[0])"
5568 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5571 ;; Avoid store forwarding (partial memory) stall penalty
5572 ;; by passing DImode value through XMM registers. */
5574 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5575 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5577 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5578 (clobber (match_scratch:V4SI 3 "=X,x"))
5579 (clobber (match_scratch:V4SI 4 "=X,x"))
5580 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5581 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5582 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5584 [(set_attr "type" "multi")
5585 (set_attr "mode" "<X87MODEF:MODE>")
5586 (set_attr "unit" "i387")
5587 (set_attr "fp_int_src" "true")])
5590 [(set (match_operand:X87MODEF 0 "register_operand" "")
5591 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5592 (clobber (match_scratch:V4SI 3 ""))
5593 (clobber (match_scratch:V4SI 4 ""))
5594 (clobber (match_operand:DI 2 "memory_operand" ""))]
5595 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5596 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5598 && FP_REG_P (operands[0])"
5599 [(set (match_dup 2) (match_dup 3))
5600 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5602 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5603 Assemble the 64-bit DImode value in an xmm register. */
5604 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5605 gen_rtx_SUBREG (SImode, operands[1], 0)));
5606 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5607 gen_rtx_SUBREG (SImode, operands[1], 4)));
5608 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5610 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5614 [(set (match_operand:X87MODEF 0 "register_operand" "")
5615 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5616 (clobber (match_scratch:V4SI 3 ""))
5617 (clobber (match_scratch:V4SI 4 ""))
5618 (clobber (match_operand:DI 2 "memory_operand" ""))]
5619 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5620 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5622 && FP_REG_P (operands[0])"
5623 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5626 ;; Avoid store forwarding (partial memory) stall penalty by extending
5627 ;; SImode value to DImode through XMM register instead of pushing two
5628 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5629 ;; targets benefit from this optimization. Also note that fild
5630 ;; loads from memory only.
5632 (define_insn "*floatunssi<mode>2_1"
5633 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5634 (unsigned_float:X87MODEF
5635 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5636 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5637 (clobber (match_scratch:SI 3 "=X,x"))]
5639 && TARGET_80387 && TARGET_SSE"
5641 [(set_attr "type" "multi")
5642 (set_attr "mode" "<MODE>")])
5645 [(set (match_operand:X87MODEF 0 "register_operand" "")
5646 (unsigned_float:X87MODEF
5647 (match_operand:SI 1 "register_operand" "")))
5648 (clobber (match_operand:DI 2 "memory_operand" ""))
5649 (clobber (match_scratch:SI 3 ""))]
5651 && TARGET_80387 && TARGET_SSE
5652 && reload_completed"
5653 [(set (match_dup 2) (match_dup 1))
5655 (float:X87MODEF (match_dup 2)))]
5656 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5659 [(set (match_operand:X87MODEF 0 "register_operand" "")
5660 (unsigned_float:X87MODEF
5661 (match_operand:SI 1 "memory_operand" "")))
5662 (clobber (match_operand:DI 2 "memory_operand" ""))
5663 (clobber (match_scratch:SI 3 ""))]
5665 && TARGET_80387 && TARGET_SSE
5666 && reload_completed"
5667 [(set (match_dup 2) (match_dup 3))
5669 (float:X87MODEF (match_dup 2)))]
5671 emit_move_insn (operands[3], operands[1]);
5672 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5675 (define_expand "floatunssi<mode>2"
5677 [(set (match_operand:X87MODEF 0 "register_operand" "")
5678 (unsigned_float:X87MODEF
5679 (match_operand:SI 1 "nonimmediate_operand" "")))
5680 (clobber (match_dup 2))
5681 (clobber (match_scratch:SI 3 ""))])]
5683 && ((TARGET_80387 && TARGET_SSE)
5684 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5686 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5688 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5693 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5694 operands[2] = assign_386_stack_local (DImode, slot);
5698 (define_expand "floatunsdisf2"
5699 [(use (match_operand:SF 0 "register_operand" ""))
5700 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5701 "TARGET_64BIT && TARGET_SSE_MATH"
5702 "x86_emit_floatuns (operands); DONE;")
5704 (define_expand "floatunsdidf2"
5705 [(use (match_operand:DF 0 "register_operand" ""))
5706 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5707 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5708 && TARGET_SSE2 && TARGET_SSE_MATH"
5711 x86_emit_floatuns (operands);
5713 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5719 ;; %%% splits for addditi3
5721 (define_expand "addti3"
5722 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5723 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5724 (match_operand:TI 2 "x86_64_general_operand" "")))]
5726 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5728 (define_insn "*addti3_1"
5729 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5730 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5731 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5732 (clobber (reg:CC FLAGS_REG))]
5733 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5737 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5738 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5739 (match_operand:TI 2 "x86_64_general_operand" "")))
5740 (clobber (reg:CC FLAGS_REG))]
5741 "TARGET_64BIT && reload_completed"
5742 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5744 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5745 (parallel [(set (match_dup 3)
5746 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5749 (clobber (reg:CC FLAGS_REG))])]
5750 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5752 ;; %%% splits for addsidi3
5753 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5754 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5755 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5757 (define_expand "adddi3"
5758 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5759 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5760 (match_operand:DI 2 "x86_64_general_operand" "")))]
5762 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5764 (define_insn "*adddi3_1"
5765 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5766 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5767 (match_operand:DI 2 "general_operand" "roiF,riF")))
5768 (clobber (reg:CC FLAGS_REG))]
5769 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5773 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5774 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5775 (match_operand:DI 2 "general_operand" "")))
5776 (clobber (reg:CC FLAGS_REG))]
5777 "!TARGET_64BIT && reload_completed"
5778 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5780 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5781 (parallel [(set (match_dup 3)
5782 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5785 (clobber (reg:CC FLAGS_REG))])]
5786 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5788 (define_insn "adddi3_carry_rex64"
5789 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5790 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5791 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5792 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5793 (clobber (reg:CC FLAGS_REG))]
5794 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5795 "adc{q}\t{%2, %0|%0, %2}"
5796 [(set_attr "type" "alu")
5797 (set_attr "pent_pair" "pu")
5798 (set_attr "mode" "DI")])
5800 (define_insn "*adddi3_cc_rex64"
5801 [(set (reg:CC FLAGS_REG)
5802 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5803 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5805 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5806 (plus:DI (match_dup 1) (match_dup 2)))]
5807 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5808 "add{q}\t{%2, %0|%0, %2}"
5809 [(set_attr "type" "alu")
5810 (set_attr "mode" "DI")])
5812 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5813 [(set (reg:CCC FLAGS_REG)
5816 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5817 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5819 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5820 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5821 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5822 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5823 [(set_attr "type" "alu")
5824 (set_attr "mode" "<MODE>")])
5826 (define_insn "*add<mode>3_cconly_overflow"
5827 [(set (reg:CCC FLAGS_REG)
5829 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5830 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5832 (clobber (match_scratch:SWI 0 "=<r>"))]
5833 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5834 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5835 [(set_attr "type" "alu")
5836 (set_attr "mode" "<MODE>")])
5838 (define_insn "*sub<mode>3_cconly_overflow"
5839 [(set (reg:CCC FLAGS_REG)
5841 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5842 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5845 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5846 [(set_attr "type" "icmp")
5847 (set_attr "mode" "<MODE>")])
5849 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5850 [(set (reg:CCC FLAGS_REG)
5852 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5853 (match_operand:SI 2 "general_operand" "g"))
5855 (set (match_operand:DI 0 "register_operand" "=r")
5856 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5857 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5858 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5859 [(set_attr "type" "alu")
5860 (set_attr "mode" "SI")])
5862 (define_insn "addqi3_carry"
5863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5864 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5865 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5866 (match_operand:QI 2 "general_operand" "qn,qm")))
5867 (clobber (reg:CC FLAGS_REG))]
5868 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5869 "adc{b}\t{%2, %0|%0, %2}"
5870 [(set_attr "type" "alu")
5871 (set_attr "pent_pair" "pu")
5872 (set_attr "mode" "QI")])
5874 (define_insn "addhi3_carry"
5875 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5876 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5877 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5878 (match_operand:HI 2 "general_operand" "rn,rm")))
5879 (clobber (reg:CC FLAGS_REG))]
5880 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5881 "adc{w}\t{%2, %0|%0, %2}"
5882 [(set_attr "type" "alu")
5883 (set_attr "pent_pair" "pu")
5884 (set_attr "mode" "HI")])
5886 (define_insn "addsi3_carry"
5887 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5888 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5889 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5890 (match_operand:SI 2 "general_operand" "ri,rm")))
5891 (clobber (reg:CC FLAGS_REG))]
5892 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5893 "adc{l}\t{%2, %0|%0, %2}"
5894 [(set_attr "type" "alu")
5895 (set_attr "pent_pair" "pu")
5896 (set_attr "mode" "SI")])
5898 (define_insn "*addsi3_carry_zext"
5899 [(set (match_operand:DI 0 "register_operand" "=r")
5901 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5902 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5903 (match_operand:SI 2 "general_operand" "g"))))
5904 (clobber (reg:CC FLAGS_REG))]
5905 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5906 "adc{l}\t{%2, %k0|%k0, %2}"
5907 [(set_attr "type" "alu")
5908 (set_attr "pent_pair" "pu")
5909 (set_attr "mode" "SI")])
5911 (define_insn "*addsi3_cc"
5912 [(set (reg:CC FLAGS_REG)
5913 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5914 (match_operand:SI 2 "general_operand" "ri,rm")]
5916 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5917 (plus:SI (match_dup 1) (match_dup 2)))]
5918 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5919 "add{l}\t{%2, %0|%0, %2}"
5920 [(set_attr "type" "alu")
5921 (set_attr "mode" "SI")])
5923 (define_insn "addqi3_cc"
5924 [(set (reg:CC FLAGS_REG)
5925 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5926 (match_operand:QI 2 "general_operand" "qn,qm")]
5928 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5929 (plus:QI (match_dup 1) (match_dup 2)))]
5930 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5931 "add{b}\t{%2, %0|%0, %2}"
5932 [(set_attr "type" "alu")
5933 (set_attr "mode" "QI")])
5935 (define_expand "addsi3"
5936 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5937 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5938 (match_operand:SI 2 "general_operand" "")))]
5940 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5942 (define_insn "*lea_1"
5943 [(set (match_operand:SI 0 "register_operand" "=r")
5944 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5946 "lea{l}\t{%a1, %0|%0, %a1}"
5947 [(set_attr "type" "lea")
5948 (set_attr "mode" "SI")])
5950 (define_insn "*lea_1_rex64"
5951 [(set (match_operand:SI 0 "register_operand" "=r")
5952 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5954 "lea{l}\t{%a1, %0|%0, %a1}"
5955 [(set_attr "type" "lea")
5956 (set_attr "mode" "SI")])
5958 (define_insn "*lea_1_zext"
5959 [(set (match_operand:DI 0 "register_operand" "=r")
5961 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5963 "lea{l}\t{%a1, %k0|%k0, %a1}"
5964 [(set_attr "type" "lea")
5965 (set_attr "mode" "SI")])
5967 (define_insn "*lea_2_rex64"
5968 [(set (match_operand:DI 0 "register_operand" "=r")
5969 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5971 "lea{q}\t{%a1, %0|%0, %a1}"
5972 [(set_attr "type" "lea")
5973 (set_attr "mode" "DI")])
5975 ;; The lea patterns for non-Pmodes needs to be matched by several
5976 ;; insns converted to real lea by splitters.
5978 (define_insn_and_split "*lea_general_1"
5979 [(set (match_operand 0 "register_operand" "=r")
5980 (plus (plus (match_operand 1 "index_register_operand" "l")
5981 (match_operand 2 "register_operand" "r"))
5982 (match_operand 3 "immediate_operand" "i")))]
5983 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5984 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5985 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5986 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5987 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5988 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5989 || GET_MODE (operands[3]) == VOIDmode)"
5991 "&& reload_completed"
5995 operands[0] = gen_lowpart (SImode, operands[0]);
5996 operands[1] = gen_lowpart (Pmode, operands[1]);
5997 operands[2] = gen_lowpart (Pmode, operands[2]);
5998 operands[3] = gen_lowpart (Pmode, operands[3]);
5999 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6001 if (Pmode != SImode)
6002 pat = gen_rtx_SUBREG (SImode, pat, 0);
6003 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6006 [(set_attr "type" "lea")
6007 (set_attr "mode" "SI")])
6009 (define_insn_and_split "*lea_general_1_zext"
6010 [(set (match_operand:DI 0 "register_operand" "=r")
6012 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6013 (match_operand:SI 2 "register_operand" "r"))
6014 (match_operand:SI 3 "immediate_operand" "i"))))]
6017 "&& reload_completed"
6019 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6021 (match_dup 3)) 0)))]
6023 operands[1] = gen_lowpart (Pmode, operands[1]);
6024 operands[2] = gen_lowpart (Pmode, operands[2]);
6025 operands[3] = gen_lowpart (Pmode, operands[3]);
6027 [(set_attr "type" "lea")
6028 (set_attr "mode" "SI")])
6030 (define_insn_and_split "*lea_general_2"
6031 [(set (match_operand 0 "register_operand" "=r")
6032 (plus (mult (match_operand 1 "index_register_operand" "l")
6033 (match_operand 2 "const248_operand" "i"))
6034 (match_operand 3 "nonmemory_operand" "ri")))]
6035 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6036 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6037 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6038 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6039 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6040 || GET_MODE (operands[3]) == VOIDmode)"
6042 "&& reload_completed"
6046 operands[0] = gen_lowpart (SImode, operands[0]);
6047 operands[1] = gen_lowpart (Pmode, operands[1]);
6048 operands[3] = gen_lowpart (Pmode, operands[3]);
6049 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6051 if (Pmode != SImode)
6052 pat = gen_rtx_SUBREG (SImode, pat, 0);
6053 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6056 [(set_attr "type" "lea")
6057 (set_attr "mode" "SI")])
6059 (define_insn_and_split "*lea_general_2_zext"
6060 [(set (match_operand:DI 0 "register_operand" "=r")
6062 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6063 (match_operand:SI 2 "const248_operand" "n"))
6064 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6067 "&& reload_completed"
6069 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6071 (match_dup 3)) 0)))]
6073 operands[1] = gen_lowpart (Pmode, operands[1]);
6074 operands[3] = gen_lowpart (Pmode, operands[3]);
6076 [(set_attr "type" "lea")
6077 (set_attr "mode" "SI")])
6079 (define_insn_and_split "*lea_general_3"
6080 [(set (match_operand 0 "register_operand" "=r")
6081 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6082 (match_operand 2 "const248_operand" "i"))
6083 (match_operand 3 "register_operand" "r"))
6084 (match_operand 4 "immediate_operand" "i")))]
6085 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6086 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6087 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6088 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6089 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6091 "&& reload_completed"
6095 operands[0] = gen_lowpart (SImode, operands[0]);
6096 operands[1] = gen_lowpart (Pmode, operands[1]);
6097 operands[3] = gen_lowpart (Pmode, operands[3]);
6098 operands[4] = gen_lowpart (Pmode, operands[4]);
6099 pat = gen_rtx_PLUS (Pmode,
6100 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6104 if (Pmode != SImode)
6105 pat = gen_rtx_SUBREG (SImode, pat, 0);
6106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6109 [(set_attr "type" "lea")
6110 (set_attr "mode" "SI")])
6112 (define_insn_and_split "*lea_general_3_zext"
6113 [(set (match_operand:DI 0 "register_operand" "=r")
6115 (plus:SI (plus:SI (mult:SI
6116 (match_operand:SI 1 "index_register_operand" "l")
6117 (match_operand:SI 2 "const248_operand" "n"))
6118 (match_operand:SI 3 "register_operand" "r"))
6119 (match_operand:SI 4 "immediate_operand" "i"))))]
6122 "&& reload_completed"
6124 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6127 (match_dup 4)) 0)))]
6129 operands[1] = gen_lowpart (Pmode, operands[1]);
6130 operands[3] = gen_lowpart (Pmode, operands[3]);
6131 operands[4] = gen_lowpart (Pmode, operands[4]);
6133 [(set_attr "type" "lea")
6134 (set_attr "mode" "SI")])
6136 (define_insn "*adddi_1_rex64"
6137 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6138 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6139 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6140 (clobber (reg:CC FLAGS_REG))]
6141 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6143 switch (get_attr_type (insn))
6146 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6147 return "lea{q}\t{%a2, %0|%0, %a2}";
6150 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6151 if (operands[2] == const1_rtx)
6152 return "inc{q}\t%0";
6155 gcc_assert (operands[2] == constm1_rtx);
6156 return "dec{q}\t%0";
6160 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6162 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6163 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6164 if (CONST_INT_P (operands[2])
6165 /* Avoid overflows. */
6166 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6167 && (INTVAL (operands[2]) == 128
6168 || (INTVAL (operands[2]) < 0
6169 && INTVAL (operands[2]) != -128)))
6171 operands[2] = GEN_INT (-INTVAL (operands[2]));
6172 return "sub{q}\t{%2, %0|%0, %2}";
6174 return "add{q}\t{%2, %0|%0, %2}";
6178 (cond [(eq_attr "alternative" "2")
6179 (const_string "lea")
6180 ; Current assemblers are broken and do not allow @GOTOFF in
6181 ; ought but a memory context.
6182 (match_operand:DI 2 "pic_symbolic_operand" "")
6183 (const_string "lea")
6184 (match_operand:DI 2 "incdec_operand" "")
6185 (const_string "incdec")
6187 (const_string "alu")))
6188 (set_attr "mode" "DI")])
6190 ;; Convert lea to the lea pattern to avoid flags dependency.
6192 [(set (match_operand:DI 0 "register_operand" "")
6193 (plus:DI (match_operand:DI 1 "register_operand" "")
6194 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6195 (clobber (reg:CC FLAGS_REG))]
6196 "TARGET_64BIT && reload_completed
6197 && true_regnum (operands[0]) != true_regnum (operands[1])"
6199 (plus:DI (match_dup 1)
6203 (define_insn "*adddi_2_rex64"
6204 [(set (reg FLAGS_REG)
6206 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6207 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6209 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6210 (plus:DI (match_dup 1) (match_dup 2)))]
6211 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6212 && ix86_binary_operator_ok (PLUS, DImode, operands)
6213 /* Current assemblers are broken and do not allow @GOTOFF in
6214 ought but a memory context. */
6215 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6217 switch (get_attr_type (insn))
6220 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6221 if (operands[2] == const1_rtx)
6222 return "inc{q}\t%0";
6225 gcc_assert (operands[2] == constm1_rtx);
6226 return "dec{q}\t%0";
6230 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6231 /* ???? We ought to handle there the 32bit case too
6232 - do we need new constraint? */
6233 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6234 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6235 if (CONST_INT_P (operands[2])
6236 /* Avoid overflows. */
6237 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6238 && (INTVAL (operands[2]) == 128
6239 || (INTVAL (operands[2]) < 0
6240 && INTVAL (operands[2]) != -128)))
6242 operands[2] = GEN_INT (-INTVAL (operands[2]));
6243 return "sub{q}\t{%2, %0|%0, %2}";
6245 return "add{q}\t{%2, %0|%0, %2}";
6249 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6250 (const_string "incdec")
6251 (const_string "alu")))
6252 (set_attr "mode" "DI")])
6254 (define_insn "*adddi_3_rex64"
6255 [(set (reg FLAGS_REG)
6256 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6257 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6258 (clobber (match_scratch:DI 0 "=r"))]
6260 && ix86_match_ccmode (insn, CCZmode)
6261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6262 /* Current assemblers are broken and do not allow @GOTOFF in
6263 ought but a memory context. */
6264 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6266 switch (get_attr_type (insn))
6269 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6270 if (operands[2] == const1_rtx)
6271 return "inc{q}\t%0";
6274 gcc_assert (operands[2] == constm1_rtx);
6275 return "dec{q}\t%0";
6279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6280 /* ???? We ought to handle there the 32bit case too
6281 - do we need new constraint? */
6282 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6283 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6284 if (CONST_INT_P (operands[2])
6285 /* Avoid overflows. */
6286 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6287 && (INTVAL (operands[2]) == 128
6288 || (INTVAL (operands[2]) < 0
6289 && INTVAL (operands[2]) != -128)))
6291 operands[2] = GEN_INT (-INTVAL (operands[2]));
6292 return "sub{q}\t{%2, %0|%0, %2}";
6294 return "add{q}\t{%2, %0|%0, %2}";
6298 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6299 (const_string "incdec")
6300 (const_string "alu")))
6301 (set_attr "mode" "DI")])
6303 ; For comparisons against 1, -1 and 128, we may generate better code
6304 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6305 ; is matched then. We can't accept general immediate, because for
6306 ; case of overflows, the result is messed up.
6307 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6309 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6310 ; only for comparisons not depending on it.
6311 (define_insn "*adddi_4_rex64"
6312 [(set (reg FLAGS_REG)
6313 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6314 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6315 (clobber (match_scratch:DI 0 "=rm"))]
6317 && ix86_match_ccmode (insn, CCGCmode)"
6319 switch (get_attr_type (insn))
6322 if (operands[2] == constm1_rtx)
6323 return "inc{q}\t%0";
6326 gcc_assert (operands[2] == const1_rtx);
6327 return "dec{q}\t%0";
6331 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6332 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6333 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6334 if ((INTVAL (operands[2]) == -128
6335 || (INTVAL (operands[2]) > 0
6336 && INTVAL (operands[2]) != 128))
6337 /* Avoid overflows. */
6338 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6339 return "sub{q}\t{%2, %0|%0, %2}";
6340 operands[2] = GEN_INT (-INTVAL (operands[2]));
6341 return "add{q}\t{%2, %0|%0, %2}";
6345 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6346 (const_string "incdec")
6347 (const_string "alu")))
6348 (set_attr "mode" "DI")])
6350 (define_insn "*adddi_5_rex64"
6351 [(set (reg FLAGS_REG)
6353 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6354 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6356 (clobber (match_scratch:DI 0 "=r"))]
6358 && ix86_match_ccmode (insn, CCGOCmode)
6359 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6360 /* Current assemblers are broken and do not allow @GOTOFF in
6361 ought but a memory context. */
6362 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6364 switch (get_attr_type (insn))
6367 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6368 if (operands[2] == const1_rtx)
6369 return "inc{q}\t%0";
6372 gcc_assert (operands[2] == constm1_rtx);
6373 return "dec{q}\t%0";
6377 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6378 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6379 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6380 if (CONST_INT_P (operands[2])
6381 /* Avoid overflows. */
6382 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6383 && (INTVAL (operands[2]) == 128
6384 || (INTVAL (operands[2]) < 0
6385 && INTVAL (operands[2]) != -128)))
6387 operands[2] = GEN_INT (-INTVAL (operands[2]));
6388 return "sub{q}\t{%2, %0|%0, %2}";
6390 return "add{q}\t{%2, %0|%0, %2}";
6394 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6395 (const_string "incdec")
6396 (const_string "alu")))
6397 (set_attr "mode" "DI")])
6400 (define_insn "*addsi_1"
6401 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6402 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6403 (match_operand:SI 2 "general_operand" "g,ri,li")))
6404 (clobber (reg:CC FLAGS_REG))]
6405 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6407 switch (get_attr_type (insn))
6410 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6411 return "lea{l}\t{%a2, %0|%0, %a2}";
6414 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6415 if (operands[2] == const1_rtx)
6416 return "inc{l}\t%0";
6419 gcc_assert (operands[2] == constm1_rtx);
6420 return "dec{l}\t%0";
6424 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6426 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6427 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6428 if (CONST_INT_P (operands[2])
6429 && (INTVAL (operands[2]) == 128
6430 || (INTVAL (operands[2]) < 0
6431 && INTVAL (operands[2]) != -128)))
6433 operands[2] = GEN_INT (-INTVAL (operands[2]));
6434 return "sub{l}\t{%2, %0|%0, %2}";
6436 return "add{l}\t{%2, %0|%0, %2}";
6440 (cond [(eq_attr "alternative" "2")
6441 (const_string "lea")
6442 ; Current assemblers are broken and do not allow @GOTOFF in
6443 ; ought but a memory context.
6444 (match_operand:SI 2 "pic_symbolic_operand" "")
6445 (const_string "lea")
6446 (match_operand:SI 2 "incdec_operand" "")
6447 (const_string "incdec")
6449 (const_string "alu")))
6450 (set_attr "mode" "SI")])
6452 ;; Convert lea to the lea pattern to avoid flags dependency.
6454 [(set (match_operand 0 "register_operand" "")
6455 (plus (match_operand 1 "register_operand" "")
6456 (match_operand 2 "nonmemory_operand" "")))
6457 (clobber (reg:CC FLAGS_REG))]
6459 && true_regnum (operands[0]) != true_regnum (operands[1])"
6463 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6464 may confuse gen_lowpart. */
6465 if (GET_MODE (operands[0]) != Pmode)
6467 operands[1] = gen_lowpart (Pmode, operands[1]);
6468 operands[2] = gen_lowpart (Pmode, operands[2]);
6470 operands[0] = gen_lowpart (SImode, operands[0]);
6471 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6472 if (Pmode != SImode)
6473 pat = gen_rtx_SUBREG (SImode, pat, 0);
6474 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6478 ;; It may seem that nonimmediate operand is proper one for operand 1.
6479 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6480 ;; we take care in ix86_binary_operator_ok to not allow two memory
6481 ;; operands so proper swapping will be done in reload. This allow
6482 ;; patterns constructed from addsi_1 to match.
6483 (define_insn "addsi_1_zext"
6484 [(set (match_operand:DI 0 "register_operand" "=r,r")
6486 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6487 (match_operand:SI 2 "general_operand" "g,li"))))
6488 (clobber (reg:CC FLAGS_REG))]
6489 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6491 switch (get_attr_type (insn))
6494 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6495 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6498 if (operands[2] == const1_rtx)
6499 return "inc{l}\t%k0";
6502 gcc_assert (operands[2] == constm1_rtx);
6503 return "dec{l}\t%k0";
6507 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6508 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6509 if (CONST_INT_P (operands[2])
6510 && (INTVAL (operands[2]) == 128
6511 || (INTVAL (operands[2]) < 0
6512 && INTVAL (operands[2]) != -128)))
6514 operands[2] = GEN_INT (-INTVAL (operands[2]));
6515 return "sub{l}\t{%2, %k0|%k0, %2}";
6517 return "add{l}\t{%2, %k0|%k0, %2}";
6521 (cond [(eq_attr "alternative" "1")
6522 (const_string "lea")
6523 ; Current assemblers are broken and do not allow @GOTOFF in
6524 ; ought but a memory context.
6525 (match_operand:SI 2 "pic_symbolic_operand" "")
6526 (const_string "lea")
6527 (match_operand:SI 2 "incdec_operand" "")
6528 (const_string "incdec")
6530 (const_string "alu")))
6531 (set_attr "mode" "SI")])
6533 ;; Convert lea to the lea pattern to avoid flags dependency.
6535 [(set (match_operand:DI 0 "register_operand" "")
6537 (plus:SI (match_operand:SI 1 "register_operand" "")
6538 (match_operand:SI 2 "nonmemory_operand" ""))))
6539 (clobber (reg:CC FLAGS_REG))]
6540 "TARGET_64BIT && reload_completed
6541 && true_regnum (operands[0]) != true_regnum (operands[1])"
6543 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6545 operands[1] = gen_lowpart (Pmode, operands[1]);
6546 operands[2] = gen_lowpart (Pmode, operands[2]);
6549 (define_insn "*addsi_2"
6550 [(set (reg FLAGS_REG)
6552 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6553 (match_operand:SI 2 "general_operand" "g,ri"))
6555 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6556 (plus:SI (match_dup 1) (match_dup 2)))]
6557 "ix86_match_ccmode (insn, CCGOCmode)
6558 && ix86_binary_operator_ok (PLUS, SImode, operands)
6559 /* Current assemblers are broken and do not allow @GOTOFF in
6560 ought but a memory context. */
6561 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6563 switch (get_attr_type (insn))
6566 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6567 if (operands[2] == const1_rtx)
6568 return "inc{l}\t%0";
6571 gcc_assert (operands[2] == constm1_rtx);
6572 return "dec{l}\t%0";
6576 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6577 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6578 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6579 if (CONST_INT_P (operands[2])
6580 && (INTVAL (operands[2]) == 128
6581 || (INTVAL (operands[2]) < 0
6582 && INTVAL (operands[2]) != -128)))
6584 operands[2] = GEN_INT (-INTVAL (operands[2]));
6585 return "sub{l}\t{%2, %0|%0, %2}";
6587 return "add{l}\t{%2, %0|%0, %2}";
6591 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6592 (const_string "incdec")
6593 (const_string "alu")))
6594 (set_attr "mode" "SI")])
6596 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6597 (define_insn "*addsi_2_zext"
6598 [(set (reg FLAGS_REG)
6600 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6601 (match_operand:SI 2 "general_operand" "g"))
6603 (set (match_operand:DI 0 "register_operand" "=r")
6604 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6605 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6606 && ix86_binary_operator_ok (PLUS, SImode, operands)
6607 /* Current assemblers are broken and do not allow @GOTOFF in
6608 ought but a memory context. */
6609 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6611 switch (get_attr_type (insn))
6614 if (operands[2] == const1_rtx)
6615 return "inc{l}\t%k0";
6618 gcc_assert (operands[2] == constm1_rtx);
6619 return "dec{l}\t%k0";
6623 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6624 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6625 if (CONST_INT_P (operands[2])
6626 && (INTVAL (operands[2]) == 128
6627 || (INTVAL (operands[2]) < 0
6628 && INTVAL (operands[2]) != -128)))
6630 operands[2] = GEN_INT (-INTVAL (operands[2]));
6631 return "sub{l}\t{%2, %k0|%k0, %2}";
6633 return "add{l}\t{%2, %k0|%k0, %2}";
6637 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6638 (const_string "incdec")
6639 (const_string "alu")))
6640 (set_attr "mode" "SI")])
6642 (define_insn "*addsi_3"
6643 [(set (reg FLAGS_REG)
6644 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6645 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6646 (clobber (match_scratch:SI 0 "=r"))]
6647 "ix86_match_ccmode (insn, CCZmode)
6648 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6649 /* Current assemblers are broken and do not allow @GOTOFF in
6650 ought but a memory context. */
6651 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6653 switch (get_attr_type (insn))
6656 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6657 if (operands[2] == const1_rtx)
6658 return "inc{l}\t%0";
6661 gcc_assert (operands[2] == constm1_rtx);
6662 return "dec{l}\t%0";
6666 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6667 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6668 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6669 if (CONST_INT_P (operands[2])
6670 && (INTVAL (operands[2]) == 128
6671 || (INTVAL (operands[2]) < 0
6672 && INTVAL (operands[2]) != -128)))
6674 operands[2] = GEN_INT (-INTVAL (operands[2]));
6675 return "sub{l}\t{%2, %0|%0, %2}";
6677 return "add{l}\t{%2, %0|%0, %2}";
6681 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6682 (const_string "incdec")
6683 (const_string "alu")))
6684 (set_attr "mode" "SI")])
6686 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6687 (define_insn "*addsi_3_zext"
6688 [(set (reg FLAGS_REG)
6689 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6690 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6691 (set (match_operand:DI 0 "register_operand" "=r")
6692 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6693 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6694 && ix86_binary_operator_ok (PLUS, SImode, operands)
6695 /* Current assemblers are broken and do not allow @GOTOFF in
6696 ought but a memory context. */
6697 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6699 switch (get_attr_type (insn))
6702 if (operands[2] == const1_rtx)
6703 return "inc{l}\t%k0";
6706 gcc_assert (operands[2] == constm1_rtx);
6707 return "dec{l}\t%k0";
6711 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6712 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6713 if (CONST_INT_P (operands[2])
6714 && (INTVAL (operands[2]) == 128
6715 || (INTVAL (operands[2]) < 0
6716 && INTVAL (operands[2]) != -128)))
6718 operands[2] = GEN_INT (-INTVAL (operands[2]));
6719 return "sub{l}\t{%2, %k0|%k0, %2}";
6721 return "add{l}\t{%2, %k0|%k0, %2}";
6725 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6726 (const_string "incdec")
6727 (const_string "alu")))
6728 (set_attr "mode" "SI")])
6730 ; For comparisons against 1, -1 and 128, we may generate better code
6731 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6732 ; is matched then. We can't accept general immediate, because for
6733 ; case of overflows, the result is messed up.
6734 ; This pattern also don't hold of 0x80000000, since the value overflows
6736 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6737 ; only for comparisons not depending on it.
6738 (define_insn "*addsi_4"
6739 [(set (reg FLAGS_REG)
6740 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6741 (match_operand:SI 2 "const_int_operand" "n")))
6742 (clobber (match_scratch:SI 0 "=rm"))]
6743 "ix86_match_ccmode (insn, CCGCmode)
6744 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6746 switch (get_attr_type (insn))
6749 if (operands[2] == constm1_rtx)
6750 return "inc{l}\t%0";
6753 gcc_assert (operands[2] == const1_rtx);
6754 return "dec{l}\t%0";
6758 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6759 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6760 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6761 if ((INTVAL (operands[2]) == -128
6762 || (INTVAL (operands[2]) > 0
6763 && INTVAL (operands[2]) != 128)))
6764 return "sub{l}\t{%2, %0|%0, %2}";
6765 operands[2] = GEN_INT (-INTVAL (operands[2]));
6766 return "add{l}\t{%2, %0|%0, %2}";
6770 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6771 (const_string "incdec")
6772 (const_string "alu")))
6773 (set_attr "mode" "SI")])
6775 (define_insn "*addsi_5"
6776 [(set (reg FLAGS_REG)
6778 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6779 (match_operand:SI 2 "general_operand" "g"))
6781 (clobber (match_scratch:SI 0 "=r"))]
6782 "ix86_match_ccmode (insn, CCGOCmode)
6783 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6784 /* Current assemblers are broken and do not allow @GOTOFF in
6785 ought but a memory context. */
6786 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6788 switch (get_attr_type (insn))
6791 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6792 if (operands[2] == const1_rtx)
6793 return "inc{l}\t%0";
6796 gcc_assert (operands[2] == constm1_rtx);
6797 return "dec{l}\t%0";
6801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6802 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6803 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6804 if (CONST_INT_P (operands[2])
6805 && (INTVAL (operands[2]) == 128
6806 || (INTVAL (operands[2]) < 0
6807 && INTVAL (operands[2]) != -128)))
6809 operands[2] = GEN_INT (-INTVAL (operands[2]));
6810 return "sub{l}\t{%2, %0|%0, %2}";
6812 return "add{l}\t{%2, %0|%0, %2}";
6816 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6817 (const_string "incdec")
6818 (const_string "alu")))
6819 (set_attr "mode" "SI")])
6821 (define_expand "addhi3"
6822 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6823 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6824 (match_operand:HI 2 "general_operand" "")))]
6825 "TARGET_HIMODE_MATH"
6826 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6828 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6829 ;; type optimizations enabled by define-splits. This is not important
6830 ;; for PII, and in fact harmful because of partial register stalls.
6832 (define_insn "*addhi_1_lea"
6833 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6834 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6835 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6836 (clobber (reg:CC FLAGS_REG))]
6837 "!TARGET_PARTIAL_REG_STALL
6838 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6840 switch (get_attr_type (insn))
6845 if (operands[2] == const1_rtx)
6846 return "inc{w}\t%0";
6849 gcc_assert (operands[2] == constm1_rtx);
6850 return "dec{w}\t%0";
6854 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6855 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6856 if (CONST_INT_P (operands[2])
6857 && (INTVAL (operands[2]) == 128
6858 || (INTVAL (operands[2]) < 0
6859 && INTVAL (operands[2]) != -128)))
6861 operands[2] = GEN_INT (-INTVAL (operands[2]));
6862 return "sub{w}\t{%2, %0|%0, %2}";
6864 return "add{w}\t{%2, %0|%0, %2}";
6868 (if_then_else (eq_attr "alternative" "2")
6869 (const_string "lea")
6870 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6871 (const_string "incdec")
6872 (const_string "alu"))))
6873 (set_attr "mode" "HI,HI,SI")])
6875 (define_insn "*addhi_1"
6876 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6877 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6878 (match_operand:HI 2 "general_operand" "rn,rm")))
6879 (clobber (reg:CC FLAGS_REG))]
6880 "TARGET_PARTIAL_REG_STALL
6881 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6883 switch (get_attr_type (insn))
6886 if (operands[2] == const1_rtx)
6887 return "inc{w}\t%0";
6890 gcc_assert (operands[2] == constm1_rtx);
6891 return "dec{w}\t%0";
6895 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6896 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6897 if (CONST_INT_P (operands[2])
6898 && (INTVAL (operands[2]) == 128
6899 || (INTVAL (operands[2]) < 0
6900 && INTVAL (operands[2]) != -128)))
6902 operands[2] = GEN_INT (-INTVAL (operands[2]));
6903 return "sub{w}\t{%2, %0|%0, %2}";
6905 return "add{w}\t{%2, %0|%0, %2}";
6909 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6910 (const_string "incdec")
6911 (const_string "alu")))
6912 (set_attr "mode" "HI")])
6914 (define_insn "*addhi_2"
6915 [(set (reg FLAGS_REG)
6917 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6918 (match_operand:HI 2 "general_operand" "rmn,rn"))
6920 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6921 (plus:HI (match_dup 1) (match_dup 2)))]
6922 "ix86_match_ccmode (insn, CCGOCmode)
6923 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6925 switch (get_attr_type (insn))
6928 if (operands[2] == const1_rtx)
6929 return "inc{w}\t%0";
6932 gcc_assert (operands[2] == constm1_rtx);
6933 return "dec{w}\t%0";
6937 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6938 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6939 if (CONST_INT_P (operands[2])
6940 && (INTVAL (operands[2]) == 128
6941 || (INTVAL (operands[2]) < 0
6942 && INTVAL (operands[2]) != -128)))
6944 operands[2] = GEN_INT (-INTVAL (operands[2]));
6945 return "sub{w}\t{%2, %0|%0, %2}";
6947 return "add{w}\t{%2, %0|%0, %2}";
6951 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6952 (const_string "incdec")
6953 (const_string "alu")))
6954 (set_attr "mode" "HI")])
6956 (define_insn "*addhi_3"
6957 [(set (reg FLAGS_REG)
6958 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6959 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6960 (clobber (match_scratch:HI 0 "=r"))]
6961 "ix86_match_ccmode (insn, CCZmode)
6962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6964 switch (get_attr_type (insn))
6967 if (operands[2] == const1_rtx)
6968 return "inc{w}\t%0";
6971 gcc_assert (operands[2] == constm1_rtx);
6972 return "dec{w}\t%0";
6976 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6977 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6978 if (CONST_INT_P (operands[2])
6979 && (INTVAL (operands[2]) == 128
6980 || (INTVAL (operands[2]) < 0
6981 && INTVAL (operands[2]) != -128)))
6983 operands[2] = GEN_INT (-INTVAL (operands[2]));
6984 return "sub{w}\t{%2, %0|%0, %2}";
6986 return "add{w}\t{%2, %0|%0, %2}";
6990 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6991 (const_string "incdec")
6992 (const_string "alu")))
6993 (set_attr "mode" "HI")])
6995 ; See comments above addsi_4 for details.
6996 (define_insn "*addhi_4"
6997 [(set (reg FLAGS_REG)
6998 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6999 (match_operand:HI 2 "const_int_operand" "n")))
7000 (clobber (match_scratch:HI 0 "=rm"))]
7001 "ix86_match_ccmode (insn, CCGCmode)
7002 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7004 switch (get_attr_type (insn))
7007 if (operands[2] == constm1_rtx)
7008 return "inc{w}\t%0";
7011 gcc_assert (operands[2] == const1_rtx);
7012 return "dec{w}\t%0";
7016 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7017 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7018 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7019 if ((INTVAL (operands[2]) == -128
7020 || (INTVAL (operands[2]) > 0
7021 && INTVAL (operands[2]) != 128)))
7022 return "sub{w}\t{%2, %0|%0, %2}";
7023 operands[2] = GEN_INT (-INTVAL (operands[2]));
7024 return "add{w}\t{%2, %0|%0, %2}";
7028 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7029 (const_string "incdec")
7030 (const_string "alu")))
7031 (set_attr "mode" "SI")])
7034 (define_insn "*addhi_5"
7035 [(set (reg FLAGS_REG)
7037 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7038 (match_operand:HI 2 "general_operand" "rmn"))
7040 (clobber (match_scratch:HI 0 "=r"))]
7041 "ix86_match_ccmode (insn, CCGOCmode)
7042 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7044 switch (get_attr_type (insn))
7047 if (operands[2] == const1_rtx)
7048 return "inc{w}\t%0";
7051 gcc_assert (operands[2] == constm1_rtx);
7052 return "dec{w}\t%0";
7056 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7057 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7058 if (CONST_INT_P (operands[2])
7059 && (INTVAL (operands[2]) == 128
7060 || (INTVAL (operands[2]) < 0
7061 && INTVAL (operands[2]) != -128)))
7063 operands[2] = GEN_INT (-INTVAL (operands[2]));
7064 return "sub{w}\t{%2, %0|%0, %2}";
7066 return "add{w}\t{%2, %0|%0, %2}";
7070 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7071 (const_string "incdec")
7072 (const_string "alu")))
7073 (set_attr "mode" "HI")])
7075 (define_expand "addqi3"
7076 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7077 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7078 (match_operand:QI 2 "general_operand" "")))]
7079 "TARGET_QIMODE_MATH"
7080 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7082 ;; %%% Potential partial reg stall on alternative 2. What to do?
7083 (define_insn "*addqi_1_lea"
7084 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7085 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7086 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7087 (clobber (reg:CC FLAGS_REG))]
7088 "!TARGET_PARTIAL_REG_STALL
7089 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7091 int widen = (which_alternative == 2);
7092 switch (get_attr_type (insn))
7097 if (operands[2] == const1_rtx)
7098 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7101 gcc_assert (operands[2] == constm1_rtx);
7102 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7106 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7107 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7108 if (CONST_INT_P (operands[2])
7109 && (INTVAL (operands[2]) == 128
7110 || (INTVAL (operands[2]) < 0
7111 && INTVAL (operands[2]) != -128)))
7113 operands[2] = GEN_INT (-INTVAL (operands[2]));
7115 return "sub{l}\t{%2, %k0|%k0, %2}";
7117 return "sub{b}\t{%2, %0|%0, %2}";
7120 return "add{l}\t{%k2, %k0|%k0, %k2}";
7122 return "add{b}\t{%2, %0|%0, %2}";
7126 (if_then_else (eq_attr "alternative" "3")
7127 (const_string "lea")
7128 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7129 (const_string "incdec")
7130 (const_string "alu"))))
7131 (set_attr "mode" "QI,QI,SI,SI")])
7133 (define_insn "*addqi_1"
7134 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7135 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7136 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7137 (clobber (reg:CC FLAGS_REG))]
7138 "TARGET_PARTIAL_REG_STALL
7139 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7141 int widen = (which_alternative == 2);
7142 switch (get_attr_type (insn))
7145 if (operands[2] == const1_rtx)
7146 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7149 gcc_assert (operands[2] == constm1_rtx);
7150 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7154 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7155 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7156 if (CONST_INT_P (operands[2])
7157 && (INTVAL (operands[2]) == 128
7158 || (INTVAL (operands[2]) < 0
7159 && INTVAL (operands[2]) != -128)))
7161 operands[2] = GEN_INT (-INTVAL (operands[2]));
7163 return "sub{l}\t{%2, %k0|%k0, %2}";
7165 return "sub{b}\t{%2, %0|%0, %2}";
7168 return "add{l}\t{%k2, %k0|%k0, %k2}";
7170 return "add{b}\t{%2, %0|%0, %2}";
7174 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7175 (const_string "incdec")
7176 (const_string "alu")))
7177 (set_attr "mode" "QI,QI,SI")])
7179 (define_insn "*addqi_1_slp"
7180 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7181 (plus:QI (match_dup 0)
7182 (match_operand:QI 1 "general_operand" "qn,qnm")))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7185 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7187 switch (get_attr_type (insn))
7190 if (operands[1] == const1_rtx)
7191 return "inc{b}\t%0";
7194 gcc_assert (operands[1] == constm1_rtx);
7195 return "dec{b}\t%0";
7199 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7200 if (CONST_INT_P (operands[1])
7201 && INTVAL (operands[1]) < 0)
7203 operands[1] = GEN_INT (-INTVAL (operands[1]));
7204 return "sub{b}\t{%1, %0|%0, %1}";
7206 return "add{b}\t{%1, %0|%0, %1}";
7210 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7211 (const_string "incdec")
7212 (const_string "alu1")))
7213 (set (attr "memory")
7214 (if_then_else (match_operand 1 "memory_operand" "")
7215 (const_string "load")
7216 (const_string "none")))
7217 (set_attr "mode" "QI")])
7219 (define_insn "*addqi_2"
7220 [(set (reg FLAGS_REG)
7222 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7223 (match_operand:QI 2 "general_operand" "qmn,qn"))
7225 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7226 (plus:QI (match_dup 1) (match_dup 2)))]
7227 "ix86_match_ccmode (insn, CCGOCmode)
7228 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7230 switch (get_attr_type (insn))
7233 if (operands[2] == const1_rtx)
7234 return "inc{b}\t%0";
7237 gcc_assert (operands[2] == constm1_rtx
7238 || (CONST_INT_P (operands[2])
7239 && INTVAL (operands[2]) == 255));
7240 return "dec{b}\t%0";
7244 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7245 if (CONST_INT_P (operands[2])
7246 && INTVAL (operands[2]) < 0)
7248 operands[2] = GEN_INT (-INTVAL (operands[2]));
7249 return "sub{b}\t{%2, %0|%0, %2}";
7251 return "add{b}\t{%2, %0|%0, %2}";
7255 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7256 (const_string "incdec")
7257 (const_string "alu")))
7258 (set_attr "mode" "QI")])
7260 (define_insn "*addqi_3"
7261 [(set (reg FLAGS_REG)
7262 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7263 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7264 (clobber (match_scratch:QI 0 "=q"))]
7265 "ix86_match_ccmode (insn, CCZmode)
7266 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7268 switch (get_attr_type (insn))
7271 if (operands[2] == const1_rtx)
7272 return "inc{b}\t%0";
7275 gcc_assert (operands[2] == constm1_rtx
7276 || (CONST_INT_P (operands[2])
7277 && INTVAL (operands[2]) == 255));
7278 return "dec{b}\t%0";
7282 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7283 if (CONST_INT_P (operands[2])
7284 && INTVAL (operands[2]) < 0)
7286 operands[2] = GEN_INT (-INTVAL (operands[2]));
7287 return "sub{b}\t{%2, %0|%0, %2}";
7289 return "add{b}\t{%2, %0|%0, %2}";
7293 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7294 (const_string "incdec")
7295 (const_string "alu")))
7296 (set_attr "mode" "QI")])
7298 ; See comments above addsi_4 for details.
7299 (define_insn "*addqi_4"
7300 [(set (reg FLAGS_REG)
7301 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7302 (match_operand:QI 2 "const_int_operand" "n")))
7303 (clobber (match_scratch:QI 0 "=qm"))]
7304 "ix86_match_ccmode (insn, CCGCmode)
7305 && (INTVAL (operands[2]) & 0xff) != 0x80"
7307 switch (get_attr_type (insn))
7310 if (operands[2] == constm1_rtx
7311 || (CONST_INT_P (operands[2])
7312 && INTVAL (operands[2]) == 255))
7313 return "inc{b}\t%0";
7316 gcc_assert (operands[2] == const1_rtx);
7317 return "dec{b}\t%0";
7321 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7322 if (INTVAL (operands[2]) < 0)
7324 operands[2] = GEN_INT (-INTVAL (operands[2]));
7325 return "add{b}\t{%2, %0|%0, %2}";
7327 return "sub{b}\t{%2, %0|%0, %2}";
7331 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7332 (const_string "incdec")
7333 (const_string "alu")))
7334 (set_attr "mode" "QI")])
7337 (define_insn "*addqi_5"
7338 [(set (reg FLAGS_REG)
7340 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7341 (match_operand:QI 2 "general_operand" "qmn"))
7343 (clobber (match_scratch:QI 0 "=q"))]
7344 "ix86_match_ccmode (insn, CCGOCmode)
7345 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7347 switch (get_attr_type (insn))
7350 if (operands[2] == const1_rtx)
7351 return "inc{b}\t%0";
7354 gcc_assert (operands[2] == constm1_rtx
7355 || (CONST_INT_P (operands[2])
7356 && INTVAL (operands[2]) == 255));
7357 return "dec{b}\t%0";
7361 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7362 if (CONST_INT_P (operands[2])
7363 && INTVAL (operands[2]) < 0)
7365 operands[2] = GEN_INT (-INTVAL (operands[2]));
7366 return "sub{b}\t{%2, %0|%0, %2}";
7368 return "add{b}\t{%2, %0|%0, %2}";
7372 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7373 (const_string "incdec")
7374 (const_string "alu")))
7375 (set_attr "mode" "QI")])
7378 (define_insn "addqi_ext_1"
7379 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7384 (match_operand 1 "ext_register_operand" "0")
7387 (match_operand:QI 2 "general_operand" "Qmn")))
7388 (clobber (reg:CC FLAGS_REG))]
7391 switch (get_attr_type (insn))
7394 if (operands[2] == const1_rtx)
7395 return "inc{b}\t%h0";
7398 gcc_assert (operands[2] == constm1_rtx
7399 || (CONST_INT_P (operands[2])
7400 && INTVAL (operands[2]) == 255));
7401 return "dec{b}\t%h0";
7405 return "add{b}\t{%2, %h0|%h0, %2}";
7409 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7410 (const_string "incdec")
7411 (const_string "alu")))
7412 (set_attr "mode" "QI")])
7414 (define_insn "*addqi_ext_1_rex64"
7415 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7420 (match_operand 1 "ext_register_operand" "0")
7423 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7424 (clobber (reg:CC FLAGS_REG))]
7427 switch (get_attr_type (insn))
7430 if (operands[2] == const1_rtx)
7431 return "inc{b}\t%h0";
7434 gcc_assert (operands[2] == constm1_rtx
7435 || (CONST_INT_P (operands[2])
7436 && INTVAL (operands[2]) == 255));
7437 return "dec{b}\t%h0";
7441 return "add{b}\t{%2, %h0|%h0, %2}";
7445 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7446 (const_string "incdec")
7447 (const_string "alu")))
7448 (set_attr "mode" "QI")])
7450 (define_insn "*addqi_ext_2"
7451 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7456 (match_operand 1 "ext_register_operand" "%0")
7460 (match_operand 2 "ext_register_operand" "Q")
7463 (clobber (reg:CC FLAGS_REG))]
7465 "add{b}\t{%h2, %h0|%h0, %h2}"
7466 [(set_attr "type" "alu")
7467 (set_attr "mode" "QI")])
7469 ;; The patterns that match these are at the end of this file.
7471 (define_expand "addxf3"
7472 [(set (match_operand:XF 0 "register_operand" "")
7473 (plus:XF (match_operand:XF 1 "register_operand" "")
7474 (match_operand:XF 2 "register_operand" "")))]
7478 (define_expand "add<mode>3"
7479 [(set (match_operand:MODEF 0 "register_operand" "")
7480 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7481 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7482 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7485 ;; Subtract instructions
7487 ;; %%% splits for subditi3
7489 (define_expand "subti3"
7490 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7491 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7492 (match_operand:TI 2 "x86_64_general_operand" "")))]
7494 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7496 (define_insn "*subti3_1"
7497 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7498 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7499 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7500 (clobber (reg:CC FLAGS_REG))]
7501 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7505 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7506 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7507 (match_operand:TI 2 "x86_64_general_operand" "")))
7508 (clobber (reg:CC FLAGS_REG))]
7509 "TARGET_64BIT && reload_completed"
7510 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7511 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7512 (parallel [(set (match_dup 3)
7513 (minus:DI (match_dup 4)
7514 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7516 (clobber (reg:CC FLAGS_REG))])]
7517 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7519 ;; %%% splits for subsidi3
7521 (define_expand "subdi3"
7522 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7523 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7524 (match_operand:DI 2 "x86_64_general_operand" "")))]
7526 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7528 (define_insn "*subdi3_1"
7529 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7530 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7531 (match_operand:DI 2 "general_operand" "roiF,riF")))
7532 (clobber (reg:CC FLAGS_REG))]
7533 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7537 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7538 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7539 (match_operand:DI 2 "general_operand" "")))
7540 (clobber (reg:CC FLAGS_REG))]
7541 "!TARGET_64BIT && reload_completed"
7542 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7543 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7544 (parallel [(set (match_dup 3)
7545 (minus:SI (match_dup 4)
7546 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7548 (clobber (reg:CC FLAGS_REG))])]
7549 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7551 (define_insn "subdi3_carry_rex64"
7552 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7553 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7554 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7555 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7556 (clobber (reg:CC FLAGS_REG))]
7557 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7558 "sbb{q}\t{%2, %0|%0, %2}"
7559 [(set_attr "type" "alu")
7560 (set_attr "pent_pair" "pu")
7561 (set_attr "mode" "DI")])
7563 (define_insn "*subdi_1_rex64"
7564 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7565 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7566 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7567 (clobber (reg:CC FLAGS_REG))]
7568 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7569 "sub{q}\t{%2, %0|%0, %2}"
7570 [(set_attr "type" "alu")
7571 (set_attr "mode" "DI")])
7573 (define_insn "*subdi_2_rex64"
7574 [(set (reg FLAGS_REG)
7576 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7577 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7579 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7580 (minus:DI (match_dup 1) (match_dup 2)))]
7581 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7582 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7583 "sub{q}\t{%2, %0|%0, %2}"
7584 [(set_attr "type" "alu")
7585 (set_attr "mode" "DI")])
7587 (define_insn "*subdi_3_rex63"
7588 [(set (reg FLAGS_REG)
7589 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7590 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7591 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7592 (minus:DI (match_dup 1) (match_dup 2)))]
7593 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7594 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7595 "sub{q}\t{%2, %0|%0, %2}"
7596 [(set_attr "type" "alu")
7597 (set_attr "mode" "DI")])
7599 (define_insn "subqi3_carry"
7600 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7601 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7602 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7603 (match_operand:QI 2 "general_operand" "qn,qm"))))
7604 (clobber (reg:CC FLAGS_REG))]
7605 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7606 "sbb{b}\t{%2, %0|%0, %2}"
7607 [(set_attr "type" "alu")
7608 (set_attr "pent_pair" "pu")
7609 (set_attr "mode" "QI")])
7611 (define_insn "subhi3_carry"
7612 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7613 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7614 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7615 (match_operand:HI 2 "general_operand" "rn,rm"))))
7616 (clobber (reg:CC FLAGS_REG))]
7617 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7618 "sbb{w}\t{%2, %0|%0, %2}"
7619 [(set_attr "type" "alu")
7620 (set_attr "pent_pair" "pu")
7621 (set_attr "mode" "HI")])
7623 (define_insn "subsi3_carry"
7624 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7625 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7626 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7627 (match_operand:SI 2 "general_operand" "ri,rm"))))
7628 (clobber (reg:CC FLAGS_REG))]
7629 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7630 "sbb{l}\t{%2, %0|%0, %2}"
7631 [(set_attr "type" "alu")
7632 (set_attr "pent_pair" "pu")
7633 (set_attr "mode" "SI")])
7635 (define_insn "subsi3_carry_zext"
7636 [(set (match_operand:DI 0 "register_operand" "=r")
7638 (minus:SI (match_operand:SI 1 "register_operand" "0")
7639 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7640 (match_operand:SI 2 "general_operand" "g")))))
7641 (clobber (reg:CC FLAGS_REG))]
7642 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7643 "sbb{l}\t{%2, %k0|%k0, %2}"
7644 [(set_attr "type" "alu")
7645 (set_attr "pent_pair" "pu")
7646 (set_attr "mode" "SI")])
7648 (define_expand "subsi3"
7649 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7650 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7651 (match_operand:SI 2 "general_operand" "")))]
7653 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7655 (define_insn "*subsi_1"
7656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7657 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7658 (match_operand:SI 2 "general_operand" "ri,rm")))
7659 (clobber (reg:CC FLAGS_REG))]
7660 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7661 "sub{l}\t{%2, %0|%0, %2}"
7662 [(set_attr "type" "alu")
7663 (set_attr "mode" "SI")])
7665 (define_insn "*subsi_1_zext"
7666 [(set (match_operand:DI 0 "register_operand" "=r")
7668 (minus:SI (match_operand:SI 1 "register_operand" "0")
7669 (match_operand:SI 2 "general_operand" "g"))))
7670 (clobber (reg:CC FLAGS_REG))]
7671 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7672 "sub{l}\t{%2, %k0|%k0, %2}"
7673 [(set_attr "type" "alu")
7674 (set_attr "mode" "SI")])
7676 (define_insn "*subsi_2"
7677 [(set (reg FLAGS_REG)
7679 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7680 (match_operand:SI 2 "general_operand" "ri,rm"))
7682 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7683 (minus:SI (match_dup 1) (match_dup 2)))]
7684 "ix86_match_ccmode (insn, CCGOCmode)
7685 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7686 "sub{l}\t{%2, %0|%0, %2}"
7687 [(set_attr "type" "alu")
7688 (set_attr "mode" "SI")])
7690 (define_insn "*subsi_2_zext"
7691 [(set (reg FLAGS_REG)
7693 (minus:SI (match_operand:SI 1 "register_operand" "0")
7694 (match_operand:SI 2 "general_operand" "g"))
7696 (set (match_operand:DI 0 "register_operand" "=r")
7698 (minus:SI (match_dup 1)
7700 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7701 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7702 "sub{l}\t{%2, %k0|%k0, %2}"
7703 [(set_attr "type" "alu")
7704 (set_attr "mode" "SI")])
7706 (define_insn "*subsi_3"
7707 [(set (reg FLAGS_REG)
7708 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7709 (match_operand:SI 2 "general_operand" "ri,rm")))
7710 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7711 (minus:SI (match_dup 1) (match_dup 2)))]
7712 "ix86_match_ccmode (insn, CCmode)
7713 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7714 "sub{l}\t{%2, %0|%0, %2}"
7715 [(set_attr "type" "alu")
7716 (set_attr "mode" "SI")])
7718 (define_insn "*subsi_3_zext"
7719 [(set (reg FLAGS_REG)
7720 (compare (match_operand:SI 1 "register_operand" "0")
7721 (match_operand:SI 2 "general_operand" "g")))
7722 (set (match_operand:DI 0 "register_operand" "=r")
7724 (minus:SI (match_dup 1)
7726 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7727 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7728 "sub{l}\t{%2, %1|%1, %2}"
7729 [(set_attr "type" "alu")
7730 (set_attr "mode" "DI")])
7732 (define_expand "subhi3"
7733 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7734 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7735 (match_operand:HI 2 "general_operand" "")))]
7736 "TARGET_HIMODE_MATH"
7737 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7739 (define_insn "*subhi_1"
7740 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7741 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7742 (match_operand:HI 2 "general_operand" "rn,rm")))
7743 (clobber (reg:CC FLAGS_REG))]
7744 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7745 "sub{w}\t{%2, %0|%0, %2}"
7746 [(set_attr "type" "alu")
7747 (set_attr "mode" "HI")])
7749 (define_insn "*subhi_2"
7750 [(set (reg FLAGS_REG)
7752 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7753 (match_operand:HI 2 "general_operand" "rn,rm"))
7755 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7756 (minus:HI (match_dup 1) (match_dup 2)))]
7757 "ix86_match_ccmode (insn, CCGOCmode)
7758 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7759 "sub{w}\t{%2, %0|%0, %2}"
7760 [(set_attr "type" "alu")
7761 (set_attr "mode" "HI")])
7763 (define_insn "*subhi_3"
7764 [(set (reg FLAGS_REG)
7765 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7766 (match_operand:HI 2 "general_operand" "rn,rm")))
7767 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7768 (minus:HI (match_dup 1) (match_dup 2)))]
7769 "ix86_match_ccmode (insn, CCmode)
7770 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7771 "sub{w}\t{%2, %0|%0, %2}"
7772 [(set_attr "type" "alu")
7773 (set_attr "mode" "HI")])
7775 (define_expand "subqi3"
7776 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7777 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7778 (match_operand:QI 2 "general_operand" "")))]
7779 "TARGET_QIMODE_MATH"
7780 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7782 (define_insn "*subqi_1"
7783 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7784 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7785 (match_operand:QI 2 "general_operand" "qn,qm")))
7786 (clobber (reg:CC FLAGS_REG))]
7787 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7788 "sub{b}\t{%2, %0|%0, %2}"
7789 [(set_attr "type" "alu")
7790 (set_attr "mode" "QI")])
7792 (define_insn "*subqi_1_slp"
7793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7794 (minus:QI (match_dup 0)
7795 (match_operand:QI 1 "general_operand" "qn,qm")))
7796 (clobber (reg:CC FLAGS_REG))]
7797 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7798 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7799 "sub{b}\t{%1, %0|%0, %1}"
7800 [(set_attr "type" "alu1")
7801 (set_attr "mode" "QI")])
7803 (define_insn "*subqi_2"
7804 [(set (reg FLAGS_REG)
7806 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7807 (match_operand:QI 2 "general_operand" "qn,qm"))
7809 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7810 (minus:QI (match_dup 1) (match_dup 2)))]
7811 "ix86_match_ccmode (insn, CCGOCmode)
7812 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7813 "sub{b}\t{%2, %0|%0, %2}"
7814 [(set_attr "type" "alu")
7815 (set_attr "mode" "QI")])
7817 (define_insn "*subqi_3"
7818 [(set (reg FLAGS_REG)
7819 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7820 (match_operand:QI 2 "general_operand" "qn,qm")))
7821 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7822 (minus:QI (match_dup 1) (match_dup 2)))]
7823 "ix86_match_ccmode (insn, CCmode)
7824 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7825 "sub{b}\t{%2, %0|%0, %2}"
7826 [(set_attr "type" "alu")
7827 (set_attr "mode" "QI")])
7829 ;; The patterns that match these are at the end of this file.
7831 (define_expand "subxf3"
7832 [(set (match_operand:XF 0 "register_operand" "")
7833 (minus:XF (match_operand:XF 1 "register_operand" "")
7834 (match_operand:XF 2 "register_operand" "")))]
7838 (define_expand "sub<mode>3"
7839 [(set (match_operand:MODEF 0 "register_operand" "")
7840 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7841 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7842 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7845 ;; Multiply instructions
7847 (define_expand "muldi3"
7848 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7849 (mult:DI (match_operand:DI 1 "register_operand" "")
7850 (match_operand:DI 2 "x86_64_general_operand" "")))
7851 (clobber (reg:CC FLAGS_REG))])]
7856 ;; IMUL reg64, reg64, imm8 Direct
7857 ;; IMUL reg64, mem64, imm8 VectorPath
7858 ;; IMUL reg64, reg64, imm32 Direct
7859 ;; IMUL reg64, mem64, imm32 VectorPath
7860 ;; IMUL reg64, reg64 Direct
7861 ;; IMUL reg64, mem64 Direct
7863 (define_insn "*muldi3_1_rex64"
7864 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7865 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7866 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7867 (clobber (reg:CC FLAGS_REG))]
7869 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7871 imul{q}\t{%2, %1, %0|%0, %1, %2}
7872 imul{q}\t{%2, %1, %0|%0, %1, %2}
7873 imul{q}\t{%2, %0|%0, %2}"
7874 [(set_attr "type" "imul")
7875 (set_attr "prefix_0f" "0,0,1")
7876 (set (attr "athlon_decode")
7877 (cond [(eq_attr "cpu" "athlon")
7878 (const_string "vector")
7879 (eq_attr "alternative" "1")
7880 (const_string "vector")
7881 (and (eq_attr "alternative" "2")
7882 (match_operand 1 "memory_operand" ""))
7883 (const_string "vector")]
7884 (const_string "direct")))
7885 (set (attr "amdfam10_decode")
7886 (cond [(and (eq_attr "alternative" "0,1")
7887 (match_operand 1 "memory_operand" ""))
7888 (const_string "vector")]
7889 (const_string "direct")))
7890 (set_attr "mode" "DI")])
7892 (define_expand "mulsi3"
7893 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7894 (mult:SI (match_operand:SI 1 "register_operand" "")
7895 (match_operand:SI 2 "general_operand" "")))
7896 (clobber (reg:CC FLAGS_REG))])]
7901 ;; IMUL reg32, reg32, imm8 Direct
7902 ;; IMUL reg32, mem32, imm8 VectorPath
7903 ;; IMUL reg32, reg32, imm32 Direct
7904 ;; IMUL reg32, mem32, imm32 VectorPath
7905 ;; IMUL reg32, reg32 Direct
7906 ;; IMUL reg32, mem32 Direct
7908 (define_insn "*mulsi3_1"
7909 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7910 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7911 (match_operand:SI 2 "general_operand" "K,i,mr")))
7912 (clobber (reg:CC FLAGS_REG))]
7913 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7915 imul{l}\t{%2, %1, %0|%0, %1, %2}
7916 imul{l}\t{%2, %1, %0|%0, %1, %2}
7917 imul{l}\t{%2, %0|%0, %2}"
7918 [(set_attr "type" "imul")
7919 (set_attr "prefix_0f" "0,0,1")
7920 (set (attr "athlon_decode")
7921 (cond [(eq_attr "cpu" "athlon")
7922 (const_string "vector")
7923 (eq_attr "alternative" "1")
7924 (const_string "vector")
7925 (and (eq_attr "alternative" "2")
7926 (match_operand 1 "memory_operand" ""))
7927 (const_string "vector")]
7928 (const_string "direct")))
7929 (set (attr "amdfam10_decode")
7930 (cond [(and (eq_attr "alternative" "0,1")
7931 (match_operand 1 "memory_operand" ""))
7932 (const_string "vector")]
7933 (const_string "direct")))
7934 (set_attr "mode" "SI")])
7936 (define_insn "*mulsi3_1_zext"
7937 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7939 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7940 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7941 (clobber (reg:CC FLAGS_REG))]
7943 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7945 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7946 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7947 imul{l}\t{%2, %k0|%k0, %2}"
7948 [(set_attr "type" "imul")
7949 (set_attr "prefix_0f" "0,0,1")
7950 (set (attr "athlon_decode")
7951 (cond [(eq_attr "cpu" "athlon")
7952 (const_string "vector")
7953 (eq_attr "alternative" "1")
7954 (const_string "vector")
7955 (and (eq_attr "alternative" "2")
7956 (match_operand 1 "memory_operand" ""))
7957 (const_string "vector")]
7958 (const_string "direct")))
7959 (set (attr "amdfam10_decode")
7960 (cond [(and (eq_attr "alternative" "0,1")
7961 (match_operand 1 "memory_operand" ""))
7962 (const_string "vector")]
7963 (const_string "direct")))
7964 (set_attr "mode" "SI")])
7966 (define_expand "mulhi3"
7967 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7968 (mult:HI (match_operand:HI 1 "register_operand" "")
7969 (match_operand:HI 2 "general_operand" "")))
7970 (clobber (reg:CC FLAGS_REG))])]
7971 "TARGET_HIMODE_MATH"
7975 ;; IMUL reg16, reg16, imm8 VectorPath
7976 ;; IMUL reg16, mem16, imm8 VectorPath
7977 ;; IMUL reg16, reg16, imm16 VectorPath
7978 ;; IMUL reg16, mem16, imm16 VectorPath
7979 ;; IMUL reg16, reg16 Direct
7980 ;; IMUL reg16, mem16 Direct
7981 (define_insn "*mulhi3_1"
7982 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7983 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7984 (match_operand:HI 2 "general_operand" "K,n,mr")))
7985 (clobber (reg:CC FLAGS_REG))]
7986 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7988 imul{w}\t{%2, %1, %0|%0, %1, %2}
7989 imul{w}\t{%2, %1, %0|%0, %1, %2}
7990 imul{w}\t{%2, %0|%0, %2}"
7991 [(set_attr "type" "imul")
7992 (set_attr "prefix_0f" "0,0,1")
7993 (set (attr "athlon_decode")
7994 (cond [(eq_attr "cpu" "athlon")
7995 (const_string "vector")
7996 (eq_attr "alternative" "1,2")
7997 (const_string "vector")]
7998 (const_string "direct")))
7999 (set (attr "amdfam10_decode")
8000 (cond [(eq_attr "alternative" "0,1")
8001 (const_string "vector")]
8002 (const_string "direct")))
8003 (set_attr "mode" "HI")])
8005 (define_expand "mulqi3"
8006 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8007 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8008 (match_operand:QI 2 "register_operand" "")))
8009 (clobber (reg:CC FLAGS_REG))])]
8010 "TARGET_QIMODE_MATH"
8017 (define_insn "*mulqi3_1"
8018 [(set (match_operand:QI 0 "register_operand" "=a")
8019 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8020 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8021 (clobber (reg:CC FLAGS_REG))]
8023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8025 [(set_attr "type" "imul")
8026 (set_attr "length_immediate" "0")
8027 (set (attr "athlon_decode")
8028 (if_then_else (eq_attr "cpu" "athlon")
8029 (const_string "vector")
8030 (const_string "direct")))
8031 (set_attr "amdfam10_decode" "direct")
8032 (set_attr "mode" "QI")])
8034 (define_expand "umulqihi3"
8035 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8036 (mult:HI (zero_extend:HI
8037 (match_operand:QI 1 "nonimmediate_operand" ""))
8039 (match_operand:QI 2 "register_operand" ""))))
8040 (clobber (reg:CC FLAGS_REG))])]
8041 "TARGET_QIMODE_MATH"
8044 (define_insn "*umulqihi3_1"
8045 [(set (match_operand:HI 0 "register_operand" "=a")
8046 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8047 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8048 (clobber (reg:CC FLAGS_REG))]
8050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8052 [(set_attr "type" "imul")
8053 (set_attr "length_immediate" "0")
8054 (set (attr "athlon_decode")
8055 (if_then_else (eq_attr "cpu" "athlon")
8056 (const_string "vector")
8057 (const_string "direct")))
8058 (set_attr "amdfam10_decode" "direct")
8059 (set_attr "mode" "QI")])
8061 (define_expand "mulqihi3"
8062 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8063 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8064 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8065 (clobber (reg:CC FLAGS_REG))])]
8066 "TARGET_QIMODE_MATH"
8069 (define_insn "*mulqihi3_insn"
8070 [(set (match_operand:HI 0 "register_operand" "=a")
8071 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8072 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8073 (clobber (reg:CC FLAGS_REG))]
8075 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8077 [(set_attr "type" "imul")
8078 (set_attr "length_immediate" "0")
8079 (set (attr "athlon_decode")
8080 (if_then_else (eq_attr "cpu" "athlon")
8081 (const_string "vector")
8082 (const_string "direct")))
8083 (set_attr "amdfam10_decode" "direct")
8084 (set_attr "mode" "QI")])
8086 (define_expand "umulditi3"
8087 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8088 (mult:TI (zero_extend:TI
8089 (match_operand:DI 1 "nonimmediate_operand" ""))
8091 (match_operand:DI 2 "register_operand" ""))))
8092 (clobber (reg:CC FLAGS_REG))])]
8096 (define_insn "*umulditi3_insn"
8097 [(set (match_operand:TI 0 "register_operand" "=A")
8098 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8099 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8100 (clobber (reg:CC FLAGS_REG))]
8102 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8104 [(set_attr "type" "imul")
8105 (set_attr "length_immediate" "0")
8106 (set (attr "athlon_decode")
8107 (if_then_else (eq_attr "cpu" "athlon")
8108 (const_string "vector")
8109 (const_string "double")))
8110 (set_attr "amdfam10_decode" "double")
8111 (set_attr "mode" "DI")])
8113 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8114 (define_expand "umulsidi3"
8115 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8116 (mult:DI (zero_extend:DI
8117 (match_operand:SI 1 "nonimmediate_operand" ""))
8119 (match_operand:SI 2 "register_operand" ""))))
8120 (clobber (reg:CC FLAGS_REG))])]
8124 (define_insn "*umulsidi3_insn"
8125 [(set (match_operand:DI 0 "register_operand" "=A")
8126 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8127 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8128 (clobber (reg:CC FLAGS_REG))]
8130 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8132 [(set_attr "type" "imul")
8133 (set_attr "length_immediate" "0")
8134 (set (attr "athlon_decode")
8135 (if_then_else (eq_attr "cpu" "athlon")
8136 (const_string "vector")
8137 (const_string "double")))
8138 (set_attr "amdfam10_decode" "double")
8139 (set_attr "mode" "SI")])
8141 (define_expand "mulditi3"
8142 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8143 (mult:TI (sign_extend:TI
8144 (match_operand:DI 1 "nonimmediate_operand" ""))
8146 (match_operand:DI 2 "register_operand" ""))))
8147 (clobber (reg:CC FLAGS_REG))])]
8151 (define_insn "*mulditi3_insn"
8152 [(set (match_operand:TI 0 "register_operand" "=A")
8153 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8154 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8155 (clobber (reg:CC FLAGS_REG))]
8157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8159 [(set_attr "type" "imul")
8160 (set_attr "length_immediate" "0")
8161 (set (attr "athlon_decode")
8162 (if_then_else (eq_attr "cpu" "athlon")
8163 (const_string "vector")
8164 (const_string "double")))
8165 (set_attr "amdfam10_decode" "double")
8166 (set_attr "mode" "DI")])
8168 (define_expand "mulsidi3"
8169 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8170 (mult:DI (sign_extend:DI
8171 (match_operand:SI 1 "nonimmediate_operand" ""))
8173 (match_operand:SI 2 "register_operand" ""))))
8174 (clobber (reg:CC FLAGS_REG))])]
8178 (define_insn "*mulsidi3_insn"
8179 [(set (match_operand:DI 0 "register_operand" "=A")
8180 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8181 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8182 (clobber (reg:CC FLAGS_REG))]
8184 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8186 [(set_attr "type" "imul")
8187 (set_attr "length_immediate" "0")
8188 (set (attr "athlon_decode")
8189 (if_then_else (eq_attr "cpu" "athlon")
8190 (const_string "vector")
8191 (const_string "double")))
8192 (set_attr "amdfam10_decode" "double")
8193 (set_attr "mode" "SI")])
8195 (define_expand "umuldi3_highpart"
8196 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8199 (mult:TI (zero_extend:TI
8200 (match_operand:DI 1 "nonimmediate_operand" ""))
8202 (match_operand:DI 2 "register_operand" "")))
8204 (clobber (match_scratch:DI 3 ""))
8205 (clobber (reg:CC FLAGS_REG))])]
8209 (define_insn "*umuldi3_highpart_rex64"
8210 [(set (match_operand:DI 0 "register_operand" "=d")
8213 (mult:TI (zero_extend:TI
8214 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8216 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8218 (clobber (match_scratch:DI 3 "=1"))
8219 (clobber (reg:CC FLAGS_REG))]
8221 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8223 [(set_attr "type" "imul")
8224 (set_attr "length_immediate" "0")
8225 (set (attr "athlon_decode")
8226 (if_then_else (eq_attr "cpu" "athlon")
8227 (const_string "vector")
8228 (const_string "double")))
8229 (set_attr "amdfam10_decode" "double")
8230 (set_attr "mode" "DI")])
8232 (define_expand "umulsi3_highpart"
8233 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8236 (mult:DI (zero_extend:DI
8237 (match_operand:SI 1 "nonimmediate_operand" ""))
8239 (match_operand:SI 2 "register_operand" "")))
8241 (clobber (match_scratch:SI 3 ""))
8242 (clobber (reg:CC FLAGS_REG))])]
8246 (define_insn "*umulsi3_highpart_insn"
8247 [(set (match_operand:SI 0 "register_operand" "=d")
8250 (mult:DI (zero_extend:DI
8251 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8253 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8255 (clobber (match_scratch:SI 3 "=1"))
8256 (clobber (reg:CC FLAGS_REG))]
8257 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8259 [(set_attr "type" "imul")
8260 (set_attr "length_immediate" "0")
8261 (set (attr "athlon_decode")
8262 (if_then_else (eq_attr "cpu" "athlon")
8263 (const_string "vector")
8264 (const_string "double")))
8265 (set_attr "amdfam10_decode" "double")
8266 (set_attr "mode" "SI")])
8268 (define_insn "*umulsi3_highpart_zext"
8269 [(set (match_operand:DI 0 "register_operand" "=d")
8270 (zero_extend:DI (truncate:SI
8272 (mult:DI (zero_extend:DI
8273 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8275 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8277 (clobber (match_scratch:SI 3 "=1"))
8278 (clobber (reg:CC FLAGS_REG))]
8280 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8282 [(set_attr "type" "imul")
8283 (set_attr "length_immediate" "0")
8284 (set (attr "athlon_decode")
8285 (if_then_else (eq_attr "cpu" "athlon")
8286 (const_string "vector")
8287 (const_string "double")))
8288 (set_attr "amdfam10_decode" "double")
8289 (set_attr "mode" "SI")])
8291 (define_expand "smuldi3_highpart"
8292 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8295 (mult:TI (sign_extend:TI
8296 (match_operand:DI 1 "nonimmediate_operand" ""))
8298 (match_operand:DI 2 "register_operand" "")))
8300 (clobber (match_scratch:DI 3 ""))
8301 (clobber (reg:CC FLAGS_REG))])]
8305 (define_insn "*smuldi3_highpart_rex64"
8306 [(set (match_operand:DI 0 "register_operand" "=d")
8309 (mult:TI (sign_extend:TI
8310 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8312 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8314 (clobber (match_scratch:DI 3 "=1"))
8315 (clobber (reg:CC FLAGS_REG))]
8317 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8319 [(set_attr "type" "imul")
8320 (set (attr "athlon_decode")
8321 (if_then_else (eq_attr "cpu" "athlon")
8322 (const_string "vector")
8323 (const_string "double")))
8324 (set_attr "amdfam10_decode" "double")
8325 (set_attr "mode" "DI")])
8327 (define_expand "smulsi3_highpart"
8328 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8331 (mult:DI (sign_extend:DI
8332 (match_operand:SI 1 "nonimmediate_operand" ""))
8334 (match_operand:SI 2 "register_operand" "")))
8336 (clobber (match_scratch:SI 3 ""))
8337 (clobber (reg:CC FLAGS_REG))])]
8341 (define_insn "*smulsi3_highpart_insn"
8342 [(set (match_operand:SI 0 "register_operand" "=d")
8345 (mult:DI (sign_extend:DI
8346 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8348 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8350 (clobber (match_scratch:SI 3 "=1"))
8351 (clobber (reg:CC FLAGS_REG))]
8352 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8354 [(set_attr "type" "imul")
8355 (set (attr "athlon_decode")
8356 (if_then_else (eq_attr "cpu" "athlon")
8357 (const_string "vector")
8358 (const_string "double")))
8359 (set_attr "amdfam10_decode" "double")
8360 (set_attr "mode" "SI")])
8362 (define_insn "*smulsi3_highpart_zext"
8363 [(set (match_operand:DI 0 "register_operand" "=d")
8364 (zero_extend:DI (truncate:SI
8366 (mult:DI (sign_extend:DI
8367 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8369 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8371 (clobber (match_scratch:SI 3 "=1"))
8372 (clobber (reg:CC FLAGS_REG))]
8374 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8376 [(set_attr "type" "imul")
8377 (set (attr "athlon_decode")
8378 (if_then_else (eq_attr "cpu" "athlon")
8379 (const_string "vector")
8380 (const_string "double")))
8381 (set_attr "amdfam10_decode" "double")
8382 (set_attr "mode" "SI")])
8384 ;; The patterns that match these are at the end of this file.
8386 (define_expand "mulxf3"
8387 [(set (match_operand:XF 0 "register_operand" "")
8388 (mult:XF (match_operand:XF 1 "register_operand" "")
8389 (match_operand:XF 2 "register_operand" "")))]
8393 (define_expand "mul<mode>3"
8394 [(set (match_operand:MODEF 0 "register_operand" "")
8395 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8396 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8397 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8400 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8403 ;; Divide instructions
8405 (define_insn "divqi3"
8406 [(set (match_operand:QI 0 "register_operand" "=a")
8407 (div:QI (match_operand:HI 1 "register_operand" "0")
8408 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8409 (clobber (reg:CC FLAGS_REG))]
8410 "TARGET_QIMODE_MATH"
8412 [(set_attr "type" "idiv")
8413 (set_attr "mode" "QI")])
8415 (define_insn "udivqi3"
8416 [(set (match_operand:QI 0 "register_operand" "=a")
8417 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8418 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8419 (clobber (reg:CC FLAGS_REG))]
8420 "TARGET_QIMODE_MATH"
8422 [(set_attr "type" "idiv")
8423 (set_attr "mode" "QI")])
8425 ;; The patterns that match these are at the end of this file.
8427 (define_expand "divxf3"
8428 [(set (match_operand:XF 0 "register_operand" "")
8429 (div:XF (match_operand:XF 1 "register_operand" "")
8430 (match_operand:XF 2 "register_operand" "")))]
8434 (define_expand "divdf3"
8435 [(set (match_operand:DF 0 "register_operand" "")
8436 (div:DF (match_operand:DF 1 "register_operand" "")
8437 (match_operand:DF 2 "nonimmediate_operand" "")))]
8438 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8441 (define_expand "divsf3"
8442 [(set (match_operand:SF 0 "register_operand" "")
8443 (div:SF (match_operand:SF 1 "register_operand" "")
8444 (match_operand:SF 2 "nonimmediate_operand" "")))]
8445 "TARGET_80387 || TARGET_SSE_MATH"
8447 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8448 && flag_finite_math_only && !flag_trapping_math
8449 && flag_unsafe_math_optimizations)
8451 ix86_emit_swdivsf (operands[0], operands[1],
8452 operands[2], SFmode);
8457 ;; Remainder instructions.
8459 (define_expand "divmoddi4"
8460 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8461 (div:DI (match_operand:DI 1 "register_operand" "")
8462 (match_operand:DI 2 "nonimmediate_operand" "")))
8463 (set (match_operand:DI 3 "register_operand" "")
8464 (mod:DI (match_dup 1) (match_dup 2)))
8465 (clobber (reg:CC FLAGS_REG))])]
8469 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8470 ;; Penalize eax case slightly because it results in worse scheduling
8472 (define_insn "*divmoddi4_nocltd_rex64"
8473 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8474 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8475 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8476 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8477 (mod:DI (match_dup 2) (match_dup 3)))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8481 [(set_attr "type" "multi")])
8483 (define_insn "*divmoddi4_cltd_rex64"
8484 [(set (match_operand:DI 0 "register_operand" "=a")
8485 (div:DI (match_operand:DI 2 "register_operand" "a")
8486 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8487 (set (match_operand:DI 1 "register_operand" "=&d")
8488 (mod:DI (match_dup 2) (match_dup 3)))
8489 (clobber (reg:CC FLAGS_REG))]
8490 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8492 [(set_attr "type" "multi")])
8494 (define_insn "*divmoddi_noext_rex64"
8495 [(set (match_operand:DI 0 "register_operand" "=a")
8496 (div:DI (match_operand:DI 1 "register_operand" "0")
8497 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8498 (set (match_operand:DI 3 "register_operand" "=d")
8499 (mod:DI (match_dup 1) (match_dup 2)))
8500 (use (match_operand:DI 4 "register_operand" "3"))
8501 (clobber (reg:CC FLAGS_REG))]
8504 [(set_attr "type" "idiv")
8505 (set_attr "mode" "DI")])
8508 [(set (match_operand:DI 0 "register_operand" "")
8509 (div:DI (match_operand:DI 1 "register_operand" "")
8510 (match_operand:DI 2 "nonimmediate_operand" "")))
8511 (set (match_operand:DI 3 "register_operand" "")
8512 (mod:DI (match_dup 1) (match_dup 2)))
8513 (clobber (reg:CC FLAGS_REG))]
8514 "TARGET_64BIT && reload_completed"
8515 [(parallel [(set (match_dup 3)
8516 (ashiftrt:DI (match_dup 4) (const_int 63)))
8517 (clobber (reg:CC FLAGS_REG))])
8518 (parallel [(set (match_dup 0)
8519 (div:DI (reg:DI 0) (match_dup 2)))
8521 (mod:DI (reg:DI 0) (match_dup 2)))
8523 (clobber (reg:CC FLAGS_REG))])]
8525 /* Avoid use of cltd in favor of a mov+shift. */
8526 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8528 if (true_regnum (operands[1]))
8529 emit_move_insn (operands[0], operands[1]);
8531 emit_move_insn (operands[3], operands[1]);
8532 operands[4] = operands[3];
8536 gcc_assert (!true_regnum (operands[1]));
8537 operands[4] = operands[1];
8542 (define_expand "divmodsi4"
8543 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8544 (div:SI (match_operand:SI 1 "register_operand" "")
8545 (match_operand:SI 2 "nonimmediate_operand" "")))
8546 (set (match_operand:SI 3 "register_operand" "")
8547 (mod:SI (match_dup 1) (match_dup 2)))
8548 (clobber (reg:CC FLAGS_REG))])]
8552 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8553 ;; Penalize eax case slightly because it results in worse scheduling
8555 (define_insn "*divmodsi4_nocltd"
8556 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8557 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8558 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8559 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8560 (mod:SI (match_dup 2) (match_dup 3)))
8561 (clobber (reg:CC FLAGS_REG))]
8562 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8564 [(set_attr "type" "multi")])
8566 (define_insn "*divmodsi4_cltd"
8567 [(set (match_operand:SI 0 "register_operand" "=a")
8568 (div:SI (match_operand:SI 2 "register_operand" "a")
8569 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8570 (set (match_operand:SI 1 "register_operand" "=&d")
8571 (mod:SI (match_dup 2) (match_dup 3)))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8575 [(set_attr "type" "multi")])
8577 (define_insn "*divmodsi_noext"
8578 [(set (match_operand:SI 0 "register_operand" "=a")
8579 (div:SI (match_operand:SI 1 "register_operand" "0")
8580 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8581 (set (match_operand:SI 3 "register_operand" "=d")
8582 (mod:SI (match_dup 1) (match_dup 2)))
8583 (use (match_operand:SI 4 "register_operand" "3"))
8584 (clobber (reg:CC FLAGS_REG))]
8587 [(set_attr "type" "idiv")
8588 (set_attr "mode" "SI")])
8591 [(set (match_operand:SI 0 "register_operand" "")
8592 (div:SI (match_operand:SI 1 "register_operand" "")
8593 (match_operand:SI 2 "nonimmediate_operand" "")))
8594 (set (match_operand:SI 3 "register_operand" "")
8595 (mod:SI (match_dup 1) (match_dup 2)))
8596 (clobber (reg:CC FLAGS_REG))]
8598 [(parallel [(set (match_dup 3)
8599 (ashiftrt:SI (match_dup 4) (const_int 31)))
8600 (clobber (reg:CC FLAGS_REG))])
8601 (parallel [(set (match_dup 0)
8602 (div:SI (reg:SI 0) (match_dup 2)))
8604 (mod:SI (reg:SI 0) (match_dup 2)))
8606 (clobber (reg:CC FLAGS_REG))])]
8608 /* Avoid use of cltd in favor of a mov+shift. */
8609 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8611 if (true_regnum (operands[1]))
8612 emit_move_insn (operands[0], operands[1]);
8614 emit_move_insn (operands[3], operands[1]);
8615 operands[4] = operands[3];
8619 gcc_assert (!true_regnum (operands[1]));
8620 operands[4] = operands[1];
8624 (define_insn "divmodhi4"
8625 [(set (match_operand:HI 0 "register_operand" "=a")
8626 (div:HI (match_operand:HI 1 "register_operand" "0")
8627 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8628 (set (match_operand:HI 3 "register_operand" "=&d")
8629 (mod:HI (match_dup 1) (match_dup 2)))
8630 (clobber (reg:CC FLAGS_REG))]
8631 "TARGET_HIMODE_MATH"
8633 [(set_attr "type" "multi")
8634 (set_attr "length_immediate" "0")
8635 (set_attr "mode" "SI")])
8637 (define_insn "udivmoddi4"
8638 [(set (match_operand:DI 0 "register_operand" "=a")
8639 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8640 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8641 (set (match_operand:DI 3 "register_operand" "=&d")
8642 (umod:DI (match_dup 1) (match_dup 2)))
8643 (clobber (reg:CC FLAGS_REG))]
8645 "xor{q}\t%3, %3\;div{q}\t%2"
8646 [(set_attr "type" "multi")
8647 (set_attr "length_immediate" "0")
8648 (set_attr "mode" "DI")])
8650 (define_insn "*udivmoddi4_noext"
8651 [(set (match_operand:DI 0 "register_operand" "=a")
8652 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8653 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8654 (set (match_operand:DI 3 "register_operand" "=d")
8655 (umod:DI (match_dup 1) (match_dup 2)))
8657 (clobber (reg:CC FLAGS_REG))]
8660 [(set_attr "type" "idiv")
8661 (set_attr "mode" "DI")])
8664 [(set (match_operand:DI 0 "register_operand" "")
8665 (udiv:DI (match_operand:DI 1 "register_operand" "")
8666 (match_operand:DI 2 "nonimmediate_operand" "")))
8667 (set (match_operand:DI 3 "register_operand" "")
8668 (umod:DI (match_dup 1) (match_dup 2)))
8669 (clobber (reg:CC FLAGS_REG))]
8670 "TARGET_64BIT && reload_completed"
8671 [(set (match_dup 3) (const_int 0))
8672 (parallel [(set (match_dup 0)
8673 (udiv:DI (match_dup 1) (match_dup 2)))
8675 (umod:DI (match_dup 1) (match_dup 2)))
8677 (clobber (reg:CC FLAGS_REG))])]
8680 (define_insn "udivmodsi4"
8681 [(set (match_operand:SI 0 "register_operand" "=a")
8682 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8683 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8684 (set (match_operand:SI 3 "register_operand" "=&d")
8685 (umod:SI (match_dup 1) (match_dup 2)))
8686 (clobber (reg:CC FLAGS_REG))]
8688 "xor{l}\t%3, %3\;div{l}\t%2"
8689 [(set_attr "type" "multi")
8690 (set_attr "length_immediate" "0")
8691 (set_attr "mode" "SI")])
8693 (define_insn "*udivmodsi4_noext"
8694 [(set (match_operand:SI 0 "register_operand" "=a")
8695 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8696 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8697 (set (match_operand:SI 3 "register_operand" "=d")
8698 (umod:SI (match_dup 1) (match_dup 2)))
8700 (clobber (reg:CC FLAGS_REG))]
8703 [(set_attr "type" "idiv")
8704 (set_attr "mode" "SI")])
8707 [(set (match_operand:SI 0 "register_operand" "")
8708 (udiv:SI (match_operand:SI 1 "register_operand" "")
8709 (match_operand:SI 2 "nonimmediate_operand" "")))
8710 (set (match_operand:SI 3 "register_operand" "")
8711 (umod:SI (match_dup 1) (match_dup 2)))
8712 (clobber (reg:CC FLAGS_REG))]
8714 [(set (match_dup 3) (const_int 0))
8715 (parallel [(set (match_dup 0)
8716 (udiv:SI (match_dup 1) (match_dup 2)))
8718 (umod:SI (match_dup 1) (match_dup 2)))
8720 (clobber (reg:CC FLAGS_REG))])]
8723 (define_expand "udivmodhi4"
8724 [(set (match_dup 4) (const_int 0))
8725 (parallel [(set (match_operand:HI 0 "register_operand" "")
8726 (udiv:HI (match_operand:HI 1 "register_operand" "")
8727 (match_operand:HI 2 "nonimmediate_operand" "")))
8728 (set (match_operand:HI 3 "register_operand" "")
8729 (umod:HI (match_dup 1) (match_dup 2)))
8731 (clobber (reg:CC FLAGS_REG))])]
8732 "TARGET_HIMODE_MATH"
8733 "operands[4] = gen_reg_rtx (HImode);")
8735 (define_insn "*udivmodhi_noext"
8736 [(set (match_operand:HI 0 "register_operand" "=a")
8737 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8738 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8739 (set (match_operand:HI 3 "register_operand" "=d")
8740 (umod:HI (match_dup 1) (match_dup 2)))
8741 (use (match_operand:HI 4 "register_operand" "3"))
8742 (clobber (reg:CC FLAGS_REG))]
8745 [(set_attr "type" "idiv")
8746 (set_attr "mode" "HI")])
8748 ;; We cannot use div/idiv for double division, because it causes
8749 ;; "division by zero" on the overflow and that's not what we expect
8750 ;; from truncate. Because true (non truncating) double division is
8751 ;; never generated, we can't create this insn anyway.
8754 ; [(set (match_operand:SI 0 "register_operand" "=a")
8756 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8758 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8759 ; (set (match_operand:SI 3 "register_operand" "=d")
8761 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8762 ; (clobber (reg:CC FLAGS_REG))]
8764 ; "div{l}\t{%2, %0|%0, %2}"
8765 ; [(set_attr "type" "idiv")])
8767 ;;- Logical AND instructions
8769 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8770 ;; Note that this excludes ah.
8772 (define_insn "*testdi_1_rex64"
8773 [(set (reg FLAGS_REG)
8775 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8776 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8778 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8781 test{l}\t{%k1, %k0|%k0, %k1}
8782 test{l}\t{%k1, %k0|%k0, %k1}
8783 test{q}\t{%1, %0|%0, %1}
8784 test{q}\t{%1, %0|%0, %1}
8785 test{q}\t{%1, %0|%0, %1}"
8786 [(set_attr "type" "test")
8787 (set_attr "modrm" "0,1,0,1,1")
8788 (set_attr "mode" "SI,SI,DI,DI,DI")
8789 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8791 (define_insn "testsi_1"
8792 [(set (reg FLAGS_REG)
8794 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8795 (match_operand:SI 1 "general_operand" "i,i,ri"))
8797 "ix86_match_ccmode (insn, CCNOmode)
8798 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8799 "test{l}\t{%1, %0|%0, %1}"
8800 [(set_attr "type" "test")
8801 (set_attr "modrm" "0,1,1")
8802 (set_attr "mode" "SI")
8803 (set_attr "pent_pair" "uv,np,uv")])
8805 (define_expand "testsi_ccno_1"
8806 [(set (reg:CCNO FLAGS_REG)
8808 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8809 (match_operand:SI 1 "nonmemory_operand" ""))
8814 (define_insn "*testhi_1"
8815 [(set (reg FLAGS_REG)
8816 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8817 (match_operand:HI 1 "general_operand" "n,n,rn"))
8819 "ix86_match_ccmode (insn, CCNOmode)
8820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8821 "test{w}\t{%1, %0|%0, %1}"
8822 [(set_attr "type" "test")
8823 (set_attr "modrm" "0,1,1")
8824 (set_attr "mode" "HI")
8825 (set_attr "pent_pair" "uv,np,uv")])
8827 (define_expand "testqi_ccz_1"
8828 [(set (reg:CCZ FLAGS_REG)
8829 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8830 (match_operand:QI 1 "nonmemory_operand" ""))
8835 (define_insn "*testqi_1_maybe_si"
8836 [(set (reg FLAGS_REG)
8839 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8840 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8842 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8843 && ix86_match_ccmode (insn,
8844 CONST_INT_P (operands[1])
8845 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8847 if (which_alternative == 3)
8849 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8850 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8851 return "test{l}\t{%1, %k0|%k0, %1}";
8853 return "test{b}\t{%1, %0|%0, %1}";
8855 [(set_attr "type" "test")
8856 (set_attr "modrm" "0,1,1,1")
8857 (set_attr "mode" "QI,QI,QI,SI")
8858 (set_attr "pent_pair" "uv,np,uv,np")])
8860 (define_insn "*testqi_1"
8861 [(set (reg FLAGS_REG)
8864 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8865 (match_operand:QI 1 "general_operand" "n,n,qn"))
8867 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8868 && ix86_match_ccmode (insn, CCNOmode)"
8869 "test{b}\t{%1, %0|%0, %1}"
8870 [(set_attr "type" "test")
8871 (set_attr "modrm" "0,1,1")
8872 (set_attr "mode" "QI")
8873 (set_attr "pent_pair" "uv,np,uv")])
8875 (define_expand "testqi_ext_ccno_0"
8876 [(set (reg:CCNO FLAGS_REG)
8880 (match_operand 0 "ext_register_operand" "")
8883 (match_operand 1 "const_int_operand" ""))
8888 (define_insn "*testqi_ext_0"
8889 [(set (reg FLAGS_REG)
8893 (match_operand 0 "ext_register_operand" "Q")
8896 (match_operand 1 "const_int_operand" "n"))
8898 "ix86_match_ccmode (insn, CCNOmode)"
8899 "test{b}\t{%1, %h0|%h0, %1}"
8900 [(set_attr "type" "test")
8901 (set_attr "mode" "QI")
8902 (set_attr "length_immediate" "1")
8903 (set_attr "pent_pair" "np")])
8905 (define_insn "*testqi_ext_1"
8906 [(set (reg FLAGS_REG)
8910 (match_operand 0 "ext_register_operand" "Q")
8914 (match_operand:QI 1 "general_operand" "Qm")))
8916 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8917 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8918 "test{b}\t{%1, %h0|%h0, %1}"
8919 [(set_attr "type" "test")
8920 (set_attr "mode" "QI")])
8922 (define_insn "*testqi_ext_1_rex64"
8923 [(set (reg FLAGS_REG)
8927 (match_operand 0 "ext_register_operand" "Q")
8931 (match_operand:QI 1 "register_operand" "Q")))
8933 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8934 "test{b}\t{%1, %h0|%h0, %1}"
8935 [(set_attr "type" "test")
8936 (set_attr "mode" "QI")])
8938 (define_insn "*testqi_ext_2"
8939 [(set (reg FLAGS_REG)
8943 (match_operand 0 "ext_register_operand" "Q")
8947 (match_operand 1 "ext_register_operand" "Q")
8951 "ix86_match_ccmode (insn, CCNOmode)"
8952 "test{b}\t{%h1, %h0|%h0, %h1}"
8953 [(set_attr "type" "test")
8954 (set_attr "mode" "QI")])
8956 ;; Combine likes to form bit extractions for some tests. Humor it.
8957 (define_insn "*testqi_ext_3"
8958 [(set (reg FLAGS_REG)
8959 (compare (zero_extract:SI
8960 (match_operand 0 "nonimmediate_operand" "rm")
8961 (match_operand:SI 1 "const_int_operand" "")
8962 (match_operand:SI 2 "const_int_operand" ""))
8964 "ix86_match_ccmode (insn, CCNOmode)
8965 && INTVAL (operands[1]) > 0
8966 && INTVAL (operands[2]) >= 0
8967 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8968 && (GET_MODE (operands[0]) == SImode
8969 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8970 || GET_MODE (operands[0]) == HImode
8971 || GET_MODE (operands[0]) == QImode)"
8974 (define_insn "*testqi_ext_3_rex64"
8975 [(set (reg FLAGS_REG)
8976 (compare (zero_extract:DI
8977 (match_operand 0 "nonimmediate_operand" "rm")
8978 (match_operand:DI 1 "const_int_operand" "")
8979 (match_operand:DI 2 "const_int_operand" ""))
8982 && ix86_match_ccmode (insn, CCNOmode)
8983 && INTVAL (operands[1]) > 0
8984 && INTVAL (operands[2]) >= 0
8985 /* Ensure that resulting mask is zero or sign extended operand. */
8986 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8987 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8988 && INTVAL (operands[1]) > 32))
8989 && (GET_MODE (operands[0]) == SImode
8990 || GET_MODE (operands[0]) == DImode
8991 || GET_MODE (operands[0]) == HImode
8992 || GET_MODE (operands[0]) == QImode)"
8996 [(set (match_operand 0 "flags_reg_operand" "")
8997 (match_operator 1 "compare_operator"
8999 (match_operand 2 "nonimmediate_operand" "")
9000 (match_operand 3 "const_int_operand" "")
9001 (match_operand 4 "const_int_operand" ""))
9003 "ix86_match_ccmode (insn, CCNOmode)"
9004 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9006 rtx val = operands[2];
9007 HOST_WIDE_INT len = INTVAL (operands[3]);
9008 HOST_WIDE_INT pos = INTVAL (operands[4]);
9010 enum machine_mode mode, submode;
9012 mode = GET_MODE (val);
9015 /* ??? Combine likes to put non-volatile mem extractions in QImode
9016 no matter the size of the test. So find a mode that works. */
9017 if (! MEM_VOLATILE_P (val))
9019 mode = smallest_mode_for_size (pos + len, MODE_INT);
9020 val = adjust_address (val, mode, 0);
9023 else if (GET_CODE (val) == SUBREG
9024 && (submode = GET_MODE (SUBREG_REG (val)),
9025 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9026 && pos + len <= GET_MODE_BITSIZE (submode))
9028 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9030 val = SUBREG_REG (val);
9032 else if (mode == HImode && pos + len <= 8)
9034 /* Small HImode tests can be converted to QImode. */
9036 val = gen_lowpart (QImode, val);
9039 if (len == HOST_BITS_PER_WIDE_INT)
9042 mask = ((HOST_WIDE_INT)1 << len) - 1;
9045 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9048 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9049 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9050 ;; this is relatively important trick.
9051 ;; Do the conversion only post-reload to avoid limiting of the register class
9054 [(set (match_operand 0 "flags_reg_operand" "")
9055 (match_operator 1 "compare_operator"
9056 [(and (match_operand 2 "register_operand" "")
9057 (match_operand 3 "const_int_operand" ""))
9060 && QI_REG_P (operands[2])
9061 && GET_MODE (operands[2]) != QImode
9062 && ((ix86_match_ccmode (insn, CCZmode)
9063 && !(INTVAL (operands[3]) & ~(255 << 8)))
9064 || (ix86_match_ccmode (insn, CCNOmode)
9065 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9068 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9071 "operands[2] = gen_lowpart (SImode, operands[2]);
9072 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9075 [(set (match_operand 0 "flags_reg_operand" "")
9076 (match_operator 1 "compare_operator"
9077 [(and (match_operand 2 "nonimmediate_operand" "")
9078 (match_operand 3 "const_int_operand" ""))
9081 && GET_MODE (operands[2]) != QImode
9082 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9083 && ((ix86_match_ccmode (insn, CCZmode)
9084 && !(INTVAL (operands[3]) & ~255))
9085 || (ix86_match_ccmode (insn, CCNOmode)
9086 && !(INTVAL (operands[3]) & ~127)))"
9088 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9090 "operands[2] = gen_lowpart (QImode, operands[2]);
9091 operands[3] = gen_lowpart (QImode, operands[3]);")
9094 ;; %%% This used to optimize known byte-wide and operations to memory,
9095 ;; and sometimes to QImode registers. If this is considered useful,
9096 ;; it should be done with splitters.
9098 (define_expand "anddi3"
9099 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9100 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9101 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9103 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9105 (define_insn "*anddi_1_rex64"
9106 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9107 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9108 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9109 (clobber (reg:CC FLAGS_REG))]
9110 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9112 switch (get_attr_type (insn))
9116 enum machine_mode mode;
9118 gcc_assert (CONST_INT_P (operands[2]));
9119 if (INTVAL (operands[2]) == 0xff)
9123 gcc_assert (INTVAL (operands[2]) == 0xffff);
9127 operands[1] = gen_lowpart (mode, operands[1]);
9129 return "movz{bq|x}\t{%1,%0|%0, %1}";
9131 return "movz{wq|x}\t{%1,%0|%0, %1}";
9135 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9136 if (get_attr_mode (insn) == MODE_SI)
9137 return "and{l}\t{%k2, %k0|%k0, %k2}";
9139 return "and{q}\t{%2, %0|%0, %2}";
9142 [(set_attr "type" "alu,alu,alu,imovx")
9143 (set_attr "length_immediate" "*,*,*,0")
9144 (set_attr "mode" "SI,DI,DI,DI")])
9146 (define_insn "*anddi_2"
9147 [(set (reg FLAGS_REG)
9148 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9149 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9151 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9152 (and:DI (match_dup 1) (match_dup 2)))]
9153 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9154 && ix86_binary_operator_ok (AND, DImode, operands)"
9156 and{l}\t{%k2, %k0|%k0, %k2}
9157 and{q}\t{%2, %0|%0, %2}
9158 and{q}\t{%2, %0|%0, %2}"
9159 [(set_attr "type" "alu")
9160 (set_attr "mode" "SI,DI,DI")])
9162 (define_expand "andsi3"
9163 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9164 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9165 (match_operand:SI 2 "general_operand" "")))]
9167 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9169 (define_insn "*andsi_1"
9170 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9171 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9172 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "ix86_binary_operator_ok (AND, SImode, operands)"
9176 switch (get_attr_type (insn))
9180 enum machine_mode mode;
9182 gcc_assert (CONST_INT_P (operands[2]));
9183 if (INTVAL (operands[2]) == 0xff)
9187 gcc_assert (INTVAL (operands[2]) == 0xffff);
9191 operands[1] = gen_lowpart (mode, operands[1]);
9193 return "movz{bl|x}\t{%1,%0|%0, %1}";
9195 return "movz{wl|x}\t{%1,%0|%0, %1}";
9199 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9200 return "and{l}\t{%2, %0|%0, %2}";
9203 [(set_attr "type" "alu,alu,imovx")
9204 (set_attr "length_immediate" "*,*,0")
9205 (set_attr "mode" "SI")])
9208 [(set (match_operand 0 "register_operand" "")
9210 (const_int -65536)))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9213 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9214 "operands[1] = gen_lowpart (HImode, operands[0]);")
9217 [(set (match_operand 0 "ext_register_operand" "")
9220 (clobber (reg:CC FLAGS_REG))]
9221 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9222 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9223 "operands[1] = gen_lowpart (QImode, operands[0]);")
9226 [(set (match_operand 0 "ext_register_operand" "")
9228 (const_int -65281)))
9229 (clobber (reg:CC FLAGS_REG))]
9230 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9231 [(parallel [(set (zero_extract:SI (match_dup 0)
9235 (zero_extract:SI (match_dup 0)
9238 (zero_extract:SI (match_dup 0)
9241 (clobber (reg:CC FLAGS_REG))])]
9242 "operands[0] = gen_lowpart (SImode, operands[0]);")
9244 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9245 (define_insn "*andsi_1_zext"
9246 [(set (match_operand:DI 0 "register_operand" "=r")
9248 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9249 (match_operand:SI 2 "general_operand" "g"))))
9250 (clobber (reg:CC FLAGS_REG))]
9251 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9252 "and{l}\t{%2, %k0|%k0, %2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "mode" "SI")])
9256 (define_insn "*andsi_2"
9257 [(set (reg FLAGS_REG)
9258 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9259 (match_operand:SI 2 "general_operand" "g,ri"))
9261 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9262 (and:SI (match_dup 1) (match_dup 2)))]
9263 "ix86_match_ccmode (insn, CCNOmode)
9264 && ix86_binary_operator_ok (AND, SImode, operands)"
9265 "and{l}\t{%2, %0|%0, %2}"
9266 [(set_attr "type" "alu")
9267 (set_attr "mode" "SI")])
9269 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9270 (define_insn "*andsi_2_zext"
9271 [(set (reg FLAGS_REG)
9272 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9273 (match_operand:SI 2 "general_operand" "g"))
9275 (set (match_operand:DI 0 "register_operand" "=r")
9276 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9277 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9278 && 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_expand "andhi3"
9284 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9285 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9286 (match_operand:HI 2 "general_operand" "")))]
9287 "TARGET_HIMODE_MATH"
9288 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9290 (define_insn "*andhi_1"
9291 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9292 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9293 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9294 (clobber (reg:CC FLAGS_REG))]
9295 "ix86_binary_operator_ok (AND, HImode, operands)"
9297 switch (get_attr_type (insn))
9300 gcc_assert (CONST_INT_P (operands[2]));
9301 gcc_assert (INTVAL (operands[2]) == 0xff);
9302 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9305 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9307 return "and{w}\t{%2, %0|%0, %2}";
9310 [(set_attr "type" "alu,alu,imovx")
9311 (set_attr "length_immediate" "*,*,0")
9312 (set_attr "mode" "HI,HI,SI")])
9314 (define_insn "*andhi_2"
9315 [(set (reg FLAGS_REG)
9316 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9317 (match_operand:HI 2 "general_operand" "rmn,rn"))
9319 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9320 (and:HI (match_dup 1) (match_dup 2)))]
9321 "ix86_match_ccmode (insn, CCNOmode)
9322 && ix86_binary_operator_ok (AND, HImode, operands)"
9323 "and{w}\t{%2, %0|%0, %2}"
9324 [(set_attr "type" "alu")
9325 (set_attr "mode" "HI")])
9327 (define_expand "andqi3"
9328 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9329 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9330 (match_operand:QI 2 "general_operand" "")))]
9331 "TARGET_QIMODE_MATH"
9332 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9334 ;; %%% Potential partial reg stall on alternative 2. What to do?
9335 (define_insn "*andqi_1"
9336 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9337 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9338 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9339 (clobber (reg:CC FLAGS_REG))]
9340 "ix86_binary_operator_ok (AND, QImode, operands)"
9342 and{b}\t{%2, %0|%0, %2}
9343 and{b}\t{%2, %0|%0, %2}
9344 and{l}\t{%k2, %k0|%k0, %k2}"
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "QI,QI,SI")])
9348 (define_insn "*andqi_1_slp"
9349 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9350 (and:QI (match_dup 0)
9351 (match_operand:QI 1 "general_operand" "qn,qmn")))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9354 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9355 "and{b}\t{%1, %0|%0, %1}"
9356 [(set_attr "type" "alu1")
9357 (set_attr "mode" "QI")])
9359 (define_insn "*andqi_2_maybe_si"
9360 [(set (reg FLAGS_REG)
9362 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9363 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9365 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9366 (and:QI (match_dup 1) (match_dup 2)))]
9367 "ix86_binary_operator_ok (AND, QImode, operands)
9368 && ix86_match_ccmode (insn,
9369 CONST_INT_P (operands[2])
9370 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9372 if (which_alternative == 2)
9374 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9375 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9376 return "and{l}\t{%2, %k0|%k0, %2}";
9378 return "and{b}\t{%2, %0|%0, %2}";
9380 [(set_attr "type" "alu")
9381 (set_attr "mode" "QI,QI,SI")])
9383 (define_insn "*andqi_2"
9384 [(set (reg FLAGS_REG)
9386 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9387 (match_operand:QI 2 "general_operand" "qmn,qn"))
9389 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9390 (and:QI (match_dup 1) (match_dup 2)))]
9391 "ix86_match_ccmode (insn, CCNOmode)
9392 && ix86_binary_operator_ok (AND, QImode, operands)"
9393 "and{b}\t{%2, %0|%0, %2}"
9394 [(set_attr "type" "alu")
9395 (set_attr "mode" "QI")])
9397 (define_insn "*andqi_2_slp"
9398 [(set (reg FLAGS_REG)
9400 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9401 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9403 (set (strict_low_part (match_dup 0))
9404 (and:QI (match_dup 0) (match_dup 1)))]
9405 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9406 && ix86_match_ccmode (insn, CCNOmode)
9407 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9408 "and{b}\t{%1, %0|%0, %1}"
9409 [(set_attr "type" "alu1")
9410 (set_attr "mode" "QI")])
9412 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9413 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9414 ;; for a QImode operand, which of course failed.
9416 (define_insn "andqi_ext_0"
9417 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9422 (match_operand 1 "ext_register_operand" "0")
9425 (match_operand 2 "const_int_operand" "n")))
9426 (clobber (reg:CC FLAGS_REG))]
9428 "and{b}\t{%2, %h0|%h0, %2}"
9429 [(set_attr "type" "alu")
9430 (set_attr "length_immediate" "1")
9431 (set_attr "mode" "QI")])
9433 ;; Generated by peephole translating test to and. This shows up
9434 ;; often in fp comparisons.
9436 (define_insn "*andqi_ext_0_cc"
9437 [(set (reg FLAGS_REG)
9441 (match_operand 1 "ext_register_operand" "0")
9444 (match_operand 2 "const_int_operand" "n"))
9446 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9455 "ix86_match_ccmode (insn, CCNOmode)"
9456 "and{b}\t{%2, %h0|%h0, %2}"
9457 [(set_attr "type" "alu")
9458 (set_attr "length_immediate" "1")
9459 (set_attr "mode" "QI")])
9461 (define_insn "*andqi_ext_1"
9462 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9467 (match_operand 1 "ext_register_operand" "0")
9471 (match_operand:QI 2 "general_operand" "Qm"))))
9472 (clobber (reg:CC FLAGS_REG))]
9474 "and{b}\t{%2, %h0|%h0, %2}"
9475 [(set_attr "type" "alu")
9476 (set_attr "length_immediate" "0")
9477 (set_attr "mode" "QI")])
9479 (define_insn "*andqi_ext_1_rex64"
9480 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9485 (match_operand 1 "ext_register_operand" "0")
9489 (match_operand 2 "ext_register_operand" "Q"))))
9490 (clobber (reg:CC FLAGS_REG))]
9492 "and{b}\t{%2, %h0|%h0, %2}"
9493 [(set_attr "type" "alu")
9494 (set_attr "length_immediate" "0")
9495 (set_attr "mode" "QI")])
9497 (define_insn "*andqi_ext_2"
9498 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9503 (match_operand 1 "ext_register_operand" "%0")
9507 (match_operand 2 "ext_register_operand" "Q")
9510 (clobber (reg:CC FLAGS_REG))]
9512 "and{b}\t{%h2, %h0|%h0, %h2}"
9513 [(set_attr "type" "alu")
9514 (set_attr "length_immediate" "0")
9515 (set_attr "mode" "QI")])
9517 ;; Convert wide AND instructions with immediate operand to shorter QImode
9518 ;; equivalents when possible.
9519 ;; Don't do the splitting with memory operands, since it introduces risk
9520 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9521 ;; for size, but that can (should?) be handled by generic code instead.
9523 [(set (match_operand 0 "register_operand" "")
9524 (and (match_operand 1 "register_operand" "")
9525 (match_operand 2 "const_int_operand" "")))
9526 (clobber (reg:CC FLAGS_REG))]
9528 && QI_REG_P (operands[0])
9529 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9530 && !(~INTVAL (operands[2]) & ~(255 << 8))
9531 && GET_MODE (operands[0]) != QImode"
9532 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9533 (and:SI (zero_extract:SI (match_dup 1)
9534 (const_int 8) (const_int 8))
9536 (clobber (reg:CC FLAGS_REG))])]
9537 "operands[0] = gen_lowpart (SImode, operands[0]);
9538 operands[1] = gen_lowpart (SImode, operands[1]);
9539 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9541 ;; Since AND can be encoded with sign extended immediate, this is only
9542 ;; profitable when 7th bit is not set.
9544 [(set (match_operand 0 "register_operand" "")
9545 (and (match_operand 1 "general_operand" "")
9546 (match_operand 2 "const_int_operand" "")))
9547 (clobber (reg:CC FLAGS_REG))]
9549 && ANY_QI_REG_P (operands[0])
9550 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9551 && !(~INTVAL (operands[2]) & ~255)
9552 && !(INTVAL (operands[2]) & 128)
9553 && GET_MODE (operands[0]) != QImode"
9554 [(parallel [(set (strict_low_part (match_dup 0))
9555 (and:QI (match_dup 1)
9557 (clobber (reg:CC FLAGS_REG))])]
9558 "operands[0] = gen_lowpart (QImode, operands[0]);
9559 operands[1] = gen_lowpart (QImode, operands[1]);
9560 operands[2] = gen_lowpart (QImode, operands[2]);")
9562 ;; Logical inclusive OR instructions
9564 ;; %%% This used to optimize known byte-wide and operations to memory.
9565 ;; If this is considered useful, it should be done with splitters.
9567 (define_expand "iordi3"
9568 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9569 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9570 (match_operand:DI 2 "x86_64_general_operand" "")))]
9572 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9574 (define_insn "*iordi_1_rex64"
9575 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9576 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9577 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9578 (clobber (reg:CC FLAGS_REG))]
9580 && ix86_binary_operator_ok (IOR, DImode, operands)"
9581 "or{q}\t{%2, %0|%0, %2}"
9582 [(set_attr "type" "alu")
9583 (set_attr "mode" "DI")])
9585 (define_insn "*iordi_2_rex64"
9586 [(set (reg FLAGS_REG)
9587 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9588 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9590 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9591 (ior:DI (match_dup 1) (match_dup 2)))]
9593 && ix86_match_ccmode (insn, CCNOmode)
9594 && ix86_binary_operator_ok (IOR, DImode, operands)"
9595 "or{q}\t{%2, %0|%0, %2}"
9596 [(set_attr "type" "alu")
9597 (set_attr "mode" "DI")])
9599 (define_insn "*iordi_3_rex64"
9600 [(set (reg FLAGS_REG)
9601 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9602 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9604 (clobber (match_scratch:DI 0 "=r"))]
9606 && ix86_match_ccmode (insn, CCNOmode)
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")])
9613 (define_expand "iorsi3"
9614 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9615 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9616 (match_operand:SI 2 "general_operand" "")))]
9618 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9620 (define_insn "*iorsi_1"
9621 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9622 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9623 (match_operand:SI 2 "general_operand" "ri,g")))
9624 (clobber (reg:CC FLAGS_REG))]
9625 "ix86_binary_operator_ok (IOR, SImode, operands)"
9626 "or{l}\t{%2, %0|%0, %2}"
9627 [(set_attr "type" "alu")
9628 (set_attr "mode" "SI")])
9630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9631 (define_insn "*iorsi_1_zext"
9632 [(set (match_operand:DI 0 "register_operand" "=r")
9634 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9635 (match_operand:SI 2 "general_operand" "g"))))
9636 (clobber (reg:CC FLAGS_REG))]
9637 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9638 "or{l}\t{%2, %k0|%k0, %2}"
9639 [(set_attr "type" "alu")
9640 (set_attr "mode" "SI")])
9642 (define_insn "*iorsi_1_zext_imm"
9643 [(set (match_operand:DI 0 "register_operand" "=r")
9644 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9645 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9646 (clobber (reg:CC FLAGS_REG))]
9648 "or{l}\t{%2, %k0|%k0, %2}"
9649 [(set_attr "type" "alu")
9650 (set_attr "mode" "SI")])
9652 (define_insn "*iorsi_2"
9653 [(set (reg FLAGS_REG)
9654 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9655 (match_operand:SI 2 "general_operand" "g,ri"))
9657 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9658 (ior:SI (match_dup 1) (match_dup 2)))]
9659 "ix86_match_ccmode (insn, CCNOmode)
9660 && ix86_binary_operator_ok (IOR, SImode, operands)"
9661 "or{l}\t{%2, %0|%0, %2}"
9662 [(set_attr "type" "alu")
9663 (set_attr "mode" "SI")])
9665 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9666 ;; ??? Special case for immediate operand is missing - it is tricky.
9667 (define_insn "*iorsi_2_zext"
9668 [(set (reg FLAGS_REG)
9669 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9670 (match_operand:SI 2 "general_operand" "g"))
9672 (set (match_operand:DI 0 "register_operand" "=r")
9673 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9674 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9675 && ix86_binary_operator_ok (IOR, SImode, operands)"
9676 "or{l}\t{%2, %k0|%k0, %2}"
9677 [(set_attr "type" "alu")
9678 (set_attr "mode" "SI")])
9680 (define_insn "*iorsi_2_zext_imm"
9681 [(set (reg FLAGS_REG)
9682 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9683 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9685 (set (match_operand:DI 0 "register_operand" "=r")
9686 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9688 && ix86_binary_operator_ok (IOR, SImode, operands)"
9689 "or{l}\t{%2, %k0|%k0, %2}"
9690 [(set_attr "type" "alu")
9691 (set_attr "mode" "SI")])
9693 (define_insn "*iorsi_3"
9694 [(set (reg FLAGS_REG)
9695 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9696 (match_operand:SI 2 "general_operand" "g"))
9698 (clobber (match_scratch:SI 0 "=r"))]
9699 "ix86_match_ccmode (insn, CCNOmode)
9700 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9701 "or{l}\t{%2, %0|%0, %2}"
9702 [(set_attr "type" "alu")
9703 (set_attr "mode" "SI")])
9705 (define_expand "iorhi3"
9706 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9707 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9708 (match_operand:HI 2 "general_operand" "")))]
9709 "TARGET_HIMODE_MATH"
9710 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9712 (define_insn "*iorhi_1"
9713 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9714 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9715 (match_operand:HI 2 "general_operand" "rmn,rn")))
9716 (clobber (reg:CC FLAGS_REG))]
9717 "ix86_binary_operator_ok (IOR, HImode, operands)"
9718 "or{w}\t{%2, %0|%0, %2}"
9719 [(set_attr "type" "alu")
9720 (set_attr "mode" "HI")])
9722 (define_insn "*iorhi_2"
9723 [(set (reg FLAGS_REG)
9724 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9725 (match_operand:HI 2 "general_operand" "rmn,rn"))
9727 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9728 (ior:HI (match_dup 1) (match_dup 2)))]
9729 "ix86_match_ccmode (insn, CCNOmode)
9730 && ix86_binary_operator_ok (IOR, HImode, operands)"
9731 "or{w}\t{%2, %0|%0, %2}"
9732 [(set_attr "type" "alu")
9733 (set_attr "mode" "HI")])
9735 (define_insn "*iorhi_3"
9736 [(set (reg FLAGS_REG)
9737 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9738 (match_operand:HI 2 "general_operand" "rmn"))
9740 (clobber (match_scratch:HI 0 "=r"))]
9741 "ix86_match_ccmode (insn, CCNOmode)
9742 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9743 "or{w}\t{%2, %0|%0, %2}"
9744 [(set_attr "type" "alu")
9745 (set_attr "mode" "HI")])
9747 (define_expand "iorqi3"
9748 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9749 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9750 (match_operand:QI 2 "general_operand" "")))]
9751 "TARGET_QIMODE_MATH"
9752 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9754 ;; %%% Potential partial reg stall on alternative 2. What to do?
9755 (define_insn "*iorqi_1"
9756 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9757 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9758 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9759 (clobber (reg:CC FLAGS_REG))]
9760 "ix86_binary_operator_ok (IOR, QImode, operands)"
9762 or{b}\t{%2, %0|%0, %2}
9763 or{b}\t{%2, %0|%0, %2}
9764 or{l}\t{%k2, %k0|%k0, %k2}"
9765 [(set_attr "type" "alu")
9766 (set_attr "mode" "QI,QI,SI")])
9768 (define_insn "*iorqi_1_slp"
9769 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9770 (ior:QI (match_dup 0)
9771 (match_operand:QI 1 "general_operand" "qmn,qn")))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9774 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9775 "or{b}\t{%1, %0|%0, %1}"
9776 [(set_attr "type" "alu1")
9777 (set_attr "mode" "QI")])
9779 (define_insn "*iorqi_2"
9780 [(set (reg FLAGS_REG)
9781 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9782 (match_operand:QI 2 "general_operand" "qmn,qn"))
9784 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9785 (ior:QI (match_dup 1) (match_dup 2)))]
9786 "ix86_match_ccmode (insn, CCNOmode)
9787 && ix86_binary_operator_ok (IOR, QImode, operands)"
9788 "or{b}\t{%2, %0|%0, %2}"
9789 [(set_attr "type" "alu")
9790 (set_attr "mode" "QI")])
9792 (define_insn "*iorqi_2_slp"
9793 [(set (reg FLAGS_REG)
9794 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9795 (match_operand:QI 1 "general_operand" "qmn,qn"))
9797 (set (strict_low_part (match_dup 0))
9798 (ior:QI (match_dup 0) (match_dup 1)))]
9799 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9800 && ix86_match_ccmode (insn, CCNOmode)
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_3"
9807 [(set (reg FLAGS_REG)
9808 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9809 (match_operand:QI 2 "general_operand" "qmn"))
9811 (clobber (match_scratch:QI 0 "=q"))]
9812 "ix86_match_ccmode (insn, CCNOmode)
9813 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9814 "or{b}\t{%2, %0|%0, %2}"
9815 [(set_attr "type" "alu")
9816 (set_attr "mode" "QI")])
9818 (define_insn "*iorqi_ext_0"
9819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9824 (match_operand 1 "ext_register_operand" "0")
9827 (match_operand 2 "const_int_operand" "n")))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9830 "or{b}\t{%2, %h0|%h0, %2}"
9831 [(set_attr "type" "alu")
9832 (set_attr "length_immediate" "1")
9833 (set_attr "mode" "QI")])
9835 (define_insn "*iorqi_ext_1"
9836 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9841 (match_operand 1 "ext_register_operand" "0")
9845 (match_operand:QI 2 "general_operand" "Qm"))))
9846 (clobber (reg:CC FLAGS_REG))]
9848 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9849 "or{b}\t{%2, %h0|%h0, %2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "length_immediate" "0")
9852 (set_attr "mode" "QI")])
9854 (define_insn "*iorqi_ext_1_rex64"
9855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9860 (match_operand 1 "ext_register_operand" "0")
9864 (match_operand 2 "ext_register_operand" "Q"))))
9865 (clobber (reg:CC FLAGS_REG))]
9867 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9868 "or{b}\t{%2, %h0|%h0, %2}"
9869 [(set_attr "type" "alu")
9870 (set_attr "length_immediate" "0")
9871 (set_attr "mode" "QI")])
9873 (define_insn "*iorqi_ext_2"
9874 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9878 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9881 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9884 (clobber (reg:CC FLAGS_REG))]
9885 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9886 "ior{b}\t{%h2, %h0|%h0, %h2}"
9887 [(set_attr "type" "alu")
9888 (set_attr "length_immediate" "0")
9889 (set_attr "mode" "QI")])
9892 [(set (match_operand 0 "register_operand" "")
9893 (ior (match_operand 1 "register_operand" "")
9894 (match_operand 2 "const_int_operand" "")))
9895 (clobber (reg:CC FLAGS_REG))]
9897 && QI_REG_P (operands[0])
9898 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9899 && !(INTVAL (operands[2]) & ~(255 << 8))
9900 && GET_MODE (operands[0]) != QImode"
9901 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9902 (ior:SI (zero_extract:SI (match_dup 1)
9903 (const_int 8) (const_int 8))
9905 (clobber (reg:CC FLAGS_REG))])]
9906 "operands[0] = gen_lowpart (SImode, operands[0]);
9907 operands[1] = gen_lowpart (SImode, operands[1]);
9908 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9910 ;; Since OR can be encoded with sign extended immediate, this is only
9911 ;; profitable when 7th bit is set.
9913 [(set (match_operand 0 "register_operand" "")
9914 (ior (match_operand 1 "general_operand" "")
9915 (match_operand 2 "const_int_operand" "")))
9916 (clobber (reg:CC FLAGS_REG))]
9918 && ANY_QI_REG_P (operands[0])
9919 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9920 && !(INTVAL (operands[2]) & ~255)
9921 && (INTVAL (operands[2]) & 128)
9922 && GET_MODE (operands[0]) != QImode"
9923 [(parallel [(set (strict_low_part (match_dup 0))
9924 (ior:QI (match_dup 1)
9926 (clobber (reg:CC FLAGS_REG))])]
9927 "operands[0] = gen_lowpart (QImode, operands[0]);
9928 operands[1] = gen_lowpart (QImode, operands[1]);
9929 operands[2] = gen_lowpart (QImode, operands[2]);")
9931 ;; Logical XOR instructions
9933 ;; %%% This used to optimize known byte-wide and operations to memory.
9934 ;; If this is considered useful, it should be done with splitters.
9936 (define_expand "xordi3"
9937 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9938 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9939 (match_operand:DI 2 "x86_64_general_operand" "")))]
9941 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9943 (define_insn "*xordi_1_rex64"
9944 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9945 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9946 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9947 (clobber (reg:CC FLAGS_REG))]
9949 && ix86_binary_operator_ok (XOR, DImode, operands)"
9950 "xor{q}\t{%2, %0|%0, %2}"
9951 [(set_attr "type" "alu")
9952 (set_attr "mode" "DI")])
9954 (define_insn "*xordi_2_rex64"
9955 [(set (reg FLAGS_REG)
9956 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9957 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9959 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9960 (xor:DI (match_dup 1) (match_dup 2)))]
9962 && ix86_match_ccmode (insn, CCNOmode)
9963 && ix86_binary_operator_ok (XOR, DImode, operands)"
9964 "xor{q}\t{%2, %0|%0, %2}"
9965 [(set_attr "type" "alu")
9966 (set_attr "mode" "DI")])
9968 (define_insn "*xordi_3_rex64"
9969 [(set (reg FLAGS_REG)
9970 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9971 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9973 (clobber (match_scratch:DI 0 "=r"))]
9975 && ix86_match_ccmode (insn, CCNOmode)
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_expand "xorsi3"
9982 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9983 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9984 (match_operand:SI 2 "general_operand" "")))]
9986 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9988 (define_insn "*xorsi_1"
9989 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9990 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9991 (match_operand:SI 2 "general_operand" "ri,rm")))
9992 (clobber (reg:CC FLAGS_REG))]
9993 "ix86_binary_operator_ok (XOR, SImode, operands)"
9994 "xor{l}\t{%2, %0|%0, %2}"
9995 [(set_attr "type" "alu")
9996 (set_attr "mode" "SI")])
9998 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9999 ;; Add speccase for immediates
10000 (define_insn "*xorsi_1_zext"
10001 [(set (match_operand:DI 0 "register_operand" "=r")
10003 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10004 (match_operand:SI 2 "general_operand" "g"))))
10005 (clobber (reg:CC FLAGS_REG))]
10006 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10007 "xor{l}\t{%2, %k0|%k0, %2}"
10008 [(set_attr "type" "alu")
10009 (set_attr "mode" "SI")])
10011 (define_insn "*xorsi_1_zext_imm"
10012 [(set (match_operand:DI 0 "register_operand" "=r")
10013 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10014 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10015 (clobber (reg:CC FLAGS_REG))]
10016 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10017 "xor{l}\t{%2, %k0|%k0, %2}"
10018 [(set_attr "type" "alu")
10019 (set_attr "mode" "SI")])
10021 (define_insn "*xorsi_2"
10022 [(set (reg FLAGS_REG)
10023 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10024 (match_operand:SI 2 "general_operand" "g,ri"))
10026 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10027 (xor:SI (match_dup 1) (match_dup 2)))]
10028 "ix86_match_ccmode (insn, CCNOmode)
10029 && ix86_binary_operator_ok (XOR, SImode, operands)"
10030 "xor{l}\t{%2, %0|%0, %2}"
10031 [(set_attr "type" "alu")
10032 (set_attr "mode" "SI")])
10034 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10035 ;; ??? Special case for immediate operand is missing - it is tricky.
10036 (define_insn "*xorsi_2_zext"
10037 [(set (reg FLAGS_REG)
10038 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10039 (match_operand:SI 2 "general_operand" "g"))
10041 (set (match_operand:DI 0 "register_operand" "=r")
10042 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10043 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10044 && ix86_binary_operator_ok (XOR, SImode, operands)"
10045 "xor{l}\t{%2, %k0|%k0, %2}"
10046 [(set_attr "type" "alu")
10047 (set_attr "mode" "SI")])
10049 (define_insn "*xorsi_2_zext_imm"
10050 [(set (reg FLAGS_REG)
10051 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10052 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10054 (set (match_operand:DI 0 "register_operand" "=r")
10055 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10056 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10057 && ix86_binary_operator_ok (XOR, SImode, operands)"
10058 "xor{l}\t{%2, %k0|%k0, %2}"
10059 [(set_attr "type" "alu")
10060 (set_attr "mode" "SI")])
10062 (define_insn "*xorsi_3"
10063 [(set (reg FLAGS_REG)
10064 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10065 (match_operand:SI 2 "general_operand" "g"))
10067 (clobber (match_scratch:SI 0 "=r"))]
10068 "ix86_match_ccmode (insn, CCNOmode)
10069 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10070 "xor{l}\t{%2, %0|%0, %2}"
10071 [(set_attr "type" "alu")
10072 (set_attr "mode" "SI")])
10074 (define_expand "xorhi3"
10075 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10076 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10077 (match_operand:HI 2 "general_operand" "")))]
10078 "TARGET_HIMODE_MATH"
10079 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10081 (define_insn "*xorhi_1"
10082 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10083 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10084 (match_operand:HI 2 "general_operand" "rmn,rn")))
10085 (clobber (reg:CC FLAGS_REG))]
10086 "ix86_binary_operator_ok (XOR, HImode, operands)"
10087 "xor{w}\t{%2, %0|%0, %2}"
10088 [(set_attr "type" "alu")
10089 (set_attr "mode" "HI")])
10091 (define_insn "*xorhi_2"
10092 [(set (reg FLAGS_REG)
10093 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10094 (match_operand:HI 2 "general_operand" "rmn,rn"))
10096 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10097 (xor:HI (match_dup 1) (match_dup 2)))]
10098 "ix86_match_ccmode (insn, CCNOmode)
10099 && ix86_binary_operator_ok (XOR, HImode, operands)"
10100 "xor{w}\t{%2, %0|%0, %2}"
10101 [(set_attr "type" "alu")
10102 (set_attr "mode" "HI")])
10104 (define_insn "*xorhi_3"
10105 [(set (reg FLAGS_REG)
10106 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10107 (match_operand:HI 2 "general_operand" "rmn"))
10109 (clobber (match_scratch:HI 0 "=r"))]
10110 "ix86_match_ccmode (insn, CCNOmode)
10111 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10112 "xor{w}\t{%2, %0|%0, %2}"
10113 [(set_attr "type" "alu")
10114 (set_attr "mode" "HI")])
10116 (define_expand "xorqi3"
10117 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10118 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10119 (match_operand:QI 2 "general_operand" "")))]
10120 "TARGET_QIMODE_MATH"
10121 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10123 ;; %%% Potential partial reg stall on alternative 2. What to do?
10124 (define_insn "*xorqi_1"
10125 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10126 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10127 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10128 (clobber (reg:CC FLAGS_REG))]
10129 "ix86_binary_operator_ok (XOR, QImode, operands)"
10131 xor{b}\t{%2, %0|%0, %2}
10132 xor{b}\t{%2, %0|%0, %2}
10133 xor{l}\t{%k2, %k0|%k0, %k2}"
10134 [(set_attr "type" "alu")
10135 (set_attr "mode" "QI,QI,SI")])
10137 (define_insn "*xorqi_1_slp"
10138 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10139 (xor:QI (match_dup 0)
10140 (match_operand:QI 1 "general_operand" "qn,qmn")))
10141 (clobber (reg:CC FLAGS_REG))]
10142 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10143 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10144 "xor{b}\t{%1, %0|%0, %1}"
10145 [(set_attr "type" "alu1")
10146 (set_attr "mode" "QI")])
10148 (define_insn "*xorqi_ext_0"
10149 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10154 (match_operand 1 "ext_register_operand" "0")
10157 (match_operand 2 "const_int_operand" "n")))
10158 (clobber (reg:CC FLAGS_REG))]
10159 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10160 "xor{b}\t{%2, %h0|%h0, %2}"
10161 [(set_attr "type" "alu")
10162 (set_attr "length_immediate" "1")
10163 (set_attr "mode" "QI")])
10165 (define_insn "*xorqi_ext_1"
10166 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10171 (match_operand 1 "ext_register_operand" "0")
10175 (match_operand:QI 2 "general_operand" "Qm"))))
10176 (clobber (reg:CC FLAGS_REG))]
10178 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10179 "xor{b}\t{%2, %h0|%h0, %2}"
10180 [(set_attr "type" "alu")
10181 (set_attr "length_immediate" "0")
10182 (set_attr "mode" "QI")])
10184 (define_insn "*xorqi_ext_1_rex64"
10185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10190 (match_operand 1 "ext_register_operand" "0")
10194 (match_operand 2 "ext_register_operand" "Q"))))
10195 (clobber (reg:CC FLAGS_REG))]
10197 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10198 "xor{b}\t{%2, %h0|%h0, %2}"
10199 [(set_attr "type" "alu")
10200 (set_attr "length_immediate" "0")
10201 (set_attr "mode" "QI")])
10203 (define_insn "*xorqi_ext_2"
10204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10208 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10211 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10214 (clobber (reg:CC FLAGS_REG))]
10215 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10216 "xor{b}\t{%h2, %h0|%h0, %h2}"
10217 [(set_attr "type" "alu")
10218 (set_attr "length_immediate" "0")
10219 (set_attr "mode" "QI")])
10221 (define_insn "*xorqi_cc_1"
10222 [(set (reg FLAGS_REG)
10224 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10225 (match_operand:QI 2 "general_operand" "qmn,qn"))
10227 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10228 (xor:QI (match_dup 1) (match_dup 2)))]
10229 "ix86_match_ccmode (insn, CCNOmode)
10230 && ix86_binary_operator_ok (XOR, QImode, operands)"
10231 "xor{b}\t{%2, %0|%0, %2}"
10232 [(set_attr "type" "alu")
10233 (set_attr "mode" "QI")])
10235 (define_insn "*xorqi_2_slp"
10236 [(set (reg FLAGS_REG)
10237 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10238 (match_operand:QI 1 "general_operand" "qmn,qn"))
10240 (set (strict_low_part (match_dup 0))
10241 (xor:QI (match_dup 0) (match_dup 1)))]
10242 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10243 && ix86_match_ccmode (insn, CCNOmode)
10244 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10245 "xor{b}\t{%1, %0|%0, %1}"
10246 [(set_attr "type" "alu1")
10247 (set_attr "mode" "QI")])
10249 (define_insn "*xorqi_cc_2"
10250 [(set (reg FLAGS_REG)
10252 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10253 (match_operand:QI 2 "general_operand" "qmn"))
10255 (clobber (match_scratch:QI 0 "=q"))]
10256 "ix86_match_ccmode (insn, CCNOmode)
10257 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10258 "xor{b}\t{%2, %0|%0, %2}"
10259 [(set_attr "type" "alu")
10260 (set_attr "mode" "QI")])
10262 (define_insn "*xorqi_cc_ext_1"
10263 [(set (reg FLAGS_REG)
10267 (match_operand 1 "ext_register_operand" "0")
10270 (match_operand:QI 2 "general_operand" "qmn"))
10272 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10276 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10278 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10279 "xor{b}\t{%2, %h0|%h0, %2}"
10280 [(set_attr "type" "alu")
10281 (set_attr "mode" "QI")])
10283 (define_insn "*xorqi_cc_ext_1_rex64"
10284 [(set (reg FLAGS_REG)
10288 (match_operand 1 "ext_register_operand" "0")
10291 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10293 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10297 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10299 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10300 "xor{b}\t{%2, %h0|%h0, %2}"
10301 [(set_attr "type" "alu")
10302 (set_attr "mode" "QI")])
10304 (define_expand "xorqi_cc_ext_1"
10306 (set (reg:CCNO FLAGS_REG)
10310 (match_operand 1 "ext_register_operand" "")
10313 (match_operand:QI 2 "general_operand" ""))
10315 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10319 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10325 [(set (match_operand 0 "register_operand" "")
10326 (xor (match_operand 1 "register_operand" "")
10327 (match_operand 2 "const_int_operand" "")))
10328 (clobber (reg:CC FLAGS_REG))]
10330 && QI_REG_P (operands[0])
10331 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10332 && !(INTVAL (operands[2]) & ~(255 << 8))
10333 && GET_MODE (operands[0]) != QImode"
10334 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10335 (xor:SI (zero_extract:SI (match_dup 1)
10336 (const_int 8) (const_int 8))
10338 (clobber (reg:CC FLAGS_REG))])]
10339 "operands[0] = gen_lowpart (SImode, operands[0]);
10340 operands[1] = gen_lowpart (SImode, operands[1]);
10341 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10343 ;; Since XOR can be encoded with sign extended immediate, this is only
10344 ;; profitable when 7th bit is set.
10346 [(set (match_operand 0 "register_operand" "")
10347 (xor (match_operand 1 "general_operand" "")
10348 (match_operand 2 "const_int_operand" "")))
10349 (clobber (reg:CC FLAGS_REG))]
10351 && ANY_QI_REG_P (operands[0])
10352 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10353 && !(INTVAL (operands[2]) & ~255)
10354 && (INTVAL (operands[2]) & 128)
10355 && GET_MODE (operands[0]) != QImode"
10356 [(parallel [(set (strict_low_part (match_dup 0))
10357 (xor:QI (match_dup 1)
10359 (clobber (reg:CC FLAGS_REG))])]
10360 "operands[0] = gen_lowpart (QImode, operands[0]);
10361 operands[1] = gen_lowpart (QImode, operands[1]);
10362 operands[2] = gen_lowpart (QImode, operands[2]);")
10364 ;; Negation instructions
10366 (define_expand "negti2"
10367 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10368 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10370 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10372 (define_insn "*negti2_1"
10373 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10374 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10375 (clobber (reg:CC FLAGS_REG))]
10377 && ix86_unary_operator_ok (NEG, TImode, operands)"
10381 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10382 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10383 (clobber (reg:CC FLAGS_REG))]
10384 "TARGET_64BIT && reload_completed"
10386 [(set (reg:CCZ FLAGS_REG)
10387 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10388 (set (match_dup 0) (neg:DI (match_dup 1)))])
10390 [(set (match_dup 2)
10391 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10394 (clobber (reg:CC FLAGS_REG))])
10396 [(set (match_dup 2)
10397 (neg:DI (match_dup 2)))
10398 (clobber (reg:CC FLAGS_REG))])]
10399 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10401 (define_expand "negdi2"
10402 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10403 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10405 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10407 (define_insn "*negdi2_1"
10408 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10409 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10410 (clobber (reg:CC FLAGS_REG))]
10412 && ix86_unary_operator_ok (NEG, DImode, operands)"
10416 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10417 (neg:DI (match_operand:DI 1 "general_operand" "")))
10418 (clobber (reg:CC FLAGS_REG))]
10419 "!TARGET_64BIT && reload_completed"
10421 [(set (reg:CCZ FLAGS_REG)
10422 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10423 (set (match_dup 0) (neg:SI (match_dup 1)))])
10425 [(set (match_dup 2)
10426 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10429 (clobber (reg:CC FLAGS_REG))])
10431 [(set (match_dup 2)
10432 (neg:SI (match_dup 2)))
10433 (clobber (reg:CC FLAGS_REG))])]
10434 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10436 (define_insn "*negdi2_1_rex64"
10437 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10438 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10439 (clobber (reg:CC FLAGS_REG))]
10440 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10442 [(set_attr "type" "negnot")
10443 (set_attr "mode" "DI")])
10445 ;; The problem with neg is that it does not perform (compare x 0),
10446 ;; it really performs (compare 0 x), which leaves us with the zero
10447 ;; flag being the only useful item.
10449 (define_insn "*negdi2_cmpz_rex64"
10450 [(set (reg:CCZ FLAGS_REG)
10451 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10453 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10454 (neg:DI (match_dup 1)))]
10455 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10457 [(set_attr "type" "negnot")
10458 (set_attr "mode" "DI")])
10461 (define_expand "negsi2"
10462 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10463 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10465 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10467 (define_insn "*negsi2_1"
10468 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10469 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10470 (clobber (reg:CC FLAGS_REG))]
10471 "ix86_unary_operator_ok (NEG, SImode, operands)"
10473 [(set_attr "type" "negnot")
10474 (set_attr "mode" "SI")])
10476 ;; Combine is quite creative about this pattern.
10477 (define_insn "*negsi2_1_zext"
10478 [(set (match_operand:DI 0 "register_operand" "=r")
10479 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10482 (clobber (reg:CC FLAGS_REG))]
10483 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10485 [(set_attr "type" "negnot")
10486 (set_attr "mode" "SI")])
10488 ;; The problem with neg is that it does not perform (compare x 0),
10489 ;; it really performs (compare 0 x), which leaves us with the zero
10490 ;; flag being the only useful item.
10492 (define_insn "*negsi2_cmpz"
10493 [(set (reg:CCZ FLAGS_REG)
10494 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10496 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10497 (neg:SI (match_dup 1)))]
10498 "ix86_unary_operator_ok (NEG, SImode, operands)"
10500 [(set_attr "type" "negnot")
10501 (set_attr "mode" "SI")])
10503 (define_insn "*negsi2_cmpz_zext"
10504 [(set (reg:CCZ FLAGS_REG)
10505 (compare:CCZ (lshiftrt:DI
10507 (match_operand:DI 1 "register_operand" "0")
10511 (set (match_operand:DI 0 "register_operand" "=r")
10512 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10515 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10517 [(set_attr "type" "negnot")
10518 (set_attr "mode" "SI")])
10520 (define_expand "neghi2"
10521 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10522 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10523 "TARGET_HIMODE_MATH"
10524 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10526 (define_insn "*neghi2_1"
10527 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10528 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10529 (clobber (reg:CC FLAGS_REG))]
10530 "ix86_unary_operator_ok (NEG, HImode, operands)"
10532 [(set_attr "type" "negnot")
10533 (set_attr "mode" "HI")])
10535 (define_insn "*neghi2_cmpz"
10536 [(set (reg:CCZ FLAGS_REG)
10537 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10539 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10540 (neg:HI (match_dup 1)))]
10541 "ix86_unary_operator_ok (NEG, HImode, operands)"
10543 [(set_attr "type" "negnot")
10544 (set_attr "mode" "HI")])
10546 (define_expand "negqi2"
10547 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10548 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10549 "TARGET_QIMODE_MATH"
10550 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10552 (define_insn "*negqi2_1"
10553 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10554 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10555 (clobber (reg:CC FLAGS_REG))]
10556 "ix86_unary_operator_ok (NEG, QImode, operands)"
10558 [(set_attr "type" "negnot")
10559 (set_attr "mode" "QI")])
10561 (define_insn "*negqi2_cmpz"
10562 [(set (reg:CCZ FLAGS_REG)
10563 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10565 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10566 (neg:QI (match_dup 1)))]
10567 "ix86_unary_operator_ok (NEG, QImode, operands)"
10569 [(set_attr "type" "negnot")
10570 (set_attr "mode" "QI")])
10572 ;; Changing of sign for FP values is doable using integer unit too.
10574 (define_expand "<code><mode>2"
10575 [(set (match_operand:X87MODEF 0 "register_operand" "")
10576 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10577 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10578 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10580 (define_insn "*absneg<mode>2_mixed"
10581 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10582 (match_operator:MODEF 3 "absneg_operator"
10583 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10584 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10585 (clobber (reg:CC FLAGS_REG))]
10586 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10589 (define_insn "*absneg<mode>2_sse"
10590 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10591 (match_operator:MODEF 3 "absneg_operator"
10592 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10593 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10594 (clobber (reg:CC FLAGS_REG))]
10595 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10598 (define_insn "*absneg<mode>2_i387"
10599 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10600 (match_operator:X87MODEF 3 "absneg_operator"
10601 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10602 (use (match_operand 2 "" ""))
10603 (clobber (reg:CC FLAGS_REG))]
10604 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10607 (define_expand "<code>tf2"
10608 [(set (match_operand:TF 0 "register_operand" "")
10609 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10611 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10613 (define_insn "*absnegtf2_sse"
10614 [(set (match_operand:TF 0 "register_operand" "=x,x")
10615 (match_operator:TF 3 "absneg_operator"
10616 [(match_operand:TF 1 "register_operand" "0,x")]))
10617 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10618 (clobber (reg:CC FLAGS_REG))]
10622 ;; Splitters for fp abs and neg.
10625 [(set (match_operand 0 "fp_register_operand" "")
10626 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10627 (use (match_operand 2 "" ""))
10628 (clobber (reg:CC FLAGS_REG))]
10630 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10633 [(set (match_operand 0 "register_operand" "")
10634 (match_operator 3 "absneg_operator"
10635 [(match_operand 1 "register_operand" "")]))
10636 (use (match_operand 2 "nonimmediate_operand" ""))
10637 (clobber (reg:CC FLAGS_REG))]
10638 "reload_completed && SSE_REG_P (operands[0])"
10639 [(set (match_dup 0) (match_dup 3))]
10641 enum machine_mode mode = GET_MODE (operands[0]);
10642 enum machine_mode vmode = GET_MODE (operands[2]);
10645 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10646 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10647 if (operands_match_p (operands[0], operands[2]))
10650 operands[1] = operands[2];
10653 if (GET_CODE (operands[3]) == ABS)
10654 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10656 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10661 [(set (match_operand:SF 0 "register_operand" "")
10662 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10663 (use (match_operand:V4SF 2 "" ""))
10664 (clobber (reg:CC FLAGS_REG))]
10666 [(parallel [(set (match_dup 0) (match_dup 1))
10667 (clobber (reg:CC FLAGS_REG))])]
10670 operands[0] = gen_lowpart (SImode, operands[0]);
10671 if (GET_CODE (operands[1]) == ABS)
10673 tmp = gen_int_mode (0x7fffffff, SImode);
10674 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10678 tmp = gen_int_mode (0x80000000, SImode);
10679 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10685 [(set (match_operand:DF 0 "register_operand" "")
10686 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10687 (use (match_operand 2 "" ""))
10688 (clobber (reg:CC FLAGS_REG))]
10690 [(parallel [(set (match_dup 0) (match_dup 1))
10691 (clobber (reg:CC FLAGS_REG))])]
10696 tmp = gen_lowpart (DImode, operands[0]);
10697 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10700 if (GET_CODE (operands[1]) == ABS)
10703 tmp = gen_rtx_NOT (DImode, tmp);
10707 operands[0] = gen_highpart (SImode, operands[0]);
10708 if (GET_CODE (operands[1]) == ABS)
10710 tmp = gen_int_mode (0x7fffffff, SImode);
10711 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10715 tmp = gen_int_mode (0x80000000, SImode);
10716 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10723 [(set (match_operand:XF 0 "register_operand" "")
10724 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10725 (use (match_operand 2 "" ""))
10726 (clobber (reg:CC FLAGS_REG))]
10728 [(parallel [(set (match_dup 0) (match_dup 1))
10729 (clobber (reg:CC FLAGS_REG))])]
10732 operands[0] = gen_rtx_REG (SImode,
10733 true_regnum (operands[0])
10734 + (TARGET_64BIT ? 1 : 2));
10735 if (GET_CODE (operands[1]) == ABS)
10737 tmp = GEN_INT (0x7fff);
10738 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10742 tmp = GEN_INT (0x8000);
10743 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10748 ;; Conditionalize these after reload. If they match before reload, we
10749 ;; lose the clobber and ability to use integer instructions.
10751 (define_insn "*<code><mode>2_1"
10752 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10753 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10755 && (reload_completed
10756 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10758 [(set_attr "type" "fsgn")
10759 (set_attr "mode" "<MODE>")])
10761 (define_insn "*<code>extendsfdf2"
10762 [(set (match_operand:DF 0 "register_operand" "=f")
10763 (absneg:DF (float_extend:DF
10764 (match_operand:SF 1 "register_operand" "0"))))]
10765 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10767 [(set_attr "type" "fsgn")
10768 (set_attr "mode" "DF")])
10770 (define_insn "*<code>extendsfxf2"
10771 [(set (match_operand:XF 0 "register_operand" "=f")
10772 (absneg:XF (float_extend:XF
10773 (match_operand:SF 1 "register_operand" "0"))))]
10776 [(set_attr "type" "fsgn")
10777 (set_attr "mode" "XF")])
10779 (define_insn "*<code>extenddfxf2"
10780 [(set (match_operand:XF 0 "register_operand" "=f")
10781 (absneg:XF (float_extend:XF
10782 (match_operand:DF 1 "register_operand" "0"))))]
10785 [(set_attr "type" "fsgn")
10786 (set_attr "mode" "XF")])
10788 ;; Copysign instructions
10790 (define_mode_iterator CSGNMODE [SF DF TF])
10791 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10793 (define_expand "copysign<mode>3"
10794 [(match_operand:CSGNMODE 0 "register_operand" "")
10795 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10796 (match_operand:CSGNMODE 2 "register_operand" "")]
10797 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10798 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10800 ix86_expand_copysign (operands);
10804 (define_insn_and_split "copysign<mode>3_const"
10805 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10807 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10808 (match_operand:CSGNMODE 2 "register_operand" "0")
10809 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10811 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10812 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10814 "&& reload_completed"
10817 ix86_split_copysign_const (operands);
10821 (define_insn "copysign<mode>3_var"
10822 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10824 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10825 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10826 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10827 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10829 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10830 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10831 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10835 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10837 [(match_operand:CSGNMODE 2 "register_operand" "")
10838 (match_operand:CSGNMODE 3 "register_operand" "")
10839 (match_operand:<CSGNVMODE> 4 "" "")
10840 (match_operand:<CSGNVMODE> 5 "" "")]
10842 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10843 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10844 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10845 && reload_completed"
10848 ix86_split_copysign_var (operands);
10852 ;; One complement instructions
10854 (define_expand "one_cmpldi2"
10855 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10856 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10858 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10860 (define_insn "*one_cmpldi2_1_rex64"
10861 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10862 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10863 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10865 [(set_attr "type" "negnot")
10866 (set_attr "mode" "DI")])
10868 (define_insn "*one_cmpldi2_2_rex64"
10869 [(set (reg FLAGS_REG)
10870 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10872 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10873 (not:DI (match_dup 1)))]
10874 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10875 && ix86_unary_operator_ok (NOT, DImode, operands)"
10877 [(set_attr "type" "alu1")
10878 (set_attr "mode" "DI")])
10881 [(set (match_operand 0 "flags_reg_operand" "")
10882 (match_operator 2 "compare_operator"
10883 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10885 (set (match_operand:DI 1 "nonimmediate_operand" "")
10886 (not:DI (match_dup 3)))]
10887 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10888 [(parallel [(set (match_dup 0)
10890 [(xor:DI (match_dup 3) (const_int -1))
10893 (xor:DI (match_dup 3) (const_int -1)))])]
10896 (define_expand "one_cmplsi2"
10897 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10898 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10900 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10902 (define_insn "*one_cmplsi2_1"
10903 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10904 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10905 "ix86_unary_operator_ok (NOT, SImode, operands)"
10907 [(set_attr "type" "negnot")
10908 (set_attr "mode" "SI")])
10910 ;; ??? Currently never generated - xor is used instead.
10911 (define_insn "*one_cmplsi2_1_zext"
10912 [(set (match_operand:DI 0 "register_operand" "=r")
10913 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10914 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10916 [(set_attr "type" "negnot")
10917 (set_attr "mode" "SI")])
10919 (define_insn "*one_cmplsi2_2"
10920 [(set (reg FLAGS_REG)
10921 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10923 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10924 (not:SI (match_dup 1)))]
10925 "ix86_match_ccmode (insn, CCNOmode)
10926 && ix86_unary_operator_ok (NOT, SImode, operands)"
10928 [(set_attr "type" "alu1")
10929 (set_attr "mode" "SI")])
10932 [(set (match_operand 0 "flags_reg_operand" "")
10933 (match_operator 2 "compare_operator"
10934 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10936 (set (match_operand:SI 1 "nonimmediate_operand" "")
10937 (not:SI (match_dup 3)))]
10938 "ix86_match_ccmode (insn, CCNOmode)"
10939 [(parallel [(set (match_dup 0)
10940 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10943 (xor:SI (match_dup 3) (const_int -1)))])]
10946 ;; ??? Currently never generated - xor is used instead.
10947 (define_insn "*one_cmplsi2_2_zext"
10948 [(set (reg FLAGS_REG)
10949 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10951 (set (match_operand:DI 0 "register_operand" "=r")
10952 (zero_extend:DI (not:SI (match_dup 1))))]
10953 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10954 && ix86_unary_operator_ok (NOT, SImode, operands)"
10956 [(set_attr "type" "alu1")
10957 (set_attr "mode" "SI")])
10960 [(set (match_operand 0 "flags_reg_operand" "")
10961 (match_operator 2 "compare_operator"
10962 [(not:SI (match_operand:SI 3 "register_operand" ""))
10964 (set (match_operand:DI 1 "register_operand" "")
10965 (zero_extend:DI (not:SI (match_dup 3))))]
10966 "ix86_match_ccmode (insn, CCNOmode)"
10967 [(parallel [(set (match_dup 0)
10968 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10971 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10974 (define_expand "one_cmplhi2"
10975 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10976 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10977 "TARGET_HIMODE_MATH"
10978 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10980 (define_insn "*one_cmplhi2_1"
10981 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10982 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10983 "ix86_unary_operator_ok (NOT, HImode, operands)"
10985 [(set_attr "type" "negnot")
10986 (set_attr "mode" "HI")])
10988 (define_insn "*one_cmplhi2_2"
10989 [(set (reg FLAGS_REG)
10990 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10992 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10993 (not:HI (match_dup 1)))]
10994 "ix86_match_ccmode (insn, CCNOmode)
10995 && ix86_unary_operator_ok (NEG, HImode, operands)"
10997 [(set_attr "type" "alu1")
10998 (set_attr "mode" "HI")])
11001 [(set (match_operand 0 "flags_reg_operand" "")
11002 (match_operator 2 "compare_operator"
11003 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11005 (set (match_operand:HI 1 "nonimmediate_operand" "")
11006 (not:HI (match_dup 3)))]
11007 "ix86_match_ccmode (insn, CCNOmode)"
11008 [(parallel [(set (match_dup 0)
11009 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11012 (xor:HI (match_dup 3) (const_int -1)))])]
11015 ;; %%% Potential partial reg stall on alternative 1. What to do?
11016 (define_expand "one_cmplqi2"
11017 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11018 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11019 "TARGET_QIMODE_MATH"
11020 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11022 (define_insn "*one_cmplqi2_1"
11023 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11024 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11025 "ix86_unary_operator_ok (NOT, QImode, operands)"
11029 [(set_attr "type" "negnot")
11030 (set_attr "mode" "QI,SI")])
11032 (define_insn "*one_cmplqi2_2"
11033 [(set (reg FLAGS_REG)
11034 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11036 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11037 (not:QI (match_dup 1)))]
11038 "ix86_match_ccmode (insn, CCNOmode)
11039 && ix86_unary_operator_ok (NOT, QImode, operands)"
11041 [(set_attr "type" "alu1")
11042 (set_attr "mode" "QI")])
11045 [(set (match_operand 0 "flags_reg_operand" "")
11046 (match_operator 2 "compare_operator"
11047 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11049 (set (match_operand:QI 1 "nonimmediate_operand" "")
11050 (not:QI (match_dup 3)))]
11051 "ix86_match_ccmode (insn, CCNOmode)"
11052 [(parallel [(set (match_dup 0)
11053 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11056 (xor:QI (match_dup 3) (const_int -1)))])]
11059 ;; Arithmetic shift instructions
11061 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11062 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11063 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11064 ;; from the assembler input.
11066 ;; This instruction shifts the target reg/mem as usual, but instead of
11067 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11068 ;; is a left shift double, bits are taken from the high order bits of
11069 ;; reg, else if the insn is a shift right double, bits are taken from the
11070 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11071 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11073 ;; Since sh[lr]d does not change the `reg' operand, that is done
11074 ;; separately, making all shifts emit pairs of shift double and normal
11075 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11076 ;; support a 63 bit shift, each shift where the count is in a reg expands
11077 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11079 ;; If the shift count is a constant, we need never emit more than one
11080 ;; shift pair, instead using moves and sign extension for counts greater
11083 (define_expand "ashlti3"
11084 [(set (match_operand:TI 0 "register_operand" "")
11085 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11086 (match_operand:QI 2 "nonmemory_operand" "")))]
11088 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11090 ;; This pattern must be defined before *ashlti3_1 to prevent
11091 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11093 (define_insn "*avx_ashlti3"
11094 [(set (match_operand:TI 0 "register_operand" "=x")
11095 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11096 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11099 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11100 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11102 [(set_attr "type" "sseishft")
11103 (set_attr "prefix" "vex")
11104 (set_attr "mode" "TI")])
11106 (define_insn "sse2_ashlti3"
11107 [(set (match_operand:TI 0 "register_operand" "=x")
11108 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11109 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11112 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11113 return "pslldq\t{%2, %0|%0, %2}";
11115 [(set_attr "type" "sseishft")
11116 (set_attr "prefix_data16" "1")
11117 (set_attr "mode" "TI")])
11119 (define_insn "*ashlti3_1"
11120 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11121 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11122 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11123 (clobber (reg:CC FLAGS_REG))]
11126 [(set_attr "type" "multi")])
11129 [(match_scratch:DI 3 "r")
11130 (parallel [(set (match_operand:TI 0 "register_operand" "")
11131 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11132 (match_operand:QI 2 "nonmemory_operand" "")))
11133 (clobber (reg:CC FLAGS_REG))])
11137 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11140 [(set (match_operand:TI 0 "register_operand" "")
11141 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11142 (match_operand:QI 2 "nonmemory_operand" "")))
11143 (clobber (reg:CC FLAGS_REG))]
11144 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11145 ? epilogue_completed : reload_completed)"
11147 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11149 (define_insn "x86_64_shld"
11150 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11151 (ior:DI (ashift:DI (match_dup 0)
11152 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11153 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11154 (minus:QI (const_int 64) (match_dup 2)))))
11155 (clobber (reg:CC FLAGS_REG))]
11157 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11158 [(set_attr "type" "ishift")
11159 (set_attr "prefix_0f" "1")
11160 (set_attr "mode" "DI")
11161 (set_attr "athlon_decode" "vector")
11162 (set_attr "amdfam10_decode" "vector")])
11164 (define_expand "x86_64_shift_adj_1"
11165 [(set (reg:CCZ FLAGS_REG)
11166 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11169 (set (match_operand:DI 0 "register_operand" "")
11170 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11171 (match_operand:DI 1 "register_operand" "")
11174 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11175 (match_operand:DI 3 "register_operand" "r")
11180 (define_expand "x86_64_shift_adj_2"
11181 [(use (match_operand:DI 0 "register_operand" ""))
11182 (use (match_operand:DI 1 "register_operand" ""))
11183 (use (match_operand:QI 2 "register_operand" ""))]
11186 rtx label = gen_label_rtx ();
11189 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11191 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11192 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11193 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11194 gen_rtx_LABEL_REF (VOIDmode, label),
11196 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11197 JUMP_LABEL (tmp) = label;
11199 emit_move_insn (operands[0], operands[1]);
11200 ix86_expand_clear (operands[1]);
11202 emit_label (label);
11203 LABEL_NUSES (label) = 1;
11208 (define_expand "ashldi3"
11209 [(set (match_operand:DI 0 "shiftdi_operand" "")
11210 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11211 (match_operand:QI 2 "nonmemory_operand" "")))]
11213 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11215 (define_insn "*ashldi3_1_rex64"
11216 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11217 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11218 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11219 (clobber (reg:CC FLAGS_REG))]
11220 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11222 switch (get_attr_type (insn))
11225 gcc_assert (operands[2] == const1_rtx);
11226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11227 return "add{q}\t%0, %0";
11230 gcc_assert (CONST_INT_P (operands[2]));
11231 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11232 operands[1] = gen_rtx_MULT (DImode, operands[1],
11233 GEN_INT (1 << INTVAL (operands[2])));
11234 return "lea{q}\t{%a1, %0|%0, %a1}";
11237 if (REG_P (operands[2]))
11238 return "sal{q}\t{%b2, %0|%0, %b2}";
11239 else if (operands[2] == const1_rtx
11240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11241 return "sal{q}\t%0";
11243 return "sal{q}\t{%2, %0|%0, %2}";
11246 [(set (attr "type")
11247 (cond [(eq_attr "alternative" "1")
11248 (const_string "lea")
11249 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11251 (match_operand 0 "register_operand" ""))
11252 (match_operand 2 "const1_operand" ""))
11253 (const_string "alu")
11255 (const_string "ishift")))
11256 (set_attr "mode" "DI")])
11258 ;; Convert lea to the lea pattern to avoid flags dependency.
11260 [(set (match_operand:DI 0 "register_operand" "")
11261 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11262 (match_operand:QI 2 "immediate_operand" "")))
11263 (clobber (reg:CC FLAGS_REG))]
11264 "TARGET_64BIT && reload_completed
11265 && true_regnum (operands[0]) != true_regnum (operands[1])"
11266 [(set (match_dup 0)
11267 (mult:DI (match_dup 1)
11269 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11271 ;; This pattern can't accept a variable shift count, since shifts by
11272 ;; zero don't affect the flags. We assume that shifts by constant
11273 ;; zero are optimized away.
11274 (define_insn "*ashldi3_cmp_rex64"
11275 [(set (reg FLAGS_REG)
11277 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11278 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11280 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11281 (ashift:DI (match_dup 1) (match_dup 2)))]
11283 && (optimize_function_for_size_p (cfun)
11284 || !TARGET_PARTIAL_FLAG_REG_STALL
11285 || (operands[2] == const1_rtx
11287 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11288 && ix86_match_ccmode (insn, CCGOCmode)
11289 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11291 switch (get_attr_type (insn))
11294 gcc_assert (operands[2] == const1_rtx);
11295 return "add{q}\t%0, %0";
11298 if (REG_P (operands[2]))
11299 return "sal{q}\t{%b2, %0|%0, %b2}";
11300 else if (operands[2] == const1_rtx
11301 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11302 return "sal{q}\t%0";
11304 return "sal{q}\t{%2, %0|%0, %2}";
11307 [(set (attr "type")
11308 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11310 (match_operand 0 "register_operand" ""))
11311 (match_operand 2 "const1_operand" ""))
11312 (const_string "alu")
11314 (const_string "ishift")))
11315 (set_attr "mode" "DI")])
11317 (define_insn "*ashldi3_cconly_rex64"
11318 [(set (reg FLAGS_REG)
11320 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11321 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11323 (clobber (match_scratch:DI 0 "=r"))]
11325 && (optimize_function_for_size_p (cfun)
11326 || !TARGET_PARTIAL_FLAG_REG_STALL
11327 || (operands[2] == const1_rtx
11329 || TARGET_DOUBLE_WITH_ADD)))
11330 && ix86_match_ccmode (insn, CCGOCmode)
11331 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11333 switch (get_attr_type (insn))
11336 gcc_assert (operands[2] == const1_rtx);
11337 return "add{q}\t%0, %0";
11340 if (REG_P (operands[2]))
11341 return "sal{q}\t{%b2, %0|%0, %b2}";
11342 else if (operands[2] == const1_rtx
11343 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11344 return "sal{q}\t%0";
11346 return "sal{q}\t{%2, %0|%0, %2}";
11349 [(set (attr "type")
11350 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11352 (match_operand 0 "register_operand" ""))
11353 (match_operand 2 "const1_operand" ""))
11354 (const_string "alu")
11356 (const_string "ishift")))
11357 (set_attr "mode" "DI")])
11359 (define_insn "*ashldi3_1"
11360 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11361 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11362 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11363 (clobber (reg:CC FLAGS_REG))]
11366 [(set_attr "type" "multi")])
11368 ;; By default we don't ask for a scratch register, because when DImode
11369 ;; values are manipulated, registers are already at a premium. But if
11370 ;; we have one handy, we won't turn it away.
11372 [(match_scratch:SI 3 "r")
11373 (parallel [(set (match_operand:DI 0 "register_operand" "")
11374 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11375 (match_operand:QI 2 "nonmemory_operand" "")))
11376 (clobber (reg:CC FLAGS_REG))])
11378 "!TARGET_64BIT && TARGET_CMOVE"
11380 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11383 [(set (match_operand:DI 0 "register_operand" "")
11384 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11385 (match_operand:QI 2 "nonmemory_operand" "")))
11386 (clobber (reg:CC FLAGS_REG))]
11387 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11388 ? epilogue_completed : reload_completed)"
11390 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11392 (define_insn "x86_shld"
11393 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11394 (ior:SI (ashift:SI (match_dup 0)
11395 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11396 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11397 (minus:QI (const_int 32) (match_dup 2)))))
11398 (clobber (reg:CC FLAGS_REG))]
11400 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11401 [(set_attr "type" "ishift")
11402 (set_attr "prefix_0f" "1")
11403 (set_attr "mode" "SI")
11404 (set_attr "pent_pair" "np")
11405 (set_attr "athlon_decode" "vector")
11406 (set_attr "amdfam10_decode" "vector")])
11408 (define_expand "x86_shift_adj_1"
11409 [(set (reg:CCZ FLAGS_REG)
11410 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11413 (set (match_operand:SI 0 "register_operand" "")
11414 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11415 (match_operand:SI 1 "register_operand" "")
11418 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11419 (match_operand:SI 3 "register_operand" "r")
11424 (define_expand "x86_shift_adj_2"
11425 [(use (match_operand:SI 0 "register_operand" ""))
11426 (use (match_operand:SI 1 "register_operand" ""))
11427 (use (match_operand:QI 2 "register_operand" ""))]
11430 rtx label = gen_label_rtx ();
11433 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11435 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11436 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11437 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11438 gen_rtx_LABEL_REF (VOIDmode, label),
11440 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11441 JUMP_LABEL (tmp) = label;
11443 emit_move_insn (operands[0], operands[1]);
11444 ix86_expand_clear (operands[1]);
11446 emit_label (label);
11447 LABEL_NUSES (label) = 1;
11452 (define_expand "ashlsi3"
11453 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11454 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11455 (match_operand:QI 2 "nonmemory_operand" "")))]
11457 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11459 (define_insn "*ashlsi3_1"
11460 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11461 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11462 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11463 (clobber (reg:CC FLAGS_REG))]
11464 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11466 switch (get_attr_type (insn))
11469 gcc_assert (operands[2] == const1_rtx);
11470 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11471 return "add{l}\t%0, %0";
11477 if (REG_P (operands[2]))
11478 return "sal{l}\t{%b2, %0|%0, %b2}";
11479 else if (operands[2] == const1_rtx
11480 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11481 return "sal{l}\t%0";
11483 return "sal{l}\t{%2, %0|%0, %2}";
11486 [(set (attr "type")
11487 (cond [(eq_attr "alternative" "1")
11488 (const_string "lea")
11489 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11491 (match_operand 0 "register_operand" ""))
11492 (match_operand 2 "const1_operand" ""))
11493 (const_string "alu")
11495 (const_string "ishift")))
11496 (set_attr "mode" "SI")])
11498 ;; Convert lea to the lea pattern to avoid flags dependency.
11500 [(set (match_operand 0 "register_operand" "")
11501 (ashift (match_operand 1 "index_register_operand" "")
11502 (match_operand:QI 2 "const_int_operand" "")))
11503 (clobber (reg:CC FLAGS_REG))]
11505 && true_regnum (operands[0]) != true_regnum (operands[1])
11506 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11510 enum machine_mode mode = GET_MODE (operands[0]);
11512 if (GET_MODE_SIZE (mode) < 4)
11513 operands[0] = gen_lowpart (SImode, operands[0]);
11515 operands[1] = gen_lowpart (Pmode, operands[1]);
11516 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11518 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11519 if (Pmode != SImode)
11520 pat = gen_rtx_SUBREG (SImode, pat, 0);
11521 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11525 ;; Rare case of shifting RSP is handled by generating move and shift
11527 [(set (match_operand 0 "register_operand" "")
11528 (ashift (match_operand 1 "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])"
11536 emit_move_insn (operands[0], operands[1]);
11537 pat = gen_rtx_SET (VOIDmode, operands[0],
11538 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11539 operands[0], operands[2]));
11540 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11541 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11545 (define_insn "*ashlsi3_1_zext"
11546 [(set (match_operand:DI 0 "register_operand" "=r,r")
11547 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11548 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11549 (clobber (reg:CC FLAGS_REG))]
11550 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11552 switch (get_attr_type (insn))
11555 gcc_assert (operands[2] == const1_rtx);
11556 return "add{l}\t%k0, %k0";
11562 if (REG_P (operands[2]))
11563 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11564 else if (operands[2] == const1_rtx
11565 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11566 return "sal{l}\t%k0";
11568 return "sal{l}\t{%2, %k0|%k0, %2}";
11571 [(set (attr "type")
11572 (cond [(eq_attr "alternative" "1")
11573 (const_string "lea")
11574 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11576 (match_operand 2 "const1_operand" ""))
11577 (const_string "alu")
11579 (const_string "ishift")))
11580 (set_attr "mode" "SI")])
11582 ;; Convert lea to the lea pattern to avoid flags dependency.
11584 [(set (match_operand:DI 0 "register_operand" "")
11585 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11586 (match_operand:QI 2 "const_int_operand" ""))))
11587 (clobber (reg:CC FLAGS_REG))]
11588 "TARGET_64BIT && reload_completed
11589 && true_regnum (operands[0]) != true_regnum (operands[1])"
11590 [(set (match_dup 0) (zero_extend:DI
11591 (subreg:SI (mult:SI (match_dup 1)
11592 (match_dup 2)) 0)))]
11594 operands[1] = gen_lowpart (Pmode, operands[1]);
11595 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11598 ;; This pattern can't accept a variable shift count, since shifts by
11599 ;; zero don't affect the flags. We assume that shifts by constant
11600 ;; zero are optimized away.
11601 (define_insn "*ashlsi3_cmp"
11602 [(set (reg FLAGS_REG)
11604 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11605 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11607 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11608 (ashift:SI (match_dup 1) (match_dup 2)))]
11609 "(optimize_function_for_size_p (cfun)
11610 || !TARGET_PARTIAL_FLAG_REG_STALL
11611 || (operands[2] == const1_rtx
11613 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11614 && ix86_match_ccmode (insn, CCGOCmode)
11615 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11617 switch (get_attr_type (insn))
11620 gcc_assert (operands[2] == const1_rtx);
11621 return "add{l}\t%0, %0";
11624 if (REG_P (operands[2]))
11625 return "sal{l}\t{%b2, %0|%0, %b2}";
11626 else if (operands[2] == const1_rtx
11627 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11628 return "sal{l}\t%0";
11630 return "sal{l}\t{%2, %0|%0, %2}";
11633 [(set (attr "type")
11634 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11636 (match_operand 0 "register_operand" ""))
11637 (match_operand 2 "const1_operand" ""))
11638 (const_string "alu")
11640 (const_string "ishift")))
11641 (set_attr "mode" "SI")])
11643 (define_insn "*ashlsi3_cconly"
11644 [(set (reg FLAGS_REG)
11646 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11647 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11649 (clobber (match_scratch:SI 0 "=r"))]
11650 "(optimize_function_for_size_p (cfun)
11651 || !TARGET_PARTIAL_FLAG_REG_STALL
11652 || (operands[2] == const1_rtx
11654 || TARGET_DOUBLE_WITH_ADD)))
11655 && ix86_match_ccmode (insn, CCGOCmode)
11656 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11658 switch (get_attr_type (insn))
11661 gcc_assert (operands[2] == const1_rtx);
11662 return "add{l}\t%0, %0";
11665 if (REG_P (operands[2]))
11666 return "sal{l}\t{%b2, %0|%0, %b2}";
11667 else if (operands[2] == const1_rtx
11668 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11669 return "sal{l}\t%0";
11671 return "sal{l}\t{%2, %0|%0, %2}";
11674 [(set (attr "type")
11675 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11677 (match_operand 0 "register_operand" ""))
11678 (match_operand 2 "const1_operand" ""))
11679 (const_string "alu")
11681 (const_string "ishift")))
11682 (set_attr "mode" "SI")])
11684 (define_insn "*ashlsi3_cmp_zext"
11685 [(set (reg FLAGS_REG)
11687 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11688 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11690 (set (match_operand:DI 0 "register_operand" "=r")
11691 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11693 && (optimize_function_for_size_p (cfun)
11694 || !TARGET_PARTIAL_FLAG_REG_STALL
11695 || (operands[2] == const1_rtx
11697 || TARGET_DOUBLE_WITH_ADD)))
11698 && ix86_match_ccmode (insn, CCGOCmode)
11699 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11701 switch (get_attr_type (insn))
11704 gcc_assert (operands[2] == const1_rtx);
11705 return "add{l}\t%k0, %k0";
11708 if (REG_P (operands[2]))
11709 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11710 else if (operands[2] == const1_rtx
11711 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11712 return "sal{l}\t%k0";
11714 return "sal{l}\t{%2, %k0|%k0, %2}";
11717 [(set (attr "type")
11718 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11720 (match_operand 2 "const1_operand" ""))
11721 (const_string "alu")
11723 (const_string "ishift")))
11724 (set_attr "mode" "SI")])
11726 (define_expand "ashlhi3"
11727 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11728 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11729 (match_operand:QI 2 "nonmemory_operand" "")))]
11730 "TARGET_HIMODE_MATH"
11731 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11733 (define_insn "*ashlhi3_1_lea"
11734 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11735 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11736 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11737 (clobber (reg:CC FLAGS_REG))]
11738 "!TARGET_PARTIAL_REG_STALL
11739 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11741 switch (get_attr_type (insn))
11746 gcc_assert (operands[2] == const1_rtx);
11747 return "add{w}\t%0, %0";
11750 if (REG_P (operands[2]))
11751 return "sal{w}\t{%b2, %0|%0, %b2}";
11752 else if (operands[2] == const1_rtx
11753 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11754 return "sal{w}\t%0";
11756 return "sal{w}\t{%2, %0|%0, %2}";
11759 [(set (attr "type")
11760 (cond [(eq_attr "alternative" "1")
11761 (const_string "lea")
11762 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11764 (match_operand 0 "register_operand" ""))
11765 (match_operand 2 "const1_operand" ""))
11766 (const_string "alu")
11768 (const_string "ishift")))
11769 (set_attr "mode" "HI,SI")])
11771 (define_insn "*ashlhi3_1"
11772 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11773 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11774 (match_operand:QI 2 "nonmemory_operand" "cI")))
11775 (clobber (reg:CC FLAGS_REG))]
11776 "TARGET_PARTIAL_REG_STALL
11777 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11779 switch (get_attr_type (insn))
11782 gcc_assert (operands[2] == const1_rtx);
11783 return "add{w}\t%0, %0";
11786 if (REG_P (operands[2]))
11787 return "sal{w}\t{%b2, %0|%0, %b2}";
11788 else if (operands[2] == const1_rtx
11789 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11790 return "sal{w}\t%0";
11792 return "sal{w}\t{%2, %0|%0, %2}";
11795 [(set (attr "type")
11796 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11798 (match_operand 0 "register_operand" ""))
11799 (match_operand 2 "const1_operand" ""))
11800 (const_string "alu")
11802 (const_string "ishift")))
11803 (set_attr "mode" "HI")])
11805 ;; This pattern can't accept a variable shift count, since shifts by
11806 ;; zero don't affect the flags. We assume that shifts by constant
11807 ;; zero are optimized away.
11808 (define_insn "*ashlhi3_cmp"
11809 [(set (reg FLAGS_REG)
11811 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11812 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11814 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11815 (ashift:HI (match_dup 1) (match_dup 2)))]
11816 "(optimize_function_for_size_p (cfun)
11817 || !TARGET_PARTIAL_FLAG_REG_STALL
11818 || (operands[2] == const1_rtx
11820 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11821 && ix86_match_ccmode (insn, CCGOCmode)
11822 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11824 switch (get_attr_type (insn))
11827 gcc_assert (operands[2] == const1_rtx);
11828 return "add{w}\t%0, %0";
11831 if (REG_P (operands[2]))
11832 return "sal{w}\t{%b2, %0|%0, %b2}";
11833 else if (operands[2] == const1_rtx
11834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11835 return "sal{w}\t%0";
11837 return "sal{w}\t{%2, %0|%0, %2}";
11840 [(set (attr "type")
11841 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11843 (match_operand 0 "register_operand" ""))
11844 (match_operand 2 "const1_operand" ""))
11845 (const_string "alu")
11847 (const_string "ishift")))
11848 (set_attr "mode" "HI")])
11850 (define_insn "*ashlhi3_cconly"
11851 [(set (reg FLAGS_REG)
11853 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11854 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11856 (clobber (match_scratch:HI 0 "=r"))]
11857 "(optimize_function_for_size_p (cfun)
11858 || !TARGET_PARTIAL_FLAG_REG_STALL
11859 || (operands[2] == const1_rtx
11861 || TARGET_DOUBLE_WITH_ADD)))
11862 && ix86_match_ccmode (insn, CCGOCmode)
11863 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11865 switch (get_attr_type (insn))
11868 gcc_assert (operands[2] == const1_rtx);
11869 return "add{w}\t%0, %0";
11872 if (REG_P (operands[2]))
11873 return "sal{w}\t{%b2, %0|%0, %b2}";
11874 else if (operands[2] == const1_rtx
11875 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11876 return "sal{w}\t%0";
11878 return "sal{w}\t{%2, %0|%0, %2}";
11881 [(set (attr "type")
11882 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11884 (match_operand 0 "register_operand" ""))
11885 (match_operand 2 "const1_operand" ""))
11886 (const_string "alu")
11888 (const_string "ishift")))
11889 (set_attr "mode" "HI")])
11891 (define_expand "ashlqi3"
11892 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11893 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11894 (match_operand:QI 2 "nonmemory_operand" "")))]
11895 "TARGET_QIMODE_MATH"
11896 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11898 ;; %%% Potential partial reg stall on alternative 2. What to do?
11900 (define_insn "*ashlqi3_1_lea"
11901 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11902 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11903 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11904 (clobber (reg:CC FLAGS_REG))]
11905 "!TARGET_PARTIAL_REG_STALL
11906 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11908 switch (get_attr_type (insn))
11913 gcc_assert (operands[2] == const1_rtx);
11914 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11915 return "add{l}\t%k0, %k0";
11917 return "add{b}\t%0, %0";
11920 if (REG_P (operands[2]))
11922 if (get_attr_mode (insn) == MODE_SI)
11923 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11925 return "sal{b}\t{%b2, %0|%0, %b2}";
11927 else if (operands[2] == const1_rtx
11928 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11930 if (get_attr_mode (insn) == MODE_SI)
11931 return "sal{l}\t%0";
11933 return "sal{b}\t%0";
11937 if (get_attr_mode (insn) == MODE_SI)
11938 return "sal{l}\t{%2, %k0|%k0, %2}";
11940 return "sal{b}\t{%2, %0|%0, %2}";
11944 [(set (attr "type")
11945 (cond [(eq_attr "alternative" "2")
11946 (const_string "lea")
11947 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11949 (match_operand 0 "register_operand" ""))
11950 (match_operand 2 "const1_operand" ""))
11951 (const_string "alu")
11953 (const_string "ishift")))
11954 (set_attr "mode" "QI,SI,SI")])
11956 (define_insn "*ashlqi3_1"
11957 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11958 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11959 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11960 (clobber (reg:CC FLAGS_REG))]
11961 "TARGET_PARTIAL_REG_STALL
11962 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11964 switch (get_attr_type (insn))
11967 gcc_assert (operands[2] == const1_rtx);
11968 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11969 return "add{l}\t%k0, %k0";
11971 return "add{b}\t%0, %0";
11974 if (REG_P (operands[2]))
11976 if (get_attr_mode (insn) == MODE_SI)
11977 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11979 return "sal{b}\t{%b2, %0|%0, %b2}";
11981 else if (operands[2] == const1_rtx
11982 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11984 if (get_attr_mode (insn) == MODE_SI)
11985 return "sal{l}\t%0";
11987 return "sal{b}\t%0";
11991 if (get_attr_mode (insn) == MODE_SI)
11992 return "sal{l}\t{%2, %k0|%k0, %2}";
11994 return "sal{b}\t{%2, %0|%0, %2}";
11998 [(set (attr "type")
11999 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12001 (match_operand 0 "register_operand" ""))
12002 (match_operand 2 "const1_operand" ""))
12003 (const_string "alu")
12005 (const_string "ishift")))
12006 (set_attr "mode" "QI,SI")])
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags. We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*ashlqi3_cmp"
12012 [(set (reg FLAGS_REG)
12014 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12015 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12017 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12018 (ashift:QI (match_dup 1) (match_dup 2)))]
12019 "(optimize_function_for_size_p (cfun)
12020 || !TARGET_PARTIAL_FLAG_REG_STALL
12021 || (operands[2] == const1_rtx
12023 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12024 && ix86_match_ccmode (insn, CCGOCmode)
12025 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12027 switch (get_attr_type (insn))
12030 gcc_assert (operands[2] == const1_rtx);
12031 return "add{b}\t%0, %0";
12034 if (REG_P (operands[2]))
12035 return "sal{b}\t{%b2, %0|%0, %b2}";
12036 else if (operands[2] == const1_rtx
12037 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12038 return "sal{b}\t%0";
12040 return "sal{b}\t{%2, %0|%0, %2}";
12043 [(set (attr "type")
12044 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12046 (match_operand 0 "register_operand" ""))
12047 (match_operand 2 "const1_operand" ""))
12048 (const_string "alu")
12050 (const_string "ishift")))
12051 (set_attr "mode" "QI")])
12053 (define_insn "*ashlqi3_cconly"
12054 [(set (reg FLAGS_REG)
12056 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12057 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12059 (clobber (match_scratch:QI 0 "=q"))]
12060 "(optimize_function_for_size_p (cfun)
12061 || !TARGET_PARTIAL_FLAG_REG_STALL
12062 || (operands[2] == const1_rtx
12064 || TARGET_DOUBLE_WITH_ADD)))
12065 && ix86_match_ccmode (insn, CCGOCmode)
12066 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12068 switch (get_attr_type (insn))
12071 gcc_assert (operands[2] == const1_rtx);
12072 return "add{b}\t%0, %0";
12075 if (REG_P (operands[2]))
12076 return "sal{b}\t{%b2, %0|%0, %b2}";
12077 else if (operands[2] == const1_rtx
12078 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12079 return "sal{b}\t%0";
12081 return "sal{b}\t{%2, %0|%0, %2}";
12084 [(set (attr "type")
12085 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12087 (match_operand 0 "register_operand" ""))
12088 (match_operand 2 "const1_operand" ""))
12089 (const_string "alu")
12091 (const_string "ishift")))
12092 (set_attr "mode" "QI")])
12094 ;; See comment above `ashldi3' about how this works.
12096 (define_expand "ashrti3"
12097 [(set (match_operand:TI 0 "register_operand" "")
12098 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12099 (match_operand:QI 2 "nonmemory_operand" "")))]
12101 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12103 (define_insn "*ashrti3_1"
12104 [(set (match_operand:TI 0 "register_operand" "=r")
12105 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12106 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12107 (clobber (reg:CC FLAGS_REG))]
12110 [(set_attr "type" "multi")])
12113 [(match_scratch:DI 3 "r")
12114 (parallel [(set (match_operand:TI 0 "register_operand" "")
12115 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12116 (match_operand:QI 2 "nonmemory_operand" "")))
12117 (clobber (reg:CC FLAGS_REG))])
12121 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12124 [(set (match_operand:TI 0 "register_operand" "")
12125 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12126 (match_operand:QI 2 "nonmemory_operand" "")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12129 ? epilogue_completed : reload_completed)"
12131 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12133 (define_insn "x86_64_shrd"
12134 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12135 (ior:DI (ashiftrt:DI (match_dup 0)
12136 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12137 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12138 (minus:QI (const_int 64) (match_dup 2)))))
12139 (clobber (reg:CC FLAGS_REG))]
12141 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12142 [(set_attr "type" "ishift")
12143 (set_attr "prefix_0f" "1")
12144 (set_attr "mode" "DI")
12145 (set_attr "athlon_decode" "vector")
12146 (set_attr "amdfam10_decode" "vector")])
12148 (define_expand "ashrdi3"
12149 [(set (match_operand:DI 0 "shiftdi_operand" "")
12150 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12151 (match_operand:QI 2 "nonmemory_operand" "")))]
12153 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12155 (define_expand "x86_64_shift_adj_3"
12156 [(use (match_operand:DI 0 "register_operand" ""))
12157 (use (match_operand:DI 1 "register_operand" ""))
12158 (use (match_operand:QI 2 "register_operand" ""))]
12161 rtx label = gen_label_rtx ();
12164 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12166 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12167 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12168 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12169 gen_rtx_LABEL_REF (VOIDmode, label),
12171 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12172 JUMP_LABEL (tmp) = label;
12174 emit_move_insn (operands[0], operands[1]);
12175 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12177 emit_label (label);
12178 LABEL_NUSES (label) = 1;
12183 (define_insn "ashrdi3_63_rex64"
12184 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12185 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12186 (match_operand:DI 2 "const_int_operand" "i,i")))
12187 (clobber (reg:CC FLAGS_REG))]
12188 "TARGET_64BIT && INTVAL (operands[2]) == 63
12189 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12190 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12193 sar{q}\t{%2, %0|%0, %2}"
12194 [(set_attr "type" "imovx,ishift")
12195 (set_attr "prefix_0f" "0,*")
12196 (set_attr "length_immediate" "0,*")
12197 (set_attr "modrm" "0,1")
12198 (set_attr "mode" "DI")])
12200 (define_insn "*ashrdi3_1_one_bit_rex64"
12201 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12202 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12203 (match_operand:QI 2 "const1_operand" "")))
12204 (clobber (reg:CC FLAGS_REG))]
12206 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12207 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12209 [(set_attr "type" "ishift")
12210 (set (attr "length")
12211 (if_then_else (match_operand:DI 0 "register_operand" "")
12213 (const_string "*")))])
12215 (define_insn "*ashrdi3_1_rex64"
12216 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12217 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12218 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12219 (clobber (reg:CC FLAGS_REG))]
12220 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12222 sar{q}\t{%2, %0|%0, %2}
12223 sar{q}\t{%b2, %0|%0, %b2}"
12224 [(set_attr "type" "ishift")
12225 (set_attr "mode" "DI")])
12227 ;; This pattern can't accept a variable shift count, since shifts by
12228 ;; zero don't affect the flags. We assume that shifts by constant
12229 ;; zero are optimized away.
12230 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12231 [(set (reg FLAGS_REG)
12233 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const1_operand" ""))
12236 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12237 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12239 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12240 && ix86_match_ccmode (insn, CCGOCmode)
12241 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12243 [(set_attr "type" "ishift")
12244 (set (attr "length")
12245 (if_then_else (match_operand:DI 0 "register_operand" "")
12247 (const_string "*")))])
12249 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12250 [(set (reg FLAGS_REG)
12252 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12253 (match_operand:QI 2 "const1_operand" ""))
12255 (clobber (match_scratch:DI 0 "=r"))]
12257 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12258 && ix86_match_ccmode (insn, CCGOCmode)
12259 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12261 [(set_attr "type" "ishift")
12262 (set_attr "length" "2")])
12264 ;; This pattern can't accept a variable shift count, since shifts by
12265 ;; zero don't affect the flags. We assume that shifts by constant
12266 ;; zero are optimized away.
12267 (define_insn "*ashrdi3_cmp_rex64"
12268 [(set (reg FLAGS_REG)
12270 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12271 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12273 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12274 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12276 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12277 && ix86_match_ccmode (insn, CCGOCmode)
12278 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12279 "sar{q}\t{%2, %0|%0, %2}"
12280 [(set_attr "type" "ishift")
12281 (set_attr "mode" "DI")])
12283 (define_insn "*ashrdi3_cconly_rex64"
12284 [(set (reg FLAGS_REG)
12286 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12287 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12289 (clobber (match_scratch:DI 0 "=r"))]
12291 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12292 && ix86_match_ccmode (insn, CCGOCmode)
12293 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12294 "sar{q}\t{%2, %0|%0, %2}"
12295 [(set_attr "type" "ishift")
12296 (set_attr "mode" "DI")])
12298 (define_insn "*ashrdi3_1"
12299 [(set (match_operand:DI 0 "register_operand" "=r")
12300 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12301 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12302 (clobber (reg:CC FLAGS_REG))]
12305 [(set_attr "type" "multi")])
12307 ;; By default we don't ask for a scratch register, because when DImode
12308 ;; values are manipulated, registers are already at a premium. But if
12309 ;; we have one handy, we won't turn it away.
12311 [(match_scratch:SI 3 "r")
12312 (parallel [(set (match_operand:DI 0 "register_operand" "")
12313 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12314 (match_operand:QI 2 "nonmemory_operand" "")))
12315 (clobber (reg:CC FLAGS_REG))])
12317 "!TARGET_64BIT && TARGET_CMOVE"
12319 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12322 [(set (match_operand:DI 0 "register_operand" "")
12323 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12324 (match_operand:QI 2 "nonmemory_operand" "")))
12325 (clobber (reg:CC FLAGS_REG))]
12326 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12327 ? epilogue_completed : reload_completed)"
12329 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12331 (define_insn "x86_shrd"
12332 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12333 (ior:SI (ashiftrt:SI (match_dup 0)
12334 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12335 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12336 (minus:QI (const_int 32) (match_dup 2)))))
12337 (clobber (reg:CC FLAGS_REG))]
12339 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12340 [(set_attr "type" "ishift")
12341 (set_attr "prefix_0f" "1")
12342 (set_attr "pent_pair" "np")
12343 (set_attr "mode" "SI")])
12345 (define_expand "x86_shift_adj_3"
12346 [(use (match_operand:SI 0 "register_operand" ""))
12347 (use (match_operand:SI 1 "register_operand" ""))
12348 (use (match_operand:QI 2 "register_operand" ""))]
12351 rtx label = gen_label_rtx ();
12354 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12356 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12357 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12358 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12359 gen_rtx_LABEL_REF (VOIDmode, label),
12361 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12362 JUMP_LABEL (tmp) = label;
12364 emit_move_insn (operands[0], operands[1]);
12365 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12367 emit_label (label);
12368 LABEL_NUSES (label) = 1;
12373 (define_expand "ashrsi3_31"
12374 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12375 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12376 (match_operand:SI 2 "const_int_operand" "i,i")))
12377 (clobber (reg:CC FLAGS_REG))])]
12380 (define_insn "*ashrsi3_31"
12381 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12382 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12383 (match_operand:SI 2 "const_int_operand" "i,i")))
12384 (clobber (reg:CC FLAGS_REG))]
12385 "INTVAL (operands[2]) == 31
12386 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12387 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12390 sar{l}\t{%2, %0|%0, %2}"
12391 [(set_attr "type" "imovx,ishift")
12392 (set_attr "prefix_0f" "0,*")
12393 (set_attr "length_immediate" "0,*")
12394 (set_attr "modrm" "0,1")
12395 (set_attr "mode" "SI")])
12397 (define_insn "*ashrsi3_31_zext"
12398 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12399 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12400 (match_operand:SI 2 "const_int_operand" "i,i"))))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12403 && INTVAL (operands[2]) == 31
12404 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12407 sar{l}\t{%2, %k0|%k0, %2}"
12408 [(set_attr "type" "imovx,ishift")
12409 (set_attr "prefix_0f" "0,*")
12410 (set_attr "length_immediate" "0,*")
12411 (set_attr "modrm" "0,1")
12412 (set_attr "mode" "SI")])
12414 (define_expand "ashrsi3"
12415 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12416 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12417 (match_operand:QI 2 "nonmemory_operand" "")))]
12419 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12421 (define_insn "*ashrsi3_1_one_bit"
12422 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12423 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12424 (match_operand:QI 2 "const1_operand" "")))
12425 (clobber (reg:CC FLAGS_REG))]
12426 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12427 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12429 [(set_attr "type" "ishift")
12430 (set (attr "length")
12431 (if_then_else (match_operand:SI 0 "register_operand" "")
12433 (const_string "*")))])
12435 (define_insn "*ashrsi3_1_one_bit_zext"
12436 [(set (match_operand:DI 0 "register_operand" "=r")
12437 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12438 (match_operand:QI 2 "const1_operand" ""))))
12439 (clobber (reg:CC FLAGS_REG))]
12441 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12442 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12444 [(set_attr "type" "ishift")
12445 (set_attr "length" "2")])
12447 (define_insn "*ashrsi3_1"
12448 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12449 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12450 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12451 (clobber (reg:CC FLAGS_REG))]
12452 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12454 sar{l}\t{%2, %0|%0, %2}
12455 sar{l}\t{%b2, %0|%0, %b2}"
12456 [(set_attr "type" "ishift")
12457 (set_attr "mode" "SI")])
12459 (define_insn "*ashrsi3_1_zext"
12460 [(set (match_operand:DI 0 "register_operand" "=r,r")
12461 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12462 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12463 (clobber (reg:CC FLAGS_REG))]
12464 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12466 sar{l}\t{%2, %k0|%k0, %2}
12467 sar{l}\t{%b2, %k0|%k0, %b2}"
12468 [(set_attr "type" "ishift")
12469 (set_attr "mode" "SI")])
12471 ;; This pattern can't accept a variable shift count, since shifts by
12472 ;; zero don't affect the flags. We assume that shifts by constant
12473 ;; zero are optimized away.
12474 (define_insn "*ashrsi3_one_bit_cmp"
12475 [(set (reg FLAGS_REG)
12477 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12478 (match_operand:QI 2 "const1_operand" ""))
12480 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12481 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12482 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12483 && ix86_match_ccmode (insn, CCGOCmode)
12484 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12486 [(set_attr "type" "ishift")
12487 (set (attr "length")
12488 (if_then_else (match_operand:SI 0 "register_operand" "")
12490 (const_string "*")))])
12492 (define_insn "*ashrsi3_one_bit_cconly"
12493 [(set (reg FLAGS_REG)
12495 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12496 (match_operand:QI 2 "const1_operand" ""))
12498 (clobber (match_scratch:SI 0 "=r"))]
12499 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12500 && ix86_match_ccmode (insn, CCGOCmode)
12501 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12503 [(set_attr "type" "ishift")
12504 (set_attr "length" "2")])
12506 (define_insn "*ashrsi3_one_bit_cmp_zext"
12507 [(set (reg FLAGS_REG)
12509 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12510 (match_operand:QI 2 "const1_operand" ""))
12512 (set (match_operand:DI 0 "register_operand" "=r")
12513 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12515 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12516 && ix86_match_ccmode (insn, CCmode)
12517 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12519 [(set_attr "type" "ishift")
12520 (set_attr "length" "2")])
12522 ;; This pattern can't accept a variable shift count, since shifts by
12523 ;; zero don't affect the flags. We assume that shifts by constant
12524 ;; zero are optimized away.
12525 (define_insn "*ashrsi3_cmp"
12526 [(set (reg FLAGS_REG)
12528 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12529 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12531 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12532 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12533 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12534 && ix86_match_ccmode (insn, CCGOCmode)
12535 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12536 "sar{l}\t{%2, %0|%0, %2}"
12537 [(set_attr "type" "ishift")
12538 (set_attr "mode" "SI")])
12540 (define_insn "*ashrsi3_cconly"
12541 [(set (reg FLAGS_REG)
12543 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12544 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12546 (clobber (match_scratch:SI 0 "=r"))]
12547 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12548 && ix86_match_ccmode (insn, CCGOCmode)
12549 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12550 "sar{l}\t{%2, %0|%0, %2}"
12551 [(set_attr "type" "ishift")
12552 (set_attr "mode" "SI")])
12554 (define_insn "*ashrsi3_cmp_zext"
12555 [(set (reg FLAGS_REG)
12557 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12558 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12560 (set (match_operand:DI 0 "register_operand" "=r")
12561 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12563 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12564 && ix86_match_ccmode (insn, CCGOCmode)
12565 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12566 "sar{l}\t{%2, %k0|%k0, %2}"
12567 [(set_attr "type" "ishift")
12568 (set_attr "mode" "SI")])
12570 (define_expand "ashrhi3"
12571 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12572 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12573 (match_operand:QI 2 "nonmemory_operand" "")))]
12574 "TARGET_HIMODE_MATH"
12575 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12577 (define_insn "*ashrhi3_1_one_bit"
12578 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12579 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12580 (match_operand:QI 2 "const1_operand" "")))
12581 (clobber (reg:CC FLAGS_REG))]
12582 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12583 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12585 [(set_attr "type" "ishift")
12586 (set (attr "length")
12587 (if_then_else (match_operand 0 "register_operand" "")
12589 (const_string "*")))])
12591 (define_insn "*ashrhi3_1"
12592 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12593 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12594 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12595 (clobber (reg:CC FLAGS_REG))]
12596 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12598 sar{w}\t{%2, %0|%0, %2}
12599 sar{w}\t{%b2, %0|%0, %b2}"
12600 [(set_attr "type" "ishift")
12601 (set_attr "mode" "HI")])
12603 ;; This pattern can't accept a variable shift count, since shifts by
12604 ;; zero don't affect the flags. We assume that shifts by constant
12605 ;; zero are optimized away.
12606 (define_insn "*ashrhi3_one_bit_cmp"
12607 [(set (reg FLAGS_REG)
12609 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12610 (match_operand:QI 2 "const1_operand" ""))
12612 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12613 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12614 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12615 && ix86_match_ccmode (insn, CCGOCmode)
12616 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12618 [(set_attr "type" "ishift")
12619 (set (attr "length")
12620 (if_then_else (match_operand 0 "register_operand" "")
12622 (const_string "*")))])
12624 (define_insn "*ashrhi3_one_bit_cconly"
12625 [(set (reg FLAGS_REG)
12627 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12628 (match_operand:QI 2 "const1_operand" ""))
12630 (clobber (match_scratch:HI 0 "=r"))]
12631 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12632 && ix86_match_ccmode (insn, CCGOCmode)
12633 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12635 [(set_attr "type" "ishift")
12636 (set_attr "length" "2")])
12638 ;; This pattern can't accept a variable shift count, since shifts by
12639 ;; zero don't affect the flags. We assume that shifts by constant
12640 ;; zero are optimized away.
12641 (define_insn "*ashrhi3_cmp"
12642 [(set (reg FLAGS_REG)
12644 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12645 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12647 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12648 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12649 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12650 && ix86_match_ccmode (insn, CCGOCmode)
12651 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12652 "sar{w}\t{%2, %0|%0, %2}"
12653 [(set_attr "type" "ishift")
12654 (set_attr "mode" "HI")])
12656 (define_insn "*ashrhi3_cconly"
12657 [(set (reg FLAGS_REG)
12659 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12660 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12662 (clobber (match_scratch:HI 0 "=r"))]
12663 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12664 && ix86_match_ccmode (insn, CCGOCmode)
12665 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12666 "sar{w}\t{%2, %0|%0, %2}"
12667 [(set_attr "type" "ishift")
12668 (set_attr "mode" "HI")])
12670 (define_expand "ashrqi3"
12671 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12672 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12673 (match_operand:QI 2 "nonmemory_operand" "")))]
12674 "TARGET_QIMODE_MATH"
12675 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12677 (define_insn "*ashrqi3_1_one_bit"
12678 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12679 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12680 (match_operand:QI 2 "const1_operand" "")))
12681 (clobber (reg:CC FLAGS_REG))]
12682 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12683 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12685 [(set_attr "type" "ishift")
12686 (set (attr "length")
12687 (if_then_else (match_operand 0 "register_operand" "")
12689 (const_string "*")))])
12691 (define_insn "*ashrqi3_1_one_bit_slp"
12692 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12693 (ashiftrt:QI (match_dup 0)
12694 (match_operand:QI 1 "const1_operand" "")))
12695 (clobber (reg:CC FLAGS_REG))]
12696 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12697 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12698 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12700 [(set_attr "type" "ishift1")
12701 (set (attr "length")
12702 (if_then_else (match_operand 0 "register_operand" "")
12704 (const_string "*")))])
12706 (define_insn "*ashrqi3_1"
12707 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12708 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12709 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12713 sar{b}\t{%2, %0|%0, %2}
12714 sar{b}\t{%b2, %0|%0, %b2}"
12715 [(set_attr "type" "ishift")
12716 (set_attr "mode" "QI")])
12718 (define_insn "*ashrqi3_1_slp"
12719 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12720 (ashiftrt:QI (match_dup 0)
12721 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12722 (clobber (reg:CC FLAGS_REG))]
12723 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12724 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12726 sar{b}\t{%1, %0|%0, %1}
12727 sar{b}\t{%b1, %0|%0, %b1}"
12728 [(set_attr "type" "ishift1")
12729 (set_attr "mode" "QI")])
12731 ;; This pattern can't accept a variable shift count, since shifts by
12732 ;; zero don't affect the flags. We assume that shifts by constant
12733 ;; zero are optimized away.
12734 (define_insn "*ashrqi3_one_bit_cmp"
12735 [(set (reg FLAGS_REG)
12737 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12738 (match_operand:QI 2 "const1_operand" "I"))
12740 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12741 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12742 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12743 && ix86_match_ccmode (insn, CCGOCmode)
12744 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12746 [(set_attr "type" "ishift")
12747 (set (attr "length")
12748 (if_then_else (match_operand 0 "register_operand" "")
12750 (const_string "*")))])
12752 (define_insn "*ashrqi3_one_bit_cconly"
12753 [(set (reg FLAGS_REG)
12755 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12756 (match_operand:QI 2 "const1_operand" ""))
12758 (clobber (match_scratch:QI 0 "=q"))]
12759 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12760 && ix86_match_ccmode (insn, CCGOCmode)
12761 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12763 [(set_attr "type" "ishift")
12764 (set_attr "length" "2")])
12766 ;; This pattern can't accept a variable shift count, since shifts by
12767 ;; zero don't affect the flags. We assume that shifts by constant
12768 ;; zero are optimized away.
12769 (define_insn "*ashrqi3_cmp"
12770 [(set (reg FLAGS_REG)
12772 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12773 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12775 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12776 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12777 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12778 && ix86_match_ccmode (insn, CCGOCmode)
12779 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12780 "sar{b}\t{%2, %0|%0, %2}"
12781 [(set_attr "type" "ishift")
12782 (set_attr "mode" "QI")])
12784 (define_insn "*ashrqi3_cconly"
12785 [(set (reg FLAGS_REG)
12787 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12788 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12790 (clobber (match_scratch:QI 0 "=q"))]
12791 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12792 && ix86_match_ccmode (insn, CCGOCmode)
12793 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12794 "sar{b}\t{%2, %0|%0, %2}"
12795 [(set_attr "type" "ishift")
12796 (set_attr "mode" "QI")])
12799 ;; Logical shift instructions
12801 ;; See comment above `ashldi3' about how this works.
12803 (define_expand "lshrti3"
12804 [(set (match_operand:TI 0 "register_operand" "")
12805 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12806 (match_operand:QI 2 "nonmemory_operand" "")))]
12808 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12810 ;; This pattern must be defined before *lshrti3_1 to prevent
12811 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12813 (define_insn "*avx_lshrti3"
12814 [(set (match_operand:TI 0 "register_operand" "=x")
12815 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12816 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12819 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12820 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12822 [(set_attr "type" "sseishft")
12823 (set_attr "prefix" "vex")
12824 (set_attr "mode" "TI")])
12826 (define_insn "sse2_lshrti3"
12827 [(set (match_operand:TI 0 "register_operand" "=x")
12828 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12829 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12832 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12833 return "psrldq\t{%2, %0|%0, %2}";
12835 [(set_attr "type" "sseishft")
12836 (set_attr "prefix_data16" "1")
12837 (set_attr "mode" "TI")])
12839 (define_insn "*lshrti3_1"
12840 [(set (match_operand:TI 0 "register_operand" "=r")
12841 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12842 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12843 (clobber (reg:CC FLAGS_REG))]
12846 [(set_attr "type" "multi")])
12849 [(match_scratch:DI 3 "r")
12850 (parallel [(set (match_operand:TI 0 "register_operand" "")
12851 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12852 (match_operand:QI 2 "nonmemory_operand" "")))
12853 (clobber (reg:CC FLAGS_REG))])
12857 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12860 [(set (match_operand:TI 0 "register_operand" "")
12861 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12862 (match_operand:QI 2 "nonmemory_operand" "")))
12863 (clobber (reg:CC FLAGS_REG))]
12864 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12865 ? epilogue_completed : reload_completed)"
12867 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12869 (define_expand "lshrdi3"
12870 [(set (match_operand:DI 0 "shiftdi_operand" "")
12871 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12872 (match_operand:QI 2 "nonmemory_operand" "")))]
12874 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12876 (define_insn "*lshrdi3_1_one_bit_rex64"
12877 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12878 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12879 (match_operand:QI 2 "const1_operand" "")))
12880 (clobber (reg:CC FLAGS_REG))]
12882 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12883 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12885 [(set_attr "type" "ishift")
12886 (set (attr "length")
12887 (if_then_else (match_operand:DI 0 "register_operand" "")
12889 (const_string "*")))])
12891 (define_insn "*lshrdi3_1_rex64"
12892 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12893 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12894 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12895 (clobber (reg:CC FLAGS_REG))]
12896 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12898 shr{q}\t{%2, %0|%0, %2}
12899 shr{q}\t{%b2, %0|%0, %b2}"
12900 [(set_attr "type" "ishift")
12901 (set_attr "mode" "DI")])
12903 ;; This pattern can't accept a variable shift count, since shifts by
12904 ;; zero don't affect the flags. We assume that shifts by constant
12905 ;; zero are optimized away.
12906 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12907 [(set (reg FLAGS_REG)
12909 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12910 (match_operand:QI 2 "const1_operand" ""))
12912 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12913 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12915 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12916 && ix86_match_ccmode (insn, CCGOCmode)
12917 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12919 [(set_attr "type" "ishift")
12920 (set (attr "length")
12921 (if_then_else (match_operand:DI 0 "register_operand" "")
12923 (const_string "*")))])
12925 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12926 [(set (reg FLAGS_REG)
12928 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12929 (match_operand:QI 2 "const1_operand" ""))
12931 (clobber (match_scratch:DI 0 "=r"))]
12933 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12934 && ix86_match_ccmode (insn, CCGOCmode)
12935 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12937 [(set_attr "type" "ishift")
12938 (set_attr "length" "2")])
12940 ;; This pattern can't accept a variable shift count, since shifts by
12941 ;; zero don't affect the flags. We assume that shifts by constant
12942 ;; zero are optimized away.
12943 (define_insn "*lshrdi3_cmp_rex64"
12944 [(set (reg FLAGS_REG)
12946 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12947 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12949 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12950 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12952 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12953 && ix86_match_ccmode (insn, CCGOCmode)
12954 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12955 "shr{q}\t{%2, %0|%0, %2}"
12956 [(set_attr "type" "ishift")
12957 (set_attr "mode" "DI")])
12959 (define_insn "*lshrdi3_cconly_rex64"
12960 [(set (reg FLAGS_REG)
12962 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12963 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12965 (clobber (match_scratch:DI 0 "=r"))]
12967 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12968 && ix86_match_ccmode (insn, CCGOCmode)
12969 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12970 "shr{q}\t{%2, %0|%0, %2}"
12971 [(set_attr "type" "ishift")
12972 (set_attr "mode" "DI")])
12974 (define_insn "*lshrdi3_1"
12975 [(set (match_operand:DI 0 "register_operand" "=r")
12976 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12977 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12978 (clobber (reg:CC FLAGS_REG))]
12981 [(set_attr "type" "multi")])
12983 ;; By default we don't ask for a scratch register, because when DImode
12984 ;; values are manipulated, registers are already at a premium. But if
12985 ;; we have one handy, we won't turn it away.
12987 [(match_scratch:SI 3 "r")
12988 (parallel [(set (match_operand:DI 0 "register_operand" "")
12989 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12990 (match_operand:QI 2 "nonmemory_operand" "")))
12991 (clobber (reg:CC FLAGS_REG))])
12993 "!TARGET_64BIT && TARGET_CMOVE"
12995 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12998 [(set (match_operand:DI 0 "register_operand" "")
12999 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13000 (match_operand:QI 2 "nonmemory_operand" "")))
13001 (clobber (reg:CC FLAGS_REG))]
13002 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13003 ? epilogue_completed : reload_completed)"
13005 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13007 (define_expand "lshrsi3"
13008 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13009 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13010 (match_operand:QI 2 "nonmemory_operand" "")))]
13012 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13014 (define_insn "*lshrsi3_1_one_bit"
13015 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13016 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13017 (match_operand:QI 2 "const1_operand" "")))
13018 (clobber (reg:CC FLAGS_REG))]
13019 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13020 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13022 [(set_attr "type" "ishift")
13023 (set (attr "length")
13024 (if_then_else (match_operand:SI 0 "register_operand" "")
13026 (const_string "*")))])
13028 (define_insn "*lshrsi3_1_one_bit_zext"
13029 [(set (match_operand:DI 0 "register_operand" "=r")
13030 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13031 (match_operand:QI 2 "const1_operand" "")))
13032 (clobber (reg:CC FLAGS_REG))]
13034 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13035 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13037 [(set_attr "type" "ishift")
13038 (set_attr "length" "2")])
13040 (define_insn "*lshrsi3_1"
13041 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13042 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13043 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13044 (clobber (reg:CC FLAGS_REG))]
13045 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13047 shr{l}\t{%2, %0|%0, %2}
13048 shr{l}\t{%b2, %0|%0, %b2}"
13049 [(set_attr "type" "ishift")
13050 (set_attr "mode" "SI")])
13052 (define_insn "*lshrsi3_1_zext"
13053 [(set (match_operand:DI 0 "register_operand" "=r,r")
13055 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13056 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13057 (clobber (reg:CC FLAGS_REG))]
13058 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060 shr{l}\t{%2, %k0|%k0, %2}
13061 shr{l}\t{%b2, %k0|%k0, %b2}"
13062 [(set_attr "type" "ishift")
13063 (set_attr "mode" "SI")])
13065 ;; This pattern can't accept a variable shift count, since shifts by
13066 ;; zero don't affect the flags. We assume that shifts by constant
13067 ;; zero are optimized away.
13068 (define_insn "*lshrsi3_one_bit_cmp"
13069 [(set (reg FLAGS_REG)
13071 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13072 (match_operand:QI 2 "const1_operand" ""))
13074 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13075 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13076 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13077 && ix86_match_ccmode (insn, CCGOCmode)
13078 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13080 [(set_attr "type" "ishift")
13081 (set (attr "length")
13082 (if_then_else (match_operand:SI 0 "register_operand" "")
13084 (const_string "*")))])
13086 (define_insn "*lshrsi3_one_bit_cconly"
13087 [(set (reg FLAGS_REG)
13089 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13090 (match_operand:QI 2 "const1_operand" ""))
13092 (clobber (match_scratch:SI 0 "=r"))]
13093 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13094 && ix86_match_ccmode (insn, CCGOCmode)
13095 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13097 [(set_attr "type" "ishift")
13098 (set_attr "length" "2")])
13100 (define_insn "*lshrsi3_cmp_one_bit_zext"
13101 [(set (reg FLAGS_REG)
13103 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13104 (match_operand:QI 2 "const1_operand" ""))
13106 (set (match_operand:DI 0 "register_operand" "=r")
13107 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13109 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13110 && ix86_match_ccmode (insn, CCGOCmode)
13111 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13113 [(set_attr "type" "ishift")
13114 (set_attr "length" "2")])
13116 ;; This pattern can't accept a variable shift count, since shifts by
13117 ;; zero don't affect the flags. We assume that shifts by constant
13118 ;; zero are optimized away.
13119 (define_insn "*lshrsi3_cmp"
13120 [(set (reg FLAGS_REG)
13122 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13123 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13125 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13126 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13127 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13128 && ix86_match_ccmode (insn, CCGOCmode)
13129 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13130 "shr{l}\t{%2, %0|%0, %2}"
13131 [(set_attr "type" "ishift")
13132 (set_attr "mode" "SI")])
13134 (define_insn "*lshrsi3_cconly"
13135 [(set (reg FLAGS_REG)
13137 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13138 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13140 (clobber (match_scratch:SI 0 "=r"))]
13141 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13142 && ix86_match_ccmode (insn, CCGOCmode)
13143 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13144 "shr{l}\t{%2, %0|%0, %2}"
13145 [(set_attr "type" "ishift")
13146 (set_attr "mode" "SI")])
13148 (define_insn "*lshrsi3_cmp_zext"
13149 [(set (reg FLAGS_REG)
13151 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13152 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13154 (set (match_operand:DI 0 "register_operand" "=r")
13155 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13157 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13158 && ix86_match_ccmode (insn, CCGOCmode)
13159 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13160 "shr{l}\t{%2, %k0|%k0, %2}"
13161 [(set_attr "type" "ishift")
13162 (set_attr "mode" "SI")])
13164 (define_expand "lshrhi3"
13165 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13166 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13167 (match_operand:QI 2 "nonmemory_operand" "")))]
13168 "TARGET_HIMODE_MATH"
13169 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13171 (define_insn "*lshrhi3_1_one_bit"
13172 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13173 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13174 (match_operand:QI 2 "const1_operand" "")))
13175 (clobber (reg:CC FLAGS_REG))]
13176 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13177 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13179 [(set_attr "type" "ishift")
13180 (set (attr "length")
13181 (if_then_else (match_operand 0 "register_operand" "")
13183 (const_string "*")))])
13185 (define_insn "*lshrhi3_1"
13186 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13187 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13188 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13189 (clobber (reg:CC FLAGS_REG))]
13190 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13192 shr{w}\t{%2, %0|%0, %2}
13193 shr{w}\t{%b2, %0|%0, %b2}"
13194 [(set_attr "type" "ishift")
13195 (set_attr "mode" "HI")])
13197 ;; This pattern can't accept a variable shift count, since shifts by
13198 ;; zero don't affect the flags. We assume that shifts by constant
13199 ;; zero are optimized away.
13200 (define_insn "*lshrhi3_one_bit_cmp"
13201 [(set (reg FLAGS_REG)
13203 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13204 (match_operand:QI 2 "const1_operand" ""))
13206 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13207 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13208 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13209 && ix86_match_ccmode (insn, CCGOCmode)
13210 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13212 [(set_attr "type" "ishift")
13213 (set (attr "length")
13214 (if_then_else (match_operand:SI 0 "register_operand" "")
13216 (const_string "*")))])
13218 (define_insn "*lshrhi3_one_bit_cconly"
13219 [(set (reg FLAGS_REG)
13221 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13222 (match_operand:QI 2 "const1_operand" ""))
13224 (clobber (match_scratch:HI 0 "=r"))]
13225 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13226 && ix86_match_ccmode (insn, CCGOCmode)
13227 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13229 [(set_attr "type" "ishift")
13230 (set_attr "length" "2")])
13232 ;; This pattern can't accept a variable shift count, since shifts by
13233 ;; zero don't affect the flags. We assume that shifts by constant
13234 ;; zero are optimized away.
13235 (define_insn "*lshrhi3_cmp"
13236 [(set (reg FLAGS_REG)
13238 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13239 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13241 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13242 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13243 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13244 && ix86_match_ccmode (insn, CCGOCmode)
13245 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13246 "shr{w}\t{%2, %0|%0, %2}"
13247 [(set_attr "type" "ishift")
13248 (set_attr "mode" "HI")])
13250 (define_insn "*lshrhi3_cconly"
13251 [(set (reg FLAGS_REG)
13253 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13254 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13256 (clobber (match_scratch:HI 0 "=r"))]
13257 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13258 && ix86_match_ccmode (insn, CCGOCmode)
13259 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13260 "shr{w}\t{%2, %0|%0, %2}"
13261 [(set_attr "type" "ishift")
13262 (set_attr "mode" "HI")])
13264 (define_expand "lshrqi3"
13265 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13266 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13267 (match_operand:QI 2 "nonmemory_operand" "")))]
13268 "TARGET_QIMODE_MATH"
13269 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13271 (define_insn "*lshrqi3_1_one_bit"
13272 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13273 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13274 (match_operand:QI 2 "const1_operand" "")))
13275 (clobber (reg:CC FLAGS_REG))]
13276 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13277 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13279 [(set_attr "type" "ishift")
13280 (set (attr "length")
13281 (if_then_else (match_operand 0 "register_operand" "")
13283 (const_string "*")))])
13285 (define_insn "*lshrqi3_1_one_bit_slp"
13286 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13287 (lshiftrt:QI (match_dup 0)
13288 (match_operand:QI 1 "const1_operand" "")))
13289 (clobber (reg:CC FLAGS_REG))]
13290 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13293 [(set_attr "type" "ishift1")
13294 (set (attr "length")
13295 (if_then_else (match_operand 0 "register_operand" "")
13297 (const_string "*")))])
13299 (define_insn "*lshrqi3_1"
13300 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13301 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13302 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13303 (clobber (reg:CC FLAGS_REG))]
13304 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13306 shr{b}\t{%2, %0|%0, %2}
13307 shr{b}\t{%b2, %0|%0, %b2}"
13308 [(set_attr "type" "ishift")
13309 (set_attr "mode" "QI")])
13311 (define_insn "*lshrqi3_1_slp"
13312 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13313 (lshiftrt:QI (match_dup 0)
13314 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13315 (clobber (reg:CC FLAGS_REG))]
13316 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13317 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13319 shr{b}\t{%1, %0|%0, %1}
13320 shr{b}\t{%b1, %0|%0, %b1}"
13321 [(set_attr "type" "ishift1")
13322 (set_attr "mode" "QI")])
13324 ;; This pattern can't accept a variable shift count, since shifts by
13325 ;; zero don't affect the flags. We assume that shifts by constant
13326 ;; zero are optimized away.
13327 (define_insn "*lshrqi2_one_bit_cmp"
13328 [(set (reg FLAGS_REG)
13330 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13331 (match_operand:QI 2 "const1_operand" ""))
13333 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13334 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13335 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13336 && ix86_match_ccmode (insn, CCGOCmode)
13337 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13339 [(set_attr "type" "ishift")
13340 (set (attr "length")
13341 (if_then_else (match_operand:SI 0 "register_operand" "")
13343 (const_string "*")))])
13345 (define_insn "*lshrqi2_one_bit_cconly"
13346 [(set (reg FLAGS_REG)
13348 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13349 (match_operand:QI 2 "const1_operand" ""))
13351 (clobber (match_scratch:QI 0 "=q"))]
13352 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13353 && ix86_match_ccmode (insn, CCGOCmode)
13354 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13356 [(set_attr "type" "ishift")
13357 (set_attr "length" "2")])
13359 ;; This pattern can't accept a variable shift count, since shifts by
13360 ;; zero don't affect the flags. We assume that shifts by constant
13361 ;; zero are optimized away.
13362 (define_insn "*lshrqi2_cmp"
13363 [(set (reg FLAGS_REG)
13365 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13366 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13368 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13369 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13370 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13371 && ix86_match_ccmode (insn, CCGOCmode)
13372 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13373 "shr{b}\t{%2, %0|%0, %2}"
13374 [(set_attr "type" "ishift")
13375 (set_attr "mode" "QI")])
13377 (define_insn "*lshrqi2_cconly"
13378 [(set (reg FLAGS_REG)
13380 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13381 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13383 (clobber (match_scratch:QI 0 "=q"))]
13384 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13385 && ix86_match_ccmode (insn, CCGOCmode)
13386 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13387 "shr{b}\t{%2, %0|%0, %2}"
13388 [(set_attr "type" "ishift")
13389 (set_attr "mode" "QI")])
13391 ;; Rotate instructions
13393 (define_expand "rotldi3"
13394 [(set (match_operand:DI 0 "shiftdi_operand" "")
13395 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13396 (match_operand:QI 2 "nonmemory_operand" "")))]
13401 ix86_expand_binary_operator (ROTATE, DImode, operands);
13404 if (!const_1_to_31_operand (operands[2], VOIDmode))
13406 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13410 ;; Implement rotation using two double-precision shift instructions
13411 ;; and a scratch register.
13412 (define_insn_and_split "ix86_rotldi3"
13413 [(set (match_operand:DI 0 "register_operand" "=r")
13414 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13415 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13416 (clobber (reg:CC FLAGS_REG))
13417 (clobber (match_scratch:SI 3 "=&r"))]
13420 "&& reload_completed"
13421 [(set (match_dup 3) (match_dup 4))
13423 [(set (match_dup 4)
13424 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13425 (lshiftrt:SI (match_dup 5)
13426 (minus:QI (const_int 32) (match_dup 2)))))
13427 (clobber (reg:CC FLAGS_REG))])
13429 [(set (match_dup 5)
13430 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13431 (lshiftrt:SI (match_dup 3)
13432 (minus:QI (const_int 32) (match_dup 2)))))
13433 (clobber (reg:CC FLAGS_REG))])]
13434 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13436 (define_insn "*rotlsi3_1_one_bit_rex64"
13437 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13438 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13439 (match_operand:QI 2 "const1_operand" "")))
13440 (clobber (reg:CC FLAGS_REG))]
13442 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13443 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13445 [(set_attr "type" "rotate")
13446 (set (attr "length")
13447 (if_then_else (match_operand:DI 0 "register_operand" "")
13449 (const_string "*")))])
13451 (define_insn "*rotldi3_1_rex64"
13452 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13453 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13454 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13455 (clobber (reg:CC FLAGS_REG))]
13456 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13458 rol{q}\t{%2, %0|%0, %2}
13459 rol{q}\t{%b2, %0|%0, %b2}"
13460 [(set_attr "type" "rotate")
13461 (set_attr "mode" "DI")])
13463 (define_expand "rotlsi3"
13464 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13465 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13466 (match_operand:QI 2 "nonmemory_operand" "")))]
13468 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13470 (define_insn "*rotlsi3_1_one_bit"
13471 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13472 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13473 (match_operand:QI 2 "const1_operand" "")))
13474 (clobber (reg:CC FLAGS_REG))]
13475 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13476 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13478 [(set_attr "type" "rotate")
13479 (set (attr "length")
13480 (if_then_else (match_operand:SI 0 "register_operand" "")
13482 (const_string "*")))])
13484 (define_insn "*rotlsi3_1_one_bit_zext"
13485 [(set (match_operand:DI 0 "register_operand" "=r")
13487 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13488 (match_operand:QI 2 "const1_operand" ""))))
13489 (clobber (reg:CC FLAGS_REG))]
13491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13492 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13494 [(set_attr "type" "rotate")
13495 (set_attr "length" "2")])
13497 (define_insn "*rotlsi3_1"
13498 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13499 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13500 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13501 (clobber (reg:CC FLAGS_REG))]
13502 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13504 rol{l}\t{%2, %0|%0, %2}
13505 rol{l}\t{%b2, %0|%0, %b2}"
13506 [(set_attr "type" "rotate")
13507 (set_attr "mode" "SI")])
13509 (define_insn "*rotlsi3_1_zext"
13510 [(set (match_operand:DI 0 "register_operand" "=r,r")
13512 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13513 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13514 (clobber (reg:CC FLAGS_REG))]
13515 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13517 rol{l}\t{%2, %k0|%k0, %2}
13518 rol{l}\t{%b2, %k0|%k0, %b2}"
13519 [(set_attr "type" "rotate")
13520 (set_attr "mode" "SI")])
13522 (define_expand "rotlhi3"
13523 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13524 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13525 (match_operand:QI 2 "nonmemory_operand" "")))]
13526 "TARGET_HIMODE_MATH"
13527 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13529 (define_insn "*rotlhi3_1_one_bit"
13530 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13531 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13532 (match_operand:QI 2 "const1_operand" "")))
13533 (clobber (reg:CC FLAGS_REG))]
13534 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13535 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13537 [(set_attr "type" "rotate")
13538 (set (attr "length")
13539 (if_then_else (match_operand 0 "register_operand" "")
13541 (const_string "*")))])
13543 (define_insn "*rotlhi3_1"
13544 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13545 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13546 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13547 (clobber (reg:CC FLAGS_REG))]
13548 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13550 rol{w}\t{%2, %0|%0, %2}
13551 rol{w}\t{%b2, %0|%0, %b2}"
13552 [(set_attr "type" "rotate")
13553 (set_attr "mode" "HI")])
13556 [(set (match_operand:HI 0 "register_operand" "")
13557 (rotate:HI (match_dup 0) (const_int 8)))
13558 (clobber (reg:CC FLAGS_REG))]
13560 [(parallel [(set (strict_low_part (match_dup 0))
13561 (bswap:HI (match_dup 0)))
13562 (clobber (reg:CC FLAGS_REG))])]
13565 (define_expand "rotlqi3"
13566 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13567 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13568 (match_operand:QI 2 "nonmemory_operand" "")))]
13569 "TARGET_QIMODE_MATH"
13570 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13572 (define_insn "*rotlqi3_1_one_bit_slp"
13573 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13574 (rotate:QI (match_dup 0)
13575 (match_operand:QI 1 "const1_operand" "")))
13576 (clobber (reg:CC FLAGS_REG))]
13577 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13578 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13580 [(set_attr "type" "rotate1")
13581 (set (attr "length")
13582 (if_then_else (match_operand 0 "register_operand" "")
13584 (const_string "*")))])
13586 (define_insn "*rotlqi3_1_one_bit"
13587 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13588 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13589 (match_operand:QI 2 "const1_operand" "")))
13590 (clobber (reg:CC FLAGS_REG))]
13591 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13592 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13594 [(set_attr "type" "rotate")
13595 (set (attr "length")
13596 (if_then_else (match_operand 0 "register_operand" "")
13598 (const_string "*")))])
13600 (define_insn "*rotlqi3_1_slp"
13601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13602 (rotate:QI (match_dup 0)
13603 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13604 (clobber (reg:CC FLAGS_REG))]
13605 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13606 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13608 rol{b}\t{%1, %0|%0, %1}
13609 rol{b}\t{%b1, %0|%0, %b1}"
13610 [(set_attr "type" "rotate1")
13611 (set_attr "mode" "QI")])
13613 (define_insn "*rotlqi3_1"
13614 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13615 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13616 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13617 (clobber (reg:CC FLAGS_REG))]
13618 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13620 rol{b}\t{%2, %0|%0, %2}
13621 rol{b}\t{%b2, %0|%0, %b2}"
13622 [(set_attr "type" "rotate")
13623 (set_attr "mode" "QI")])
13625 (define_expand "rotrdi3"
13626 [(set (match_operand:DI 0 "shiftdi_operand" "")
13627 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13628 (match_operand:QI 2 "nonmemory_operand" "")))]
13633 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13636 if (!const_1_to_31_operand (operands[2], VOIDmode))
13638 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13642 ;; Implement rotation using two double-precision shift instructions
13643 ;; and a scratch register.
13644 (define_insn_and_split "ix86_rotrdi3"
13645 [(set (match_operand:DI 0 "register_operand" "=r")
13646 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13647 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13648 (clobber (reg:CC FLAGS_REG))
13649 (clobber (match_scratch:SI 3 "=&r"))]
13652 "&& reload_completed"
13653 [(set (match_dup 3) (match_dup 4))
13655 [(set (match_dup 4)
13656 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13657 (ashift:SI (match_dup 5)
13658 (minus:QI (const_int 32) (match_dup 2)))))
13659 (clobber (reg:CC FLAGS_REG))])
13661 [(set (match_dup 5)
13662 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13663 (ashift:SI (match_dup 3)
13664 (minus:QI (const_int 32) (match_dup 2)))))
13665 (clobber (reg:CC FLAGS_REG))])]
13666 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13668 (define_insn "*rotrdi3_1_one_bit_rex64"
13669 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13670 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13671 (match_operand:QI 2 "const1_operand" "")))
13672 (clobber (reg:CC FLAGS_REG))]
13674 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13675 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13677 [(set_attr "type" "rotate")
13678 (set (attr "length")
13679 (if_then_else (match_operand:DI 0 "register_operand" "")
13681 (const_string "*")))])
13683 (define_insn "*rotrdi3_1_rex64"
13684 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13685 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13686 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13687 (clobber (reg:CC FLAGS_REG))]
13688 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13690 ror{q}\t{%2, %0|%0, %2}
13691 ror{q}\t{%b2, %0|%0, %b2}"
13692 [(set_attr "type" "rotate")
13693 (set_attr "mode" "DI")])
13695 (define_expand "rotrsi3"
13696 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13697 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13698 (match_operand:QI 2 "nonmemory_operand" "")))]
13700 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13702 (define_insn "*rotrsi3_1_one_bit"
13703 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13704 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13705 (match_operand:QI 2 "const1_operand" "")))
13706 (clobber (reg:CC FLAGS_REG))]
13707 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13708 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13710 [(set_attr "type" "rotate")
13711 (set (attr "length")
13712 (if_then_else (match_operand:SI 0 "register_operand" "")
13714 (const_string "*")))])
13716 (define_insn "*rotrsi3_1_one_bit_zext"
13717 [(set (match_operand:DI 0 "register_operand" "=r")
13719 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13720 (match_operand:QI 2 "const1_operand" ""))))
13721 (clobber (reg:CC FLAGS_REG))]
13723 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13724 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13726 [(set_attr "type" "rotate")
13727 (set (attr "length")
13728 (if_then_else (match_operand:SI 0 "register_operand" "")
13730 (const_string "*")))])
13732 (define_insn "*rotrsi3_1"
13733 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13734 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13735 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13736 (clobber (reg:CC FLAGS_REG))]
13737 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13739 ror{l}\t{%2, %0|%0, %2}
13740 ror{l}\t{%b2, %0|%0, %b2}"
13741 [(set_attr "type" "rotate")
13742 (set_attr "mode" "SI")])
13744 (define_insn "*rotrsi3_1_zext"
13745 [(set (match_operand:DI 0 "register_operand" "=r,r")
13747 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13748 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13749 (clobber (reg:CC FLAGS_REG))]
13750 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13752 ror{l}\t{%2, %k0|%k0, %2}
13753 ror{l}\t{%b2, %k0|%k0, %b2}"
13754 [(set_attr "type" "rotate")
13755 (set_attr "mode" "SI")])
13757 (define_expand "rotrhi3"
13758 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13759 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13760 (match_operand:QI 2 "nonmemory_operand" "")))]
13761 "TARGET_HIMODE_MATH"
13762 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13764 (define_insn "*rotrhi3_one_bit"
13765 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13766 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13767 (match_operand:QI 2 "const1_operand" "")))
13768 (clobber (reg:CC FLAGS_REG))]
13769 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13770 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13772 [(set_attr "type" "rotate")
13773 (set (attr "length")
13774 (if_then_else (match_operand 0 "register_operand" "")
13776 (const_string "*")))])
13778 (define_insn "*rotrhi3_1"
13779 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13780 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13781 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13782 (clobber (reg:CC FLAGS_REG))]
13783 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13785 ror{w}\t{%2, %0|%0, %2}
13786 ror{w}\t{%b2, %0|%0, %b2}"
13787 [(set_attr "type" "rotate")
13788 (set_attr "mode" "HI")])
13791 [(set (match_operand:HI 0 "register_operand" "")
13792 (rotatert:HI (match_dup 0) (const_int 8)))
13793 (clobber (reg:CC FLAGS_REG))]
13795 [(parallel [(set (strict_low_part (match_dup 0))
13796 (bswap:HI (match_dup 0)))
13797 (clobber (reg:CC FLAGS_REG))])]
13800 (define_expand "rotrqi3"
13801 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13802 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13803 (match_operand:QI 2 "nonmemory_operand" "")))]
13804 "TARGET_QIMODE_MATH"
13805 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13807 (define_insn "*rotrqi3_1_one_bit"
13808 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13809 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13810 (match_operand:QI 2 "const1_operand" "")))
13811 (clobber (reg:CC FLAGS_REG))]
13812 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13813 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13815 [(set_attr "type" "rotate")
13816 (set (attr "length")
13817 (if_then_else (match_operand 0 "register_operand" "")
13819 (const_string "*")))])
13821 (define_insn "*rotrqi3_1_one_bit_slp"
13822 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13823 (rotatert:QI (match_dup 0)
13824 (match_operand:QI 1 "const1_operand" "")))
13825 (clobber (reg:CC FLAGS_REG))]
13826 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13827 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13829 [(set_attr "type" "rotate1")
13830 (set (attr "length")
13831 (if_then_else (match_operand 0 "register_operand" "")
13833 (const_string "*")))])
13835 (define_insn "*rotrqi3_1"
13836 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13837 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13838 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13839 (clobber (reg:CC FLAGS_REG))]
13840 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13842 ror{b}\t{%2, %0|%0, %2}
13843 ror{b}\t{%b2, %0|%0, %b2}"
13844 [(set_attr "type" "rotate")
13845 (set_attr "mode" "QI")])
13847 (define_insn "*rotrqi3_1_slp"
13848 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13849 (rotatert:QI (match_dup 0)
13850 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13851 (clobber (reg:CC FLAGS_REG))]
13852 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13853 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13855 ror{b}\t{%1, %0|%0, %1}
13856 ror{b}\t{%b1, %0|%0, %b1}"
13857 [(set_attr "type" "rotate1")
13858 (set_attr "mode" "QI")])
13860 ;; Bit set / bit test instructions
13862 (define_expand "extv"
13863 [(set (match_operand:SI 0 "register_operand" "")
13864 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13865 (match_operand:SI 2 "const8_operand" "")
13866 (match_operand:SI 3 "const8_operand" "")))]
13869 /* Handle extractions from %ah et al. */
13870 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13873 /* From mips.md: extract_bit_field doesn't verify that our source
13874 matches the predicate, so check it again here. */
13875 if (! ext_register_operand (operands[1], VOIDmode))
13879 (define_expand "extzv"
13880 [(set (match_operand:SI 0 "register_operand" "")
13881 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13882 (match_operand:SI 2 "const8_operand" "")
13883 (match_operand:SI 3 "const8_operand" "")))]
13886 /* Handle extractions from %ah et al. */
13887 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13890 /* From mips.md: extract_bit_field doesn't verify that our source
13891 matches the predicate, so check it again here. */
13892 if (! ext_register_operand (operands[1], VOIDmode))
13896 (define_expand "insv"
13897 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13898 (match_operand 1 "const8_operand" "")
13899 (match_operand 2 "const8_operand" ""))
13900 (match_operand 3 "register_operand" ""))]
13903 /* Handle insertions to %ah et al. */
13904 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13907 /* From mips.md: insert_bit_field doesn't verify that our source
13908 matches the predicate, so check it again here. */
13909 if (! ext_register_operand (operands[0], VOIDmode))
13913 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13915 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13920 ;; %%% bts, btr, btc, bt.
13921 ;; In general these instructions are *slow* when applied to memory,
13922 ;; since they enforce atomic operation. When applied to registers,
13923 ;; it depends on the cpu implementation. They're never faster than
13924 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13925 ;; no point. But in 64-bit, we can't hold the relevant immediates
13926 ;; within the instruction itself, so operating on bits in the high
13927 ;; 32-bits of a register becomes easier.
13929 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13930 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13931 ;; negdf respectively, so they can never be disabled entirely.
13933 (define_insn "*btsq"
13934 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13936 (match_operand:DI 1 "const_0_to_63_operand" ""))
13938 (clobber (reg:CC FLAGS_REG))]
13939 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13940 "bts{q}\t{%1, %0|%0, %1}"
13941 [(set_attr "type" "alu1")])
13943 (define_insn "*btrq"
13944 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13946 (match_operand:DI 1 "const_0_to_63_operand" ""))
13948 (clobber (reg:CC FLAGS_REG))]
13949 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13950 "btr{q}\t{%1, %0|%0, %1}"
13951 [(set_attr "type" "alu1")])
13953 (define_insn "*btcq"
13954 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13956 (match_operand:DI 1 "const_0_to_63_operand" ""))
13957 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13958 (clobber (reg:CC FLAGS_REG))]
13959 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13960 "btc{q}\t{%1, %0|%0, %1}"
13961 [(set_attr "type" "alu1")])
13963 ;; Allow Nocona to avoid these instructions if a register is available.
13966 [(match_scratch:DI 2 "r")
13967 (parallel [(set (zero_extract:DI
13968 (match_operand:DI 0 "register_operand" "")
13970 (match_operand:DI 1 "const_0_to_63_operand" ""))
13972 (clobber (reg:CC FLAGS_REG))])]
13973 "TARGET_64BIT && !TARGET_USE_BT"
13976 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13979 if (HOST_BITS_PER_WIDE_INT >= 64)
13980 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13981 else if (i < HOST_BITS_PER_WIDE_INT)
13982 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13984 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13986 op1 = immed_double_const (lo, hi, DImode);
13989 emit_move_insn (operands[2], op1);
13993 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13998 [(match_scratch:DI 2 "r")
13999 (parallel [(set (zero_extract:DI
14000 (match_operand:DI 0 "register_operand" "")
14002 (match_operand:DI 1 "const_0_to_63_operand" ""))
14004 (clobber (reg:CC FLAGS_REG))])]
14005 "TARGET_64BIT && !TARGET_USE_BT"
14008 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14011 if (HOST_BITS_PER_WIDE_INT >= 64)
14012 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14013 else if (i < HOST_BITS_PER_WIDE_INT)
14014 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14016 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14018 op1 = immed_double_const (~lo, ~hi, DImode);
14021 emit_move_insn (operands[2], op1);
14025 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14030 [(match_scratch:DI 2 "r")
14031 (parallel [(set (zero_extract:DI
14032 (match_operand:DI 0 "register_operand" "")
14034 (match_operand:DI 1 "const_0_to_63_operand" ""))
14035 (not:DI (zero_extract:DI
14036 (match_dup 0) (const_int 1) (match_dup 1))))
14037 (clobber (reg:CC FLAGS_REG))])]
14038 "TARGET_64BIT && !TARGET_USE_BT"
14041 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14044 if (HOST_BITS_PER_WIDE_INT >= 64)
14045 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14046 else if (i < HOST_BITS_PER_WIDE_INT)
14047 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14049 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14051 op1 = immed_double_const (lo, hi, DImode);
14054 emit_move_insn (operands[2], op1);
14058 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14062 (define_insn "*btdi_rex64"
14063 [(set (reg:CCC FLAGS_REG)
14066 (match_operand:DI 0 "register_operand" "r")
14068 (match_operand:DI 1 "nonmemory_operand" "rN"))
14070 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14071 "bt{q}\t{%1, %0|%0, %1}"
14072 [(set_attr "type" "alu1")])
14074 (define_insn "*btsi"
14075 [(set (reg:CCC FLAGS_REG)
14078 (match_operand:SI 0 "register_operand" "r")
14080 (match_operand:SI 1 "nonmemory_operand" "rN"))
14082 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14083 "bt{l}\t{%1, %0|%0, %1}"
14084 [(set_attr "type" "alu1")])
14086 ;; Store-flag instructions.
14088 ;; For all sCOND expanders, also expand the compare or test insn that
14089 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14091 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14092 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14093 ;; way, which can later delete the movzx if only QImode is needed.
14095 (define_expand "s<code>"
14096 [(set (match_operand:QI 0 "register_operand" "")
14097 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14099 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14101 (define_expand "s<code>"
14102 [(set (match_operand:QI 0 "register_operand" "")
14103 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14104 "TARGET_80387 || TARGET_SSE"
14105 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14107 (define_insn "*setcc_1"
14108 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14109 (match_operator:QI 1 "ix86_comparison_operator"
14110 [(reg FLAGS_REG) (const_int 0)]))]
14113 [(set_attr "type" "setcc")
14114 (set_attr "mode" "QI")])
14116 (define_insn "*setcc_2"
14117 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14118 (match_operator:QI 1 "ix86_comparison_operator"
14119 [(reg FLAGS_REG) (const_int 0)]))]
14122 [(set_attr "type" "setcc")
14123 (set_attr "mode" "QI")])
14125 ;; In general it is not safe to assume too much about CCmode registers,
14126 ;; so simplify-rtx stops when it sees a second one. Under certain
14127 ;; conditions this is safe on x86, so help combine not create
14134 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14135 (ne:QI (match_operator 1 "ix86_comparison_operator"
14136 [(reg FLAGS_REG) (const_int 0)])
14139 [(set (match_dup 0) (match_dup 1))]
14141 PUT_MODE (operands[1], QImode);
14145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14146 (ne:QI (match_operator 1 "ix86_comparison_operator"
14147 [(reg FLAGS_REG) (const_int 0)])
14150 [(set (match_dup 0) (match_dup 1))]
14152 PUT_MODE (operands[1], QImode);
14156 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14157 (eq:QI (match_operator 1 "ix86_comparison_operator"
14158 [(reg FLAGS_REG) (const_int 0)])
14161 [(set (match_dup 0) (match_dup 1))]
14163 rtx new_op1 = copy_rtx (operands[1]);
14164 operands[1] = new_op1;
14165 PUT_MODE (new_op1, QImode);
14166 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14167 GET_MODE (XEXP (new_op1, 0))));
14169 /* Make sure that (a) the CCmode we have for the flags is strong
14170 enough for the reversed compare or (b) we have a valid FP compare. */
14171 if (! ix86_comparison_operator (new_op1, VOIDmode))
14176 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14177 (eq:QI (match_operator 1 "ix86_comparison_operator"
14178 [(reg FLAGS_REG) (const_int 0)])
14181 [(set (match_dup 0) (match_dup 1))]
14183 rtx new_op1 = copy_rtx (operands[1]);
14184 operands[1] = new_op1;
14185 PUT_MODE (new_op1, QImode);
14186 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14187 GET_MODE (XEXP (new_op1, 0))));
14189 /* Make sure that (a) the CCmode we have for the flags is strong
14190 enough for the reversed compare or (b) we have a valid FP compare. */
14191 if (! ix86_comparison_operator (new_op1, VOIDmode))
14195 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14196 ;; subsequent logical operations are used to imitate conditional moves.
14197 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14200 (define_insn "*avx_setcc<mode>"
14201 [(set (match_operand:MODEF 0 "register_operand" "=x")
14202 (match_operator:MODEF 1 "avx_comparison_float_operator"
14203 [(match_operand:MODEF 2 "register_operand" "x")
14204 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14206 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14207 [(set_attr "type" "ssecmp")
14208 (set_attr "prefix" "vex")
14209 (set_attr "mode" "<MODE>")])
14211 (define_insn "*sse_setcc<mode>"
14212 [(set (match_operand:MODEF 0 "register_operand" "=x")
14213 (match_operator:MODEF 1 "sse_comparison_operator"
14214 [(match_operand:MODEF 2 "register_operand" "0")
14215 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14216 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14217 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14218 [(set_attr "type" "ssecmp")
14219 (set_attr "mode" "<MODE>")])
14221 (define_insn "*sse5_setcc<mode>"
14222 [(set (match_operand:MODEF 0 "register_operand" "=x")
14223 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14224 [(match_operand:MODEF 2 "register_operand" "x")
14225 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14227 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14228 [(set_attr "type" "sse4arg")
14229 (set_attr "mode" "<MODE>")])
14232 ;; Basic conditional jump instructions.
14233 ;; We ignore the overflow flag for signed branch instructions.
14235 ;; For all bCOND expanders, also expand the compare or test insn that
14236 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14238 (define_expand "b<code>"
14240 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14242 (label_ref (match_operand 0 ""))
14245 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14247 (define_expand "b<code>"
14249 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14251 (label_ref (match_operand 0 ""))
14253 "TARGET_80387 || TARGET_SSE_MATH"
14254 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14256 (define_insn "*jcc_1"
14258 (if_then_else (match_operator 1 "ix86_comparison_operator"
14259 [(reg FLAGS_REG) (const_int 0)])
14260 (label_ref (match_operand 0 "" ""))
14264 [(set_attr "type" "ibr")
14265 (set_attr "modrm" "0")
14266 (set (attr "length")
14267 (if_then_else (and (ge (minus (match_dup 0) (pc))
14269 (lt (minus (match_dup 0) (pc))
14274 (define_insn "*jcc_2"
14276 (if_then_else (match_operator 1 "ix86_comparison_operator"
14277 [(reg FLAGS_REG) (const_int 0)])
14279 (label_ref (match_operand 0 "" ""))))]
14282 [(set_attr "type" "ibr")
14283 (set_attr "modrm" "0")
14284 (set (attr "length")
14285 (if_then_else (and (ge (minus (match_dup 0) (pc))
14287 (lt (minus (match_dup 0) (pc))
14292 ;; In general it is not safe to assume too much about CCmode registers,
14293 ;; so simplify-rtx stops when it sees a second one. Under certain
14294 ;; conditions this is safe on x86, so help combine not create
14302 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14303 [(reg FLAGS_REG) (const_int 0)])
14305 (label_ref (match_operand 1 "" ""))
14309 (if_then_else (match_dup 0)
14310 (label_ref (match_dup 1))
14313 PUT_MODE (operands[0], VOIDmode);
14318 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14319 [(reg FLAGS_REG) (const_int 0)])
14321 (label_ref (match_operand 1 "" ""))
14325 (if_then_else (match_dup 0)
14326 (label_ref (match_dup 1))
14329 rtx new_op0 = copy_rtx (operands[0]);
14330 operands[0] = new_op0;
14331 PUT_MODE (new_op0, VOIDmode);
14332 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14333 GET_MODE (XEXP (new_op0, 0))));
14335 /* Make sure that (a) the CCmode we have for the flags is strong
14336 enough for the reversed compare or (b) we have a valid FP compare. */
14337 if (! ix86_comparison_operator (new_op0, VOIDmode))
14341 ;; zero_extend in SImode is correct, since this is what combine pass
14342 ;; generates from shift insn with QImode operand. Actually, the mode of
14343 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14344 ;; appropriate modulo of the bit offset value.
14346 (define_insn_and_split "*jcc_btdi_rex64"
14348 (if_then_else (match_operator 0 "bt_comparison_operator"
14350 (match_operand:DI 1 "register_operand" "r")
14353 (match_operand:QI 2 "register_operand" "r")))
14355 (label_ref (match_operand 3 "" ""))
14357 (clobber (reg:CC FLAGS_REG))]
14358 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14361 [(set (reg:CCC FLAGS_REG)
14369 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14370 (label_ref (match_dup 3))
14373 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14375 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14378 ;; avoid useless masking of bit offset operand
14379 (define_insn_and_split "*jcc_btdi_mask_rex64"
14381 (if_then_else (match_operator 0 "bt_comparison_operator"
14383 (match_operand:DI 1 "register_operand" "r")
14386 (match_operand:SI 2 "register_operand" "r")
14387 (match_operand:SI 3 "const_int_operand" "n")))])
14388 (label_ref (match_operand 4 "" ""))
14390 (clobber (reg:CC FLAGS_REG))]
14391 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14392 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14395 [(set (reg:CCC FLAGS_REG)
14403 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14404 (label_ref (match_dup 4))
14407 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14409 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14412 (define_insn_and_split "*jcc_btsi"
14414 (if_then_else (match_operator 0 "bt_comparison_operator"
14416 (match_operand:SI 1 "register_operand" "r")
14419 (match_operand:QI 2 "register_operand" "r")))
14421 (label_ref (match_operand 3 "" ""))
14423 (clobber (reg:CC FLAGS_REG))]
14424 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14427 [(set (reg:CCC FLAGS_REG)
14435 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14436 (label_ref (match_dup 3))
14439 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14441 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14444 ;; avoid useless masking of bit offset operand
14445 (define_insn_and_split "*jcc_btsi_mask"
14447 (if_then_else (match_operator 0 "bt_comparison_operator"
14449 (match_operand:SI 1 "register_operand" "r")
14452 (match_operand:SI 2 "register_operand" "r")
14453 (match_operand:SI 3 "const_int_operand" "n")))])
14454 (label_ref (match_operand 4 "" ""))
14456 (clobber (reg:CC FLAGS_REG))]
14457 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14458 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14461 [(set (reg:CCC FLAGS_REG)
14469 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14470 (label_ref (match_dup 4))
14472 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14474 (define_insn_and_split "*jcc_btsi_1"
14476 (if_then_else (match_operator 0 "bt_comparison_operator"
14479 (match_operand:SI 1 "register_operand" "r")
14480 (match_operand:QI 2 "register_operand" "r"))
14483 (label_ref (match_operand 3 "" ""))
14485 (clobber (reg:CC FLAGS_REG))]
14486 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14489 [(set (reg:CCC FLAGS_REG)
14497 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14498 (label_ref (match_dup 3))
14501 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14503 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14506 ;; avoid useless masking of bit offset operand
14507 (define_insn_and_split "*jcc_btsi_mask_1"
14510 (match_operator 0 "bt_comparison_operator"
14513 (match_operand:SI 1 "register_operand" "r")
14516 (match_operand:SI 2 "register_operand" "r")
14517 (match_operand:SI 3 "const_int_operand" "n")) 0))
14520 (label_ref (match_operand 4 "" ""))
14522 (clobber (reg:CC FLAGS_REG))]
14523 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14524 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14527 [(set (reg:CCC FLAGS_REG)
14535 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14536 (label_ref (match_dup 4))
14538 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14540 ;; Define combination compare-and-branch fp compare instructions to use
14541 ;; during early optimization. Splitting the operation apart early makes
14542 ;; for bad code when we want to reverse the operation.
14544 (define_insn "*fp_jcc_1_mixed"
14546 (if_then_else (match_operator 0 "comparison_operator"
14547 [(match_operand 1 "register_operand" "f,x")
14548 (match_operand 2 "nonimmediate_operand" "f,xm")])
14549 (label_ref (match_operand 3 "" ""))
14551 (clobber (reg:CCFP FPSR_REG))
14552 (clobber (reg:CCFP FLAGS_REG))]
14553 "TARGET_MIX_SSE_I387
14554 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14555 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14556 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14559 (define_insn "*fp_jcc_1_sse"
14561 (if_then_else (match_operator 0 "comparison_operator"
14562 [(match_operand 1 "register_operand" "x")
14563 (match_operand 2 "nonimmediate_operand" "xm")])
14564 (label_ref (match_operand 3 "" ""))
14566 (clobber (reg:CCFP FPSR_REG))
14567 (clobber (reg:CCFP FLAGS_REG))]
14569 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14570 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14571 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14574 (define_insn "*fp_jcc_1_387"
14576 (if_then_else (match_operator 0 "comparison_operator"
14577 [(match_operand 1 "register_operand" "f")
14578 (match_operand 2 "register_operand" "f")])
14579 (label_ref (match_operand 3 "" ""))
14581 (clobber (reg:CCFP FPSR_REG))
14582 (clobber (reg:CCFP FLAGS_REG))]
14583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14585 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14586 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14589 (define_insn "*fp_jcc_2_mixed"
14591 (if_then_else (match_operator 0 "comparison_operator"
14592 [(match_operand 1 "register_operand" "f,x")
14593 (match_operand 2 "nonimmediate_operand" "f,xm")])
14595 (label_ref (match_operand 3 "" ""))))
14596 (clobber (reg:CCFP FPSR_REG))
14597 (clobber (reg:CCFP FLAGS_REG))]
14598 "TARGET_MIX_SSE_I387
14599 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14600 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14601 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14604 (define_insn "*fp_jcc_2_sse"
14606 (if_then_else (match_operator 0 "comparison_operator"
14607 [(match_operand 1 "register_operand" "x")
14608 (match_operand 2 "nonimmediate_operand" "xm")])
14610 (label_ref (match_operand 3 "" ""))))
14611 (clobber (reg:CCFP FPSR_REG))
14612 (clobber (reg:CCFP FLAGS_REG))]
14614 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14615 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14616 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14619 (define_insn "*fp_jcc_2_387"
14621 (if_then_else (match_operator 0 "comparison_operator"
14622 [(match_operand 1 "register_operand" "f")
14623 (match_operand 2 "register_operand" "f")])
14625 (label_ref (match_operand 3 "" ""))))
14626 (clobber (reg:CCFP FPSR_REG))
14627 (clobber (reg:CCFP FLAGS_REG))]
14628 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14630 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14631 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14634 (define_insn "*fp_jcc_3_387"
14636 (if_then_else (match_operator 0 "comparison_operator"
14637 [(match_operand 1 "register_operand" "f")
14638 (match_operand 2 "nonimmediate_operand" "fm")])
14639 (label_ref (match_operand 3 "" ""))
14641 (clobber (reg:CCFP FPSR_REG))
14642 (clobber (reg:CCFP FLAGS_REG))
14643 (clobber (match_scratch:HI 4 "=a"))]
14645 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14646 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14647 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14648 && SELECT_CC_MODE (GET_CODE (operands[0]),
14649 operands[1], operands[2]) == CCFPmode
14650 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14653 (define_insn "*fp_jcc_4_387"
14655 (if_then_else (match_operator 0 "comparison_operator"
14656 [(match_operand 1 "register_operand" "f")
14657 (match_operand 2 "nonimmediate_operand" "fm")])
14659 (label_ref (match_operand 3 "" ""))))
14660 (clobber (reg:CCFP FPSR_REG))
14661 (clobber (reg:CCFP FLAGS_REG))
14662 (clobber (match_scratch:HI 4 "=a"))]
14664 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14665 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14666 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14667 && SELECT_CC_MODE (GET_CODE (operands[0]),
14668 operands[1], operands[2]) == CCFPmode
14669 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14672 (define_insn "*fp_jcc_5_387"
14674 (if_then_else (match_operator 0 "comparison_operator"
14675 [(match_operand 1 "register_operand" "f")
14676 (match_operand 2 "register_operand" "f")])
14677 (label_ref (match_operand 3 "" ""))
14679 (clobber (reg:CCFP FPSR_REG))
14680 (clobber (reg:CCFP FLAGS_REG))
14681 (clobber (match_scratch:HI 4 "=a"))]
14682 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14683 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14684 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14687 (define_insn "*fp_jcc_6_387"
14689 (if_then_else (match_operator 0 "comparison_operator"
14690 [(match_operand 1 "register_operand" "f")
14691 (match_operand 2 "register_operand" "f")])
14693 (label_ref (match_operand 3 "" ""))))
14694 (clobber (reg:CCFP FPSR_REG))
14695 (clobber (reg:CCFP FLAGS_REG))
14696 (clobber (match_scratch:HI 4 "=a"))]
14697 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14698 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14699 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14702 (define_insn "*fp_jcc_7_387"
14704 (if_then_else (match_operator 0 "comparison_operator"
14705 [(match_operand 1 "register_operand" "f")
14706 (match_operand 2 "const0_operand" "")])
14707 (label_ref (match_operand 3 "" ""))
14709 (clobber (reg:CCFP FPSR_REG))
14710 (clobber (reg:CCFP FLAGS_REG))
14711 (clobber (match_scratch:HI 4 "=a"))]
14712 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14713 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14714 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14715 && SELECT_CC_MODE (GET_CODE (operands[0]),
14716 operands[1], operands[2]) == CCFPmode
14717 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14720 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14721 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14722 ;; with a precedence over other operators and is always put in the first
14723 ;; place. Swap condition and operands to match ficom instruction.
14725 (define_insn "*fp_jcc_8<mode>_387"
14727 (if_then_else (match_operator 0 "comparison_operator"
14728 [(match_operator 1 "float_operator"
14729 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14730 (match_operand 3 "register_operand" "f,f")])
14731 (label_ref (match_operand 4 "" ""))
14733 (clobber (reg:CCFP FPSR_REG))
14734 (clobber (reg:CCFP FLAGS_REG))
14735 (clobber (match_scratch:HI 5 "=a,a"))]
14736 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14737 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14738 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14739 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14740 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14741 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14746 (if_then_else (match_operator 0 "comparison_operator"
14747 [(match_operand 1 "register_operand" "")
14748 (match_operand 2 "nonimmediate_operand" "")])
14749 (match_operand 3 "" "")
14750 (match_operand 4 "" "")))
14751 (clobber (reg:CCFP FPSR_REG))
14752 (clobber (reg:CCFP FLAGS_REG))]
14756 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14757 operands[3], operands[4], NULL_RTX, NULL_RTX);
14763 (if_then_else (match_operator 0 "comparison_operator"
14764 [(match_operand 1 "register_operand" "")
14765 (match_operand 2 "general_operand" "")])
14766 (match_operand 3 "" "")
14767 (match_operand 4 "" "")))
14768 (clobber (reg:CCFP FPSR_REG))
14769 (clobber (reg:CCFP FLAGS_REG))
14770 (clobber (match_scratch:HI 5 "=a"))]
14774 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14775 operands[3], operands[4], operands[5], NULL_RTX);
14781 (if_then_else (match_operator 0 "comparison_operator"
14782 [(match_operator 1 "float_operator"
14783 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14784 (match_operand 3 "register_operand" "")])
14785 (match_operand 4 "" "")
14786 (match_operand 5 "" "")))
14787 (clobber (reg:CCFP FPSR_REG))
14788 (clobber (reg:CCFP FLAGS_REG))
14789 (clobber (match_scratch:HI 6 "=a"))]
14793 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14794 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14795 operands[3], operands[7],
14796 operands[4], operands[5], operands[6], NULL_RTX);
14800 ;; %%% Kill this when reload knows how to do it.
14803 (if_then_else (match_operator 0 "comparison_operator"
14804 [(match_operator 1 "float_operator"
14805 [(match_operand:X87MODEI12 2 "register_operand" "")])
14806 (match_operand 3 "register_operand" "")])
14807 (match_operand 4 "" "")
14808 (match_operand 5 "" "")))
14809 (clobber (reg:CCFP FPSR_REG))
14810 (clobber (reg:CCFP FLAGS_REG))
14811 (clobber (match_scratch:HI 6 "=a"))]
14815 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14816 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14817 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14818 operands[3], operands[7],
14819 operands[4], operands[5], operands[6], operands[2]);
14823 ;; Unconditional and other jump instructions
14825 (define_insn "jump"
14827 (label_ref (match_operand 0 "" "")))]
14830 [(set_attr "type" "ibr")
14831 (set (attr "length")
14832 (if_then_else (and (ge (minus (match_dup 0) (pc))
14834 (lt (minus (match_dup 0) (pc))
14838 (set_attr "modrm" "0")])
14840 (define_expand "indirect_jump"
14841 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14845 (define_insn "*indirect_jump"
14846 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14849 [(set_attr "type" "ibr")
14850 (set_attr "length_immediate" "0")])
14852 (define_expand "tablejump"
14853 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14854 (use (label_ref (match_operand 1 "" "")))])]
14857 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14858 relative. Convert the relative address to an absolute address. */
14862 enum rtx_code code;
14864 /* We can't use @GOTOFF for text labels on VxWorks;
14865 see gotoff_operand. */
14866 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14870 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14872 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14876 op1 = pic_offset_table_rtx;
14881 op0 = pic_offset_table_rtx;
14885 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14890 (define_insn "*tablejump_1"
14891 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14892 (use (label_ref (match_operand 1 "" "")))]
14895 [(set_attr "type" "ibr")
14896 (set_attr "length_immediate" "0")])
14898 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14901 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14902 (set (match_operand:QI 1 "register_operand" "")
14903 (match_operator:QI 2 "ix86_comparison_operator"
14904 [(reg FLAGS_REG) (const_int 0)]))
14905 (set (match_operand 3 "q_regs_operand" "")
14906 (zero_extend (match_dup 1)))]
14907 "(peep2_reg_dead_p (3, operands[1])
14908 || operands_match_p (operands[1], operands[3]))
14909 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14910 [(set (match_dup 4) (match_dup 0))
14911 (set (strict_low_part (match_dup 5))
14914 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14915 operands[5] = gen_lowpart (QImode, operands[3]);
14916 ix86_expand_clear (operands[3]);
14919 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14922 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14923 (set (match_operand:QI 1 "register_operand" "")
14924 (match_operator:QI 2 "ix86_comparison_operator"
14925 [(reg FLAGS_REG) (const_int 0)]))
14926 (parallel [(set (match_operand 3 "q_regs_operand" "")
14927 (zero_extend (match_dup 1)))
14928 (clobber (reg:CC FLAGS_REG))])]
14929 "(peep2_reg_dead_p (3, operands[1])
14930 || operands_match_p (operands[1], operands[3]))
14931 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14932 [(set (match_dup 4) (match_dup 0))
14933 (set (strict_low_part (match_dup 5))
14936 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14937 operands[5] = gen_lowpart (QImode, operands[3]);
14938 ix86_expand_clear (operands[3]);
14941 ;; Call instructions.
14943 ;; The predicates normally associated with named expanders are not properly
14944 ;; checked for calls. This is a bug in the generic code, but it isn't that
14945 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14947 ;; Call subroutine returning no value.
14949 (define_expand "call_pop"
14950 [(parallel [(call (match_operand:QI 0 "" "")
14951 (match_operand:SI 1 "" ""))
14952 (set (reg:SI SP_REG)
14953 (plus:SI (reg:SI SP_REG)
14954 (match_operand:SI 3 "" "")))])]
14957 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14961 (define_insn "*call_pop_0"
14962 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14963 (match_operand:SI 1 "" ""))
14964 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14965 (match_operand:SI 2 "immediate_operand" "")))]
14968 if (SIBLING_CALL_P (insn))
14971 return "call\t%P0";
14973 [(set_attr "type" "call")])
14975 (define_insn "*call_pop_1"
14976 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14977 (match_operand:SI 1 "" ""))
14978 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14979 (match_operand:SI 2 "immediate_operand" "i")))]
14982 if (constant_call_address_operand (operands[0], Pmode))
14984 if (SIBLING_CALL_P (insn))
14987 return "call\t%P0";
14989 if (SIBLING_CALL_P (insn))
14992 return "call\t%A0";
14994 [(set_attr "type" "call")])
14996 (define_expand "call"
14997 [(call (match_operand:QI 0 "" "")
14998 (match_operand 1 "" ""))
14999 (use (match_operand 2 "" ""))]
15002 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15006 (define_expand "sibcall"
15007 [(call (match_operand:QI 0 "" "")
15008 (match_operand 1 "" ""))
15009 (use (match_operand 2 "" ""))]
15012 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15016 (define_insn "*call_0"
15017 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15018 (match_operand 1 "" ""))]
15021 if (SIBLING_CALL_P (insn))
15024 return "call\t%P0";
15026 [(set_attr "type" "call")])
15028 (define_insn "*call_1"
15029 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15030 (match_operand 1 "" ""))]
15031 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15033 if (constant_call_address_operand (operands[0], Pmode))
15034 return "call\t%P0";
15035 return "call\t%A0";
15037 [(set_attr "type" "call")])
15039 (define_insn "*sibcall_1"
15040 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15041 (match_operand 1 "" ""))]
15042 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15044 if (constant_call_address_operand (operands[0], Pmode))
15048 [(set_attr "type" "call")])
15050 (define_insn "*call_1_rex64"
15051 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15052 (match_operand 1 "" ""))]
15053 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15054 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15056 if (constant_call_address_operand (operands[0], Pmode))
15057 return "call\t%P0";
15058 return "call\t%A0";
15060 [(set_attr "type" "call")])
15062 (define_insn "*call_1_rex64_ms_sysv"
15063 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15064 (match_operand 1 "" ""))
15065 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15066 (clobber (reg:TI XMM6_REG))
15067 (clobber (reg:TI XMM7_REG))
15068 (clobber (reg:TI XMM8_REG))
15069 (clobber (reg:TI XMM9_REG))
15070 (clobber (reg:TI XMM10_REG))
15071 (clobber (reg:TI XMM11_REG))
15072 (clobber (reg:TI XMM12_REG))
15073 (clobber (reg:TI XMM13_REG))
15074 (clobber (reg:TI XMM14_REG))
15075 (clobber (reg:TI XMM15_REG))
15076 (clobber (reg:DI SI_REG))
15077 (clobber (reg:DI DI_REG))]
15078 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15080 if (constant_call_address_operand (operands[0], Pmode))
15081 return "call\t%P0";
15082 return "call\t%A0";
15084 [(set_attr "type" "call")])
15086 (define_insn "*call_1_rex64_large"
15087 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15088 (match_operand 1 "" ""))]
15089 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15091 [(set_attr "type" "call")])
15093 (define_insn "*sibcall_1_rex64"
15094 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15095 (match_operand 1 "" ""))]
15096 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15098 [(set_attr "type" "call")])
15100 (define_insn "*sibcall_1_rex64_v"
15101 [(call (mem:QI (reg:DI R11_REG))
15102 (match_operand 0 "" ""))]
15103 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15105 [(set_attr "type" "call")])
15108 ;; Call subroutine, returning value in operand 0
15110 (define_expand "call_value_pop"
15111 [(parallel [(set (match_operand 0 "" "")
15112 (call (match_operand:QI 1 "" "")
15113 (match_operand:SI 2 "" "")))
15114 (set (reg:SI SP_REG)
15115 (plus:SI (reg:SI SP_REG)
15116 (match_operand:SI 4 "" "")))])]
15119 ix86_expand_call (operands[0], operands[1], operands[2],
15120 operands[3], operands[4], 0);
15124 (define_expand "call_value"
15125 [(set (match_operand 0 "" "")
15126 (call (match_operand:QI 1 "" "")
15127 (match_operand:SI 2 "" "")))
15128 (use (match_operand:SI 3 "" ""))]
15129 ;; Operand 2 not used on the i386.
15132 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15136 (define_expand "sibcall_value"
15137 [(set (match_operand 0 "" "")
15138 (call (match_operand:QI 1 "" "")
15139 (match_operand:SI 2 "" "")))
15140 (use (match_operand:SI 3 "" ""))]
15141 ;; Operand 2 not used on the i386.
15144 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15148 ;; Call subroutine returning any type.
15150 (define_expand "untyped_call"
15151 [(parallel [(call (match_operand 0 "" "")
15153 (match_operand 1 "" "")
15154 (match_operand 2 "" "")])]
15159 /* In order to give reg-stack an easier job in validating two
15160 coprocessor registers as containing a possible return value,
15161 simply pretend the untyped call returns a complex long double
15164 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15165 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15166 operands[0], const0_rtx,
15167 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15168 : X64_SSE_REGPARM_MAX)
15172 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15174 rtx set = XVECEXP (operands[2], 0, i);
15175 emit_move_insn (SET_DEST (set), SET_SRC (set));
15178 /* The optimizer does not know that the call sets the function value
15179 registers we stored in the result block. We avoid problems by
15180 claiming that all hard registers are used and clobbered at this
15182 emit_insn (gen_blockage ());
15187 ;; Prologue and epilogue instructions
15189 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15190 ;; all of memory. This blocks insns from being moved across this point.
15192 (define_insn "blockage"
15193 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15196 [(set_attr "length" "0")])
15198 ;; Do not schedule instructions accessing memory across this point.
15200 (define_expand "memory_blockage"
15201 [(set (match_dup 0)
15202 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15205 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15206 MEM_VOLATILE_P (operands[0]) = 1;
15209 (define_insn "*memory_blockage"
15210 [(set (match_operand:BLK 0 "" "")
15211 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15214 [(set_attr "length" "0")])
15216 ;; As USE insns aren't meaningful after reload, this is used instead
15217 ;; to prevent deleting instructions setting registers for PIC code
15218 (define_insn "prologue_use"
15219 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15222 [(set_attr "length" "0")])
15224 ;; Insn emitted into the body of a function to return from a function.
15225 ;; This is only done if the function's epilogue is known to be simple.
15226 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15228 (define_expand "return"
15230 "ix86_can_use_return_insn_p ()"
15232 if (crtl->args.pops_args)
15234 rtx popc = GEN_INT (crtl->args.pops_args);
15235 emit_jump_insn (gen_return_pop_internal (popc));
15240 (define_insn "return_internal"
15244 [(set_attr "length" "1")
15245 (set_attr "length_immediate" "0")
15246 (set_attr "modrm" "0")])
15248 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15249 ;; instruction Athlon and K8 have.
15251 (define_insn "return_internal_long"
15253 (unspec [(const_int 0)] UNSPEC_REP)]
15256 [(set_attr "length" "1")
15257 (set_attr "length_immediate" "0")
15258 (set_attr "prefix_rep" "1")
15259 (set_attr "modrm" "0")])
15261 (define_insn "return_pop_internal"
15263 (use (match_operand:SI 0 "const_int_operand" ""))]
15266 [(set_attr "length" "3")
15267 (set_attr "length_immediate" "2")
15268 (set_attr "modrm" "0")])
15270 (define_insn "return_indirect_internal"
15272 (use (match_operand:SI 0 "register_operand" "r"))]
15275 [(set_attr "type" "ibr")
15276 (set_attr "length_immediate" "0")])
15282 [(set_attr "length" "1")
15283 (set_attr "length_immediate" "0")
15284 (set_attr "modrm" "0")])
15286 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15287 ;; branch prediction penalty for the third jump in a 16-byte
15290 (define_insn "align"
15291 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15294 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15295 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15297 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15298 The align insn is used to avoid 3 jump instructions in the row to improve
15299 branch prediction and the benefits hardly outweigh the cost of extra 8
15300 nops on the average inserted by full alignment pseudo operation. */
15304 [(set_attr "length" "16")])
15306 (define_expand "prologue"
15309 "ix86_expand_prologue (); DONE;")
15311 (define_insn "set_got"
15312 [(set (match_operand:SI 0 "register_operand" "=r")
15313 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15314 (clobber (reg:CC FLAGS_REG))]
15316 { return output_set_got (operands[0], NULL_RTX); }
15317 [(set_attr "type" "multi")
15318 (set_attr "length" "12")])
15320 (define_insn "set_got_labelled"
15321 [(set (match_operand:SI 0 "register_operand" "=r")
15322 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15324 (clobber (reg:CC FLAGS_REG))]
15326 { return output_set_got (operands[0], operands[1]); }
15327 [(set_attr "type" "multi")
15328 (set_attr "length" "12")])
15330 (define_insn "set_got_rex64"
15331 [(set (match_operand:DI 0 "register_operand" "=r")
15332 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15334 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15335 [(set_attr "type" "lea")
15336 (set_attr "length" "6")])
15338 (define_insn "set_rip_rex64"
15339 [(set (match_operand:DI 0 "register_operand" "=r")
15340 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15342 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15343 [(set_attr "type" "lea")
15344 (set_attr "length" "6")])
15346 (define_insn "set_got_offset_rex64"
15347 [(set (match_operand:DI 0 "register_operand" "=r")
15349 [(label_ref (match_operand 1 "" ""))]
15350 UNSPEC_SET_GOT_OFFSET))]
15352 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15353 [(set_attr "type" "imov")
15354 (set_attr "length" "11")])
15356 (define_expand "epilogue"
15359 "ix86_expand_epilogue (1); DONE;")
15361 (define_expand "sibcall_epilogue"
15364 "ix86_expand_epilogue (0); DONE;")
15366 (define_expand "eh_return"
15367 [(use (match_operand 0 "register_operand" ""))]
15370 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15372 /* Tricky bit: we write the address of the handler to which we will
15373 be returning into someone else's stack frame, one word below the
15374 stack address we wish to restore. */
15375 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15376 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15377 tmp = gen_rtx_MEM (Pmode, tmp);
15378 emit_move_insn (tmp, ra);
15380 if (Pmode == SImode)
15381 emit_jump_insn (gen_eh_return_si (sa));
15383 emit_jump_insn (gen_eh_return_di (sa));
15388 (define_insn_and_split "eh_return_<mode>"
15390 (unspec [(match_operand:P 0 "register_operand" "c")]
15391 UNSPEC_EH_RETURN))]
15396 "ix86_expand_epilogue (2); DONE;")
15398 (define_insn "leave"
15399 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15400 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15401 (clobber (mem:BLK (scratch)))]
15404 [(set_attr "type" "leave")])
15406 (define_insn "leave_rex64"
15407 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15408 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15409 (clobber (mem:BLK (scratch)))]
15412 [(set_attr "type" "leave")])
15414 (define_expand "ffssi2"
15416 [(set (match_operand:SI 0 "register_operand" "")
15417 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15418 (clobber (match_scratch:SI 2 ""))
15419 (clobber (reg:CC FLAGS_REG))])]
15424 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15429 (define_expand "ffs_cmove"
15430 [(set (match_dup 2) (const_int -1))
15431 (parallel [(set (reg:CCZ FLAGS_REG)
15432 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15434 (set (match_operand:SI 0 "register_operand" "")
15435 (ctz:SI (match_dup 1)))])
15436 (set (match_dup 0) (if_then_else:SI
15437 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15440 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15441 (clobber (reg:CC FLAGS_REG))])]
15443 "operands[2] = gen_reg_rtx (SImode);")
15445 (define_insn_and_split "*ffs_no_cmove"
15446 [(set (match_operand:SI 0 "register_operand" "=r")
15447 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15448 (clobber (match_scratch:SI 2 "=&q"))
15449 (clobber (reg:CC FLAGS_REG))]
15452 "&& reload_completed"
15453 [(parallel [(set (reg:CCZ FLAGS_REG)
15454 (compare:CCZ (match_dup 1) (const_int 0)))
15455 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15456 (set (strict_low_part (match_dup 3))
15457 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15458 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15459 (clobber (reg:CC FLAGS_REG))])
15460 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15461 (clobber (reg:CC FLAGS_REG))])
15462 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15463 (clobber (reg:CC FLAGS_REG))])]
15465 operands[3] = gen_lowpart (QImode, operands[2]);
15466 ix86_expand_clear (operands[2]);
15469 (define_insn "*ffssi_1"
15470 [(set (reg:CCZ FLAGS_REG)
15471 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15473 (set (match_operand:SI 0 "register_operand" "=r")
15474 (ctz:SI (match_dup 1)))]
15476 "bsf{l}\t{%1, %0|%0, %1}"
15477 [(set_attr "prefix_0f" "1")])
15479 (define_expand "ffsdi2"
15480 [(set (match_dup 2) (const_int -1))
15481 (parallel [(set (reg:CCZ FLAGS_REG)
15482 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15484 (set (match_operand:DI 0 "register_operand" "")
15485 (ctz:DI (match_dup 1)))])
15486 (set (match_dup 0) (if_then_else:DI
15487 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15490 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15491 (clobber (reg:CC FLAGS_REG))])]
15493 "operands[2] = gen_reg_rtx (DImode);")
15495 (define_insn "*ffsdi_1"
15496 [(set (reg:CCZ FLAGS_REG)
15497 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15499 (set (match_operand:DI 0 "register_operand" "=r")
15500 (ctz:DI (match_dup 1)))]
15502 "bsf{q}\t{%1, %0|%0, %1}"
15503 [(set_attr "prefix_0f" "1")])
15505 (define_insn "ctzsi2"
15506 [(set (match_operand:SI 0 "register_operand" "=r")
15507 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15508 (clobber (reg:CC FLAGS_REG))]
15510 "bsf{l}\t{%1, %0|%0, %1}"
15511 [(set_attr "prefix_0f" "1")])
15513 (define_insn "ctzdi2"
15514 [(set (match_operand:DI 0 "register_operand" "=r")
15515 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15516 (clobber (reg:CC FLAGS_REG))]
15518 "bsf{q}\t{%1, %0|%0, %1}"
15519 [(set_attr "prefix_0f" "1")])
15521 (define_expand "clzsi2"
15523 [(set (match_operand:SI 0 "register_operand" "")
15524 (minus:SI (const_int 31)
15525 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15526 (clobber (reg:CC FLAGS_REG))])
15528 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15529 (clobber (reg:CC FLAGS_REG))])]
15534 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15539 (define_insn "clzsi2_abm"
15540 [(set (match_operand:SI 0 "register_operand" "=r")
15541 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15542 (clobber (reg:CC FLAGS_REG))]
15544 "lzcnt{l}\t{%1, %0|%0, %1}"
15545 [(set_attr "prefix_rep" "1")
15546 (set_attr "type" "bitmanip")
15547 (set_attr "mode" "SI")])
15549 (define_insn "*bsr"
15550 [(set (match_operand:SI 0 "register_operand" "=r")
15551 (minus:SI (const_int 31)
15552 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15553 (clobber (reg:CC FLAGS_REG))]
15555 "bsr{l}\t{%1, %0|%0, %1}"
15556 [(set_attr "prefix_0f" "1")
15557 (set_attr "mode" "SI")])
15559 (define_insn "popcount<mode>2"
15560 [(set (match_operand:SWI248 0 "register_operand" "=r")
15562 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15563 (clobber (reg:CC FLAGS_REG))]
15567 return "popcnt\t{%1, %0|%0, %1}";
15569 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15572 [(set_attr "prefix_rep" "1")
15573 (set_attr "type" "bitmanip")
15574 (set_attr "mode" "<MODE>")])
15576 (define_insn "*popcount<mode>2_cmp"
15577 [(set (reg FLAGS_REG)
15580 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15582 (set (match_operand:SWI248 0 "register_operand" "=r")
15583 (popcount:SWI248 (match_dup 1)))]
15584 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15587 return "popcnt\t{%1, %0|%0, %1}";
15589 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15592 [(set_attr "prefix_rep" "1")
15593 (set_attr "type" "bitmanip")
15594 (set_attr "mode" "<MODE>")])
15596 (define_insn "*popcountsi2_cmp_zext"
15597 [(set (reg FLAGS_REG)
15599 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15601 (set (match_operand:DI 0 "register_operand" "=r")
15602 (zero_extend:DI(popcount:SI (match_dup 1))))]
15603 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15606 return "popcnt\t{%1, %0|%0, %1}";
15608 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15611 [(set_attr "prefix_rep" "1")
15612 (set_attr "type" "bitmanip")
15613 (set_attr "mode" "SI")])
15615 (define_expand "bswapsi2"
15616 [(set (match_operand:SI 0 "register_operand" "")
15617 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15622 rtx x = operands[0];
15624 emit_move_insn (x, operands[1]);
15625 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15626 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15627 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15632 (define_insn "*bswapsi_1"
15633 [(set (match_operand:SI 0 "register_operand" "=r")
15634 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15637 [(set_attr "prefix_0f" "1")
15638 (set_attr "length" "2")])
15640 (define_insn "*bswaphi_lowpart_1"
15641 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15642 (bswap:HI (match_dup 0)))
15643 (clobber (reg:CC FLAGS_REG))]
15644 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15646 xchg{b}\t{%h0, %b0|%b0, %h0}
15647 rol{w}\t{$8, %0|%0, 8}"
15648 [(set_attr "length" "2,4")
15649 (set_attr "mode" "QI,HI")])
15651 (define_insn "bswaphi_lowpart"
15652 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15653 (bswap:HI (match_dup 0)))
15654 (clobber (reg:CC FLAGS_REG))]
15656 "rol{w}\t{$8, %0|%0, 8}"
15657 [(set_attr "length" "4")
15658 (set_attr "mode" "HI")])
15660 (define_insn "bswapdi2"
15661 [(set (match_operand:DI 0 "register_operand" "=r")
15662 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15665 [(set_attr "prefix_0f" "1")
15666 (set_attr "length" "3")])
15668 (define_expand "clzdi2"
15670 [(set (match_operand:DI 0 "register_operand" "")
15671 (minus:DI (const_int 63)
15672 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15673 (clobber (reg:CC FLAGS_REG))])
15675 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15676 (clobber (reg:CC FLAGS_REG))])]
15681 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15686 (define_insn "clzdi2_abm"
15687 [(set (match_operand:DI 0 "register_operand" "=r")
15688 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15689 (clobber (reg:CC FLAGS_REG))]
15690 "TARGET_64BIT && TARGET_ABM"
15691 "lzcnt{q}\t{%1, %0|%0, %1}"
15692 [(set_attr "prefix_rep" "1")
15693 (set_attr "type" "bitmanip")
15694 (set_attr "mode" "DI")])
15696 (define_insn "*bsr_rex64"
15697 [(set (match_operand:DI 0 "register_operand" "=r")
15698 (minus:DI (const_int 63)
15699 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15700 (clobber (reg:CC FLAGS_REG))]
15702 "bsr{q}\t{%1, %0|%0, %1}"
15703 [(set_attr "prefix_0f" "1")
15704 (set_attr "mode" "DI")])
15706 (define_expand "clzhi2"
15708 [(set (match_operand:HI 0 "register_operand" "")
15709 (minus:HI (const_int 15)
15710 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15711 (clobber (reg:CC FLAGS_REG))])
15713 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15714 (clobber (reg:CC FLAGS_REG))])]
15719 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15724 (define_insn "clzhi2_abm"
15725 [(set (match_operand:HI 0 "register_operand" "=r")
15726 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15727 (clobber (reg:CC FLAGS_REG))]
15729 "lzcnt{w}\t{%1, %0|%0, %1}"
15730 [(set_attr "prefix_rep" "1")
15731 (set_attr "type" "bitmanip")
15732 (set_attr "mode" "HI")])
15734 (define_insn "*bsrhi"
15735 [(set (match_operand:HI 0 "register_operand" "=r")
15736 (minus:HI (const_int 15)
15737 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15738 (clobber (reg:CC FLAGS_REG))]
15740 "bsr{w}\t{%1, %0|%0, %1}"
15741 [(set_attr "prefix_0f" "1")
15742 (set_attr "mode" "HI")])
15744 (define_expand "paritydi2"
15745 [(set (match_operand:DI 0 "register_operand" "")
15746 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15749 rtx scratch = gen_reg_rtx (QImode);
15752 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15753 NULL_RTX, operands[1]));
15755 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15756 gen_rtx_REG (CCmode, FLAGS_REG),
15758 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15761 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15764 rtx tmp = gen_reg_rtx (SImode);
15766 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15767 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15772 (define_insn_and_split "paritydi2_cmp"
15773 [(set (reg:CC FLAGS_REG)
15774 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15775 (clobber (match_scratch:DI 0 "=r"))
15776 (clobber (match_scratch:SI 1 "=&r"))
15777 (clobber (match_scratch:HI 2 "=Q"))]
15780 "&& reload_completed"
15782 [(set (match_dup 1)
15783 (xor:SI (match_dup 1) (match_dup 4)))
15784 (clobber (reg:CC FLAGS_REG))])
15786 [(set (reg:CC FLAGS_REG)
15787 (parity:CC (match_dup 1)))
15788 (clobber (match_dup 1))
15789 (clobber (match_dup 2))])]
15791 operands[4] = gen_lowpart (SImode, operands[3]);
15795 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15796 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15799 operands[1] = gen_highpart (SImode, operands[3]);
15802 (define_expand "paritysi2"
15803 [(set (match_operand:SI 0 "register_operand" "")
15804 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15807 rtx scratch = gen_reg_rtx (QImode);
15810 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15812 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15813 gen_rtx_REG (CCmode, FLAGS_REG),
15815 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15817 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15821 (define_insn_and_split "paritysi2_cmp"
15822 [(set (reg:CC FLAGS_REG)
15823 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15824 (clobber (match_scratch:SI 0 "=r"))
15825 (clobber (match_scratch:HI 1 "=&Q"))]
15828 "&& reload_completed"
15830 [(set (match_dup 1)
15831 (xor:HI (match_dup 1) (match_dup 3)))
15832 (clobber (reg:CC FLAGS_REG))])
15834 [(set (reg:CC FLAGS_REG)
15835 (parity:CC (match_dup 1)))
15836 (clobber (match_dup 1))])]
15838 operands[3] = gen_lowpart (HImode, operands[2]);
15840 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15841 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15844 (define_insn "*parityhi2_cmp"
15845 [(set (reg:CC FLAGS_REG)
15846 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15847 (clobber (match_scratch:HI 0 "=Q"))]
15849 "xor{b}\t{%h0, %b0|%b0, %h0}"
15850 [(set_attr "length" "2")
15851 (set_attr "mode" "HI")])
15853 (define_insn "*parityqi2_cmp"
15854 [(set (reg:CC FLAGS_REG)
15855 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15858 [(set_attr "length" "2")
15859 (set_attr "mode" "QI")])
15861 ;; Thread-local storage patterns for ELF.
15863 ;; Note that these code sequences must appear exactly as shown
15864 ;; in order to allow linker relaxation.
15866 (define_insn "*tls_global_dynamic_32_gnu"
15867 [(set (match_operand:SI 0 "register_operand" "=a")
15868 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15869 (match_operand:SI 2 "tls_symbolic_operand" "")
15870 (match_operand:SI 3 "call_insn_operand" "")]
15872 (clobber (match_scratch:SI 4 "=d"))
15873 (clobber (match_scratch:SI 5 "=c"))
15874 (clobber (reg:CC FLAGS_REG))]
15875 "!TARGET_64BIT && TARGET_GNU_TLS"
15876 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15877 [(set_attr "type" "multi")
15878 (set_attr "length" "12")])
15880 (define_insn "*tls_global_dynamic_32_sun"
15881 [(set (match_operand:SI 0 "register_operand" "=a")
15882 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15883 (match_operand:SI 2 "tls_symbolic_operand" "")
15884 (match_operand:SI 3 "call_insn_operand" "")]
15886 (clobber (match_scratch:SI 4 "=d"))
15887 (clobber (match_scratch:SI 5 "=c"))
15888 (clobber (reg:CC FLAGS_REG))]
15889 "!TARGET_64BIT && TARGET_SUN_TLS"
15890 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15891 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15892 [(set_attr "type" "multi")
15893 (set_attr "length" "14")])
15895 (define_expand "tls_global_dynamic_32"
15896 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15899 (match_operand:SI 1 "tls_symbolic_operand" "")
15902 (clobber (match_scratch:SI 4 ""))
15903 (clobber (match_scratch:SI 5 ""))
15904 (clobber (reg:CC FLAGS_REG))])]
15908 operands[2] = pic_offset_table_rtx;
15911 operands[2] = gen_reg_rtx (Pmode);
15912 emit_insn (gen_set_got (operands[2]));
15914 if (TARGET_GNU2_TLS)
15916 emit_insn (gen_tls_dynamic_gnu2_32
15917 (operands[0], operands[1], operands[2]));
15920 operands[3] = ix86_tls_get_addr ();
15923 (define_insn "*tls_global_dynamic_64"
15924 [(set (match_operand:DI 0 "register_operand" "=a")
15925 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15926 (match_operand:DI 3 "" "")))
15927 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15930 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15931 [(set_attr "type" "multi")
15932 (set_attr "length" "16")])
15934 (define_expand "tls_global_dynamic_64"
15935 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15936 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15937 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15941 if (TARGET_GNU2_TLS)
15943 emit_insn (gen_tls_dynamic_gnu2_64
15944 (operands[0], operands[1]));
15947 operands[2] = ix86_tls_get_addr ();
15950 (define_insn "*tls_local_dynamic_base_32_gnu"
15951 [(set (match_operand:SI 0 "register_operand" "=a")
15952 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15953 (match_operand:SI 2 "call_insn_operand" "")]
15954 UNSPEC_TLS_LD_BASE))
15955 (clobber (match_scratch:SI 3 "=d"))
15956 (clobber (match_scratch:SI 4 "=c"))
15957 (clobber (reg:CC FLAGS_REG))]
15958 "!TARGET_64BIT && TARGET_GNU_TLS"
15959 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15960 [(set_attr "type" "multi")
15961 (set_attr "length" "11")])
15963 (define_insn "*tls_local_dynamic_base_32_sun"
15964 [(set (match_operand:SI 0 "register_operand" "=a")
15965 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15966 (match_operand:SI 2 "call_insn_operand" "")]
15967 UNSPEC_TLS_LD_BASE))
15968 (clobber (match_scratch:SI 3 "=d"))
15969 (clobber (match_scratch:SI 4 "=c"))
15970 (clobber (reg:CC FLAGS_REG))]
15971 "!TARGET_64BIT && TARGET_SUN_TLS"
15972 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15973 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15974 [(set_attr "type" "multi")
15975 (set_attr "length" "13")])
15977 (define_expand "tls_local_dynamic_base_32"
15978 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15979 (unspec:SI [(match_dup 1) (match_dup 2)]
15980 UNSPEC_TLS_LD_BASE))
15981 (clobber (match_scratch:SI 3 ""))
15982 (clobber (match_scratch:SI 4 ""))
15983 (clobber (reg:CC FLAGS_REG))])]
15987 operands[1] = pic_offset_table_rtx;
15990 operands[1] = gen_reg_rtx (Pmode);
15991 emit_insn (gen_set_got (operands[1]));
15993 if (TARGET_GNU2_TLS)
15995 emit_insn (gen_tls_dynamic_gnu2_32
15996 (operands[0], ix86_tls_module_base (), operands[1]));
15999 operands[2] = ix86_tls_get_addr ();
16002 (define_insn "*tls_local_dynamic_base_64"
16003 [(set (match_operand:DI 0 "register_operand" "=a")
16004 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16005 (match_operand:DI 2 "" "")))
16006 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16008 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16009 [(set_attr "type" "multi")
16010 (set_attr "length" "12")])
16012 (define_expand "tls_local_dynamic_base_64"
16013 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16014 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16015 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16018 if (TARGET_GNU2_TLS)
16020 emit_insn (gen_tls_dynamic_gnu2_64
16021 (operands[0], ix86_tls_module_base ()));
16024 operands[1] = ix86_tls_get_addr ();
16027 ;; Local dynamic of a single variable is a lose. Show combine how
16028 ;; to convert that back to global dynamic.
16030 (define_insn_and_split "*tls_local_dynamic_32_once"
16031 [(set (match_operand:SI 0 "register_operand" "=a")
16032 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16033 (match_operand:SI 2 "call_insn_operand" "")]
16034 UNSPEC_TLS_LD_BASE)
16035 (const:SI (unspec:SI
16036 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16038 (clobber (match_scratch:SI 4 "=d"))
16039 (clobber (match_scratch:SI 5 "=c"))
16040 (clobber (reg:CC FLAGS_REG))]
16044 [(parallel [(set (match_dup 0)
16045 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16047 (clobber (match_dup 4))
16048 (clobber (match_dup 5))
16049 (clobber (reg:CC FLAGS_REG))])]
16052 ;; Load and add the thread base pointer from %gs:0.
16054 (define_insn "*load_tp_si"
16055 [(set (match_operand:SI 0 "register_operand" "=r")
16056 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16058 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16059 [(set_attr "type" "imov")
16060 (set_attr "modrm" "0")
16061 (set_attr "length" "7")
16062 (set_attr "memory" "load")
16063 (set_attr "imm_disp" "false")])
16065 (define_insn "*add_tp_si"
16066 [(set (match_operand:SI 0 "register_operand" "=r")
16067 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16068 (match_operand:SI 1 "register_operand" "0")))
16069 (clobber (reg:CC FLAGS_REG))]
16071 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16072 [(set_attr "type" "alu")
16073 (set_attr "modrm" "0")
16074 (set_attr "length" "7")
16075 (set_attr "memory" "load")
16076 (set_attr "imm_disp" "false")])
16078 (define_insn "*load_tp_di"
16079 [(set (match_operand:DI 0 "register_operand" "=r")
16080 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16082 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16083 [(set_attr "type" "imov")
16084 (set_attr "modrm" "0")
16085 (set_attr "length" "7")
16086 (set_attr "memory" "load")
16087 (set_attr "imm_disp" "false")])
16089 (define_insn "*add_tp_di"
16090 [(set (match_operand:DI 0 "register_operand" "=r")
16091 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16092 (match_operand:DI 1 "register_operand" "0")))
16093 (clobber (reg:CC FLAGS_REG))]
16095 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16096 [(set_attr "type" "alu")
16097 (set_attr "modrm" "0")
16098 (set_attr "length" "7")
16099 (set_attr "memory" "load")
16100 (set_attr "imm_disp" "false")])
16102 ;; GNU2 TLS patterns can be split.
16104 (define_expand "tls_dynamic_gnu2_32"
16105 [(set (match_dup 3)
16106 (plus:SI (match_operand:SI 2 "register_operand" "")
16108 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16111 [(set (match_operand:SI 0 "register_operand" "")
16112 (unspec:SI [(match_dup 1) (match_dup 3)
16113 (match_dup 2) (reg:SI SP_REG)]
16115 (clobber (reg:CC FLAGS_REG))])]
16116 "!TARGET_64BIT && TARGET_GNU2_TLS"
16118 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16119 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16122 (define_insn "*tls_dynamic_lea_32"
16123 [(set (match_operand:SI 0 "register_operand" "=r")
16124 (plus:SI (match_operand:SI 1 "register_operand" "b")
16126 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16127 UNSPEC_TLSDESC))))]
16128 "!TARGET_64BIT && TARGET_GNU2_TLS"
16129 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16130 [(set_attr "type" "lea")
16131 (set_attr "mode" "SI")
16132 (set_attr "length" "6")
16133 (set_attr "length_address" "4")])
16135 (define_insn "*tls_dynamic_call_32"
16136 [(set (match_operand:SI 0 "register_operand" "=a")
16137 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16138 (match_operand:SI 2 "register_operand" "0")
16139 ;; we have to make sure %ebx still points to the GOT
16140 (match_operand:SI 3 "register_operand" "b")
16143 (clobber (reg:CC FLAGS_REG))]
16144 "!TARGET_64BIT && TARGET_GNU2_TLS"
16145 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16146 [(set_attr "type" "call")
16147 (set_attr "length" "2")
16148 (set_attr "length_address" "0")])
16150 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16151 [(set (match_operand:SI 0 "register_operand" "=&a")
16153 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16154 (match_operand:SI 4 "" "")
16155 (match_operand:SI 2 "register_operand" "b")
16158 (const:SI (unspec:SI
16159 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16161 (clobber (reg:CC FLAGS_REG))]
16162 "!TARGET_64BIT && TARGET_GNU2_TLS"
16165 [(set (match_dup 0) (match_dup 5))]
16167 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16168 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16171 (define_expand "tls_dynamic_gnu2_64"
16172 [(set (match_dup 2)
16173 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16176 [(set (match_operand:DI 0 "register_operand" "")
16177 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16179 (clobber (reg:CC FLAGS_REG))])]
16180 "TARGET_64BIT && TARGET_GNU2_TLS"
16182 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16183 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16186 (define_insn "*tls_dynamic_lea_64"
16187 [(set (match_operand:DI 0 "register_operand" "=r")
16188 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16190 "TARGET_64BIT && TARGET_GNU2_TLS"
16191 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16192 [(set_attr "type" "lea")
16193 (set_attr "mode" "DI")
16194 (set_attr "length" "7")
16195 (set_attr "length_address" "4")])
16197 (define_insn "*tls_dynamic_call_64"
16198 [(set (match_operand:DI 0 "register_operand" "=a")
16199 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16200 (match_operand:DI 2 "register_operand" "0")
16203 (clobber (reg:CC FLAGS_REG))]
16204 "TARGET_64BIT && TARGET_GNU2_TLS"
16205 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16206 [(set_attr "type" "call")
16207 (set_attr "length" "2")
16208 (set_attr "length_address" "0")])
16210 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16211 [(set (match_operand:DI 0 "register_operand" "=&a")
16213 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16214 (match_operand:DI 3 "" "")
16217 (const:DI (unspec:DI
16218 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16220 (clobber (reg:CC FLAGS_REG))]
16221 "TARGET_64BIT && TARGET_GNU2_TLS"
16224 [(set (match_dup 0) (match_dup 4))]
16226 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16227 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16232 ;; These patterns match the binary 387 instructions for addM3, subM3,
16233 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16234 ;; SFmode. The first is the normal insn, the second the same insn but
16235 ;; with one operand a conversion, and the third the same insn but with
16236 ;; the other operand a conversion. The conversion may be SFmode or
16237 ;; SImode if the target mode DFmode, but only SImode if the target mode
16240 ;; Gcc is slightly more smart about handling normal two address instructions
16241 ;; so use special patterns for add and mull.
16243 (define_insn "*fop_<mode>_comm_mixed_avx"
16244 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16245 (match_operator:MODEF 3 "binary_fp_operator"
16246 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16247 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16248 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16249 && COMMUTATIVE_ARITH_P (operands[3])
16250 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16251 "* return output_387_binary_op (insn, operands);"
16252 [(set (attr "type")
16253 (if_then_else (eq_attr "alternative" "1")
16254 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16255 (const_string "ssemul")
16256 (const_string "sseadd"))
16257 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16258 (const_string "fmul")
16259 (const_string "fop"))))
16260 (set_attr "prefix" "orig,maybe_vex")
16261 (set_attr "mode" "<MODE>")])
16263 (define_insn "*fop_<mode>_comm_mixed"
16264 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16265 (match_operator:MODEF 3 "binary_fp_operator"
16266 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16267 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16268 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16269 && COMMUTATIVE_ARITH_P (operands[3])
16270 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16271 "* return output_387_binary_op (insn, operands);"
16272 [(set (attr "type")
16273 (if_then_else (eq_attr "alternative" "1")
16274 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16275 (const_string "ssemul")
16276 (const_string "sseadd"))
16277 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16278 (const_string "fmul")
16279 (const_string "fop"))))
16280 (set_attr "mode" "<MODE>")])
16282 (define_insn "*fop_<mode>_comm_avx"
16283 [(set (match_operand:MODEF 0 "register_operand" "=x")
16284 (match_operator:MODEF 3 "binary_fp_operator"
16285 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16286 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16287 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16288 && COMMUTATIVE_ARITH_P (operands[3])
16289 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16290 "* return output_387_binary_op (insn, operands);"
16291 [(set (attr "type")
16292 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16293 (const_string "ssemul")
16294 (const_string "sseadd")))
16295 (set_attr "prefix" "vex")
16296 (set_attr "mode" "<MODE>")])
16298 (define_insn "*fop_<mode>_comm_sse"
16299 [(set (match_operand:MODEF 0 "register_operand" "=x")
16300 (match_operator:MODEF 3 "binary_fp_operator"
16301 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16302 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16303 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16304 && COMMUTATIVE_ARITH_P (operands[3])
16305 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16306 "* return output_387_binary_op (insn, operands);"
16307 [(set (attr "type")
16308 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16309 (const_string "ssemul")
16310 (const_string "sseadd")))
16311 (set_attr "mode" "<MODE>")])
16313 (define_insn "*fop_<mode>_comm_i387"
16314 [(set (match_operand:MODEF 0 "register_operand" "=f")
16315 (match_operator:MODEF 3 "binary_fp_operator"
16316 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16317 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16319 && COMMUTATIVE_ARITH_P (operands[3])
16320 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16321 "* return output_387_binary_op (insn, operands);"
16322 [(set (attr "type")
16323 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16324 (const_string "fmul")
16325 (const_string "fop")))
16326 (set_attr "mode" "<MODE>")])
16328 (define_insn "*fop_<mode>_1_mixed_avx"
16329 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16330 (match_operator:MODEF 3 "binary_fp_operator"
16331 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16332 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16333 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16334 && !COMMUTATIVE_ARITH_P (operands[3])
16335 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16336 "* return output_387_binary_op (insn, operands);"
16337 [(set (attr "type")
16338 (cond [(and (eq_attr "alternative" "2")
16339 (match_operand:MODEF 3 "mult_operator" ""))
16340 (const_string "ssemul")
16341 (and (eq_attr "alternative" "2")
16342 (match_operand:MODEF 3 "div_operator" ""))
16343 (const_string "ssediv")
16344 (eq_attr "alternative" "2")
16345 (const_string "sseadd")
16346 (match_operand:MODEF 3 "mult_operator" "")
16347 (const_string "fmul")
16348 (match_operand:MODEF 3 "div_operator" "")
16349 (const_string "fdiv")
16351 (const_string "fop")))
16352 (set_attr "prefix" "orig,orig,maybe_vex")
16353 (set_attr "mode" "<MODE>")])
16355 (define_insn "*fop_<mode>_1_mixed"
16356 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16357 (match_operator:MODEF 3 "binary_fp_operator"
16358 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16359 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16360 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16361 && !COMMUTATIVE_ARITH_P (operands[3])
16362 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16363 "* return output_387_binary_op (insn, operands);"
16364 [(set (attr "type")
16365 (cond [(and (eq_attr "alternative" "2")
16366 (match_operand:MODEF 3 "mult_operator" ""))
16367 (const_string "ssemul")
16368 (and (eq_attr "alternative" "2")
16369 (match_operand:MODEF 3 "div_operator" ""))
16370 (const_string "ssediv")
16371 (eq_attr "alternative" "2")
16372 (const_string "sseadd")
16373 (match_operand:MODEF 3 "mult_operator" "")
16374 (const_string "fmul")
16375 (match_operand:MODEF 3 "div_operator" "")
16376 (const_string "fdiv")
16378 (const_string "fop")))
16379 (set_attr "mode" "<MODE>")])
16381 (define_insn "*rcpsf2_sse"
16382 [(set (match_operand:SF 0 "register_operand" "=x")
16383 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16386 "%vrcpss\t{%1, %d0|%d0, %1}"
16387 [(set_attr "type" "sse")
16388 (set_attr "prefix" "maybe_vex")
16389 (set_attr "mode" "SF")])
16391 (define_insn "*fop_<mode>_1_avx"
16392 [(set (match_operand:MODEF 0 "register_operand" "=x")
16393 (match_operator:MODEF 3 "binary_fp_operator"
16394 [(match_operand:MODEF 1 "register_operand" "x")
16395 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16396 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16397 && !COMMUTATIVE_ARITH_P (operands[3])"
16398 "* return output_387_binary_op (insn, operands);"
16399 [(set (attr "type")
16400 (cond [(match_operand:MODEF 3 "mult_operator" "")
16401 (const_string "ssemul")
16402 (match_operand:MODEF 3 "div_operator" "")
16403 (const_string "ssediv")
16405 (const_string "sseadd")))
16406 (set_attr "prefix" "vex")
16407 (set_attr "mode" "<MODE>")])
16409 (define_insn "*fop_<mode>_1_sse"
16410 [(set (match_operand:MODEF 0 "register_operand" "=x")
16411 (match_operator:MODEF 3 "binary_fp_operator"
16412 [(match_operand:MODEF 1 "register_operand" "0")
16413 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16414 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16415 && !COMMUTATIVE_ARITH_P (operands[3])"
16416 "* return output_387_binary_op (insn, operands);"
16417 [(set (attr "type")
16418 (cond [(match_operand:MODEF 3 "mult_operator" "")
16419 (const_string "ssemul")
16420 (match_operand:MODEF 3 "div_operator" "")
16421 (const_string "ssediv")
16423 (const_string "sseadd")))
16424 (set_attr "mode" "<MODE>")])
16426 ;; This pattern is not fully shadowed by the pattern above.
16427 (define_insn "*fop_<mode>_1_i387"
16428 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16429 (match_operator:MODEF 3 "binary_fp_operator"
16430 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16431 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16432 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16433 && !COMMUTATIVE_ARITH_P (operands[3])
16434 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16435 "* return output_387_binary_op (insn, operands);"
16436 [(set (attr "type")
16437 (cond [(match_operand:MODEF 3 "mult_operator" "")
16438 (const_string "fmul")
16439 (match_operand:MODEF 3 "div_operator" "")
16440 (const_string "fdiv")
16442 (const_string "fop")))
16443 (set_attr "mode" "<MODE>")])
16445 ;; ??? Add SSE splitters for these!
16446 (define_insn "*fop_<MODEF:mode>_2_i387"
16447 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16448 (match_operator:MODEF 3 "binary_fp_operator"
16450 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16451 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16452 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16453 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16454 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16455 [(set (attr "type")
16456 (cond [(match_operand:MODEF 3 "mult_operator" "")
16457 (const_string "fmul")
16458 (match_operand:MODEF 3 "div_operator" "")
16459 (const_string "fdiv")
16461 (const_string "fop")))
16462 (set_attr "fp_int_src" "true")
16463 (set_attr "mode" "<X87MODEI12:MODE>")])
16465 (define_insn "*fop_<MODEF:mode>_3_i387"
16466 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16467 (match_operator:MODEF 3 "binary_fp_operator"
16468 [(match_operand:MODEF 1 "register_operand" "0,0")
16470 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16471 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16472 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16473 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16474 [(set (attr "type")
16475 (cond [(match_operand:MODEF 3 "mult_operator" "")
16476 (const_string "fmul")
16477 (match_operand:MODEF 3 "div_operator" "")
16478 (const_string "fdiv")
16480 (const_string "fop")))
16481 (set_attr "fp_int_src" "true")
16482 (set_attr "mode" "<MODE>")])
16484 (define_insn "*fop_df_4_i387"
16485 [(set (match_operand:DF 0 "register_operand" "=f,f")
16486 (match_operator:DF 3 "binary_fp_operator"
16488 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16489 (match_operand:DF 2 "register_operand" "0,f")]))]
16490 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16491 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16492 "* return output_387_binary_op (insn, operands);"
16493 [(set (attr "type")
16494 (cond [(match_operand:DF 3 "mult_operator" "")
16495 (const_string "fmul")
16496 (match_operand:DF 3 "div_operator" "")
16497 (const_string "fdiv")
16499 (const_string "fop")))
16500 (set_attr "mode" "SF")])
16502 (define_insn "*fop_df_5_i387"
16503 [(set (match_operand:DF 0 "register_operand" "=f,f")
16504 (match_operator:DF 3 "binary_fp_operator"
16505 [(match_operand:DF 1 "register_operand" "0,f")
16507 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16508 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16509 "* return output_387_binary_op (insn, operands);"
16510 [(set (attr "type")
16511 (cond [(match_operand:DF 3 "mult_operator" "")
16512 (const_string "fmul")
16513 (match_operand:DF 3 "div_operator" "")
16514 (const_string "fdiv")
16516 (const_string "fop")))
16517 (set_attr "mode" "SF")])
16519 (define_insn "*fop_df_6_i387"
16520 [(set (match_operand:DF 0 "register_operand" "=f,f")
16521 (match_operator:DF 3 "binary_fp_operator"
16523 (match_operand:SF 1 "register_operand" "0,f"))
16525 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16526 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16527 "* return output_387_binary_op (insn, operands);"
16528 [(set (attr "type")
16529 (cond [(match_operand:DF 3 "mult_operator" "")
16530 (const_string "fmul")
16531 (match_operand:DF 3 "div_operator" "")
16532 (const_string "fdiv")
16534 (const_string "fop")))
16535 (set_attr "mode" "SF")])
16537 (define_insn "*fop_xf_comm_i387"
16538 [(set (match_operand:XF 0 "register_operand" "=f")
16539 (match_operator:XF 3 "binary_fp_operator"
16540 [(match_operand:XF 1 "register_operand" "%0")
16541 (match_operand:XF 2 "register_operand" "f")]))]
16543 && COMMUTATIVE_ARITH_P (operands[3])"
16544 "* return output_387_binary_op (insn, operands);"
16545 [(set (attr "type")
16546 (if_then_else (match_operand:XF 3 "mult_operator" "")
16547 (const_string "fmul")
16548 (const_string "fop")))
16549 (set_attr "mode" "XF")])
16551 (define_insn "*fop_xf_1_i387"
16552 [(set (match_operand:XF 0 "register_operand" "=f,f")
16553 (match_operator:XF 3 "binary_fp_operator"
16554 [(match_operand:XF 1 "register_operand" "0,f")
16555 (match_operand:XF 2 "register_operand" "f,0")]))]
16557 && !COMMUTATIVE_ARITH_P (operands[3])"
16558 "* return output_387_binary_op (insn, operands);"
16559 [(set (attr "type")
16560 (cond [(match_operand:XF 3 "mult_operator" "")
16561 (const_string "fmul")
16562 (match_operand:XF 3 "div_operator" "")
16563 (const_string "fdiv")
16565 (const_string "fop")))
16566 (set_attr "mode" "XF")])
16568 (define_insn "*fop_xf_2_i387"
16569 [(set (match_operand:XF 0 "register_operand" "=f,f")
16570 (match_operator:XF 3 "binary_fp_operator"
16572 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16573 (match_operand:XF 2 "register_operand" "0,0")]))]
16574 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16575 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16576 [(set (attr "type")
16577 (cond [(match_operand:XF 3 "mult_operator" "")
16578 (const_string "fmul")
16579 (match_operand:XF 3 "div_operator" "")
16580 (const_string "fdiv")
16582 (const_string "fop")))
16583 (set_attr "fp_int_src" "true")
16584 (set_attr "mode" "<MODE>")])
16586 (define_insn "*fop_xf_3_i387"
16587 [(set (match_operand:XF 0 "register_operand" "=f,f")
16588 (match_operator:XF 3 "binary_fp_operator"
16589 [(match_operand:XF 1 "register_operand" "0,0")
16591 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16592 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16593 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16594 [(set (attr "type")
16595 (cond [(match_operand:XF 3 "mult_operator" "")
16596 (const_string "fmul")
16597 (match_operand:XF 3 "div_operator" "")
16598 (const_string "fdiv")
16600 (const_string "fop")))
16601 (set_attr "fp_int_src" "true")
16602 (set_attr "mode" "<MODE>")])
16604 (define_insn "*fop_xf_4_i387"
16605 [(set (match_operand:XF 0 "register_operand" "=f,f")
16606 (match_operator:XF 3 "binary_fp_operator"
16608 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16609 (match_operand:XF 2 "register_operand" "0,f")]))]
16611 "* return output_387_binary_op (insn, operands);"
16612 [(set (attr "type")
16613 (cond [(match_operand:XF 3 "mult_operator" "")
16614 (const_string "fmul")
16615 (match_operand:XF 3 "div_operator" "")
16616 (const_string "fdiv")
16618 (const_string "fop")))
16619 (set_attr "mode" "<MODE>")])
16621 (define_insn "*fop_xf_5_i387"
16622 [(set (match_operand:XF 0 "register_operand" "=f,f")
16623 (match_operator:XF 3 "binary_fp_operator"
16624 [(match_operand:XF 1 "register_operand" "0,f")
16626 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16628 "* return output_387_binary_op (insn, operands);"
16629 [(set (attr "type")
16630 (cond [(match_operand:XF 3 "mult_operator" "")
16631 (const_string "fmul")
16632 (match_operand:XF 3 "div_operator" "")
16633 (const_string "fdiv")
16635 (const_string "fop")))
16636 (set_attr "mode" "<MODE>")])
16638 (define_insn "*fop_xf_6_i387"
16639 [(set (match_operand:XF 0 "register_operand" "=f,f")
16640 (match_operator:XF 3 "binary_fp_operator"
16642 (match_operand:MODEF 1 "register_operand" "0,f"))
16644 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16646 "* return output_387_binary_op (insn, operands);"
16647 [(set (attr "type")
16648 (cond [(match_operand:XF 3 "mult_operator" "")
16649 (const_string "fmul")
16650 (match_operand:XF 3 "div_operator" "")
16651 (const_string "fdiv")
16653 (const_string "fop")))
16654 (set_attr "mode" "<MODE>")])
16657 [(set (match_operand 0 "register_operand" "")
16658 (match_operator 3 "binary_fp_operator"
16659 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16660 (match_operand 2 "register_operand" "")]))]
16662 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16665 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16666 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16667 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16668 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16669 GET_MODE (operands[3]),
16672 ix86_free_from_memory (GET_MODE (operands[1]));
16677 [(set (match_operand 0 "register_operand" "")
16678 (match_operator 3 "binary_fp_operator"
16679 [(match_operand 1 "register_operand" "")
16680 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16682 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16685 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16686 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16687 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16688 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16689 GET_MODE (operands[3]),
16692 ix86_free_from_memory (GET_MODE (operands[2]));
16696 ;; FPU special functions.
16698 ;; This pattern implements a no-op XFmode truncation for
16699 ;; all fancy i386 XFmode math functions.
16701 (define_insn "truncxf<mode>2_i387_noop_unspec"
16702 [(set (match_operand:MODEF 0 "register_operand" "=f")
16703 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16704 UNSPEC_TRUNC_NOOP))]
16705 "TARGET_USE_FANCY_MATH_387"
16706 "* return output_387_reg_move (insn, operands);"
16707 [(set_attr "type" "fmov")
16708 (set_attr "mode" "<MODE>")])
16710 (define_insn "sqrtxf2"
16711 [(set (match_operand:XF 0 "register_operand" "=f")
16712 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16713 "TARGET_USE_FANCY_MATH_387"
16715 [(set_attr "type" "fpspc")
16716 (set_attr "mode" "XF")
16717 (set_attr "athlon_decode" "direct")
16718 (set_attr "amdfam10_decode" "direct")])
16720 (define_insn "sqrt_extend<mode>xf2_i387"
16721 [(set (match_operand:XF 0 "register_operand" "=f")
16724 (match_operand:MODEF 1 "register_operand" "0"))))]
16725 "TARGET_USE_FANCY_MATH_387"
16727 [(set_attr "type" "fpspc")
16728 (set_attr "mode" "XF")
16729 (set_attr "athlon_decode" "direct")
16730 (set_attr "amdfam10_decode" "direct")])
16732 (define_insn "*rsqrtsf2_sse"
16733 [(set (match_operand:SF 0 "register_operand" "=x")
16734 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16737 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16738 [(set_attr "type" "sse")
16739 (set_attr "prefix" "maybe_vex")
16740 (set_attr "mode" "SF")])
16742 (define_expand "rsqrtsf2"
16743 [(set (match_operand:SF 0 "register_operand" "")
16744 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16748 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16752 (define_insn "*sqrt<mode>2_sse"
16753 [(set (match_operand:MODEF 0 "register_operand" "=x")
16755 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16756 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16757 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16758 [(set_attr "type" "sse")
16759 (set_attr "prefix" "maybe_vex")
16760 (set_attr "mode" "<MODE>")
16761 (set_attr "athlon_decode" "*")
16762 (set_attr "amdfam10_decode" "*")])
16764 (define_expand "sqrt<mode>2"
16765 [(set (match_operand:MODEF 0 "register_operand" "")
16767 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16768 "TARGET_USE_FANCY_MATH_387
16769 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16771 if (<MODE>mode == SFmode
16772 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16773 && flag_finite_math_only && !flag_trapping_math
16774 && flag_unsafe_math_optimizations)
16776 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16780 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16782 rtx op0 = gen_reg_rtx (XFmode);
16783 rtx op1 = force_reg (<MODE>mode, operands[1]);
16785 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16786 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16791 (define_insn "fpremxf4_i387"
16792 [(set (match_operand:XF 0 "register_operand" "=f")
16793 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16794 (match_operand:XF 3 "register_operand" "1")]
16796 (set (match_operand:XF 1 "register_operand" "=u")
16797 (unspec:XF [(match_dup 2) (match_dup 3)]
16799 (set (reg:CCFP FPSR_REG)
16800 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16802 "TARGET_USE_FANCY_MATH_387"
16804 [(set_attr "type" "fpspc")
16805 (set_attr "mode" "XF")])
16807 (define_expand "fmodxf3"
16808 [(use (match_operand:XF 0 "register_operand" ""))
16809 (use (match_operand:XF 1 "general_operand" ""))
16810 (use (match_operand:XF 2 "general_operand" ""))]
16811 "TARGET_USE_FANCY_MATH_387"
16813 rtx label = gen_label_rtx ();
16815 rtx op1 = gen_reg_rtx (XFmode);
16816 rtx op2 = gen_reg_rtx (XFmode);
16818 emit_move_insn (op2, operands[2]);
16819 emit_move_insn (op1, operands[1]);
16821 emit_label (label);
16822 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16823 ix86_emit_fp_unordered_jump (label);
16824 LABEL_NUSES (label) = 1;
16826 emit_move_insn (operands[0], op1);
16830 (define_expand "fmod<mode>3"
16831 [(use (match_operand:MODEF 0 "register_operand" ""))
16832 (use (match_operand:MODEF 1 "general_operand" ""))
16833 (use (match_operand:MODEF 2 "general_operand" ""))]
16834 "TARGET_USE_FANCY_MATH_387"
16836 rtx label = gen_label_rtx ();
16838 rtx op1 = gen_reg_rtx (XFmode);
16839 rtx op2 = gen_reg_rtx (XFmode);
16841 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16842 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16844 emit_label (label);
16845 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16846 ix86_emit_fp_unordered_jump (label);
16847 LABEL_NUSES (label) = 1;
16849 /* Truncate the result properly for strict SSE math. */
16850 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16851 && !TARGET_MIX_SSE_I387)
16852 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16854 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16859 (define_insn "fprem1xf4_i387"
16860 [(set (match_operand:XF 0 "register_operand" "=f")
16861 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16862 (match_operand:XF 3 "register_operand" "1")]
16864 (set (match_operand:XF 1 "register_operand" "=u")
16865 (unspec:XF [(match_dup 2) (match_dup 3)]
16867 (set (reg:CCFP FPSR_REG)
16868 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16870 "TARGET_USE_FANCY_MATH_387"
16872 [(set_attr "type" "fpspc")
16873 (set_attr "mode" "XF")])
16875 (define_expand "remainderxf3"
16876 [(use (match_operand:XF 0 "register_operand" ""))
16877 (use (match_operand:XF 1 "general_operand" ""))
16878 (use (match_operand:XF 2 "general_operand" ""))]
16879 "TARGET_USE_FANCY_MATH_387"
16881 rtx label = gen_label_rtx ();
16883 rtx op1 = gen_reg_rtx (XFmode);
16884 rtx op2 = gen_reg_rtx (XFmode);
16886 emit_move_insn (op2, operands[2]);
16887 emit_move_insn (op1, operands[1]);
16889 emit_label (label);
16890 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16891 ix86_emit_fp_unordered_jump (label);
16892 LABEL_NUSES (label) = 1;
16894 emit_move_insn (operands[0], op1);
16898 (define_expand "remainder<mode>3"
16899 [(use (match_operand:MODEF 0 "register_operand" ""))
16900 (use (match_operand:MODEF 1 "general_operand" ""))
16901 (use (match_operand:MODEF 2 "general_operand" ""))]
16902 "TARGET_USE_FANCY_MATH_387"
16904 rtx label = gen_label_rtx ();
16906 rtx op1 = gen_reg_rtx (XFmode);
16907 rtx op2 = gen_reg_rtx (XFmode);
16909 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16910 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16912 emit_label (label);
16914 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16915 ix86_emit_fp_unordered_jump (label);
16916 LABEL_NUSES (label) = 1;
16918 /* Truncate the result properly for strict SSE math. */
16919 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16920 && !TARGET_MIX_SSE_I387)
16921 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16923 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16928 (define_insn "*sinxf2_i387"
16929 [(set (match_operand:XF 0 "register_operand" "=f")
16930 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16931 "TARGET_USE_FANCY_MATH_387
16932 && flag_unsafe_math_optimizations"
16934 [(set_attr "type" "fpspc")
16935 (set_attr "mode" "XF")])
16937 (define_insn "*sin_extend<mode>xf2_i387"
16938 [(set (match_operand:XF 0 "register_operand" "=f")
16939 (unspec:XF [(float_extend:XF
16940 (match_operand:MODEF 1 "register_operand" "0"))]
16942 "TARGET_USE_FANCY_MATH_387
16943 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16944 || TARGET_MIX_SSE_I387)
16945 && flag_unsafe_math_optimizations"
16947 [(set_attr "type" "fpspc")
16948 (set_attr "mode" "XF")])
16950 (define_insn "*cosxf2_i387"
16951 [(set (match_operand:XF 0 "register_operand" "=f")
16952 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16953 "TARGET_USE_FANCY_MATH_387
16954 && flag_unsafe_math_optimizations"
16956 [(set_attr "type" "fpspc")
16957 (set_attr "mode" "XF")])
16959 (define_insn "*cos_extend<mode>xf2_i387"
16960 [(set (match_operand:XF 0 "register_operand" "=f")
16961 (unspec:XF [(float_extend:XF
16962 (match_operand:MODEF 1 "register_operand" "0"))]
16964 "TARGET_USE_FANCY_MATH_387
16965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16966 || TARGET_MIX_SSE_I387)
16967 && flag_unsafe_math_optimizations"
16969 [(set_attr "type" "fpspc")
16970 (set_attr "mode" "XF")])
16972 ;; When sincos pattern is defined, sin and cos builtin functions will be
16973 ;; expanded to sincos pattern with one of its outputs left unused.
16974 ;; CSE pass will figure out if two sincos patterns can be combined,
16975 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16976 ;; depending on the unused output.
16978 (define_insn "sincosxf3"
16979 [(set (match_operand:XF 0 "register_operand" "=f")
16980 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16981 UNSPEC_SINCOS_COS))
16982 (set (match_operand:XF 1 "register_operand" "=u")
16983 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16984 "TARGET_USE_FANCY_MATH_387
16985 && flag_unsafe_math_optimizations"
16987 [(set_attr "type" "fpspc")
16988 (set_attr "mode" "XF")])
16991 [(set (match_operand:XF 0 "register_operand" "")
16992 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16993 UNSPEC_SINCOS_COS))
16994 (set (match_operand:XF 1 "register_operand" "")
16995 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16996 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16997 && !(reload_completed || reload_in_progress)"
16998 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17002 [(set (match_operand:XF 0 "register_operand" "")
17003 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17004 UNSPEC_SINCOS_COS))
17005 (set (match_operand:XF 1 "register_operand" "")
17006 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17007 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17008 && !(reload_completed || reload_in_progress)"
17009 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17012 (define_insn "sincos_extend<mode>xf3_i387"
17013 [(set (match_operand:XF 0 "register_operand" "=f")
17014 (unspec:XF [(float_extend:XF
17015 (match_operand:MODEF 2 "register_operand" "0"))]
17016 UNSPEC_SINCOS_COS))
17017 (set (match_operand:XF 1 "register_operand" "=u")
17018 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17019 "TARGET_USE_FANCY_MATH_387
17020 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17021 || TARGET_MIX_SSE_I387)
17022 && flag_unsafe_math_optimizations"
17024 [(set_attr "type" "fpspc")
17025 (set_attr "mode" "XF")])
17028 [(set (match_operand:XF 0 "register_operand" "")
17029 (unspec:XF [(float_extend:XF
17030 (match_operand:MODEF 2 "register_operand" ""))]
17031 UNSPEC_SINCOS_COS))
17032 (set (match_operand:XF 1 "register_operand" "")
17033 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17034 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17035 && !(reload_completed || reload_in_progress)"
17036 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17040 [(set (match_operand:XF 0 "register_operand" "")
17041 (unspec:XF [(float_extend:XF
17042 (match_operand:MODEF 2 "register_operand" ""))]
17043 UNSPEC_SINCOS_COS))
17044 (set (match_operand:XF 1 "register_operand" "")
17045 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17046 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17047 && !(reload_completed || reload_in_progress)"
17048 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17051 (define_expand "sincos<mode>3"
17052 [(use (match_operand:MODEF 0 "register_operand" ""))
17053 (use (match_operand:MODEF 1 "register_operand" ""))
17054 (use (match_operand:MODEF 2 "register_operand" ""))]
17055 "TARGET_USE_FANCY_MATH_387
17056 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17057 || TARGET_MIX_SSE_I387)
17058 && flag_unsafe_math_optimizations"
17060 rtx op0 = gen_reg_rtx (XFmode);
17061 rtx op1 = gen_reg_rtx (XFmode);
17063 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17064 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17065 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17069 (define_insn "fptanxf4_i387"
17070 [(set (match_operand:XF 0 "register_operand" "=f")
17071 (match_operand:XF 3 "const_double_operand" "F"))
17072 (set (match_operand:XF 1 "register_operand" "=u")
17073 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17075 "TARGET_USE_FANCY_MATH_387
17076 && flag_unsafe_math_optimizations
17077 && standard_80387_constant_p (operands[3]) == 2"
17079 [(set_attr "type" "fpspc")
17080 (set_attr "mode" "XF")])
17082 (define_insn "fptan_extend<mode>xf4_i387"
17083 [(set (match_operand:MODEF 0 "register_operand" "=f")
17084 (match_operand:MODEF 3 "const_double_operand" "F"))
17085 (set (match_operand:XF 1 "register_operand" "=u")
17086 (unspec:XF [(float_extend:XF
17087 (match_operand:MODEF 2 "register_operand" "0"))]
17089 "TARGET_USE_FANCY_MATH_387
17090 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17091 || TARGET_MIX_SSE_I387)
17092 && flag_unsafe_math_optimizations
17093 && standard_80387_constant_p (operands[3]) == 2"
17095 [(set_attr "type" "fpspc")
17096 (set_attr "mode" "XF")])
17098 (define_expand "tanxf2"
17099 [(use (match_operand:XF 0 "register_operand" ""))
17100 (use (match_operand:XF 1 "register_operand" ""))]
17101 "TARGET_USE_FANCY_MATH_387
17102 && flag_unsafe_math_optimizations"
17104 rtx one = gen_reg_rtx (XFmode);
17105 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17107 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17111 (define_expand "tan<mode>2"
17112 [(use (match_operand:MODEF 0 "register_operand" ""))
17113 (use (match_operand:MODEF 1 "register_operand" ""))]
17114 "TARGET_USE_FANCY_MATH_387
17115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17116 || TARGET_MIX_SSE_I387)
17117 && flag_unsafe_math_optimizations"
17119 rtx op0 = gen_reg_rtx (XFmode);
17121 rtx one = gen_reg_rtx (<MODE>mode);
17122 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17124 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17125 operands[1], op2));
17126 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17130 (define_insn "*fpatanxf3_i387"
17131 [(set (match_operand:XF 0 "register_operand" "=f")
17132 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17133 (match_operand:XF 2 "register_operand" "u")]
17135 (clobber (match_scratch:XF 3 "=2"))]
17136 "TARGET_USE_FANCY_MATH_387
17137 && flag_unsafe_math_optimizations"
17139 [(set_attr "type" "fpspc")
17140 (set_attr "mode" "XF")])
17142 (define_insn "fpatan_extend<mode>xf3_i387"
17143 [(set (match_operand:XF 0 "register_operand" "=f")
17144 (unspec:XF [(float_extend:XF
17145 (match_operand:MODEF 1 "register_operand" "0"))
17147 (match_operand:MODEF 2 "register_operand" "u"))]
17149 (clobber (match_scratch:XF 3 "=2"))]
17150 "TARGET_USE_FANCY_MATH_387
17151 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17152 || TARGET_MIX_SSE_I387)
17153 && flag_unsafe_math_optimizations"
17155 [(set_attr "type" "fpspc")
17156 (set_attr "mode" "XF")])
17158 (define_expand "atan2xf3"
17159 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17160 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17161 (match_operand:XF 1 "register_operand" "")]
17163 (clobber (match_scratch:XF 3 ""))])]
17164 "TARGET_USE_FANCY_MATH_387
17165 && flag_unsafe_math_optimizations"
17168 (define_expand "atan2<mode>3"
17169 [(use (match_operand:MODEF 0 "register_operand" ""))
17170 (use (match_operand:MODEF 1 "register_operand" ""))
17171 (use (match_operand:MODEF 2 "register_operand" ""))]
17172 "TARGET_USE_FANCY_MATH_387
17173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17174 || TARGET_MIX_SSE_I387)
17175 && flag_unsafe_math_optimizations"
17177 rtx op0 = gen_reg_rtx (XFmode);
17179 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17180 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17184 (define_expand "atanxf2"
17185 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17186 (unspec:XF [(match_dup 2)
17187 (match_operand:XF 1 "register_operand" "")]
17189 (clobber (match_scratch:XF 3 ""))])]
17190 "TARGET_USE_FANCY_MATH_387
17191 && flag_unsafe_math_optimizations"
17193 operands[2] = gen_reg_rtx (XFmode);
17194 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17197 (define_expand "atan<mode>2"
17198 [(use (match_operand:MODEF 0 "register_operand" ""))
17199 (use (match_operand:MODEF 1 "register_operand" ""))]
17200 "TARGET_USE_FANCY_MATH_387
17201 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17202 || TARGET_MIX_SSE_I387)
17203 && flag_unsafe_math_optimizations"
17205 rtx op0 = gen_reg_rtx (XFmode);
17207 rtx op2 = gen_reg_rtx (<MODE>mode);
17208 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17210 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17211 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17215 (define_expand "asinxf2"
17216 [(set (match_dup 2)
17217 (mult:XF (match_operand:XF 1 "register_operand" "")
17219 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17220 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17221 (parallel [(set (match_operand:XF 0 "register_operand" "")
17222 (unspec:XF [(match_dup 5) (match_dup 1)]
17224 (clobber (match_scratch:XF 6 ""))])]
17225 "TARGET_USE_FANCY_MATH_387
17226 && flag_unsafe_math_optimizations"
17230 if (optimize_insn_for_size_p ())
17233 for (i = 2; i < 6; i++)
17234 operands[i] = gen_reg_rtx (XFmode);
17236 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17239 (define_expand "asin<mode>2"
17240 [(use (match_operand:MODEF 0 "register_operand" ""))
17241 (use (match_operand:MODEF 1 "general_operand" ""))]
17242 "TARGET_USE_FANCY_MATH_387
17243 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17244 || TARGET_MIX_SSE_I387)
17245 && flag_unsafe_math_optimizations"
17247 rtx op0 = gen_reg_rtx (XFmode);
17248 rtx op1 = gen_reg_rtx (XFmode);
17250 if (optimize_insn_for_size_p ())
17253 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17254 emit_insn (gen_asinxf2 (op0, op1));
17255 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17259 (define_expand "acosxf2"
17260 [(set (match_dup 2)
17261 (mult:XF (match_operand:XF 1 "register_operand" "")
17263 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17264 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17265 (parallel [(set (match_operand:XF 0 "register_operand" "")
17266 (unspec:XF [(match_dup 1) (match_dup 5)]
17268 (clobber (match_scratch:XF 6 ""))])]
17269 "TARGET_USE_FANCY_MATH_387
17270 && flag_unsafe_math_optimizations"
17274 if (optimize_insn_for_size_p ())
17277 for (i = 2; i < 6; i++)
17278 operands[i] = gen_reg_rtx (XFmode);
17280 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17283 (define_expand "acos<mode>2"
17284 [(use (match_operand:MODEF 0 "register_operand" ""))
17285 (use (match_operand:MODEF 1 "general_operand" ""))]
17286 "TARGET_USE_FANCY_MATH_387
17287 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17288 || TARGET_MIX_SSE_I387)
17289 && flag_unsafe_math_optimizations"
17291 rtx op0 = gen_reg_rtx (XFmode);
17292 rtx op1 = gen_reg_rtx (XFmode);
17294 if (optimize_insn_for_size_p ())
17297 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17298 emit_insn (gen_acosxf2 (op0, op1));
17299 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17303 (define_insn "fyl2xxf3_i387"
17304 [(set (match_operand:XF 0 "register_operand" "=f")
17305 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17306 (match_operand:XF 2 "register_operand" "u")]
17308 (clobber (match_scratch:XF 3 "=2"))]
17309 "TARGET_USE_FANCY_MATH_387
17310 && flag_unsafe_math_optimizations"
17312 [(set_attr "type" "fpspc")
17313 (set_attr "mode" "XF")])
17315 (define_insn "fyl2x_extend<mode>xf3_i387"
17316 [(set (match_operand:XF 0 "register_operand" "=f")
17317 (unspec:XF [(float_extend:XF
17318 (match_operand:MODEF 1 "register_operand" "0"))
17319 (match_operand:XF 2 "register_operand" "u")]
17321 (clobber (match_scratch:XF 3 "=2"))]
17322 "TARGET_USE_FANCY_MATH_387
17323 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17324 || TARGET_MIX_SSE_I387)
17325 && flag_unsafe_math_optimizations"
17327 [(set_attr "type" "fpspc")
17328 (set_attr "mode" "XF")])
17330 (define_expand "logxf2"
17331 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17332 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17333 (match_dup 2)] UNSPEC_FYL2X))
17334 (clobber (match_scratch:XF 3 ""))])]
17335 "TARGET_USE_FANCY_MATH_387
17336 && flag_unsafe_math_optimizations"
17338 operands[2] = gen_reg_rtx (XFmode);
17339 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17342 (define_expand "log<mode>2"
17343 [(use (match_operand:MODEF 0 "register_operand" ""))
17344 (use (match_operand:MODEF 1 "register_operand" ""))]
17345 "TARGET_USE_FANCY_MATH_387
17346 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17347 || TARGET_MIX_SSE_I387)
17348 && flag_unsafe_math_optimizations"
17350 rtx op0 = gen_reg_rtx (XFmode);
17352 rtx op2 = gen_reg_rtx (XFmode);
17353 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17355 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17356 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17360 (define_expand "log10xf2"
17361 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17362 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17363 (match_dup 2)] UNSPEC_FYL2X))
17364 (clobber (match_scratch:XF 3 ""))])]
17365 "TARGET_USE_FANCY_MATH_387
17366 && flag_unsafe_math_optimizations"
17368 operands[2] = gen_reg_rtx (XFmode);
17369 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17372 (define_expand "log10<mode>2"
17373 [(use (match_operand:MODEF 0 "register_operand" ""))
17374 (use (match_operand:MODEF 1 "register_operand" ""))]
17375 "TARGET_USE_FANCY_MATH_387
17376 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17377 || TARGET_MIX_SSE_I387)
17378 && flag_unsafe_math_optimizations"
17380 rtx op0 = gen_reg_rtx (XFmode);
17382 rtx op2 = gen_reg_rtx (XFmode);
17383 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17385 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17386 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17390 (define_expand "log2xf2"
17391 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17392 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17393 (match_dup 2)] UNSPEC_FYL2X))
17394 (clobber (match_scratch:XF 3 ""))])]
17395 "TARGET_USE_FANCY_MATH_387
17396 && flag_unsafe_math_optimizations"
17398 operands[2] = gen_reg_rtx (XFmode);
17399 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17402 (define_expand "log2<mode>2"
17403 [(use (match_operand:MODEF 0 "register_operand" ""))
17404 (use (match_operand:MODEF 1 "register_operand" ""))]
17405 "TARGET_USE_FANCY_MATH_387
17406 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17407 || TARGET_MIX_SSE_I387)
17408 && flag_unsafe_math_optimizations"
17410 rtx op0 = gen_reg_rtx (XFmode);
17412 rtx op2 = gen_reg_rtx (XFmode);
17413 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17415 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17416 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17420 (define_insn "fyl2xp1xf3_i387"
17421 [(set (match_operand:XF 0 "register_operand" "=f")
17422 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17423 (match_operand:XF 2 "register_operand" "u")]
17425 (clobber (match_scratch:XF 3 "=2"))]
17426 "TARGET_USE_FANCY_MATH_387
17427 && flag_unsafe_math_optimizations"
17429 [(set_attr "type" "fpspc")
17430 (set_attr "mode" "XF")])
17432 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17433 [(set (match_operand:XF 0 "register_operand" "=f")
17434 (unspec:XF [(float_extend:XF
17435 (match_operand:MODEF 1 "register_operand" "0"))
17436 (match_operand:XF 2 "register_operand" "u")]
17438 (clobber (match_scratch:XF 3 "=2"))]
17439 "TARGET_USE_FANCY_MATH_387
17440 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17441 || TARGET_MIX_SSE_I387)
17442 && flag_unsafe_math_optimizations"
17444 [(set_attr "type" "fpspc")
17445 (set_attr "mode" "XF")])
17447 (define_expand "log1pxf2"
17448 [(use (match_operand:XF 0 "register_operand" ""))
17449 (use (match_operand:XF 1 "register_operand" ""))]
17450 "TARGET_USE_FANCY_MATH_387
17451 && flag_unsafe_math_optimizations"
17453 if (optimize_insn_for_size_p ())
17456 ix86_emit_i387_log1p (operands[0], operands[1]);
17460 (define_expand "log1p<mode>2"
17461 [(use (match_operand:MODEF 0 "register_operand" ""))
17462 (use (match_operand:MODEF 1 "register_operand" ""))]
17463 "TARGET_USE_FANCY_MATH_387
17464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17465 || TARGET_MIX_SSE_I387)
17466 && flag_unsafe_math_optimizations"
17470 if (optimize_insn_for_size_p ())
17473 op0 = gen_reg_rtx (XFmode);
17475 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17477 ix86_emit_i387_log1p (op0, operands[1]);
17478 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17482 (define_insn "fxtractxf3_i387"
17483 [(set (match_operand:XF 0 "register_operand" "=f")
17484 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17485 UNSPEC_XTRACT_FRACT))
17486 (set (match_operand:XF 1 "register_operand" "=u")
17487 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17488 "TARGET_USE_FANCY_MATH_387
17489 && flag_unsafe_math_optimizations"
17491 [(set_attr "type" "fpspc")
17492 (set_attr "mode" "XF")])
17494 (define_insn "fxtract_extend<mode>xf3_i387"
17495 [(set (match_operand:XF 0 "register_operand" "=f")
17496 (unspec:XF [(float_extend:XF
17497 (match_operand:MODEF 2 "register_operand" "0"))]
17498 UNSPEC_XTRACT_FRACT))
17499 (set (match_operand:XF 1 "register_operand" "=u")
17500 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17501 "TARGET_USE_FANCY_MATH_387
17502 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17503 || TARGET_MIX_SSE_I387)
17504 && flag_unsafe_math_optimizations"
17506 [(set_attr "type" "fpspc")
17507 (set_attr "mode" "XF")])
17509 (define_expand "logbxf2"
17510 [(parallel [(set (match_dup 2)
17511 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17512 UNSPEC_XTRACT_FRACT))
17513 (set (match_operand:XF 0 "register_operand" "")
17514 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17515 "TARGET_USE_FANCY_MATH_387
17516 && flag_unsafe_math_optimizations"
17518 operands[2] = gen_reg_rtx (XFmode);
17521 (define_expand "logb<mode>2"
17522 [(use (match_operand:MODEF 0 "register_operand" ""))
17523 (use (match_operand:MODEF 1 "register_operand" ""))]
17524 "TARGET_USE_FANCY_MATH_387
17525 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17526 || TARGET_MIX_SSE_I387)
17527 && flag_unsafe_math_optimizations"
17529 rtx op0 = gen_reg_rtx (XFmode);
17530 rtx op1 = gen_reg_rtx (XFmode);
17532 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17533 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17537 (define_expand "ilogbxf2"
17538 [(use (match_operand:SI 0 "register_operand" ""))
17539 (use (match_operand:XF 1 "register_operand" ""))]
17540 "TARGET_USE_FANCY_MATH_387
17541 && flag_unsafe_math_optimizations"
17545 if (optimize_insn_for_size_p ())
17548 op0 = gen_reg_rtx (XFmode);
17549 op1 = gen_reg_rtx (XFmode);
17551 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17552 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17556 (define_expand "ilogb<mode>2"
17557 [(use (match_operand:SI 0 "register_operand" ""))
17558 (use (match_operand:MODEF 1 "register_operand" ""))]
17559 "TARGET_USE_FANCY_MATH_387
17560 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17561 || TARGET_MIX_SSE_I387)
17562 && flag_unsafe_math_optimizations"
17566 if (optimize_insn_for_size_p ())
17569 op0 = gen_reg_rtx (XFmode);
17570 op1 = gen_reg_rtx (XFmode);
17572 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17573 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17577 (define_insn "*f2xm1xf2_i387"
17578 [(set (match_operand:XF 0 "register_operand" "=f")
17579 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17581 "TARGET_USE_FANCY_MATH_387
17582 && flag_unsafe_math_optimizations"
17584 [(set_attr "type" "fpspc")
17585 (set_attr "mode" "XF")])
17587 (define_insn "*fscalexf4_i387"
17588 [(set (match_operand:XF 0 "register_operand" "=f")
17589 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17590 (match_operand:XF 3 "register_operand" "1")]
17591 UNSPEC_FSCALE_FRACT))
17592 (set (match_operand:XF 1 "register_operand" "=u")
17593 (unspec:XF [(match_dup 2) (match_dup 3)]
17594 UNSPEC_FSCALE_EXP))]
17595 "TARGET_USE_FANCY_MATH_387
17596 && flag_unsafe_math_optimizations"
17598 [(set_attr "type" "fpspc")
17599 (set_attr "mode" "XF")])
17601 (define_expand "expNcorexf3"
17602 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17603 (match_operand:XF 2 "register_operand" "")))
17604 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17605 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17606 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17607 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17608 (parallel [(set (match_operand:XF 0 "register_operand" "")
17609 (unspec:XF [(match_dup 8) (match_dup 4)]
17610 UNSPEC_FSCALE_FRACT))
17612 (unspec:XF [(match_dup 8) (match_dup 4)]
17613 UNSPEC_FSCALE_EXP))])]
17614 "TARGET_USE_FANCY_MATH_387
17615 && flag_unsafe_math_optimizations"
17619 if (optimize_insn_for_size_p ())
17622 for (i = 3; i < 10; i++)
17623 operands[i] = gen_reg_rtx (XFmode);
17625 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17628 (define_expand "expxf2"
17629 [(use (match_operand:XF 0 "register_operand" ""))
17630 (use (match_operand:XF 1 "register_operand" ""))]
17631 "TARGET_USE_FANCY_MATH_387
17632 && flag_unsafe_math_optimizations"
17636 if (optimize_insn_for_size_p ())
17639 op2 = gen_reg_rtx (XFmode);
17640 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17642 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17646 (define_expand "exp<mode>2"
17647 [(use (match_operand:MODEF 0 "register_operand" ""))
17648 (use (match_operand:MODEF 1 "general_operand" ""))]
17649 "TARGET_USE_FANCY_MATH_387
17650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17651 || TARGET_MIX_SSE_I387)
17652 && flag_unsafe_math_optimizations"
17656 if (optimize_insn_for_size_p ())
17659 op0 = gen_reg_rtx (XFmode);
17660 op1 = gen_reg_rtx (XFmode);
17662 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17663 emit_insn (gen_expxf2 (op0, op1));
17664 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17668 (define_expand "exp10xf2"
17669 [(use (match_operand:XF 0 "register_operand" ""))
17670 (use (match_operand:XF 1 "register_operand" ""))]
17671 "TARGET_USE_FANCY_MATH_387
17672 && flag_unsafe_math_optimizations"
17676 if (optimize_insn_for_size_p ())
17679 op2 = gen_reg_rtx (XFmode);
17680 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17682 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17686 (define_expand "exp10<mode>2"
17687 [(use (match_operand:MODEF 0 "register_operand" ""))
17688 (use (match_operand:MODEF 1 "general_operand" ""))]
17689 "TARGET_USE_FANCY_MATH_387
17690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17691 || TARGET_MIX_SSE_I387)
17692 && flag_unsafe_math_optimizations"
17696 if (optimize_insn_for_size_p ())
17699 op0 = gen_reg_rtx (XFmode);
17700 op1 = gen_reg_rtx (XFmode);
17702 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17703 emit_insn (gen_exp10xf2 (op0, op1));
17704 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17708 (define_expand "exp2xf2"
17709 [(use (match_operand:XF 0 "register_operand" ""))
17710 (use (match_operand:XF 1 "register_operand" ""))]
17711 "TARGET_USE_FANCY_MATH_387
17712 && flag_unsafe_math_optimizations"
17716 if (optimize_insn_for_size_p ())
17719 op2 = gen_reg_rtx (XFmode);
17720 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17722 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17726 (define_expand "exp2<mode>2"
17727 [(use (match_operand:MODEF 0 "register_operand" ""))
17728 (use (match_operand:MODEF 1 "general_operand" ""))]
17729 "TARGET_USE_FANCY_MATH_387
17730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17731 || TARGET_MIX_SSE_I387)
17732 && flag_unsafe_math_optimizations"
17736 if (optimize_insn_for_size_p ())
17739 op0 = gen_reg_rtx (XFmode);
17740 op1 = gen_reg_rtx (XFmode);
17742 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17743 emit_insn (gen_exp2xf2 (op0, op1));
17744 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17748 (define_expand "expm1xf2"
17749 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17751 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17752 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17753 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17754 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17755 (parallel [(set (match_dup 7)
17756 (unspec:XF [(match_dup 6) (match_dup 4)]
17757 UNSPEC_FSCALE_FRACT))
17759 (unspec:XF [(match_dup 6) (match_dup 4)]
17760 UNSPEC_FSCALE_EXP))])
17761 (parallel [(set (match_dup 10)
17762 (unspec:XF [(match_dup 9) (match_dup 8)]
17763 UNSPEC_FSCALE_FRACT))
17764 (set (match_dup 11)
17765 (unspec:XF [(match_dup 9) (match_dup 8)]
17766 UNSPEC_FSCALE_EXP))])
17767 (set (match_dup 12) (minus:XF (match_dup 10)
17768 (float_extend:XF (match_dup 13))))
17769 (set (match_operand:XF 0 "register_operand" "")
17770 (plus:XF (match_dup 12) (match_dup 7)))]
17771 "TARGET_USE_FANCY_MATH_387
17772 && flag_unsafe_math_optimizations"
17776 if (optimize_insn_for_size_p ())
17779 for (i = 2; i < 13; i++)
17780 operands[i] = gen_reg_rtx (XFmode);
17783 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17785 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17788 (define_expand "expm1<mode>2"
17789 [(use (match_operand:MODEF 0 "register_operand" ""))
17790 (use (match_operand:MODEF 1 "general_operand" ""))]
17791 "TARGET_USE_FANCY_MATH_387
17792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17793 || TARGET_MIX_SSE_I387)
17794 && flag_unsafe_math_optimizations"
17798 if (optimize_insn_for_size_p ())
17801 op0 = gen_reg_rtx (XFmode);
17802 op1 = gen_reg_rtx (XFmode);
17804 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17805 emit_insn (gen_expm1xf2 (op0, op1));
17806 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17810 (define_expand "ldexpxf3"
17811 [(set (match_dup 3)
17812 (float:XF (match_operand:SI 2 "register_operand" "")))
17813 (parallel [(set (match_operand:XF 0 " register_operand" "")
17814 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17816 UNSPEC_FSCALE_FRACT))
17818 (unspec:XF [(match_dup 1) (match_dup 3)]
17819 UNSPEC_FSCALE_EXP))])]
17820 "TARGET_USE_FANCY_MATH_387
17821 && flag_unsafe_math_optimizations"
17823 if (optimize_insn_for_size_p ())
17826 operands[3] = gen_reg_rtx (XFmode);
17827 operands[4] = gen_reg_rtx (XFmode);
17830 (define_expand "ldexp<mode>3"
17831 [(use (match_operand:MODEF 0 "register_operand" ""))
17832 (use (match_operand:MODEF 1 "general_operand" ""))
17833 (use (match_operand:SI 2 "register_operand" ""))]
17834 "TARGET_USE_FANCY_MATH_387
17835 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17836 || TARGET_MIX_SSE_I387)
17837 && flag_unsafe_math_optimizations"
17841 if (optimize_insn_for_size_p ())
17844 op0 = gen_reg_rtx (XFmode);
17845 op1 = gen_reg_rtx (XFmode);
17847 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17848 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17849 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17853 (define_expand "scalbxf3"
17854 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17855 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17856 (match_operand:XF 2 "register_operand" "")]
17857 UNSPEC_FSCALE_FRACT))
17859 (unspec:XF [(match_dup 1) (match_dup 2)]
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);
17870 (define_expand "scalb<mode>3"
17871 [(use (match_operand:MODEF 0 "register_operand" ""))
17872 (use (match_operand:MODEF 1 "general_operand" ""))
17873 (use (match_operand:MODEF 2 "register_operand" ""))]
17874 "TARGET_USE_FANCY_MATH_387
17875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17876 || TARGET_MIX_SSE_I387)
17877 && flag_unsafe_math_optimizations"
17881 if (optimize_insn_for_size_p ())
17884 op0 = gen_reg_rtx (XFmode);
17885 op1 = gen_reg_rtx (XFmode);
17886 op2 = gen_reg_rtx (XFmode);
17888 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17889 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17890 emit_insn (gen_scalbxf3 (op0, op1, op2));
17891 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17896 (define_insn "sse4_1_round<mode>2"
17897 [(set (match_operand:MODEF 0 "register_operand" "=x")
17898 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17899 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17902 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17903 [(set_attr "type" "ssecvt")
17904 (set_attr "prefix_extra" "1")
17905 (set_attr "prefix" "maybe_vex")
17906 (set_attr "mode" "<MODE>")])
17908 (define_insn "rintxf2"
17909 [(set (match_operand:XF 0 "register_operand" "=f")
17910 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17912 "TARGET_USE_FANCY_MATH_387
17913 && flag_unsafe_math_optimizations"
17915 [(set_attr "type" "fpspc")
17916 (set_attr "mode" "XF")])
17918 (define_expand "rint<mode>2"
17919 [(use (match_operand:MODEF 0 "register_operand" ""))
17920 (use (match_operand:MODEF 1 "register_operand" ""))]
17921 "(TARGET_USE_FANCY_MATH_387
17922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17923 || TARGET_MIX_SSE_I387)
17924 && flag_unsafe_math_optimizations)
17925 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17926 && !flag_trapping_math)"
17928 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17929 && !flag_trapping_math)
17931 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17934 emit_insn (gen_sse4_1_round<mode>2
17935 (operands[0], operands[1], GEN_INT (0x04)));
17937 ix86_expand_rint (operand0, operand1);
17941 rtx op0 = gen_reg_rtx (XFmode);
17942 rtx op1 = gen_reg_rtx (XFmode);
17944 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17945 emit_insn (gen_rintxf2 (op0, op1));
17947 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17952 (define_expand "round<mode>2"
17953 [(match_operand:MODEF 0 "register_operand" "")
17954 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17955 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17956 && !flag_trapping_math && !flag_rounding_math"
17958 if (optimize_insn_for_size_p ())
17960 if (TARGET_64BIT || (<MODE>mode != DFmode))
17961 ix86_expand_round (operand0, operand1);
17963 ix86_expand_rounddf_32 (operand0, operand1);
17967 (define_insn_and_split "*fistdi2_1"
17968 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17969 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17971 "TARGET_USE_FANCY_MATH_387
17972 && !(reload_completed || reload_in_progress)"
17977 if (memory_operand (operands[0], VOIDmode))
17978 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17981 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17982 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17987 [(set_attr "type" "fpspc")
17988 (set_attr "mode" "DI")])
17990 (define_insn "fistdi2"
17991 [(set (match_operand:DI 0 "memory_operand" "=m")
17992 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17994 (clobber (match_scratch:XF 2 "=&1f"))]
17995 "TARGET_USE_FANCY_MATH_387"
17996 "* return output_fix_trunc (insn, operands, 0);"
17997 [(set_attr "type" "fpspc")
17998 (set_attr "mode" "DI")])
18000 (define_insn "fistdi2_with_temp"
18001 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18002 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18004 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18005 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18006 "TARGET_USE_FANCY_MATH_387"
18008 [(set_attr "type" "fpspc")
18009 (set_attr "mode" "DI")])
18012 [(set (match_operand:DI 0 "register_operand" "")
18013 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18015 (clobber (match_operand:DI 2 "memory_operand" ""))
18016 (clobber (match_scratch 3 ""))]
18018 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18019 (clobber (match_dup 3))])
18020 (set (match_dup 0) (match_dup 2))]
18024 [(set (match_operand:DI 0 "memory_operand" "")
18025 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18027 (clobber (match_operand:DI 2 "memory_operand" ""))
18028 (clobber (match_scratch 3 ""))]
18030 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18031 (clobber (match_dup 3))])]
18034 (define_insn_and_split "*fist<mode>2_1"
18035 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18036 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18038 "TARGET_USE_FANCY_MATH_387
18039 && !(reload_completed || reload_in_progress)"
18044 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18045 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18049 [(set_attr "type" "fpspc")
18050 (set_attr "mode" "<MODE>")])
18052 (define_insn "fist<mode>2"
18053 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18054 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18056 "TARGET_USE_FANCY_MATH_387"
18057 "* return output_fix_trunc (insn, operands, 0);"
18058 [(set_attr "type" "fpspc")
18059 (set_attr "mode" "<MODE>")])
18061 (define_insn "fist<mode>2_with_temp"
18062 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18063 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18065 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18066 "TARGET_USE_FANCY_MATH_387"
18068 [(set_attr "type" "fpspc")
18069 (set_attr "mode" "<MODE>")])
18072 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18073 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18075 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18077 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18078 (set (match_dup 0) (match_dup 2))]
18082 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18083 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18085 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18087 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18090 (define_expand "lrintxf<mode>2"
18091 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18092 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18094 "TARGET_USE_FANCY_MATH_387"
18097 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18098 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18099 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18100 UNSPEC_FIX_NOTRUNC))]
18101 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18102 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18105 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18106 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18107 (match_operand:MODEF 1 "register_operand" "")]
18108 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18109 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18110 && !flag_trapping_math && !flag_rounding_math"
18112 if (optimize_insn_for_size_p ())
18114 ix86_expand_lround (operand0, operand1);
18118 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18119 (define_insn_and_split "frndintxf2_floor"
18120 [(set (match_operand:XF 0 "register_operand" "")
18121 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18122 UNSPEC_FRNDINT_FLOOR))
18123 (clobber (reg:CC FLAGS_REG))]
18124 "TARGET_USE_FANCY_MATH_387
18125 && flag_unsafe_math_optimizations
18126 && !(reload_completed || reload_in_progress)"
18131 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18133 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18134 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18136 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18137 operands[2], operands[3]));
18140 [(set_attr "type" "frndint")
18141 (set_attr "i387_cw" "floor")
18142 (set_attr "mode" "XF")])
18144 (define_insn "frndintxf2_floor_i387"
18145 [(set (match_operand:XF 0 "register_operand" "=f")
18146 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18147 UNSPEC_FRNDINT_FLOOR))
18148 (use (match_operand:HI 2 "memory_operand" "m"))
18149 (use (match_operand:HI 3 "memory_operand" "m"))]
18150 "TARGET_USE_FANCY_MATH_387
18151 && flag_unsafe_math_optimizations"
18152 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18153 [(set_attr "type" "frndint")
18154 (set_attr "i387_cw" "floor")
18155 (set_attr "mode" "XF")])
18157 (define_expand "floorxf2"
18158 [(use (match_operand:XF 0 "register_operand" ""))
18159 (use (match_operand:XF 1 "register_operand" ""))]
18160 "TARGET_USE_FANCY_MATH_387
18161 && flag_unsafe_math_optimizations"
18163 if (optimize_insn_for_size_p ())
18165 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18169 (define_expand "floor<mode>2"
18170 [(use (match_operand:MODEF 0 "register_operand" ""))
18171 (use (match_operand:MODEF 1 "register_operand" ""))]
18172 "(TARGET_USE_FANCY_MATH_387
18173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18174 || TARGET_MIX_SSE_I387)
18175 && flag_unsafe_math_optimizations)
18176 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18177 && !flag_trapping_math)"
18179 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18180 && !flag_trapping_math
18181 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18183 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18186 emit_insn (gen_sse4_1_round<mode>2
18187 (operands[0], operands[1], GEN_INT (0x01)));
18188 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18189 ix86_expand_floorceil (operand0, operand1, true);
18191 ix86_expand_floorceildf_32 (operand0, operand1, true);
18197 if (optimize_insn_for_size_p ())
18200 op0 = gen_reg_rtx (XFmode);
18201 op1 = gen_reg_rtx (XFmode);
18202 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18203 emit_insn (gen_frndintxf2_floor (op0, op1));
18205 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18210 (define_insn_and_split "*fist<mode>2_floor_1"
18211 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18212 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18213 UNSPEC_FIST_FLOOR))
18214 (clobber (reg:CC FLAGS_REG))]
18215 "TARGET_USE_FANCY_MATH_387
18216 && flag_unsafe_math_optimizations
18217 && !(reload_completed || reload_in_progress)"
18222 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18224 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18225 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18226 if (memory_operand (operands[0], VOIDmode))
18227 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18228 operands[2], operands[3]));
18231 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18232 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18233 operands[2], operands[3],
18238 [(set_attr "type" "fistp")
18239 (set_attr "i387_cw" "floor")
18240 (set_attr "mode" "<MODE>")])
18242 (define_insn "fistdi2_floor"
18243 [(set (match_operand:DI 0 "memory_operand" "=m")
18244 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18245 UNSPEC_FIST_FLOOR))
18246 (use (match_operand:HI 2 "memory_operand" "m"))
18247 (use (match_operand:HI 3 "memory_operand" "m"))
18248 (clobber (match_scratch:XF 4 "=&1f"))]
18249 "TARGET_USE_FANCY_MATH_387
18250 && flag_unsafe_math_optimizations"
18251 "* return output_fix_trunc (insn, operands, 0);"
18252 [(set_attr "type" "fistp")
18253 (set_attr "i387_cw" "floor")
18254 (set_attr "mode" "DI")])
18256 (define_insn "fistdi2_floor_with_temp"
18257 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18258 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18259 UNSPEC_FIST_FLOOR))
18260 (use (match_operand:HI 2 "memory_operand" "m,m"))
18261 (use (match_operand:HI 3 "memory_operand" "m,m"))
18262 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18263 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18264 "TARGET_USE_FANCY_MATH_387
18265 && flag_unsafe_math_optimizations"
18267 [(set_attr "type" "fistp")
18268 (set_attr "i387_cw" "floor")
18269 (set_attr "mode" "DI")])
18272 [(set (match_operand:DI 0 "register_operand" "")
18273 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18274 UNSPEC_FIST_FLOOR))
18275 (use (match_operand:HI 2 "memory_operand" ""))
18276 (use (match_operand:HI 3 "memory_operand" ""))
18277 (clobber (match_operand:DI 4 "memory_operand" ""))
18278 (clobber (match_scratch 5 ""))]
18280 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18281 (use (match_dup 2))
18282 (use (match_dup 3))
18283 (clobber (match_dup 5))])
18284 (set (match_dup 0) (match_dup 4))]
18288 [(set (match_operand:DI 0 "memory_operand" "")
18289 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18290 UNSPEC_FIST_FLOOR))
18291 (use (match_operand:HI 2 "memory_operand" ""))
18292 (use (match_operand:HI 3 "memory_operand" ""))
18293 (clobber (match_operand:DI 4 "memory_operand" ""))
18294 (clobber (match_scratch 5 ""))]
18296 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18297 (use (match_dup 2))
18298 (use (match_dup 3))
18299 (clobber (match_dup 5))])]
18302 (define_insn "fist<mode>2_floor"
18303 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18304 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18305 UNSPEC_FIST_FLOOR))
18306 (use (match_operand:HI 2 "memory_operand" "m"))
18307 (use (match_operand:HI 3 "memory_operand" "m"))]
18308 "TARGET_USE_FANCY_MATH_387
18309 && flag_unsafe_math_optimizations"
18310 "* return output_fix_trunc (insn, operands, 0);"
18311 [(set_attr "type" "fistp")
18312 (set_attr "i387_cw" "floor")
18313 (set_attr "mode" "<MODE>")])
18315 (define_insn "fist<mode>2_floor_with_temp"
18316 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18317 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18318 UNSPEC_FIST_FLOOR))
18319 (use (match_operand:HI 2 "memory_operand" "m,m"))
18320 (use (match_operand:HI 3 "memory_operand" "m,m"))
18321 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18322 "TARGET_USE_FANCY_MATH_387
18323 && flag_unsafe_math_optimizations"
18325 [(set_attr "type" "fistp")
18326 (set_attr "i387_cw" "floor")
18327 (set_attr "mode" "<MODE>")])
18330 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18331 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18332 UNSPEC_FIST_FLOOR))
18333 (use (match_operand:HI 2 "memory_operand" ""))
18334 (use (match_operand:HI 3 "memory_operand" ""))
18335 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18337 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18338 UNSPEC_FIST_FLOOR))
18339 (use (match_dup 2))
18340 (use (match_dup 3))])
18341 (set (match_dup 0) (match_dup 4))]
18345 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18346 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18347 UNSPEC_FIST_FLOOR))
18348 (use (match_operand:HI 2 "memory_operand" ""))
18349 (use (match_operand:HI 3 "memory_operand" ""))
18350 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18352 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18353 UNSPEC_FIST_FLOOR))
18354 (use (match_dup 2))
18355 (use (match_dup 3))])]
18358 (define_expand "lfloorxf<mode>2"
18359 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18360 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18361 UNSPEC_FIST_FLOOR))
18362 (clobber (reg:CC FLAGS_REG))])]
18363 "TARGET_USE_FANCY_MATH_387
18364 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18365 && flag_unsafe_math_optimizations"
18368 (define_expand "lfloor<mode>di2"
18369 [(match_operand:DI 0 "nonimmediate_operand" "")
18370 (match_operand:MODEF 1 "register_operand" "")]
18371 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18372 && !flag_trapping_math"
18374 if (optimize_insn_for_size_p ())
18376 ix86_expand_lfloorceil (operand0, operand1, true);
18380 (define_expand "lfloor<mode>si2"
18381 [(match_operand:SI 0 "nonimmediate_operand" "")
18382 (match_operand:MODEF 1 "register_operand" "")]
18383 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18384 && !flag_trapping_math"
18386 if (optimize_insn_for_size_p () && TARGET_64BIT)
18388 ix86_expand_lfloorceil (operand0, operand1, true);
18392 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18393 (define_insn_and_split "frndintxf2_ceil"
18394 [(set (match_operand:XF 0 "register_operand" "")
18395 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18396 UNSPEC_FRNDINT_CEIL))
18397 (clobber (reg:CC FLAGS_REG))]
18398 "TARGET_USE_FANCY_MATH_387
18399 && flag_unsafe_math_optimizations
18400 && !(reload_completed || reload_in_progress)"
18405 ix86_optimize_mode_switching[I387_CEIL] = 1;
18407 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18408 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18410 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18411 operands[2], operands[3]));
18414 [(set_attr "type" "frndint")
18415 (set_attr "i387_cw" "ceil")
18416 (set_attr "mode" "XF")])
18418 (define_insn "frndintxf2_ceil_i387"
18419 [(set (match_operand:XF 0 "register_operand" "=f")
18420 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18421 UNSPEC_FRNDINT_CEIL))
18422 (use (match_operand:HI 2 "memory_operand" "m"))
18423 (use (match_operand:HI 3 "memory_operand" "m"))]
18424 "TARGET_USE_FANCY_MATH_387
18425 && flag_unsafe_math_optimizations"
18426 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18427 [(set_attr "type" "frndint")
18428 (set_attr "i387_cw" "ceil")
18429 (set_attr "mode" "XF")])
18431 (define_expand "ceilxf2"
18432 [(use (match_operand:XF 0 "register_operand" ""))
18433 (use (match_operand:XF 1 "register_operand" ""))]
18434 "TARGET_USE_FANCY_MATH_387
18435 && flag_unsafe_math_optimizations"
18437 if (optimize_insn_for_size_p ())
18439 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18443 (define_expand "ceil<mode>2"
18444 [(use (match_operand:MODEF 0 "register_operand" ""))
18445 (use (match_operand:MODEF 1 "register_operand" ""))]
18446 "(TARGET_USE_FANCY_MATH_387
18447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18448 || TARGET_MIX_SSE_I387)
18449 && flag_unsafe_math_optimizations)
18450 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18451 && !flag_trapping_math)"
18453 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18454 && !flag_trapping_math
18455 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18458 emit_insn (gen_sse4_1_round<mode>2
18459 (operands[0], operands[1], GEN_INT (0x02)));
18460 else if (optimize_insn_for_size_p ())
18462 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18463 ix86_expand_floorceil (operand0, operand1, false);
18465 ix86_expand_floorceildf_32 (operand0, operand1, false);
18471 if (optimize_insn_for_size_p ())
18474 op0 = gen_reg_rtx (XFmode);
18475 op1 = gen_reg_rtx (XFmode);
18476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18477 emit_insn (gen_frndintxf2_ceil (op0, op1));
18479 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18484 (define_insn_and_split "*fist<mode>2_ceil_1"
18485 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18486 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18488 (clobber (reg:CC FLAGS_REG))]
18489 "TARGET_USE_FANCY_MATH_387
18490 && flag_unsafe_math_optimizations
18491 && !(reload_completed || reload_in_progress)"
18496 ix86_optimize_mode_switching[I387_CEIL] = 1;
18498 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18499 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18500 if (memory_operand (operands[0], VOIDmode))
18501 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18502 operands[2], operands[3]));
18505 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18506 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18507 operands[2], operands[3],
18512 [(set_attr "type" "fistp")
18513 (set_attr "i387_cw" "ceil")
18514 (set_attr "mode" "<MODE>")])
18516 (define_insn "fistdi2_ceil"
18517 [(set (match_operand:DI 0 "memory_operand" "=m")
18518 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18520 (use (match_operand:HI 2 "memory_operand" "m"))
18521 (use (match_operand:HI 3 "memory_operand" "m"))
18522 (clobber (match_scratch:XF 4 "=&1f"))]
18523 "TARGET_USE_FANCY_MATH_387
18524 && flag_unsafe_math_optimizations"
18525 "* return output_fix_trunc (insn, operands, 0);"
18526 [(set_attr "type" "fistp")
18527 (set_attr "i387_cw" "ceil")
18528 (set_attr "mode" "DI")])
18530 (define_insn "fistdi2_ceil_with_temp"
18531 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18532 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18534 (use (match_operand:HI 2 "memory_operand" "m,m"))
18535 (use (match_operand:HI 3 "memory_operand" "m,m"))
18536 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18537 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18538 "TARGET_USE_FANCY_MATH_387
18539 && flag_unsafe_math_optimizations"
18541 [(set_attr "type" "fistp")
18542 (set_attr "i387_cw" "ceil")
18543 (set_attr "mode" "DI")])
18546 [(set (match_operand:DI 0 "register_operand" "")
18547 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18549 (use (match_operand:HI 2 "memory_operand" ""))
18550 (use (match_operand:HI 3 "memory_operand" ""))
18551 (clobber (match_operand:DI 4 "memory_operand" ""))
18552 (clobber (match_scratch 5 ""))]
18554 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18555 (use (match_dup 2))
18556 (use (match_dup 3))
18557 (clobber (match_dup 5))])
18558 (set (match_dup 0) (match_dup 4))]
18562 [(set (match_operand:DI 0 "memory_operand" "")
18563 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18565 (use (match_operand:HI 2 "memory_operand" ""))
18566 (use (match_operand:HI 3 "memory_operand" ""))
18567 (clobber (match_operand:DI 4 "memory_operand" ""))
18568 (clobber (match_scratch 5 ""))]
18570 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18571 (use (match_dup 2))
18572 (use (match_dup 3))
18573 (clobber (match_dup 5))])]
18576 (define_insn "fist<mode>2_ceil"
18577 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18578 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18580 (use (match_operand:HI 2 "memory_operand" "m"))
18581 (use (match_operand:HI 3 "memory_operand" "m"))]
18582 "TARGET_USE_FANCY_MATH_387
18583 && flag_unsafe_math_optimizations"
18584 "* return output_fix_trunc (insn, operands, 0);"
18585 [(set_attr "type" "fistp")
18586 (set_attr "i387_cw" "ceil")
18587 (set_attr "mode" "<MODE>")])
18589 (define_insn "fist<mode>2_ceil_with_temp"
18590 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18591 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18593 (use (match_operand:HI 2 "memory_operand" "m,m"))
18594 (use (match_operand:HI 3 "memory_operand" "m,m"))
18595 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18596 "TARGET_USE_FANCY_MATH_387
18597 && flag_unsafe_math_optimizations"
18599 [(set_attr "type" "fistp")
18600 (set_attr "i387_cw" "ceil")
18601 (set_attr "mode" "<MODE>")])
18604 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18605 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18607 (use (match_operand:HI 2 "memory_operand" ""))
18608 (use (match_operand:HI 3 "memory_operand" ""))
18609 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18611 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18613 (use (match_dup 2))
18614 (use (match_dup 3))])
18615 (set (match_dup 0) (match_dup 4))]
18619 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18620 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18622 (use (match_operand:HI 2 "memory_operand" ""))
18623 (use (match_operand:HI 3 "memory_operand" ""))
18624 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18626 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18628 (use (match_dup 2))
18629 (use (match_dup 3))])]
18632 (define_expand "lceilxf<mode>2"
18633 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18634 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18636 (clobber (reg:CC FLAGS_REG))])]
18637 "TARGET_USE_FANCY_MATH_387
18638 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18639 && flag_unsafe_math_optimizations"
18642 (define_expand "lceil<mode>di2"
18643 [(match_operand:DI 0 "nonimmediate_operand" "")
18644 (match_operand:MODEF 1 "register_operand" "")]
18645 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18646 && !flag_trapping_math"
18648 ix86_expand_lfloorceil (operand0, operand1, false);
18652 (define_expand "lceil<mode>si2"
18653 [(match_operand:SI 0 "nonimmediate_operand" "")
18654 (match_operand:MODEF 1 "register_operand" "")]
18655 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18656 && !flag_trapping_math"
18658 ix86_expand_lfloorceil (operand0, operand1, false);
18662 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18663 (define_insn_and_split "frndintxf2_trunc"
18664 [(set (match_operand:XF 0 "register_operand" "")
18665 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18666 UNSPEC_FRNDINT_TRUNC))
18667 (clobber (reg:CC FLAGS_REG))]
18668 "TARGET_USE_FANCY_MATH_387
18669 && flag_unsafe_math_optimizations
18670 && !(reload_completed || reload_in_progress)"
18675 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18677 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18678 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18680 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18681 operands[2], operands[3]));
18684 [(set_attr "type" "frndint")
18685 (set_attr "i387_cw" "trunc")
18686 (set_attr "mode" "XF")])
18688 (define_insn "frndintxf2_trunc_i387"
18689 [(set (match_operand:XF 0 "register_operand" "=f")
18690 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18691 UNSPEC_FRNDINT_TRUNC))
18692 (use (match_operand:HI 2 "memory_operand" "m"))
18693 (use (match_operand:HI 3 "memory_operand" "m"))]
18694 "TARGET_USE_FANCY_MATH_387
18695 && flag_unsafe_math_optimizations"
18696 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18697 [(set_attr "type" "frndint")
18698 (set_attr "i387_cw" "trunc")
18699 (set_attr "mode" "XF")])
18701 (define_expand "btruncxf2"
18702 [(use (match_operand:XF 0 "register_operand" ""))
18703 (use (match_operand:XF 1 "register_operand" ""))]
18704 "TARGET_USE_FANCY_MATH_387
18705 && flag_unsafe_math_optimizations"
18707 if (optimize_insn_for_size_p ())
18709 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18713 (define_expand "btrunc<mode>2"
18714 [(use (match_operand:MODEF 0 "register_operand" ""))
18715 (use (match_operand:MODEF 1 "register_operand" ""))]
18716 "(TARGET_USE_FANCY_MATH_387
18717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18718 || TARGET_MIX_SSE_I387)
18719 && flag_unsafe_math_optimizations)
18720 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18721 && !flag_trapping_math)"
18723 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18724 && !flag_trapping_math
18725 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18728 emit_insn (gen_sse4_1_round<mode>2
18729 (operands[0], operands[1], GEN_INT (0x03)));
18730 else if (optimize_insn_for_size_p ())
18732 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18733 ix86_expand_trunc (operand0, operand1);
18735 ix86_expand_truncdf_32 (operand0, operand1);
18741 if (optimize_insn_for_size_p ())
18744 op0 = gen_reg_rtx (XFmode);
18745 op1 = gen_reg_rtx (XFmode);
18746 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18747 emit_insn (gen_frndintxf2_trunc (op0, op1));
18749 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18754 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18755 (define_insn_and_split "frndintxf2_mask_pm"
18756 [(set (match_operand:XF 0 "register_operand" "")
18757 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18758 UNSPEC_FRNDINT_MASK_PM))
18759 (clobber (reg:CC FLAGS_REG))]
18760 "TARGET_USE_FANCY_MATH_387
18761 && flag_unsafe_math_optimizations
18762 && !(reload_completed || reload_in_progress)"
18767 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18769 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18770 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18772 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18773 operands[2], operands[3]));
18776 [(set_attr "type" "frndint")
18777 (set_attr "i387_cw" "mask_pm")
18778 (set_attr "mode" "XF")])
18780 (define_insn "frndintxf2_mask_pm_i387"
18781 [(set (match_operand:XF 0 "register_operand" "=f")
18782 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18783 UNSPEC_FRNDINT_MASK_PM))
18784 (use (match_operand:HI 2 "memory_operand" "m"))
18785 (use (match_operand:HI 3 "memory_operand" "m"))]
18786 "TARGET_USE_FANCY_MATH_387
18787 && flag_unsafe_math_optimizations"
18788 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18789 [(set_attr "type" "frndint")
18790 (set_attr "i387_cw" "mask_pm")
18791 (set_attr "mode" "XF")])
18793 (define_expand "nearbyintxf2"
18794 [(use (match_operand:XF 0 "register_operand" ""))
18795 (use (match_operand:XF 1 "register_operand" ""))]
18796 "TARGET_USE_FANCY_MATH_387
18797 && flag_unsafe_math_optimizations"
18799 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18804 (define_expand "nearbyint<mode>2"
18805 [(use (match_operand:MODEF 0 "register_operand" ""))
18806 (use (match_operand:MODEF 1 "register_operand" ""))]
18807 "TARGET_USE_FANCY_MATH_387
18808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18809 || TARGET_MIX_SSE_I387)
18810 && flag_unsafe_math_optimizations"
18812 rtx op0 = gen_reg_rtx (XFmode);
18813 rtx op1 = gen_reg_rtx (XFmode);
18815 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18816 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18818 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18822 (define_insn "fxam<mode>2_i387"
18823 [(set (match_operand:HI 0 "register_operand" "=a")
18825 [(match_operand:X87MODEF 1 "register_operand" "f")]
18827 "TARGET_USE_FANCY_MATH_387"
18828 "fxam\n\tfnstsw\t%0"
18829 [(set_attr "type" "multi")
18830 (set_attr "unit" "i387")
18831 (set_attr "mode" "<MODE>")])
18833 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18834 [(set (match_operand:HI 0 "register_operand" "")
18836 [(match_operand:MODEF 1 "memory_operand" "")]
18838 "TARGET_USE_FANCY_MATH_387
18839 && !(reload_completed || reload_in_progress)"
18842 [(set (match_dup 2)(match_dup 1))
18844 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18846 operands[2] = gen_reg_rtx (<MODE>mode);
18848 MEM_VOLATILE_P (operands[1]) = 1;
18850 [(set_attr "type" "multi")
18851 (set_attr "unit" "i387")
18852 (set_attr "mode" "<MODE>")])
18854 (define_expand "isinfxf2"
18855 [(use (match_operand:SI 0 "register_operand" ""))
18856 (use (match_operand:XF 1 "register_operand" ""))]
18857 "TARGET_USE_FANCY_MATH_387
18858 && TARGET_C99_FUNCTIONS"
18860 rtx mask = GEN_INT (0x45);
18861 rtx val = GEN_INT (0x05);
18865 rtx scratch = gen_reg_rtx (HImode);
18866 rtx res = gen_reg_rtx (QImode);
18868 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18870 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18871 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18872 cond = gen_rtx_fmt_ee (EQ, QImode,
18873 gen_rtx_REG (CCmode, FLAGS_REG),
18875 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18876 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18880 (define_expand "isinf<mode>2"
18881 [(use (match_operand:SI 0 "register_operand" ""))
18882 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18883 "TARGET_USE_FANCY_MATH_387
18884 && TARGET_C99_FUNCTIONS
18885 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18887 rtx mask = GEN_INT (0x45);
18888 rtx val = GEN_INT (0x05);
18892 rtx scratch = gen_reg_rtx (HImode);
18893 rtx res = gen_reg_rtx (QImode);
18895 /* Remove excess precision by forcing value through memory. */
18896 if (memory_operand (operands[1], VOIDmode))
18897 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18900 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18901 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18903 emit_move_insn (temp, operands[1]);
18904 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18907 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18908 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18909 cond = gen_rtx_fmt_ee (EQ, QImode,
18910 gen_rtx_REG (CCmode, FLAGS_REG),
18912 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18913 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18917 (define_expand "signbit<mode>2"
18918 [(use (match_operand:SI 0 "register_operand" ""))
18919 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18920 "TARGET_USE_FANCY_MATH_387
18921 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18923 rtx mask = GEN_INT (0x0200);
18925 rtx scratch = gen_reg_rtx (HImode);
18927 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18928 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18932 ;; Block operation instructions
18935 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18938 [(set_attr "length" "1")
18939 (set_attr "length_immediate" "0")
18940 (set_attr "modrm" "0")])
18942 (define_expand "movmemsi"
18943 [(use (match_operand:BLK 0 "memory_operand" ""))
18944 (use (match_operand:BLK 1 "memory_operand" ""))
18945 (use (match_operand:SI 2 "nonmemory_operand" ""))
18946 (use (match_operand:SI 3 "const_int_operand" ""))
18947 (use (match_operand:SI 4 "const_int_operand" ""))
18948 (use (match_operand:SI 5 "const_int_operand" ""))]
18951 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18952 operands[4], operands[5]))
18958 (define_expand "movmemdi"
18959 [(use (match_operand:BLK 0 "memory_operand" ""))
18960 (use (match_operand:BLK 1 "memory_operand" ""))
18961 (use (match_operand:DI 2 "nonmemory_operand" ""))
18962 (use (match_operand:DI 3 "const_int_operand" ""))
18963 (use (match_operand:SI 4 "const_int_operand" ""))
18964 (use (match_operand:SI 5 "const_int_operand" ""))]
18967 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18968 operands[4], operands[5]))
18974 ;; Most CPUs don't like single string operations
18975 ;; Handle this case here to simplify previous expander.
18977 (define_expand "strmov"
18978 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18979 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18980 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18981 (clobber (reg:CC FLAGS_REG))])
18982 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18983 (clobber (reg:CC FLAGS_REG))])]
18986 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18988 /* If .md ever supports :P for Pmode, these can be directly
18989 in the pattern above. */
18990 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18991 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18993 /* Can't use this if the user has appropriated esi or edi. */
18994 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18995 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18997 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18998 operands[2], operands[3],
18999 operands[5], operands[6]));
19003 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19006 (define_expand "strmov_singleop"
19007 [(parallel [(set (match_operand 1 "memory_operand" "")
19008 (match_operand 3 "memory_operand" ""))
19009 (set (match_operand 0 "register_operand" "")
19010 (match_operand 4 "" ""))
19011 (set (match_operand 2 "register_operand" "")
19012 (match_operand 5 "" ""))])]
19014 "ix86_current_function_needs_cld = 1;")
19016 (define_insn "*strmovdi_rex_1"
19017 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19018 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19019 (set (match_operand:DI 0 "register_operand" "=D")
19020 (plus:DI (match_dup 2)
19022 (set (match_operand:DI 1 "register_operand" "=S")
19023 (plus:DI (match_dup 3)
19027 [(set_attr "type" "str")
19028 (set_attr "mode" "DI")
19029 (set_attr "memory" "both")])
19031 (define_insn "*strmovsi_1"
19032 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19033 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19034 (set (match_operand:SI 0 "register_operand" "=D")
19035 (plus:SI (match_dup 2)
19037 (set (match_operand:SI 1 "register_operand" "=S")
19038 (plus:SI (match_dup 3)
19042 [(set_attr "type" "str")
19043 (set_attr "mode" "SI")
19044 (set_attr "memory" "both")])
19046 (define_insn "*strmovsi_rex_1"
19047 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19048 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19049 (set (match_operand:DI 0 "register_operand" "=D")
19050 (plus:DI (match_dup 2)
19052 (set (match_operand:DI 1 "register_operand" "=S")
19053 (plus:DI (match_dup 3)
19057 [(set_attr "type" "str")
19058 (set_attr "mode" "SI")
19059 (set_attr "memory" "both")])
19061 (define_insn "*strmovhi_1"
19062 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19063 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19064 (set (match_operand:SI 0 "register_operand" "=D")
19065 (plus:SI (match_dup 2)
19067 (set (match_operand:SI 1 "register_operand" "=S")
19068 (plus:SI (match_dup 3)
19072 [(set_attr "type" "str")
19073 (set_attr "memory" "both")
19074 (set_attr "mode" "HI")])
19076 (define_insn "*strmovhi_rex_1"
19077 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19078 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19079 (set (match_operand:DI 0 "register_operand" "=D")
19080 (plus:DI (match_dup 2)
19082 (set (match_operand:DI 1 "register_operand" "=S")
19083 (plus:DI (match_dup 3)
19087 [(set_attr "type" "str")
19088 (set_attr "memory" "both")
19089 (set_attr "mode" "HI")])
19091 (define_insn "*strmovqi_1"
19092 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19093 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19094 (set (match_operand:SI 0 "register_operand" "=D")
19095 (plus:SI (match_dup 2)
19097 (set (match_operand:SI 1 "register_operand" "=S")
19098 (plus:SI (match_dup 3)
19102 [(set_attr "type" "str")
19103 (set_attr "memory" "both")
19104 (set_attr "mode" "QI")])
19106 (define_insn "*strmovqi_rex_1"
19107 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19108 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19109 (set (match_operand:DI 0 "register_operand" "=D")
19110 (plus:DI (match_dup 2)
19112 (set (match_operand:DI 1 "register_operand" "=S")
19113 (plus:DI (match_dup 3)
19117 [(set_attr "type" "str")
19118 (set_attr "memory" "both")
19119 (set_attr "mode" "QI")])
19121 (define_expand "rep_mov"
19122 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19123 (set (match_operand 0 "register_operand" "")
19124 (match_operand 5 "" ""))
19125 (set (match_operand 2 "register_operand" "")
19126 (match_operand 6 "" ""))
19127 (set (match_operand 1 "memory_operand" "")
19128 (match_operand 3 "memory_operand" ""))
19129 (use (match_dup 4))])]
19131 "ix86_current_function_needs_cld = 1;")
19133 (define_insn "*rep_movdi_rex64"
19134 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19135 (set (match_operand:DI 0 "register_operand" "=D")
19136 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19138 (match_operand:DI 3 "register_operand" "0")))
19139 (set (match_operand:DI 1 "register_operand" "=S")
19140 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19141 (match_operand:DI 4 "register_operand" "1")))
19142 (set (mem:BLK (match_dup 3))
19143 (mem:BLK (match_dup 4)))
19144 (use (match_dup 5))]
19147 [(set_attr "type" "str")
19148 (set_attr "prefix_rep" "1")
19149 (set_attr "memory" "both")
19150 (set_attr "mode" "DI")])
19152 (define_insn "*rep_movsi"
19153 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19154 (set (match_operand:SI 0 "register_operand" "=D")
19155 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19157 (match_operand:SI 3 "register_operand" "0")))
19158 (set (match_operand:SI 1 "register_operand" "=S")
19159 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19160 (match_operand:SI 4 "register_operand" "1")))
19161 (set (mem:BLK (match_dup 3))
19162 (mem:BLK (match_dup 4)))
19163 (use (match_dup 5))]
19166 [(set_attr "type" "str")
19167 (set_attr "prefix_rep" "1")
19168 (set_attr "memory" "both")
19169 (set_attr "mode" "SI")])
19171 (define_insn "*rep_movsi_rex64"
19172 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19173 (set (match_operand:DI 0 "register_operand" "=D")
19174 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19176 (match_operand:DI 3 "register_operand" "0")))
19177 (set (match_operand:DI 1 "register_operand" "=S")
19178 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19179 (match_operand:DI 4 "register_operand" "1")))
19180 (set (mem:BLK (match_dup 3))
19181 (mem:BLK (match_dup 4)))
19182 (use (match_dup 5))]
19185 [(set_attr "type" "str")
19186 (set_attr "prefix_rep" "1")
19187 (set_attr "memory" "both")
19188 (set_attr "mode" "SI")])
19190 (define_insn "*rep_movqi"
19191 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19192 (set (match_operand:SI 0 "register_operand" "=D")
19193 (plus:SI (match_operand:SI 3 "register_operand" "0")
19194 (match_operand:SI 5 "register_operand" "2")))
19195 (set (match_operand:SI 1 "register_operand" "=S")
19196 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19197 (set (mem:BLK (match_dup 3))
19198 (mem:BLK (match_dup 4)))
19199 (use (match_dup 5))]
19202 [(set_attr "type" "str")
19203 (set_attr "prefix_rep" "1")
19204 (set_attr "memory" "both")
19205 (set_attr "mode" "SI")])
19207 (define_insn "*rep_movqi_rex64"
19208 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19209 (set (match_operand:DI 0 "register_operand" "=D")
19210 (plus:DI (match_operand:DI 3 "register_operand" "0")
19211 (match_operand:DI 5 "register_operand" "2")))
19212 (set (match_operand:DI 1 "register_operand" "=S")
19213 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19214 (set (mem:BLK (match_dup 3))
19215 (mem:BLK (match_dup 4)))
19216 (use (match_dup 5))]
19219 [(set_attr "type" "str")
19220 (set_attr "prefix_rep" "1")
19221 (set_attr "memory" "both")
19222 (set_attr "mode" "SI")])
19224 (define_expand "setmemsi"
19225 [(use (match_operand:BLK 0 "memory_operand" ""))
19226 (use (match_operand:SI 1 "nonmemory_operand" ""))
19227 (use (match_operand 2 "const_int_operand" ""))
19228 (use (match_operand 3 "const_int_operand" ""))
19229 (use (match_operand:SI 4 "const_int_operand" ""))
19230 (use (match_operand:SI 5 "const_int_operand" ""))]
19233 if (ix86_expand_setmem (operands[0], operands[1],
19234 operands[2], operands[3],
19235 operands[4], operands[5]))
19241 (define_expand "setmemdi"
19242 [(use (match_operand:BLK 0 "memory_operand" ""))
19243 (use (match_operand:DI 1 "nonmemory_operand" ""))
19244 (use (match_operand 2 "const_int_operand" ""))
19245 (use (match_operand 3 "const_int_operand" ""))
19246 (use (match_operand 4 "const_int_operand" ""))
19247 (use (match_operand 5 "const_int_operand" ""))]
19250 if (ix86_expand_setmem (operands[0], operands[1],
19251 operands[2], operands[3],
19252 operands[4], operands[5]))
19258 ;; Most CPUs don't like single string operations
19259 ;; Handle this case here to simplify previous expander.
19261 (define_expand "strset"
19262 [(set (match_operand 1 "memory_operand" "")
19263 (match_operand 2 "register_operand" ""))
19264 (parallel [(set (match_operand 0 "register_operand" "")
19266 (clobber (reg:CC FLAGS_REG))])]
19269 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19270 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19272 /* If .md ever supports :P for Pmode, this can be directly
19273 in the pattern above. */
19274 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19275 GEN_INT (GET_MODE_SIZE (GET_MODE
19277 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19279 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19285 (define_expand "strset_singleop"
19286 [(parallel [(set (match_operand 1 "memory_operand" "")
19287 (match_operand 2 "register_operand" ""))
19288 (set (match_operand 0 "register_operand" "")
19289 (match_operand 3 "" ""))])]
19291 "ix86_current_function_needs_cld = 1;")
19293 (define_insn "*strsetdi_rex_1"
19294 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19295 (match_operand:DI 2 "register_operand" "a"))
19296 (set (match_operand:DI 0 "register_operand" "=D")
19297 (plus:DI (match_dup 1)
19301 [(set_attr "type" "str")
19302 (set_attr "memory" "store")
19303 (set_attr "mode" "DI")])
19305 (define_insn "*strsetsi_1"
19306 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19307 (match_operand:SI 2 "register_operand" "a"))
19308 (set (match_operand:SI 0 "register_operand" "=D")
19309 (plus:SI (match_dup 1)
19313 [(set_attr "type" "str")
19314 (set_attr "memory" "store")
19315 (set_attr "mode" "SI")])
19317 (define_insn "*strsetsi_rex_1"
19318 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19319 (match_operand:SI 2 "register_operand" "a"))
19320 (set (match_operand:DI 0 "register_operand" "=D")
19321 (plus:DI (match_dup 1)
19325 [(set_attr "type" "str")
19326 (set_attr "memory" "store")
19327 (set_attr "mode" "SI")])
19329 (define_insn "*strsethi_1"
19330 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19331 (match_operand:HI 2 "register_operand" "a"))
19332 (set (match_operand:SI 0 "register_operand" "=D")
19333 (plus:SI (match_dup 1)
19337 [(set_attr "type" "str")
19338 (set_attr "memory" "store")
19339 (set_attr "mode" "HI")])
19341 (define_insn "*strsethi_rex_1"
19342 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19343 (match_operand:HI 2 "register_operand" "a"))
19344 (set (match_operand:DI 0 "register_operand" "=D")
19345 (plus:DI (match_dup 1)
19349 [(set_attr "type" "str")
19350 (set_attr "memory" "store")
19351 (set_attr "mode" "HI")])
19353 (define_insn "*strsetqi_1"
19354 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19355 (match_operand:QI 2 "register_operand" "a"))
19356 (set (match_operand:SI 0 "register_operand" "=D")
19357 (plus:SI (match_dup 1)
19361 [(set_attr "type" "str")
19362 (set_attr "memory" "store")
19363 (set_attr "mode" "QI")])
19365 (define_insn "*strsetqi_rex_1"
19366 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19367 (match_operand:QI 2 "register_operand" "a"))
19368 (set (match_operand:DI 0 "register_operand" "=D")
19369 (plus:DI (match_dup 1)
19373 [(set_attr "type" "str")
19374 (set_attr "memory" "store")
19375 (set_attr "mode" "QI")])
19377 (define_expand "rep_stos"
19378 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19379 (set (match_operand 0 "register_operand" "")
19380 (match_operand 4 "" ""))
19381 (set (match_operand 2 "memory_operand" "") (const_int 0))
19382 (use (match_operand 3 "register_operand" ""))
19383 (use (match_dup 1))])]
19385 "ix86_current_function_needs_cld = 1;")
19387 (define_insn "*rep_stosdi_rex64"
19388 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19389 (set (match_operand:DI 0 "register_operand" "=D")
19390 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19392 (match_operand:DI 3 "register_operand" "0")))
19393 (set (mem:BLK (match_dup 3))
19395 (use (match_operand:DI 2 "register_operand" "a"))
19396 (use (match_dup 4))]
19399 [(set_attr "type" "str")
19400 (set_attr "prefix_rep" "1")
19401 (set_attr "memory" "store")
19402 (set_attr "mode" "DI")])
19404 (define_insn "*rep_stossi"
19405 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19406 (set (match_operand:SI 0 "register_operand" "=D")
19407 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19409 (match_operand:SI 3 "register_operand" "0")))
19410 (set (mem:BLK (match_dup 3))
19412 (use (match_operand:SI 2 "register_operand" "a"))
19413 (use (match_dup 4))]
19416 [(set_attr "type" "str")
19417 (set_attr "prefix_rep" "1")
19418 (set_attr "memory" "store")
19419 (set_attr "mode" "SI")])
19421 (define_insn "*rep_stossi_rex64"
19422 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19423 (set (match_operand:DI 0 "register_operand" "=D")
19424 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19426 (match_operand:DI 3 "register_operand" "0")))
19427 (set (mem:BLK (match_dup 3))
19429 (use (match_operand:SI 2 "register_operand" "a"))
19430 (use (match_dup 4))]
19433 [(set_attr "type" "str")
19434 (set_attr "prefix_rep" "1")
19435 (set_attr "memory" "store")
19436 (set_attr "mode" "SI")])
19438 (define_insn "*rep_stosqi"
19439 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19440 (set (match_operand:SI 0 "register_operand" "=D")
19441 (plus:SI (match_operand:SI 3 "register_operand" "0")
19442 (match_operand:SI 4 "register_operand" "1")))
19443 (set (mem:BLK (match_dup 3))
19445 (use (match_operand:QI 2 "register_operand" "a"))
19446 (use (match_dup 4))]
19449 [(set_attr "type" "str")
19450 (set_attr "prefix_rep" "1")
19451 (set_attr "memory" "store")
19452 (set_attr "mode" "QI")])
19454 (define_insn "*rep_stosqi_rex64"
19455 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19456 (set (match_operand:DI 0 "register_operand" "=D")
19457 (plus:DI (match_operand:DI 3 "register_operand" "0")
19458 (match_operand:DI 4 "register_operand" "1")))
19459 (set (mem:BLK (match_dup 3))
19461 (use (match_operand:QI 2 "register_operand" "a"))
19462 (use (match_dup 4))]
19465 [(set_attr "type" "str")
19466 (set_attr "prefix_rep" "1")
19467 (set_attr "memory" "store")
19468 (set_attr "mode" "QI")])
19470 (define_expand "cmpstrnsi"
19471 [(set (match_operand:SI 0 "register_operand" "")
19472 (compare:SI (match_operand:BLK 1 "general_operand" "")
19473 (match_operand:BLK 2 "general_operand" "")))
19474 (use (match_operand 3 "general_operand" ""))
19475 (use (match_operand 4 "immediate_operand" ""))]
19478 rtx addr1, addr2, out, outlow, count, countreg, align;
19480 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19483 /* Can't use this if the user has appropriated esi or edi. */
19484 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19489 out = gen_reg_rtx (SImode);
19491 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19492 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19493 if (addr1 != XEXP (operands[1], 0))
19494 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19495 if (addr2 != XEXP (operands[2], 0))
19496 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19498 count = operands[3];
19499 countreg = ix86_zero_extend_to_Pmode (count);
19501 /* %%% Iff we are testing strict equality, we can use known alignment
19502 to good advantage. This may be possible with combine, particularly
19503 once cc0 is dead. */
19504 align = operands[4];
19506 if (CONST_INT_P (count))
19508 if (INTVAL (count) == 0)
19510 emit_move_insn (operands[0], const0_rtx);
19513 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19514 operands[1], operands[2]));
19519 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19521 emit_insn (gen_cmpsi_1 (countreg, countreg));
19522 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19523 operands[1], operands[2]));
19526 outlow = gen_lowpart (QImode, out);
19527 emit_insn (gen_cmpintqi (outlow));
19528 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19530 if (operands[0] != out)
19531 emit_move_insn (operands[0], out);
19536 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19538 (define_expand "cmpintqi"
19539 [(set (match_dup 1)
19540 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19542 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19543 (parallel [(set (match_operand:QI 0 "register_operand" "")
19544 (minus:QI (match_dup 1)
19546 (clobber (reg:CC FLAGS_REG))])]
19548 "operands[1] = gen_reg_rtx (QImode);
19549 operands[2] = gen_reg_rtx (QImode);")
19551 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19552 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19554 (define_expand "cmpstrnqi_nz_1"
19555 [(parallel [(set (reg:CC FLAGS_REG)
19556 (compare:CC (match_operand 4 "memory_operand" "")
19557 (match_operand 5 "memory_operand" "")))
19558 (use (match_operand 2 "register_operand" ""))
19559 (use (match_operand:SI 3 "immediate_operand" ""))
19560 (clobber (match_operand 0 "register_operand" ""))
19561 (clobber (match_operand 1 "register_operand" ""))
19562 (clobber (match_dup 2))])]
19564 "ix86_current_function_needs_cld = 1;")
19566 (define_insn "*cmpstrnqi_nz_1"
19567 [(set (reg:CC FLAGS_REG)
19568 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19569 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19570 (use (match_operand:SI 6 "register_operand" "2"))
19571 (use (match_operand:SI 3 "immediate_operand" "i"))
19572 (clobber (match_operand:SI 0 "register_operand" "=S"))
19573 (clobber (match_operand:SI 1 "register_operand" "=D"))
19574 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19577 [(set_attr "type" "str")
19578 (set_attr "mode" "QI")
19579 (set_attr "prefix_rep" "1")])
19581 (define_insn "*cmpstrnqi_nz_rex_1"
19582 [(set (reg:CC FLAGS_REG)
19583 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19584 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19585 (use (match_operand:DI 6 "register_operand" "2"))
19586 (use (match_operand:SI 3 "immediate_operand" "i"))
19587 (clobber (match_operand:DI 0 "register_operand" "=S"))
19588 (clobber (match_operand:DI 1 "register_operand" "=D"))
19589 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19592 [(set_attr "type" "str")
19593 (set_attr "mode" "QI")
19594 (set_attr "prefix_rep" "1")])
19596 ;; The same, but the count is not known to not be zero.
19598 (define_expand "cmpstrnqi_1"
19599 [(parallel [(set (reg:CC FLAGS_REG)
19600 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19602 (compare:CC (match_operand 4 "memory_operand" "")
19603 (match_operand 5 "memory_operand" ""))
19605 (use (match_operand:SI 3 "immediate_operand" ""))
19606 (use (reg:CC FLAGS_REG))
19607 (clobber (match_operand 0 "register_operand" ""))
19608 (clobber (match_operand 1 "register_operand" ""))
19609 (clobber (match_dup 2))])]
19611 "ix86_current_function_needs_cld = 1;")
19613 (define_insn "*cmpstrnqi_1"
19614 [(set (reg:CC FLAGS_REG)
19615 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19617 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19618 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19620 (use (match_operand:SI 3 "immediate_operand" "i"))
19621 (use (reg:CC FLAGS_REG))
19622 (clobber (match_operand:SI 0 "register_operand" "=S"))
19623 (clobber (match_operand:SI 1 "register_operand" "=D"))
19624 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19627 [(set_attr "type" "str")
19628 (set_attr "mode" "QI")
19629 (set_attr "prefix_rep" "1")])
19631 (define_insn "*cmpstrnqi_rex_1"
19632 [(set (reg:CC FLAGS_REG)
19633 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19635 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19636 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19638 (use (match_operand:SI 3 "immediate_operand" "i"))
19639 (use (reg:CC FLAGS_REG))
19640 (clobber (match_operand:DI 0 "register_operand" "=S"))
19641 (clobber (match_operand:DI 1 "register_operand" "=D"))
19642 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19645 [(set_attr "type" "str")
19646 (set_attr "mode" "QI")
19647 (set_attr "prefix_rep" "1")])
19649 (define_expand "strlensi"
19650 [(set (match_operand:SI 0 "register_operand" "")
19651 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19652 (match_operand:QI 2 "immediate_operand" "")
19653 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19656 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19662 (define_expand "strlendi"
19663 [(set (match_operand:DI 0 "register_operand" "")
19664 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19665 (match_operand:QI 2 "immediate_operand" "")
19666 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19669 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19675 (define_expand "strlenqi_1"
19676 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19677 (clobber (match_operand 1 "register_operand" ""))
19678 (clobber (reg:CC FLAGS_REG))])]
19680 "ix86_current_function_needs_cld = 1;")
19682 (define_insn "*strlenqi_1"
19683 [(set (match_operand:SI 0 "register_operand" "=&c")
19684 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19685 (match_operand:QI 2 "register_operand" "a")
19686 (match_operand:SI 3 "immediate_operand" "i")
19687 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19688 (clobber (match_operand:SI 1 "register_operand" "=D"))
19689 (clobber (reg:CC FLAGS_REG))]
19692 [(set_attr "type" "str")
19693 (set_attr "mode" "QI")
19694 (set_attr "prefix_rep" "1")])
19696 (define_insn "*strlenqi_rex_1"
19697 [(set (match_operand:DI 0 "register_operand" "=&c")
19698 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19699 (match_operand:QI 2 "register_operand" "a")
19700 (match_operand:DI 3 "immediate_operand" "i")
19701 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19702 (clobber (match_operand:DI 1 "register_operand" "=D"))
19703 (clobber (reg:CC FLAGS_REG))]
19706 [(set_attr "type" "str")
19707 (set_attr "mode" "QI")
19708 (set_attr "prefix_rep" "1")])
19710 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19711 ;; handled in combine, but it is not currently up to the task.
19712 ;; When used for their truth value, the cmpstrn* expanders generate
19721 ;; The intermediate three instructions are unnecessary.
19723 ;; This one handles cmpstrn*_nz_1...
19726 (set (reg:CC FLAGS_REG)
19727 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19728 (mem:BLK (match_operand 5 "register_operand" ""))))
19729 (use (match_operand 6 "register_operand" ""))
19730 (use (match_operand:SI 3 "immediate_operand" ""))
19731 (clobber (match_operand 0 "register_operand" ""))
19732 (clobber (match_operand 1 "register_operand" ""))
19733 (clobber (match_operand 2 "register_operand" ""))])
19734 (set (match_operand:QI 7 "register_operand" "")
19735 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19736 (set (match_operand:QI 8 "register_operand" "")
19737 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19738 (set (reg FLAGS_REG)
19739 (compare (match_dup 7) (match_dup 8)))
19741 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19743 (set (reg:CC FLAGS_REG)
19744 (compare:CC (mem:BLK (match_dup 4))
19745 (mem:BLK (match_dup 5))))
19746 (use (match_dup 6))
19747 (use (match_dup 3))
19748 (clobber (match_dup 0))
19749 (clobber (match_dup 1))
19750 (clobber (match_dup 2))])]
19753 ;; ...and this one handles cmpstrn*_1.
19756 (set (reg:CC FLAGS_REG)
19757 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19759 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19760 (mem:BLK (match_operand 5 "register_operand" "")))
19762 (use (match_operand:SI 3 "immediate_operand" ""))
19763 (use (reg:CC FLAGS_REG))
19764 (clobber (match_operand 0 "register_operand" ""))
19765 (clobber (match_operand 1 "register_operand" ""))
19766 (clobber (match_operand 2 "register_operand" ""))])
19767 (set (match_operand:QI 7 "register_operand" "")
19768 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19769 (set (match_operand:QI 8 "register_operand" "")
19770 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19771 (set (reg FLAGS_REG)
19772 (compare (match_dup 7) (match_dup 8)))
19774 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19776 (set (reg:CC FLAGS_REG)
19777 (if_then_else:CC (ne (match_dup 6)
19779 (compare:CC (mem:BLK (match_dup 4))
19780 (mem:BLK (match_dup 5)))
19782 (use (match_dup 3))
19783 (use (reg:CC FLAGS_REG))
19784 (clobber (match_dup 0))
19785 (clobber (match_dup 1))
19786 (clobber (match_dup 2))])]
19791 ;; Conditional move instructions.
19793 (define_expand "movdicc"
19794 [(set (match_operand:DI 0 "register_operand" "")
19795 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19796 (match_operand:DI 2 "general_operand" "")
19797 (match_operand:DI 3 "general_operand" "")))]
19799 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19801 (define_insn "x86_movdicc_0_m1_rex64"
19802 [(set (match_operand:DI 0 "register_operand" "=r")
19803 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19806 (clobber (reg:CC FLAGS_REG))]
19809 ; Since we don't have the proper number of operands for an alu insn,
19810 ; fill in all the blanks.
19811 [(set_attr "type" "alu")
19812 (set_attr "pent_pair" "pu")
19813 (set_attr "memory" "none")
19814 (set_attr "imm_disp" "false")
19815 (set_attr "mode" "DI")
19816 (set_attr "length_immediate" "0")])
19818 (define_insn "*x86_movdicc_0_m1_se"
19819 [(set (match_operand:DI 0 "register_operand" "=r")
19820 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19823 (clobber (reg:CC FLAGS_REG))]
19826 [(set_attr "type" "alu")
19827 (set_attr "pent_pair" "pu")
19828 (set_attr "memory" "none")
19829 (set_attr "imm_disp" "false")
19830 (set_attr "mode" "DI")
19831 (set_attr "length_immediate" "0")])
19833 (define_insn "*movdicc_c_rex64"
19834 [(set (match_operand:DI 0 "register_operand" "=r,r")
19835 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19836 [(reg FLAGS_REG) (const_int 0)])
19837 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19838 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19839 "TARGET_64BIT && TARGET_CMOVE
19840 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19842 cmov%O2%C1\t{%2, %0|%0, %2}
19843 cmov%O2%c1\t{%3, %0|%0, %3}"
19844 [(set_attr "type" "icmov")
19845 (set_attr "mode" "DI")])
19847 (define_expand "movsicc"
19848 [(set (match_operand:SI 0 "register_operand" "")
19849 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19850 (match_operand:SI 2 "general_operand" "")
19851 (match_operand:SI 3 "general_operand" "")))]
19853 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19855 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19856 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19857 ;; So just document what we're doing explicitly.
19859 (define_insn "x86_movsicc_0_m1"
19860 [(set (match_operand:SI 0 "register_operand" "=r")
19861 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19864 (clobber (reg:CC FLAGS_REG))]
19867 ; Since we don't have the proper number of operands for an alu insn,
19868 ; fill in all the blanks.
19869 [(set_attr "type" "alu")
19870 (set_attr "pent_pair" "pu")
19871 (set_attr "memory" "none")
19872 (set_attr "imm_disp" "false")
19873 (set_attr "mode" "SI")
19874 (set_attr "length_immediate" "0")])
19876 (define_insn "*x86_movsicc_0_m1_se"
19877 [(set (match_operand:SI 0 "register_operand" "=r")
19878 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19881 (clobber (reg:CC FLAGS_REG))]
19884 [(set_attr "type" "alu")
19885 (set_attr "pent_pair" "pu")
19886 (set_attr "memory" "none")
19887 (set_attr "imm_disp" "false")
19888 (set_attr "mode" "SI")
19889 (set_attr "length_immediate" "0")])
19891 (define_insn "*movsicc_noc"
19892 [(set (match_operand:SI 0 "register_operand" "=r,r")
19893 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19894 [(reg FLAGS_REG) (const_int 0)])
19895 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19896 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19898 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19900 cmov%O2%C1\t{%2, %0|%0, %2}
19901 cmov%O2%c1\t{%3, %0|%0, %3}"
19902 [(set_attr "type" "icmov")
19903 (set_attr "mode" "SI")])
19905 (define_expand "movhicc"
19906 [(set (match_operand:HI 0 "register_operand" "")
19907 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19908 (match_operand:HI 2 "general_operand" "")
19909 (match_operand:HI 3 "general_operand" "")))]
19910 "TARGET_HIMODE_MATH"
19911 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19913 (define_insn "*movhicc_noc"
19914 [(set (match_operand:HI 0 "register_operand" "=r,r")
19915 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19916 [(reg FLAGS_REG) (const_int 0)])
19917 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19918 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19920 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19922 cmov%O2%C1\t{%2, %0|%0, %2}
19923 cmov%O2%c1\t{%3, %0|%0, %3}"
19924 [(set_attr "type" "icmov")
19925 (set_attr "mode" "HI")])
19927 (define_expand "movqicc"
19928 [(set (match_operand:QI 0 "register_operand" "")
19929 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19930 (match_operand:QI 2 "general_operand" "")
19931 (match_operand:QI 3 "general_operand" "")))]
19932 "TARGET_QIMODE_MATH"
19933 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19935 (define_insn_and_split "*movqicc_noc"
19936 [(set (match_operand:QI 0 "register_operand" "=r,r")
19937 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19938 [(match_operand 4 "flags_reg_operand" "")
19940 (match_operand:QI 2 "register_operand" "r,0")
19941 (match_operand:QI 3 "register_operand" "0,r")))]
19942 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19944 "&& reload_completed"
19945 [(set (match_dup 0)
19946 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19949 "operands[0] = gen_lowpart (SImode, operands[0]);
19950 operands[2] = gen_lowpart (SImode, operands[2]);
19951 operands[3] = gen_lowpart (SImode, operands[3]);"
19952 [(set_attr "type" "icmov")
19953 (set_attr "mode" "SI")])
19955 (define_expand "mov<mode>cc"
19956 [(set (match_operand:X87MODEF 0 "register_operand" "")
19957 (if_then_else:X87MODEF
19958 (match_operand 1 "comparison_operator" "")
19959 (match_operand:X87MODEF 2 "register_operand" "")
19960 (match_operand:X87MODEF 3 "register_operand" "")))]
19961 "(TARGET_80387 && TARGET_CMOVE)
19962 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19963 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19965 (define_insn "*movsfcc_1_387"
19966 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19967 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19968 [(reg FLAGS_REG) (const_int 0)])
19969 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19970 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19971 "TARGET_80387 && TARGET_CMOVE
19972 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19974 fcmov%F1\t{%2, %0|%0, %2}
19975 fcmov%f1\t{%3, %0|%0, %3}
19976 cmov%O2%C1\t{%2, %0|%0, %2}
19977 cmov%O2%c1\t{%3, %0|%0, %3}"
19978 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19979 (set_attr "mode" "SF,SF,SI,SI")])
19981 (define_insn "*movdfcc_1"
19982 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19983 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19984 [(reg FLAGS_REG) (const_int 0)])
19985 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19986 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19987 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19988 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19990 fcmov%F1\t{%2, %0|%0, %2}
19991 fcmov%f1\t{%3, %0|%0, %3}
19994 [(set_attr "type" "fcmov,fcmov,multi,multi")
19995 (set_attr "mode" "DF")])
19997 (define_insn "*movdfcc_1_rex64"
19998 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19999 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20000 [(reg FLAGS_REG) (const_int 0)])
20001 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20002 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20003 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20004 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20006 fcmov%F1\t{%2, %0|%0, %2}
20007 fcmov%f1\t{%3, %0|%0, %3}
20008 cmov%O2%C1\t{%2, %0|%0, %2}
20009 cmov%O2%c1\t{%3, %0|%0, %3}"
20010 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20011 (set_attr "mode" "DF")])
20014 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20015 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20016 [(match_operand 4 "flags_reg_operand" "")
20018 (match_operand:DF 2 "nonimmediate_operand" "")
20019 (match_operand:DF 3 "nonimmediate_operand" "")))]
20020 "!TARGET_64BIT && reload_completed"
20021 [(set (match_dup 2)
20022 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20026 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20029 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20030 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20032 (define_insn "*movxfcc_1"
20033 [(set (match_operand:XF 0 "register_operand" "=f,f")
20034 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20035 [(reg FLAGS_REG) (const_int 0)])
20036 (match_operand:XF 2 "register_operand" "f,0")
20037 (match_operand:XF 3 "register_operand" "0,f")))]
20038 "TARGET_80387 && TARGET_CMOVE"
20040 fcmov%F1\t{%2, %0|%0, %2}
20041 fcmov%f1\t{%3, %0|%0, %3}"
20042 [(set_attr "type" "fcmov")
20043 (set_attr "mode" "XF")])
20045 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20046 ;; the scalar versions to have only XMM registers as operands.
20048 ;; SSE5 conditional move
20049 (define_insn "*sse5_pcmov_<mode>"
20050 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20051 (if_then_else:MODEF
20052 (match_operand:MODEF 1 "register_operand" "x,0")
20053 (match_operand:MODEF 2 "register_operand" "0,x")
20054 (match_operand:MODEF 3 "register_operand" "x,x")))]
20055 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20056 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20057 [(set_attr "type" "sse4arg")])
20059 ;; These versions of the min/max patterns are intentionally ignorant of
20060 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20061 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20062 ;; are undefined in this condition, we're certain this is correct.
20064 (define_insn "*avx_<code><mode>3"
20065 [(set (match_operand:MODEF 0 "register_operand" "=x")
20067 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20068 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20069 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20070 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20071 [(set_attr "type" "sseadd")
20072 (set_attr "prefix" "vex")
20073 (set_attr "mode" "<MODE>")])
20075 (define_insn "<code><mode>3"
20076 [(set (match_operand:MODEF 0 "register_operand" "=x")
20078 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20079 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20080 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20081 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20082 [(set_attr "type" "sseadd")
20083 (set_attr "mode" "<MODE>")])
20085 ;; These versions of the min/max patterns implement exactly the operations
20086 ;; min = (op1 < op2 ? op1 : op2)
20087 ;; max = (!(op1 < op2) ? op1 : op2)
20088 ;; Their operands are not commutative, and thus they may be used in the
20089 ;; presence of -0.0 and NaN.
20091 (define_insn "*avx_ieee_smin<mode>3"
20092 [(set (match_operand:MODEF 0 "register_operand" "=x")
20094 [(match_operand:MODEF 1 "register_operand" "x")
20095 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20097 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20098 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20099 [(set_attr "type" "sseadd")
20100 (set_attr "prefix" "vex")
20101 (set_attr "mode" "<MODE>")])
20103 (define_insn "*ieee_smin<mode>3"
20104 [(set (match_operand:MODEF 0 "register_operand" "=x")
20106 [(match_operand:MODEF 1 "register_operand" "0")
20107 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20109 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20110 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20111 [(set_attr "type" "sseadd")
20112 (set_attr "mode" "<MODE>")])
20114 (define_insn "*avx_ieee_smax<mode>3"
20115 [(set (match_operand:MODEF 0 "register_operand" "=x")
20117 [(match_operand:MODEF 1 "register_operand" "0")
20118 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20120 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20121 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20122 [(set_attr "type" "sseadd")
20123 (set_attr "prefix" "vex")
20124 (set_attr "mode" "<MODE>")])
20126 (define_insn "*ieee_smax<mode>3"
20127 [(set (match_operand:MODEF 0 "register_operand" "=x")
20129 [(match_operand:MODEF 1 "register_operand" "0")
20130 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20132 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20133 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20134 [(set_attr "type" "sseadd")
20135 (set_attr "mode" "<MODE>")])
20137 ;; Make two stack loads independent:
20139 ;; fld %st(0) -> fld bb
20140 ;; fmul bb fmul %st(1), %st
20142 ;; Actually we only match the last two instructions for simplicity.
20144 [(set (match_operand 0 "fp_register_operand" "")
20145 (match_operand 1 "fp_register_operand" ""))
20147 (match_operator 2 "binary_fp_operator"
20149 (match_operand 3 "memory_operand" "")]))]
20150 "REGNO (operands[0]) != REGNO (operands[1])"
20151 [(set (match_dup 0) (match_dup 3))
20152 (set (match_dup 0) (match_dup 4))]
20154 ;; The % modifier is not operational anymore in peephole2's, so we have to
20155 ;; swap the operands manually in the case of addition and multiplication.
20156 "if (COMMUTATIVE_ARITH_P (operands[2]))
20157 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20158 operands[0], operands[1]);
20160 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20161 operands[1], operands[0]);")
20163 ;; Conditional addition patterns
20164 (define_expand "add<mode>cc"
20165 [(match_operand:SWI 0 "register_operand" "")
20166 (match_operand 1 "comparison_operator" "")
20167 (match_operand:SWI 2 "register_operand" "")
20168 (match_operand:SWI 3 "const_int_operand" "")]
20170 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20173 ;; Misc patterns (?)
20175 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20176 ;; Otherwise there will be nothing to keep
20178 ;; [(set (reg ebp) (reg esp))]
20179 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20180 ;; (clobber (eflags)]
20181 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20183 ;; in proper program order.
20184 (define_insn "pro_epilogue_adjust_stack_1"
20185 [(set (match_operand:SI 0 "register_operand" "=r,r")
20186 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20187 (match_operand:SI 2 "immediate_operand" "i,i")))
20188 (clobber (reg:CC FLAGS_REG))
20189 (clobber (mem:BLK (scratch)))]
20192 switch (get_attr_type (insn))
20195 return "mov{l}\t{%1, %0|%0, %1}";
20198 if (CONST_INT_P (operands[2])
20199 && (INTVAL (operands[2]) == 128
20200 || (INTVAL (operands[2]) < 0
20201 && INTVAL (operands[2]) != -128)))
20203 operands[2] = GEN_INT (-INTVAL (operands[2]));
20204 return "sub{l}\t{%2, %0|%0, %2}";
20206 return "add{l}\t{%2, %0|%0, %2}";
20209 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20210 return "lea{l}\t{%a2, %0|%0, %a2}";
20213 gcc_unreachable ();
20216 [(set (attr "type")
20217 (cond [(eq_attr "alternative" "0")
20218 (const_string "alu")
20219 (match_operand:SI 2 "const0_operand" "")
20220 (const_string "imov")
20222 (const_string "lea")))
20223 (set_attr "mode" "SI")])
20225 (define_insn "pro_epilogue_adjust_stack_rex64"
20226 [(set (match_operand:DI 0 "register_operand" "=r,r")
20227 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20228 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20229 (clobber (reg:CC FLAGS_REG))
20230 (clobber (mem:BLK (scratch)))]
20233 switch (get_attr_type (insn))
20236 return "mov{q}\t{%1, %0|%0, %1}";
20239 if (CONST_INT_P (operands[2])
20240 /* Avoid overflows. */
20241 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20242 && (INTVAL (operands[2]) == 128
20243 || (INTVAL (operands[2]) < 0
20244 && INTVAL (operands[2]) != -128)))
20246 operands[2] = GEN_INT (-INTVAL (operands[2]));
20247 return "sub{q}\t{%2, %0|%0, %2}";
20249 return "add{q}\t{%2, %0|%0, %2}";
20252 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20253 return "lea{q}\t{%a2, %0|%0, %a2}";
20256 gcc_unreachable ();
20259 [(set (attr "type")
20260 (cond [(eq_attr "alternative" "0")
20261 (const_string "alu")
20262 (match_operand:DI 2 "const0_operand" "")
20263 (const_string "imov")
20265 (const_string "lea")))
20266 (set_attr "mode" "DI")])
20268 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20269 [(set (match_operand:DI 0 "register_operand" "=r,r")
20270 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20271 (match_operand:DI 3 "immediate_operand" "i,i")))
20272 (use (match_operand:DI 2 "register_operand" "r,r"))
20273 (clobber (reg:CC FLAGS_REG))
20274 (clobber (mem:BLK (scratch)))]
20277 switch (get_attr_type (insn))
20280 return "add{q}\t{%2, %0|%0, %2}";
20283 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20284 return "lea{q}\t{%a2, %0|%0, %a2}";
20287 gcc_unreachable ();
20290 [(set_attr "type" "alu,lea")
20291 (set_attr "mode" "DI")])
20293 (define_insn "allocate_stack_worker_32"
20294 [(set (match_operand:SI 0 "register_operand" "=a")
20295 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20296 UNSPECV_STACK_PROBE))
20297 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20298 (clobber (reg:CC FLAGS_REG))]
20299 "!TARGET_64BIT && TARGET_STACK_PROBE"
20301 [(set_attr "type" "multi")
20302 (set_attr "length" "5")])
20304 (define_insn "allocate_stack_worker_64"
20305 [(set (match_operand:DI 0 "register_operand" "=a")
20306 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20307 UNSPECV_STACK_PROBE))
20308 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20309 (clobber (reg:DI R10_REG))
20310 (clobber (reg:DI R11_REG))
20311 (clobber (reg:CC FLAGS_REG))]
20312 "TARGET_64BIT && TARGET_STACK_PROBE"
20314 [(set_attr "type" "multi")
20315 (set_attr "length" "5")])
20317 (define_expand "allocate_stack"
20318 [(match_operand 0 "register_operand" "")
20319 (match_operand 1 "general_operand" "")]
20320 "TARGET_STACK_PROBE"
20324 #ifndef CHECK_STACK_LIMIT
20325 #define CHECK_STACK_LIMIT 0
20328 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20329 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20331 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20332 stack_pointer_rtx, 0, OPTAB_DIRECT);
20333 if (x != stack_pointer_rtx)
20334 emit_move_insn (stack_pointer_rtx, x);
20338 x = copy_to_mode_reg (Pmode, operands[1]);
20340 x = gen_allocate_stack_worker_64 (x, x);
20342 x = gen_allocate_stack_worker_32 (x, x);
20346 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20350 (define_expand "builtin_setjmp_receiver"
20351 [(label_ref (match_operand 0 "" ""))]
20352 "!TARGET_64BIT && flag_pic"
20358 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20359 rtx label_rtx = gen_label_rtx ();
20360 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20361 xops[0] = xops[1] = picreg;
20362 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20363 ix86_expand_binary_operator (MINUS, SImode, xops);
20367 emit_insn (gen_set_got (pic_offset_table_rtx));
20371 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20374 [(set (match_operand 0 "register_operand" "")
20375 (match_operator 3 "promotable_binary_operator"
20376 [(match_operand 1 "register_operand" "")
20377 (match_operand 2 "aligned_operand" "")]))
20378 (clobber (reg:CC FLAGS_REG))]
20379 "! TARGET_PARTIAL_REG_STALL && reload_completed
20380 && ((GET_MODE (operands[0]) == HImode
20381 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20382 /* ??? next two lines just !satisfies_constraint_K (...) */
20383 || !CONST_INT_P (operands[2])
20384 || satisfies_constraint_K (operands[2])))
20385 || (GET_MODE (operands[0]) == QImode
20386 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20387 [(parallel [(set (match_dup 0)
20388 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20389 (clobber (reg:CC FLAGS_REG))])]
20390 "operands[0] = gen_lowpart (SImode, operands[0]);
20391 operands[1] = gen_lowpart (SImode, operands[1]);
20392 if (GET_CODE (operands[3]) != ASHIFT)
20393 operands[2] = gen_lowpart (SImode, operands[2]);
20394 PUT_MODE (operands[3], SImode);")
20396 ; Promote the QImode tests, as i386 has encoding of the AND
20397 ; instruction with 32-bit sign-extended immediate and thus the
20398 ; instruction size is unchanged, except in the %eax case for
20399 ; which it is increased by one byte, hence the ! optimize_size.
20401 [(set (match_operand 0 "flags_reg_operand" "")
20402 (match_operator 2 "compare_operator"
20403 [(and (match_operand 3 "aligned_operand" "")
20404 (match_operand 4 "const_int_operand" ""))
20406 (set (match_operand 1 "register_operand" "")
20407 (and (match_dup 3) (match_dup 4)))]
20408 "! TARGET_PARTIAL_REG_STALL && reload_completed
20409 && optimize_insn_for_speed_p ()
20410 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20411 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20412 /* Ensure that the operand will remain sign-extended immediate. */
20413 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20414 [(parallel [(set (match_dup 0)
20415 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20418 (and:SI (match_dup 3) (match_dup 4)))])]
20421 = gen_int_mode (INTVAL (operands[4])
20422 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20423 operands[1] = gen_lowpart (SImode, operands[1]);
20424 operands[3] = gen_lowpart (SImode, operands[3]);
20427 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20428 ; the TEST instruction with 32-bit sign-extended immediate and thus
20429 ; the instruction size would at least double, which is not what we
20430 ; want even with ! optimize_size.
20432 [(set (match_operand 0 "flags_reg_operand" "")
20433 (match_operator 1 "compare_operator"
20434 [(and (match_operand:HI 2 "aligned_operand" "")
20435 (match_operand:HI 3 "const_int_operand" ""))
20437 "! TARGET_PARTIAL_REG_STALL && reload_completed
20438 && ! TARGET_FAST_PREFIX
20439 && optimize_insn_for_speed_p ()
20440 /* Ensure that the operand will remain sign-extended immediate. */
20441 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20442 [(set (match_dup 0)
20443 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20447 = gen_int_mode (INTVAL (operands[3])
20448 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20449 operands[2] = gen_lowpart (SImode, operands[2]);
20453 [(set (match_operand 0 "register_operand" "")
20454 (neg (match_operand 1 "register_operand" "")))
20455 (clobber (reg:CC FLAGS_REG))]
20456 "! TARGET_PARTIAL_REG_STALL && reload_completed
20457 && (GET_MODE (operands[0]) == HImode
20458 || (GET_MODE (operands[0]) == QImode
20459 && (TARGET_PROMOTE_QImode
20460 || optimize_insn_for_size_p ())))"
20461 [(parallel [(set (match_dup 0)
20462 (neg:SI (match_dup 1)))
20463 (clobber (reg:CC FLAGS_REG))])]
20464 "operands[0] = gen_lowpart (SImode, operands[0]);
20465 operands[1] = gen_lowpart (SImode, operands[1]);")
20468 [(set (match_operand 0 "register_operand" "")
20469 (not (match_operand 1 "register_operand" "")))]
20470 "! TARGET_PARTIAL_REG_STALL && reload_completed
20471 && (GET_MODE (operands[0]) == HImode
20472 || (GET_MODE (operands[0]) == QImode
20473 && (TARGET_PROMOTE_QImode
20474 || optimize_insn_for_size_p ())))"
20475 [(set (match_dup 0)
20476 (not:SI (match_dup 1)))]
20477 "operands[0] = gen_lowpart (SImode, operands[0]);
20478 operands[1] = gen_lowpart (SImode, operands[1]);")
20481 [(set (match_operand 0 "register_operand" "")
20482 (if_then_else (match_operator 1 "comparison_operator"
20483 [(reg FLAGS_REG) (const_int 0)])
20484 (match_operand 2 "register_operand" "")
20485 (match_operand 3 "register_operand" "")))]
20486 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20487 && (GET_MODE (operands[0]) == HImode
20488 || (GET_MODE (operands[0]) == QImode
20489 && (TARGET_PROMOTE_QImode
20490 || optimize_insn_for_size_p ())))"
20491 [(set (match_dup 0)
20492 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20493 "operands[0] = gen_lowpart (SImode, operands[0]);
20494 operands[2] = gen_lowpart (SImode, operands[2]);
20495 operands[3] = gen_lowpart (SImode, operands[3]);")
20498 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20499 ;; transform a complex memory operation into two memory to register operations.
20501 ;; Don't push memory operands
20503 [(set (match_operand:SI 0 "push_operand" "")
20504 (match_operand:SI 1 "memory_operand" ""))
20505 (match_scratch:SI 2 "r")]
20506 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20507 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20508 [(set (match_dup 2) (match_dup 1))
20509 (set (match_dup 0) (match_dup 2))]
20513 [(set (match_operand:DI 0 "push_operand" "")
20514 (match_operand:DI 1 "memory_operand" ""))
20515 (match_scratch:DI 2 "r")]
20516 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20517 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20518 [(set (match_dup 2) (match_dup 1))
20519 (set (match_dup 0) (match_dup 2))]
20522 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20525 [(set (match_operand:SF 0 "push_operand" "")
20526 (match_operand:SF 1 "memory_operand" ""))
20527 (match_scratch:SF 2 "r")]
20528 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20529 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20530 [(set (match_dup 2) (match_dup 1))
20531 (set (match_dup 0) (match_dup 2))]
20535 [(set (match_operand:HI 0 "push_operand" "")
20536 (match_operand:HI 1 "memory_operand" ""))
20537 (match_scratch:HI 2 "r")]
20538 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20539 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20540 [(set (match_dup 2) (match_dup 1))
20541 (set (match_dup 0) (match_dup 2))]
20545 [(set (match_operand:QI 0 "push_operand" "")
20546 (match_operand:QI 1 "memory_operand" ""))
20547 (match_scratch:QI 2 "q")]
20548 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20549 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20550 [(set (match_dup 2) (match_dup 1))
20551 (set (match_dup 0) (match_dup 2))]
20554 ;; Don't move an immediate directly to memory when the instruction
20557 [(match_scratch:SI 1 "r")
20558 (set (match_operand:SI 0 "memory_operand" "")
20560 "optimize_insn_for_speed_p ()
20561 && ! TARGET_USE_MOV0
20562 && TARGET_SPLIT_LONG_MOVES
20563 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20564 && peep2_regno_dead_p (0, FLAGS_REG)"
20565 [(parallel [(set (match_dup 1) (const_int 0))
20566 (clobber (reg:CC FLAGS_REG))])
20567 (set (match_dup 0) (match_dup 1))]
20571 [(match_scratch:HI 1 "r")
20572 (set (match_operand:HI 0 "memory_operand" "")
20574 "optimize_insn_for_speed_p ()
20575 && ! TARGET_USE_MOV0
20576 && TARGET_SPLIT_LONG_MOVES
20577 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20578 && peep2_regno_dead_p (0, FLAGS_REG)"
20579 [(parallel [(set (match_dup 2) (const_int 0))
20580 (clobber (reg:CC FLAGS_REG))])
20581 (set (match_dup 0) (match_dup 1))]
20582 "operands[2] = gen_lowpart (SImode, operands[1]);")
20585 [(match_scratch:QI 1 "q")
20586 (set (match_operand:QI 0 "memory_operand" "")
20588 "optimize_insn_for_speed_p ()
20589 && ! TARGET_USE_MOV0
20590 && TARGET_SPLIT_LONG_MOVES
20591 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20592 && peep2_regno_dead_p (0, FLAGS_REG)"
20593 [(parallel [(set (match_dup 2) (const_int 0))
20594 (clobber (reg:CC FLAGS_REG))])
20595 (set (match_dup 0) (match_dup 1))]
20596 "operands[2] = gen_lowpart (SImode, operands[1]);")
20599 [(match_scratch:SI 2 "r")
20600 (set (match_operand:SI 0 "memory_operand" "")
20601 (match_operand:SI 1 "immediate_operand" ""))]
20602 "optimize_insn_for_speed_p ()
20603 && TARGET_SPLIT_LONG_MOVES
20604 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20605 [(set (match_dup 2) (match_dup 1))
20606 (set (match_dup 0) (match_dup 2))]
20610 [(match_scratch:HI 2 "r")
20611 (set (match_operand:HI 0 "memory_operand" "")
20612 (match_operand:HI 1 "immediate_operand" ""))]
20613 "optimize_insn_for_speed_p ()
20614 && TARGET_SPLIT_LONG_MOVES
20615 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20616 [(set (match_dup 2) (match_dup 1))
20617 (set (match_dup 0) (match_dup 2))]
20621 [(match_scratch:QI 2 "q")
20622 (set (match_operand:QI 0 "memory_operand" "")
20623 (match_operand:QI 1 "immediate_operand" ""))]
20624 "optimize_insn_for_speed_p ()
20625 && TARGET_SPLIT_LONG_MOVES
20626 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20627 [(set (match_dup 2) (match_dup 1))
20628 (set (match_dup 0) (match_dup 2))]
20631 ;; Don't compare memory with zero, load and use a test instead.
20633 [(set (match_operand 0 "flags_reg_operand" "")
20634 (match_operator 1 "compare_operator"
20635 [(match_operand:SI 2 "memory_operand" "")
20637 (match_scratch:SI 3 "r")]
20638 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20639 [(set (match_dup 3) (match_dup 2))
20640 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20643 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20644 ;; Don't split NOTs with a displacement operand, because resulting XOR
20645 ;; will not be pairable anyway.
20647 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20648 ;; represented using a modRM byte. The XOR replacement is long decoded,
20649 ;; so this split helps here as well.
20651 ;; Note: Can't do this as a regular split because we can't get proper
20652 ;; lifetime information then.
20655 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20656 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20657 "optimize_insn_for_speed_p ()
20658 && ((TARGET_NOT_UNPAIRABLE
20659 && (!MEM_P (operands[0])
20660 || !memory_displacement_operand (operands[0], SImode)))
20661 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20662 && peep2_regno_dead_p (0, FLAGS_REG)"
20663 [(parallel [(set (match_dup 0)
20664 (xor:SI (match_dup 1) (const_int -1)))
20665 (clobber (reg:CC FLAGS_REG))])]
20669 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20670 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20671 "optimize_insn_for_speed_p ()
20672 && ((TARGET_NOT_UNPAIRABLE
20673 && (!MEM_P (operands[0])
20674 || !memory_displacement_operand (operands[0], HImode)))
20675 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20676 && peep2_regno_dead_p (0, FLAGS_REG)"
20677 [(parallel [(set (match_dup 0)
20678 (xor:HI (match_dup 1) (const_int -1)))
20679 (clobber (reg:CC FLAGS_REG))])]
20683 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20684 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20685 "optimize_insn_for_speed_p ()
20686 && ((TARGET_NOT_UNPAIRABLE
20687 && (!MEM_P (operands[0])
20688 || !memory_displacement_operand (operands[0], QImode)))
20689 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20690 && peep2_regno_dead_p (0, FLAGS_REG)"
20691 [(parallel [(set (match_dup 0)
20692 (xor:QI (match_dup 1) (const_int -1)))
20693 (clobber (reg:CC FLAGS_REG))])]
20696 ;; Non pairable "test imm, reg" instructions can be translated to
20697 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20698 ;; byte opcode instead of two, have a short form for byte operands),
20699 ;; so do it for other CPUs as well. Given that the value was dead,
20700 ;; this should not create any new dependencies. Pass on the sub-word
20701 ;; versions if we're concerned about partial register stalls.
20704 [(set (match_operand 0 "flags_reg_operand" "")
20705 (match_operator 1 "compare_operator"
20706 [(and:SI (match_operand:SI 2 "register_operand" "")
20707 (match_operand:SI 3 "immediate_operand" ""))
20709 "ix86_match_ccmode (insn, CCNOmode)
20710 && (true_regnum (operands[2]) != AX_REG
20711 || satisfies_constraint_K (operands[3]))
20712 && peep2_reg_dead_p (1, operands[2])"
20714 [(set (match_dup 0)
20715 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20718 (and:SI (match_dup 2) (match_dup 3)))])]
20721 ;; We don't need to handle HImode case, because it will be promoted to SImode
20722 ;; on ! TARGET_PARTIAL_REG_STALL
20725 [(set (match_operand 0 "flags_reg_operand" "")
20726 (match_operator 1 "compare_operator"
20727 [(and:QI (match_operand:QI 2 "register_operand" "")
20728 (match_operand:QI 3 "immediate_operand" ""))
20730 "! TARGET_PARTIAL_REG_STALL
20731 && ix86_match_ccmode (insn, CCNOmode)
20732 && true_regnum (operands[2]) != AX_REG
20733 && peep2_reg_dead_p (1, operands[2])"
20735 [(set (match_dup 0)
20736 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20739 (and:QI (match_dup 2) (match_dup 3)))])]
20743 [(set (match_operand 0 "flags_reg_operand" "")
20744 (match_operator 1 "compare_operator"
20747 (match_operand 2 "ext_register_operand" "")
20750 (match_operand 3 "const_int_operand" ""))
20752 "! TARGET_PARTIAL_REG_STALL
20753 && ix86_match_ccmode (insn, CCNOmode)
20754 && true_regnum (operands[2]) != AX_REG
20755 && peep2_reg_dead_p (1, operands[2])"
20756 [(parallel [(set (match_dup 0)
20765 (set (zero_extract:SI (match_dup 2)
20776 ;; Don't do logical operations with memory inputs.
20778 [(match_scratch:SI 2 "r")
20779 (parallel [(set (match_operand:SI 0 "register_operand" "")
20780 (match_operator:SI 3 "arith_or_logical_operator"
20782 (match_operand:SI 1 "memory_operand" "")]))
20783 (clobber (reg:CC FLAGS_REG))])]
20784 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20785 [(set (match_dup 2) (match_dup 1))
20786 (parallel [(set (match_dup 0)
20787 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20788 (clobber (reg:CC FLAGS_REG))])]
20792 [(match_scratch:SI 2 "r")
20793 (parallel [(set (match_operand:SI 0 "register_operand" "")
20794 (match_operator:SI 3 "arith_or_logical_operator"
20795 [(match_operand:SI 1 "memory_operand" "")
20797 (clobber (reg:CC FLAGS_REG))])]
20798 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20799 [(set (match_dup 2) (match_dup 1))
20800 (parallel [(set (match_dup 0)
20801 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20802 (clobber (reg:CC FLAGS_REG))])]
20805 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20806 ;; refers to the destination of the load!
20809 [(set (match_operand:SI 0 "register_operand" "")
20810 (match_operand:SI 1 "register_operand" ""))
20811 (parallel [(set (match_dup 0)
20812 (match_operator:SI 3 "commutative_operator"
20814 (match_operand:SI 2 "memory_operand" "")]))
20815 (clobber (reg:CC FLAGS_REG))])]
20816 "operands[0] != operands[1]
20817 && GENERAL_REGNO_P (REGNO (operands[0]))
20818 && GENERAL_REGNO_P (REGNO (operands[1]))"
20819 [(set (match_dup 0) (match_dup 4))
20820 (parallel [(set (match_dup 0)
20821 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20822 (clobber (reg:CC FLAGS_REG))])]
20823 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20826 [(set (match_operand 0 "register_operand" "")
20827 (match_operand 1 "register_operand" ""))
20829 (match_operator 3 "commutative_operator"
20831 (match_operand 2 "memory_operand" "")]))]
20832 "operands[0] != operands[1]
20833 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20834 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20835 [(set (match_dup 0) (match_dup 2))
20837 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20840 ; Don't do logical operations with memory outputs
20842 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20843 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20844 ; the same decoder scheduling characteristics as the original.
20847 [(match_scratch:SI 2 "r")
20848 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20849 (match_operator:SI 3 "arith_or_logical_operator"
20851 (match_operand:SI 1 "nonmemory_operand" "")]))
20852 (clobber (reg:CC FLAGS_REG))])]
20853 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20854 [(set (match_dup 2) (match_dup 0))
20855 (parallel [(set (match_dup 2)
20856 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20857 (clobber (reg:CC FLAGS_REG))])
20858 (set (match_dup 0) (match_dup 2))]
20862 [(match_scratch:SI 2 "r")
20863 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20864 (match_operator:SI 3 "arith_or_logical_operator"
20865 [(match_operand:SI 1 "nonmemory_operand" "")
20867 (clobber (reg:CC FLAGS_REG))])]
20868 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20869 [(set (match_dup 2) (match_dup 0))
20870 (parallel [(set (match_dup 2)
20871 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20872 (clobber (reg:CC FLAGS_REG))])
20873 (set (match_dup 0) (match_dup 2))]
20876 ;; Attempt to always use XOR for zeroing registers.
20878 [(set (match_operand 0 "register_operand" "")
20879 (match_operand 1 "const0_operand" ""))]
20880 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20881 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20882 && GENERAL_REG_P (operands[0])
20883 && peep2_regno_dead_p (0, FLAGS_REG)"
20884 [(parallel [(set (match_dup 0) (const_int 0))
20885 (clobber (reg:CC FLAGS_REG))])]
20887 operands[0] = gen_lowpart (word_mode, operands[0]);
20891 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20893 "(GET_MODE (operands[0]) == QImode
20894 || GET_MODE (operands[0]) == HImode)
20895 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20896 && peep2_regno_dead_p (0, FLAGS_REG)"
20897 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20898 (clobber (reg:CC FLAGS_REG))])])
20900 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20902 [(set (match_operand 0 "register_operand" "")
20904 "(GET_MODE (operands[0]) == HImode
20905 || GET_MODE (operands[0]) == SImode
20906 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20907 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20908 && peep2_regno_dead_p (0, FLAGS_REG)"
20909 [(parallel [(set (match_dup 0) (const_int -1))
20910 (clobber (reg:CC FLAGS_REG))])]
20911 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20914 ;; Attempt to convert simple leas to adds. These can be created by
20917 [(set (match_operand:SI 0 "register_operand" "")
20918 (plus:SI (match_dup 0)
20919 (match_operand:SI 1 "nonmemory_operand" "")))]
20920 "peep2_regno_dead_p (0, FLAGS_REG)"
20921 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20922 (clobber (reg:CC FLAGS_REG))])]
20926 [(set (match_operand:SI 0 "register_operand" "")
20927 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20928 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20929 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20930 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20931 (clobber (reg:CC FLAGS_REG))])]
20932 "operands[2] = gen_lowpart (SImode, operands[2]);")
20935 [(set (match_operand:DI 0 "register_operand" "")
20936 (plus:DI (match_dup 0)
20937 (match_operand:DI 1 "x86_64_general_operand" "")))]
20938 "peep2_regno_dead_p (0, FLAGS_REG)"
20939 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20940 (clobber (reg:CC FLAGS_REG))])]
20944 [(set (match_operand:SI 0 "register_operand" "")
20945 (mult:SI (match_dup 0)
20946 (match_operand:SI 1 "const_int_operand" "")))]
20947 "exact_log2 (INTVAL (operands[1])) >= 0
20948 && peep2_regno_dead_p (0, FLAGS_REG)"
20949 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20950 (clobber (reg:CC FLAGS_REG))])]
20951 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20954 [(set (match_operand:DI 0 "register_operand" "")
20955 (mult:DI (match_dup 0)
20956 (match_operand:DI 1 "const_int_operand" "")))]
20957 "exact_log2 (INTVAL (operands[1])) >= 0
20958 && peep2_regno_dead_p (0, FLAGS_REG)"
20959 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20960 (clobber (reg:CC FLAGS_REG))])]
20961 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20964 [(set (match_operand:SI 0 "register_operand" "")
20965 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20966 (match_operand:DI 2 "const_int_operand" "")) 0))]
20967 "exact_log2 (INTVAL (operands[2])) >= 0
20968 && REGNO (operands[0]) == REGNO (operands[1])
20969 && peep2_regno_dead_p (0, FLAGS_REG)"
20970 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20971 (clobber (reg:CC FLAGS_REG))])]
20972 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20974 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20975 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20976 ;; many CPUs it is also faster, since special hardware to avoid esp
20977 ;; dependencies is present.
20979 ;; While some of these conversions may be done using splitters, we use peepholes
20980 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20982 ;; Convert prologue esp subtractions to push.
20983 ;; We need register to push. In order to keep verify_flow_info happy we have
20985 ;; - use scratch and clobber it in order to avoid dependencies
20986 ;; - use already live register
20987 ;; We can't use the second way right now, since there is no reliable way how to
20988 ;; verify that given register is live. First choice will also most likely in
20989 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20990 ;; call clobbered registers are dead. We may want to use base pointer as an
20991 ;; alternative when no register is available later.
20994 [(match_scratch:SI 0 "r")
20995 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20996 (clobber (reg:CC FLAGS_REG))
20997 (clobber (mem:BLK (scratch)))])]
20998 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20999 [(clobber (match_dup 0))
21000 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21001 (clobber (mem:BLK (scratch)))])])
21004 [(match_scratch:SI 0 "r")
21005 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21006 (clobber (reg:CC FLAGS_REG))
21007 (clobber (mem:BLK (scratch)))])]
21008 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21009 [(clobber (match_dup 0))
21010 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21011 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21012 (clobber (mem:BLK (scratch)))])])
21014 ;; Convert esp subtractions to push.
21016 [(match_scratch:SI 0 "r")
21017 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21018 (clobber (reg:CC FLAGS_REG))])]
21019 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21020 [(clobber (match_dup 0))
21021 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21024 [(match_scratch:SI 0 "r")
21025 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21026 (clobber (reg:CC FLAGS_REG))])]
21027 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21028 [(clobber (match_dup 0))
21029 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21030 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21032 ;; Convert epilogue deallocator to pop.
21034 [(match_scratch:SI 0 "r")
21035 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21036 (clobber (reg:CC FLAGS_REG))
21037 (clobber (mem:BLK (scratch)))])]
21038 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21039 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21040 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21041 (clobber (mem:BLK (scratch)))])]
21044 ;; Two pops case is tricky, since pop causes dependency on destination register.
21045 ;; We use two registers if available.
21047 [(match_scratch:SI 0 "r")
21048 (match_scratch:SI 1 "r")
21049 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21050 (clobber (reg:CC FLAGS_REG))
21051 (clobber (mem:BLK (scratch)))])]
21052 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21053 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21054 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21055 (clobber (mem:BLK (scratch)))])
21056 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21057 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21061 [(match_scratch:SI 0 "r")
21062 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21063 (clobber (reg:CC FLAGS_REG))
21064 (clobber (mem:BLK (scratch)))])]
21065 "optimize_insn_for_size_p ()"
21066 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21067 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21068 (clobber (mem:BLK (scratch)))])
21069 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21070 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21073 ;; Convert esp additions 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))])]
21079 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21080 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21083 ;; Two pops case is tricky, since pop causes dependency on destination register.
21084 ;; We use two registers if available.
21086 [(match_scratch:SI 0 "r")
21087 (match_scratch:SI 1 "r")
21088 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21089 (clobber (reg:CC FLAGS_REG))])]
21091 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21092 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21093 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21094 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21098 [(match_scratch:SI 0 "r")
21099 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21100 (clobber (reg:CC FLAGS_REG))])]
21101 "optimize_insn_for_size_p ()"
21102 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21103 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21104 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21105 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21108 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21109 ;; required and register dies. Similarly for 128 to -128.
21111 [(set (match_operand 0 "flags_reg_operand" "")
21112 (match_operator 1 "compare_operator"
21113 [(match_operand 2 "register_operand" "")
21114 (match_operand 3 "const_int_operand" "")]))]
21115 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21116 && incdec_operand (operands[3], GET_MODE (operands[3])))
21117 || (!TARGET_FUSE_CMP_AND_BRANCH
21118 && INTVAL (operands[3]) == 128))
21119 && ix86_match_ccmode (insn, CCGCmode)
21120 && peep2_reg_dead_p (1, operands[2])"
21121 [(parallel [(set (match_dup 0)
21122 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21123 (clobber (match_dup 2))])]
21127 [(match_scratch:DI 0 "r")
21128 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21129 (clobber (reg:CC FLAGS_REG))
21130 (clobber (mem:BLK (scratch)))])]
21131 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21132 [(clobber (match_dup 0))
21133 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21134 (clobber (mem:BLK (scratch)))])])
21137 [(match_scratch:DI 0 "r")
21138 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21139 (clobber (reg:CC FLAGS_REG))
21140 (clobber (mem:BLK (scratch)))])]
21141 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21142 [(clobber (match_dup 0))
21143 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21144 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21145 (clobber (mem:BLK (scratch)))])])
21147 ;; Convert esp subtractions to push.
21149 [(match_scratch:DI 0 "r")
21150 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21151 (clobber (reg:CC FLAGS_REG))])]
21152 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21153 [(clobber (match_dup 0))
21154 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21157 [(match_scratch:DI 0 "r")
21158 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21159 (clobber (reg:CC FLAGS_REG))])]
21160 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21161 [(clobber (match_dup 0))
21162 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21163 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21165 ;; Convert epilogue deallocator to pop.
21167 [(match_scratch:DI 0 "r")
21168 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21169 (clobber (reg:CC FLAGS_REG))
21170 (clobber (mem:BLK (scratch)))])]
21171 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21172 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21173 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21174 (clobber (mem:BLK (scratch)))])]
21177 ;; Two pops case is tricky, since pop causes dependency on destination register.
21178 ;; We use two registers if available.
21180 [(match_scratch:DI 0 "r")
21181 (match_scratch:DI 1 "r")
21182 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21183 (clobber (reg:CC FLAGS_REG))
21184 (clobber (mem:BLK (scratch)))])]
21185 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21186 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21187 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21188 (clobber (mem:BLK (scratch)))])
21189 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21190 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21194 [(match_scratch:DI 0 "r")
21195 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21196 (clobber (reg:CC FLAGS_REG))
21197 (clobber (mem:BLK (scratch)))])]
21198 "optimize_insn_for_size_p ()"
21199 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21200 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21201 (clobber (mem:BLK (scratch)))])
21202 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21203 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21206 ;; Convert esp additions 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))])]
21212 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21213 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21216 ;; Two pops case is tricky, since pop causes dependency on destination register.
21217 ;; We use two registers if available.
21219 [(match_scratch:DI 0 "r")
21220 (match_scratch:DI 1 "r")
21221 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21222 (clobber (reg:CC FLAGS_REG))])]
21224 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21225 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21226 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21227 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21231 [(match_scratch:DI 0 "r")
21232 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21233 (clobber (reg:CC FLAGS_REG))])]
21234 "optimize_insn_for_size_p ()"
21235 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21236 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21237 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21238 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21241 ;; Convert imul by three, five and nine into lea
21244 [(set (match_operand:SI 0 "register_operand" "")
21245 (mult:SI (match_operand:SI 1 "register_operand" "")
21246 (match_operand:SI 2 "const_int_operand" "")))
21247 (clobber (reg:CC FLAGS_REG))])]
21248 "INTVAL (operands[2]) == 3
21249 || INTVAL (operands[2]) == 5
21250 || INTVAL (operands[2]) == 9"
21251 [(set (match_dup 0)
21252 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21254 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21258 [(set (match_operand:SI 0 "register_operand" "")
21259 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21260 (match_operand:SI 2 "const_int_operand" "")))
21261 (clobber (reg:CC FLAGS_REG))])]
21262 "optimize_insn_for_speed_p ()
21263 && (INTVAL (operands[2]) == 3
21264 || INTVAL (operands[2]) == 5
21265 || INTVAL (operands[2]) == 9)"
21266 [(set (match_dup 0) (match_dup 1))
21268 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21270 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21274 [(set (match_operand:DI 0 "register_operand" "")
21275 (mult:DI (match_operand:DI 1 "register_operand" "")
21276 (match_operand:DI 2 "const_int_operand" "")))
21277 (clobber (reg:CC FLAGS_REG))])]
21279 && (INTVAL (operands[2]) == 3
21280 || INTVAL (operands[2]) == 5
21281 || INTVAL (operands[2]) == 9)"
21282 [(set (match_dup 0)
21283 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21285 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21289 [(set (match_operand:DI 0 "register_operand" "")
21290 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21291 (match_operand:DI 2 "const_int_operand" "")))
21292 (clobber (reg:CC FLAGS_REG))])]
21294 && optimize_insn_for_speed_p ()
21295 && (INTVAL (operands[2]) == 3
21296 || INTVAL (operands[2]) == 5
21297 || INTVAL (operands[2]) == 9)"
21298 [(set (match_dup 0) (match_dup 1))
21300 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21302 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21304 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21305 ;; imul $32bit_imm, reg, reg is direct decoded.
21307 [(match_scratch:DI 3 "r")
21308 (parallel [(set (match_operand:DI 0 "register_operand" "")
21309 (mult:DI (match_operand:DI 1 "memory_operand" "")
21310 (match_operand:DI 2 "immediate_operand" "")))
21311 (clobber (reg:CC FLAGS_REG))])]
21312 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21313 && !satisfies_constraint_K (operands[2])"
21314 [(set (match_dup 3) (match_dup 1))
21315 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21316 (clobber (reg:CC FLAGS_REG))])]
21320 [(match_scratch:SI 3 "r")
21321 (parallel [(set (match_operand:SI 0 "register_operand" "")
21322 (mult:SI (match_operand:SI 1 "memory_operand" "")
21323 (match_operand:SI 2 "immediate_operand" "")))
21324 (clobber (reg:CC FLAGS_REG))])]
21325 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21326 && !satisfies_constraint_K (operands[2])"
21327 [(set (match_dup 3) (match_dup 1))
21328 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21329 (clobber (reg:CC FLAGS_REG))])]
21333 [(match_scratch:SI 3 "r")
21334 (parallel [(set (match_operand:DI 0 "register_operand" "")
21336 (mult:SI (match_operand:SI 1 "memory_operand" "")
21337 (match_operand:SI 2 "immediate_operand" ""))))
21338 (clobber (reg:CC FLAGS_REG))])]
21339 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21340 && !satisfies_constraint_K (operands[2])"
21341 [(set (match_dup 3) (match_dup 1))
21342 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21343 (clobber (reg:CC FLAGS_REG))])]
21346 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21347 ;; Convert it into imul reg, reg
21348 ;; It would be better to force assembler to encode instruction using long
21349 ;; immediate, but there is apparently no way to do so.
21351 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21352 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21353 (match_operand:DI 2 "const_int_operand" "")))
21354 (clobber (reg:CC FLAGS_REG))])
21355 (match_scratch:DI 3 "r")]
21356 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21357 && satisfies_constraint_K (operands[2])"
21358 [(set (match_dup 3) (match_dup 2))
21359 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21360 (clobber (reg:CC FLAGS_REG))])]
21362 if (!rtx_equal_p (operands[0], operands[1]))
21363 emit_move_insn (operands[0], operands[1]);
21367 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21368 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21369 (match_operand:SI 2 "const_int_operand" "")))
21370 (clobber (reg:CC FLAGS_REG))])
21371 (match_scratch:SI 3 "r")]
21372 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21373 && satisfies_constraint_K (operands[2])"
21374 [(set (match_dup 3) (match_dup 2))
21375 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21376 (clobber (reg:CC FLAGS_REG))])]
21378 if (!rtx_equal_p (operands[0], operands[1]))
21379 emit_move_insn (operands[0], operands[1]);
21383 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21384 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21385 (match_operand:HI 2 "immediate_operand" "")))
21386 (clobber (reg:CC FLAGS_REG))])
21387 (match_scratch:HI 3 "r")]
21388 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21389 [(set (match_dup 3) (match_dup 2))
21390 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21391 (clobber (reg:CC FLAGS_REG))])]
21393 if (!rtx_equal_p (operands[0], operands[1]))
21394 emit_move_insn (operands[0], operands[1]);
21397 ;; After splitting up read-modify operations, array accesses with memory
21398 ;; operands might end up in form:
21400 ;; movl 4(%esp), %edx
21402 ;; instead of pre-splitting:
21404 ;; addl 4(%esp), %eax
21406 ;; movl 4(%esp), %edx
21407 ;; leal (%edx,%eax,4), %eax
21410 [(parallel [(set (match_operand 0 "register_operand" "")
21411 (ashift (match_operand 1 "register_operand" "")
21412 (match_operand 2 "const_int_operand" "")))
21413 (clobber (reg:CC FLAGS_REG))])
21414 (set (match_operand 3 "register_operand")
21415 (match_operand 4 "x86_64_general_operand" ""))
21416 (parallel [(set (match_operand 5 "register_operand" "")
21417 (plus (match_operand 6 "register_operand" "")
21418 (match_operand 7 "register_operand" "")))
21419 (clobber (reg:CC FLAGS_REG))])]
21420 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21421 /* Validate MODE for lea. */
21422 && ((!TARGET_PARTIAL_REG_STALL
21423 && (GET_MODE (operands[0]) == QImode
21424 || GET_MODE (operands[0]) == HImode))
21425 || GET_MODE (operands[0]) == SImode
21426 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21427 /* We reorder load and the shift. */
21428 && !rtx_equal_p (operands[1], operands[3])
21429 && !reg_overlap_mentioned_p (operands[0], operands[4])
21430 /* Last PLUS must consist of operand 0 and 3. */
21431 && !rtx_equal_p (operands[0], operands[3])
21432 && (rtx_equal_p (operands[3], operands[6])
21433 || rtx_equal_p (operands[3], operands[7]))
21434 && (rtx_equal_p (operands[0], operands[6])
21435 || rtx_equal_p (operands[0], operands[7]))
21436 /* The intermediate operand 0 must die or be same as output. */
21437 && (rtx_equal_p (operands[0], operands[5])
21438 || peep2_reg_dead_p (3, operands[0]))"
21439 [(set (match_dup 3) (match_dup 4))
21440 (set (match_dup 0) (match_dup 1))]
21442 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21443 int scale = 1 << INTVAL (operands[2]);
21444 rtx index = gen_lowpart (Pmode, operands[1]);
21445 rtx base = gen_lowpart (Pmode, operands[3]);
21446 rtx dest = gen_lowpart (mode, operands[5]);
21448 operands[1] = gen_rtx_PLUS (Pmode, base,
21449 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21451 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21452 operands[0] = dest;
21455 ;; Call-value patterns last so that the wildcard operand does not
21456 ;; disrupt insn-recog's switch tables.
21458 (define_insn "*call_value_pop_0"
21459 [(set (match_operand 0 "" "")
21460 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21461 (match_operand:SI 2 "" "")))
21462 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21463 (match_operand:SI 3 "immediate_operand" "")))]
21466 if (SIBLING_CALL_P (insn))
21469 return "call\t%P1";
21471 [(set_attr "type" "callv")])
21473 (define_insn "*call_value_pop_1"
21474 [(set (match_operand 0 "" "")
21475 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21476 (match_operand:SI 2 "" "")))
21477 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21478 (match_operand:SI 3 "immediate_operand" "i")))]
21481 if (constant_call_address_operand (operands[1], Pmode))
21483 if (SIBLING_CALL_P (insn))
21486 return "call\t%P1";
21488 if (SIBLING_CALL_P (insn))
21491 return "call\t%A1";
21493 [(set_attr "type" "callv")])
21495 (define_insn "*call_value_0"
21496 [(set (match_operand 0 "" "")
21497 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21498 (match_operand:SI 2 "" "")))]
21501 if (SIBLING_CALL_P (insn))
21504 return "call\t%P1";
21506 [(set_attr "type" "callv")])
21508 (define_insn "*call_value_0_rex64"
21509 [(set (match_operand 0 "" "")
21510 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21511 (match_operand:DI 2 "const_int_operand" "")))]
21514 if (SIBLING_CALL_P (insn))
21517 return "call\t%P1";
21519 [(set_attr "type" "callv")])
21521 (define_insn "*call_value_0_rex64_ms_sysv"
21522 [(set (match_operand 0 "" "")
21523 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21524 (match_operand:DI 2 "const_int_operand" "")))
21525 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21526 (clobber (reg:TI XMM6_REG))
21527 (clobber (reg:TI XMM7_REG))
21528 (clobber (reg:TI XMM8_REG))
21529 (clobber (reg:TI XMM9_REG))
21530 (clobber (reg:TI XMM10_REG))
21531 (clobber (reg:TI XMM11_REG))
21532 (clobber (reg:TI XMM12_REG))
21533 (clobber (reg:TI XMM13_REG))
21534 (clobber (reg:TI XMM14_REG))
21535 (clobber (reg:TI XMM15_REG))
21536 (clobber (reg:DI SI_REG))
21537 (clobber (reg:DI DI_REG))]
21538 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21540 if (SIBLING_CALL_P (insn))
21543 return "call\t%P1";
21545 [(set_attr "type" "callv")])
21547 (define_insn "*call_value_1"
21548 [(set (match_operand 0 "" "")
21549 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21550 (match_operand:SI 2 "" "")))]
21551 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21553 if (constant_call_address_operand (operands[1], Pmode))
21554 return "call\t%P1";
21555 return "call\t%A1";
21557 [(set_attr "type" "callv")])
21559 (define_insn "*sibcall_value_1"
21560 [(set (match_operand 0 "" "")
21561 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21562 (match_operand:SI 2 "" "")))]
21563 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21565 if (constant_call_address_operand (operands[1], Pmode))
21569 [(set_attr "type" "callv")])
21571 (define_insn "*call_value_1_rex64"
21572 [(set (match_operand 0 "" "")
21573 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21574 (match_operand:DI 2 "" "")))]
21575 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21576 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21578 if (constant_call_address_operand (operands[1], Pmode))
21579 return "call\t%P1";
21580 return "call\t%A1";
21582 [(set_attr "type" "callv")])
21584 (define_insn "*call_value_1_rex64_ms_sysv"
21585 [(set (match_operand 0 "" "")
21586 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21587 (match_operand:DI 2 "" "")))
21588 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21589 (clobber (reg:TI 27))
21590 (clobber (reg:TI 28))
21591 (clobber (reg:TI 45))
21592 (clobber (reg:TI 46))
21593 (clobber (reg:TI 47))
21594 (clobber (reg:TI 48))
21595 (clobber (reg:TI 49))
21596 (clobber (reg:TI 50))
21597 (clobber (reg:TI 51))
21598 (clobber (reg:TI 52))
21599 (clobber (reg:DI SI_REG))
21600 (clobber (reg:DI DI_REG))]
21601 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21603 if (constant_call_address_operand (operands[1], Pmode))
21604 return "call\t%P1";
21605 return "call\t%A1";
21607 [(set_attr "type" "callv")])
21609 (define_insn "*call_value_1_rex64_large"
21610 [(set (match_operand 0 "" "")
21611 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21612 (match_operand:DI 2 "" "")))]
21613 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21615 [(set_attr "type" "callv")])
21617 (define_insn "*sibcall_value_1_rex64"
21618 [(set (match_operand 0 "" "")
21619 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21620 (match_operand:DI 2 "" "")))]
21621 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21623 [(set_attr "type" "callv")])
21625 (define_insn "*sibcall_value_1_rex64_v"
21626 [(set (match_operand 0 "" "")
21627 (call (mem:QI (reg:DI R11_REG))
21628 (match_operand:DI 1 "" "")))]
21629 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21631 [(set_attr "type" "callv")])
21633 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21634 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21635 ;; caught for use by garbage collectors and the like. Using an insn that
21636 ;; maps to SIGILL makes it more likely the program will rightfully die.
21637 ;; Keeping with tradition, "6" is in honor of #UD.
21638 (define_insn "trap"
21639 [(trap_if (const_int 1) (const_int 6))]
21641 { return ASM_SHORT "0x0b0f"; }
21642 [(set_attr "length" "2")])
21644 (define_expand "sse_prologue_save"
21645 [(parallel [(set (match_operand:BLK 0 "" "")
21646 (unspec:BLK [(reg:DI 21)
21653 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21654 (use (match_operand:DI 1 "register_operand" ""))
21655 (use (match_operand:DI 2 "immediate_operand" ""))
21656 (use (label_ref:DI (match_operand 3 "" "")))])]
21660 (define_insn "*sse_prologue_save_insn"
21661 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21662 (match_operand:DI 4 "const_int_operand" "n")))
21663 (unspec:BLK [(reg:DI 21)
21670 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21671 (use (match_operand:DI 1 "register_operand" "r"))
21672 (use (match_operand:DI 2 "const_int_operand" "i"))
21673 (use (label_ref:DI (match_operand 3 "" "X")))]
21675 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21676 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21679 operands[0] = gen_rtx_MEM (Pmode,
21680 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21681 /* VEX instruction with a REX prefix will #UD. */
21682 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21683 gcc_unreachable ();
21685 output_asm_insn ("jmp\t%A1", operands);
21686 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21688 operands[4] = adjust_address (operands[0], DImode, i*16);
21689 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21690 PUT_MODE (operands[4], TImode);
21691 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21692 output_asm_insn ("rex", operands);
21693 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21695 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21696 CODE_LABEL_NUMBER (operands[3]));
21699 [(set_attr "type" "other")
21700 (set_attr "length_immediate" "0")
21701 (set_attr "length_address" "0")
21702 (set (attr "length")
21704 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21705 (const_string "34")
21706 (const_string "42")))
21707 (set_attr "memory" "store")
21708 (set_attr "modrm" "0")
21709 (set_attr "prefix" "maybe_vex")
21710 (set_attr "mode" "DI")])
21712 (define_expand "prefetch"
21713 [(prefetch (match_operand 0 "address_operand" "")
21714 (match_operand:SI 1 "const_int_operand" "")
21715 (match_operand:SI 2 "const_int_operand" ""))]
21716 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21718 int rw = INTVAL (operands[1]);
21719 int locality = INTVAL (operands[2]);
21721 gcc_assert (rw == 0 || rw == 1);
21722 gcc_assert (locality >= 0 && locality <= 3);
21723 gcc_assert (GET_MODE (operands[0]) == Pmode
21724 || GET_MODE (operands[0]) == VOIDmode);
21726 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21727 supported by SSE counterpart or the SSE prefetch is not available
21728 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21730 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21731 operands[2] = GEN_INT (3);
21733 operands[1] = const0_rtx;
21736 (define_insn "*prefetch_sse"
21737 [(prefetch (match_operand:SI 0 "address_operand" "p")
21739 (match_operand:SI 1 "const_int_operand" ""))]
21740 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21742 static const char * const patterns[4] = {
21743 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21746 int locality = INTVAL (operands[1]);
21747 gcc_assert (locality >= 0 && locality <= 3);
21749 return patterns[locality];
21751 [(set_attr "type" "sse")
21752 (set_attr "memory" "none")])
21754 (define_insn "*prefetch_sse_rex"
21755 [(prefetch (match_operand:DI 0 "address_operand" "p")
21757 (match_operand:SI 1 "const_int_operand" ""))]
21758 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21760 static const char * const patterns[4] = {
21761 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21764 int locality = INTVAL (operands[1]);
21765 gcc_assert (locality >= 0 && locality <= 3);
21767 return patterns[locality];
21769 [(set_attr "type" "sse")
21770 (set_attr "memory" "none")])
21772 (define_insn "*prefetch_3dnow"
21773 [(prefetch (match_operand:SI 0 "address_operand" "p")
21774 (match_operand:SI 1 "const_int_operand" "n")
21776 "TARGET_3DNOW && !TARGET_64BIT"
21778 if (INTVAL (operands[1]) == 0)
21779 return "prefetch\t%a0";
21781 return "prefetchw\t%a0";
21783 [(set_attr "type" "mmx")
21784 (set_attr "memory" "none")])
21786 (define_insn "*prefetch_3dnow_rex"
21787 [(prefetch (match_operand:DI 0 "address_operand" "p")
21788 (match_operand:SI 1 "const_int_operand" "n")
21790 "TARGET_3DNOW && TARGET_64BIT"
21792 if (INTVAL (operands[1]) == 0)
21793 return "prefetch\t%a0";
21795 return "prefetchw\t%a0";
21797 [(set_attr "type" "mmx")
21798 (set_attr "memory" "none")])
21800 (define_expand "stack_protect_set"
21801 [(match_operand 0 "memory_operand" "")
21802 (match_operand 1 "memory_operand" "")]
21805 #ifdef TARGET_THREAD_SSP_OFFSET
21807 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21808 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21810 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21811 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21814 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21816 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21821 (define_insn "stack_protect_set_si"
21822 [(set (match_operand:SI 0 "memory_operand" "=m")
21823 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21824 (set (match_scratch:SI 2 "=&r") (const_int 0))
21825 (clobber (reg:CC FLAGS_REG))]
21827 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21828 [(set_attr "type" "multi")])
21830 (define_insn "stack_protect_set_di"
21831 [(set (match_operand:DI 0 "memory_operand" "=m")
21832 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21833 (set (match_scratch:DI 2 "=&r") (const_int 0))
21834 (clobber (reg:CC FLAGS_REG))]
21836 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21837 [(set_attr "type" "multi")])
21839 (define_insn "stack_tls_protect_set_si"
21840 [(set (match_operand:SI 0 "memory_operand" "=m")
21841 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21842 (set (match_scratch:SI 2 "=&r") (const_int 0))
21843 (clobber (reg:CC FLAGS_REG))]
21845 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21846 [(set_attr "type" "multi")])
21848 (define_insn "stack_tls_protect_set_di"
21849 [(set (match_operand:DI 0 "memory_operand" "=m")
21850 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21851 (set (match_scratch:DI 2 "=&r") (const_int 0))
21852 (clobber (reg:CC FLAGS_REG))]
21855 /* The kernel uses a different segment register for performance reasons; a
21856 system call would not have to trash the userspace segment register,
21857 which would be expensive */
21858 if (ix86_cmodel != CM_KERNEL)
21859 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21861 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21863 [(set_attr "type" "multi")])
21865 (define_expand "stack_protect_test"
21866 [(match_operand 0 "memory_operand" "")
21867 (match_operand 1 "memory_operand" "")
21868 (match_operand 2 "" "")]
21871 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21872 ix86_compare_op0 = operands[0];
21873 ix86_compare_op1 = operands[1];
21874 ix86_compare_emitted = flags;
21876 #ifdef TARGET_THREAD_SSP_OFFSET
21878 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21879 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21881 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21882 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21885 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21887 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21889 emit_jump_insn (gen_beq (operands[2]));
21893 (define_insn "stack_protect_test_si"
21894 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21895 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21896 (match_operand:SI 2 "memory_operand" "m")]
21898 (clobber (match_scratch:SI 3 "=&r"))]
21900 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21901 [(set_attr "type" "multi")])
21903 (define_insn "stack_protect_test_di"
21904 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21905 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21906 (match_operand:DI 2 "memory_operand" "m")]
21908 (clobber (match_scratch:DI 3 "=&r"))]
21910 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21911 [(set_attr "type" "multi")])
21913 (define_insn "stack_tls_protect_test_si"
21914 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21915 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21916 (match_operand:SI 2 "const_int_operand" "i")]
21917 UNSPEC_SP_TLS_TEST))
21918 (clobber (match_scratch:SI 3 "=r"))]
21920 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21921 [(set_attr "type" "multi")])
21923 (define_insn "stack_tls_protect_test_di"
21924 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21925 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21926 (match_operand:DI 2 "const_int_operand" "i")]
21927 UNSPEC_SP_TLS_TEST))
21928 (clobber (match_scratch:DI 3 "=r"))]
21931 /* The kernel uses a different segment register for performance reasons; a
21932 system call would not have to trash the userspace segment register,
21933 which would be expensive */
21934 if (ix86_cmodel != CM_KERNEL)
21935 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21937 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21939 [(set_attr "type" "multi")])
21941 (define_mode_iterator CRC32MODE [QI HI SI])
21942 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21943 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21945 (define_insn "sse4_2_crc32<mode>"
21946 [(set (match_operand:SI 0 "register_operand" "=r")
21948 [(match_operand:SI 1 "register_operand" "0")
21949 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21952 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21953 [(set_attr "type" "sselog1")
21954 (set_attr "prefix_rep" "1")
21955 (set_attr "prefix_extra" "1")
21956 (set_attr "mode" "SI")])
21958 (define_insn "sse4_2_crc32di"
21959 [(set (match_operand:DI 0 "register_operand" "=r")
21961 [(match_operand:DI 1 "register_operand" "0")
21962 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21964 "TARGET_SSE4_2 && TARGET_64BIT"
21965 "crc32q\t{%2, %0|%0, %2}"
21966 [(set_attr "type" "sselog1")
21967 (set_attr "prefix_rep" "1")
21968 (set_attr "prefix_extra" "1")
21969 (set_attr "mode" "DI")])
21973 (include "sync.md")