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
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)
75 (UNSPEC_TLS_LD_BASE 20)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 39)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 40)
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
162 (UNSPEC_INSERTQI 132)
167 (UNSPEC_INSERTPS 135)
169 (UNSPEC_MOVNTDQA 137)
171 (UNSPEC_PHMINPOSUW 139)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
181 (UNSPEC_SSE5_INTRINSIC 150)
182 (UNSPEC_SSE5_UNSIGNED_CMP 151)
183 (UNSPEC_SSE5_TRUEFALSE 152)
184 (UNSPEC_SSE5_PERMUTE 153)
186 (UNSPEC_CVTPH2PS 155)
187 (UNSPEC_CVTPS2PH 156)
191 (UNSPEC_AESENCLAST 160)
193 (UNSPEC_AESDECLAST 162)
195 (UNSPEC_AESKEYGENASSIST 164)
203 (UNSPEC_VPERMIL2 168)
204 (UNSPEC_VPERMIL2F128 169)
205 (UNSPEC_MASKLOAD 170)
206 (UNSPEC_MASKSTORE 171)
212 [(UNSPECV_BLOCKAGE 0)
213 (UNSPECV_STACK_PROBE 1)
225 (UNSPECV_PROLOGUE_USE 14)
227 (UNSPECV_VZEROALL 16)
228 (UNSPECV_VZEROUPPER 17)
231 ;; Constants to represent pcomtrue/pcomfalse variants
241 ;; Constants used in the SSE5 pperm instruction
243 [(PPERM_SRC 0x00) /* copy source */
244 (PPERM_INVERT 0x20) /* invert source */
245 (PPERM_REVERSE 0x40) /* bit reverse source */
246 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
247 (PPERM_ZERO 0x80) /* all 0's */
248 (PPERM_ONES 0xa0) /* all 1's */
249 (PPERM_SIGN 0xc0) /* propagate sign bit */
250 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
251 (PPERM_SRC1 0x00) /* use first source byte */
252 (PPERM_SRC2 0x10) /* use second source byte */
255 ;; Registers by name.
289 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
292 ;; In C guard expressions, put expressions which may be compile-time
293 ;; constants first. This allows for better optimization. For
294 ;; example, write "TARGET_64BIT && reload_completed", not
295 ;; "reload_completed && TARGET_64BIT".
299 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
301 (const (symbol_ref "ix86_schedule")))
303 ;; A basic instruction type. Refinements due to arguments to be
304 ;; provided in other attributes.
307 alu,alu1,negnot,imov,imovx,lea,
308 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
309 icmp,test,ibr,setcc,icmov,
310 push,pop,call,callv,leave,
312 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
313 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
314 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
316 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
317 (const_string "other"))
319 ;; Main data type used by the insn
321 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
322 (const_string "unknown"))
324 ;; The CPU unit operations uses.
325 (define_attr "unit" "integer,i387,sse,mmx,unknown"
326 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
327 (const_string "i387")
328 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
329 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
330 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
332 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
334 (eq_attr "type" "other")
335 (const_string "unknown")]
336 (const_string "integer")))
338 ;; The (bounding maximum) length of an instruction immediate.
339 (define_attr "length_immediate" ""
340 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
343 (eq_attr "unit" "i387,sse,mmx")
345 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
347 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
348 (eq_attr "type" "imov,test")
349 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
350 (eq_attr "type" "call")
351 (if_then_else (match_operand 0 "constant_call_address_operand" "")
354 (eq_attr "type" "callv")
355 (if_then_else (match_operand 1 "constant_call_address_operand" "")
358 ;; We don't know the size before shorten_branches. Expect
359 ;; the instruction to fit for better scheduling.
360 (eq_attr "type" "ibr")
363 (symbol_ref "/* Update immediate_length and other attributes! */
364 gcc_unreachable (),1")))
366 ;; The (bounding maximum) length of an instruction address.
367 (define_attr "length_address" ""
368 (cond [(eq_attr "type" "str,other,multi,fxch")
370 (and (eq_attr "type" "call")
371 (match_operand 0 "constant_call_address_operand" ""))
373 (and (eq_attr "type" "callv")
374 (match_operand 1 "constant_call_address_operand" ""))
377 (symbol_ref "ix86_attr_length_address_default (insn)")))
379 ;; Set when length prefix is used.
380 (define_attr "prefix_data16" ""
381 (if_then_else (ior (eq_attr "mode" "HI")
382 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
386 ;; Set when string REP prefix is used.
387 (define_attr "prefix_rep" ""
388 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
392 ;; Set when 0f opcode prefix is used.
393 (define_attr "prefix_0f" ""
395 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
396 (eq_attr "unit" "sse,mmx"))
400 ;; Set when REX opcode prefix is used.
401 (define_attr "prefix_rex" ""
402 (cond [(and (eq_attr "mode" "DI")
403 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
405 (and (eq_attr "mode" "QI")
406 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
409 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
415 ;; There are also additional prefixes in SSSE3.
416 (define_attr "prefix_extra" "" (const_int 0))
418 ;; Prefix used: original, VEX or maybe VEX.
419 (define_attr "prefix" "orig,vex,maybe_vex"
420 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
422 (const_string "orig")))
424 ;; There is a 8bit immediate for VEX.
425 (define_attr "prefix_vex_imm8" "" (const_int 0))
427 ;; VEX W bit is used.
428 (define_attr "prefix_vex_w" "" (const_int 0))
430 ;; The length of VEX prefix
431 (define_attr "length_vex" ""
432 (if_then_else (eq_attr "prefix_0f" "1")
433 (if_then_else (eq_attr "prefix_vex_w" "1")
434 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
435 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
436 (if_then_else (eq_attr "prefix_vex_w" "1")
437 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
438 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
440 ;; Set when modrm byte is used.
441 (define_attr "modrm" ""
442 (cond [(eq_attr "type" "str,leave")
444 (eq_attr "unit" "i387")
446 (and (eq_attr "type" "incdec")
447 (ior (match_operand:SI 1 "register_operand" "")
448 (match_operand:HI 1 "register_operand" "")))
450 (and (eq_attr "type" "push")
451 (not (match_operand 1 "memory_operand" "")))
453 (and (eq_attr "type" "pop")
454 (not (match_operand 0 "memory_operand" "")))
456 (and (eq_attr "type" "imov")
457 (ior (and (match_operand 0 "register_operand" "")
458 (match_operand 1 "immediate_operand" ""))
459 (ior (and (match_operand 0 "ax_reg_operand" "")
460 (match_operand 1 "memory_displacement_only_operand" ""))
461 (and (match_operand 0 "memory_displacement_only_operand" "")
462 (match_operand 1 "ax_reg_operand" "")))))
464 (and (eq_attr "type" "call")
465 (match_operand 0 "constant_call_address_operand" ""))
467 (and (eq_attr "type" "callv")
468 (match_operand 1 "constant_call_address_operand" ""))
473 ;; The (bounding maximum) length of an instruction in bytes.
474 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
475 ;; Later we may want to split them and compute proper length as for
477 (define_attr "length" ""
478 (cond [(eq_attr "type" "other,multi,fistp,frndint")
480 (eq_attr "type" "fcmp")
482 (eq_attr "unit" "i387")
484 (plus (attr "prefix_data16")
485 (attr "length_address")))
486 (ior (eq_attr "prefix" "vex")
487 (and (eq_attr "prefix" "maybe_vex")
488 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
489 (plus (attr "length_vex")
490 (plus (attr "prefix_vex_imm8")
492 (attr "length_address"))))]
493 (plus (plus (attr "modrm")
494 (plus (attr "prefix_0f")
495 (plus (attr "prefix_rex")
496 (plus (attr "prefix_extra")
498 (plus (attr "prefix_rep")
499 (plus (attr "prefix_data16")
500 (plus (attr "length_immediate")
501 (attr "length_address")))))))
503 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
504 ;; `store' if there is a simple memory reference therein, or `unknown'
505 ;; if the instruction is complex.
507 (define_attr "memory" "none,load,store,both,unknown"
508 (cond [(eq_attr "type" "other,multi,str")
509 (const_string "unknown")
510 (eq_attr "type" "lea,fcmov,fpspc")
511 (const_string "none")
512 (eq_attr "type" "fistp,leave")
513 (const_string "both")
514 (eq_attr "type" "frndint")
515 (const_string "load")
516 (eq_attr "type" "push")
517 (if_then_else (match_operand 1 "memory_operand" "")
518 (const_string "both")
519 (const_string "store"))
520 (eq_attr "type" "pop")
521 (if_then_else (match_operand 0 "memory_operand" "")
522 (const_string "both")
523 (const_string "load"))
524 (eq_attr "type" "setcc")
525 (if_then_else (match_operand 0 "memory_operand" "")
526 (const_string "store")
527 (const_string "none"))
528 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
529 (if_then_else (ior (match_operand 0 "memory_operand" "")
530 (match_operand 1 "memory_operand" ""))
531 (const_string "load")
532 (const_string "none"))
533 (eq_attr "type" "ibr")
534 (if_then_else (match_operand 0 "memory_operand" "")
535 (const_string "load")
536 (const_string "none"))
537 (eq_attr "type" "call")
538 (if_then_else (match_operand 0 "constant_call_address_operand" "")
539 (const_string "none")
540 (const_string "load"))
541 (eq_attr "type" "callv")
542 (if_then_else (match_operand 1 "constant_call_address_operand" "")
543 (const_string "none")
544 (const_string "load"))
545 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
546 (match_operand 1 "memory_operand" ""))
547 (const_string "both")
548 (and (match_operand 0 "memory_operand" "")
549 (match_operand 1 "memory_operand" ""))
550 (const_string "both")
551 (match_operand 0 "memory_operand" "")
552 (const_string "store")
553 (match_operand 1 "memory_operand" "")
554 (const_string "load")
556 "!alu1,negnot,ishift1,
557 imov,imovx,icmp,test,bitmanip,
559 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
560 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
561 (match_operand 2 "memory_operand" ""))
562 (const_string "load")
563 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
564 (match_operand 3 "memory_operand" ""))
565 (const_string "load")
567 (const_string "none")))
569 ;; Indicates if an instruction has both an immediate and a displacement.
571 (define_attr "imm_disp" "false,true,unknown"
572 (cond [(eq_attr "type" "other,multi")
573 (const_string "unknown")
574 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
575 (and (match_operand 0 "memory_displacement_operand" "")
576 (match_operand 1 "immediate_operand" "")))
577 (const_string "true")
578 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
579 (and (match_operand 0 "memory_displacement_operand" "")
580 (match_operand 2 "immediate_operand" "")))
581 (const_string "true")
583 (const_string "false")))
585 ;; Indicates if an FP operation has an integer source.
587 (define_attr "fp_int_src" "false,true"
588 (const_string "false"))
590 ;; Defines rounding mode of an FP operation.
592 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
593 (const_string "any"))
595 ;; Describe a user's asm statement.
596 (define_asm_attributes
597 [(set_attr "length" "128")
598 (set_attr "type" "multi")])
600 ;; All integer comparison codes.
601 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
603 ;; All floating-point comparison codes.
604 (define_code_iterator fp_cond [unordered ordered
605 uneq unge ungt unle unlt ltgt ])
607 (define_code_iterator plusminus [plus minus])
609 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
611 ;; Base name for define_insn
612 (define_code_attr plusminus_insn
613 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
614 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
616 ;; Base name for insn mnemonic.
617 (define_code_attr plusminus_mnemonic
618 [(plus "add") (ss_plus "adds") (us_plus "addus")
619 (minus "sub") (ss_minus "subs") (us_minus "subus")])
621 ;; Mark commutative operators as such in constraints.
622 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
623 (minus "") (ss_minus "") (us_minus "")])
625 ;; Mapping of signed max and min
626 (define_code_iterator smaxmin [smax smin])
628 ;; Mapping of unsigned max and min
629 (define_code_iterator umaxmin [umax umin])
631 ;; Mapping of signed/unsigned max and min
632 (define_code_iterator maxmin [smax smin umax umin])
634 ;; Base name for integer and FP insn mnemonic
635 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
636 (umax "maxu") (umin "minu")])
637 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
639 ;; Mapping of parallel logic operators
640 (define_code_iterator plogic [and ior xor])
642 ;; Base name for insn mnemonic.
643 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
645 ;; Mapping of abs neg operators
646 (define_code_iterator absneg [abs neg])
648 ;; Base name for x87 insn mnemonic.
649 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
651 ;; All single word integer modes.
652 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
654 ;; Single word integer modes without QImode.
655 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
657 ;; Instruction suffix for integer modes.
658 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
660 ;; Register class for integer modes.
661 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
663 ;; Immediate operand constraint for integer modes.
664 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
666 ;; General operand predicate for integer modes.
667 (define_mode_attr general_operand
668 [(QI "general_operand")
669 (HI "general_operand")
670 (SI "general_operand")
671 (DI "x86_64_general_operand")])
673 ;; SSE and x87 SFmode and DFmode floating point modes
674 (define_mode_iterator MODEF [SF DF])
676 ;; All x87 floating point modes
677 (define_mode_iterator X87MODEF [SF DF XF])
679 ;; All integer modes handled by x87 fisttp operator.
680 (define_mode_iterator X87MODEI [HI SI DI])
682 ;; All integer modes handled by integer x87 operators.
683 (define_mode_iterator X87MODEI12 [HI SI])
685 ;; All integer modes handled by SSE cvtts?2si* operators.
686 (define_mode_iterator SSEMODEI24 [SI DI])
688 ;; SSE asm suffix for floating point modes
689 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
691 ;; SSE vector mode corresponding to a scalar mode
692 (define_mode_attr ssevecmode
693 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
695 ;; Instruction suffix for REX 64bit operators.
696 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
698 ;; This mode iterator allows :P to be used for patterns that operate on
699 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
700 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
703 ;; Scheduling descriptions
705 (include "pentium.md")
708 (include "athlon.md")
712 ;; Operand and operator predicates and constraints
714 (include "predicates.md")
715 (include "constraints.md")
718 ;; Compare instructions.
720 ;; All compare insns have expanders that save the operands away without
721 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
722 ;; after the cmp) will actually emit the cmpM.
724 (define_expand "cmpti"
725 [(set (reg:CC FLAGS_REG)
726 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
727 (match_operand:TI 1 "x86_64_general_operand" "")))]
730 if (MEM_P (operands[0]) && MEM_P (operands[1]))
731 operands[0] = force_reg (TImode, operands[0]);
732 ix86_compare_op0 = operands[0];
733 ix86_compare_op1 = operands[1];
737 (define_expand "cmpdi"
738 [(set (reg:CC FLAGS_REG)
739 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
740 (match_operand:DI 1 "x86_64_general_operand" "")))]
743 if (MEM_P (operands[0]) && MEM_P (operands[1]))
744 operands[0] = force_reg (DImode, operands[0]);
745 ix86_compare_op0 = operands[0];
746 ix86_compare_op1 = operands[1];
750 (define_expand "cmpsi"
751 [(set (reg:CC FLAGS_REG)
752 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
753 (match_operand:SI 1 "general_operand" "")))]
756 if (MEM_P (operands[0]) && MEM_P (operands[1]))
757 operands[0] = force_reg (SImode, operands[0]);
758 ix86_compare_op0 = operands[0];
759 ix86_compare_op1 = operands[1];
763 (define_expand "cmphi"
764 [(set (reg:CC FLAGS_REG)
765 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
766 (match_operand:HI 1 "general_operand" "")))]
769 if (MEM_P (operands[0]) && MEM_P (operands[1]))
770 operands[0] = force_reg (HImode, operands[0]);
771 ix86_compare_op0 = operands[0];
772 ix86_compare_op1 = operands[1];
776 (define_expand "cmpqi"
777 [(set (reg:CC FLAGS_REG)
778 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
779 (match_operand:QI 1 "general_operand" "")))]
782 if (MEM_P (operands[0]) && MEM_P (operands[1]))
783 operands[0] = force_reg (QImode, operands[0]);
784 ix86_compare_op0 = operands[0];
785 ix86_compare_op1 = operands[1];
789 (define_insn "cmpdi_ccno_1_rex64"
790 [(set (reg FLAGS_REG)
791 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
792 (match_operand:DI 1 "const0_operand" "")))]
793 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
796 cmp{q}\t{%1, %0|%0, %1}"
797 [(set_attr "type" "test,icmp")
798 (set_attr "length_immediate" "0,1")
799 (set_attr "mode" "DI")])
801 (define_insn "*cmpdi_minus_1_rex64"
802 [(set (reg FLAGS_REG)
803 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
804 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
806 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
807 "cmp{q}\t{%1, %0|%0, %1}"
808 [(set_attr "type" "icmp")
809 (set_attr "mode" "DI")])
811 (define_expand "cmpdi_1_rex64"
812 [(set (reg:CC FLAGS_REG)
813 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
814 (match_operand:DI 1 "general_operand" "")))]
818 (define_insn "cmpdi_1_insn_rex64"
819 [(set (reg FLAGS_REG)
820 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
821 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
822 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
823 "cmp{q}\t{%1, %0|%0, %1}"
824 [(set_attr "type" "icmp")
825 (set_attr "mode" "DI")])
828 (define_insn "*cmpsi_ccno_1"
829 [(set (reg FLAGS_REG)
830 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
831 (match_operand:SI 1 "const0_operand" "")))]
832 "ix86_match_ccmode (insn, CCNOmode)"
835 cmp{l}\t{%1, %0|%0, %1}"
836 [(set_attr "type" "test,icmp")
837 (set_attr "length_immediate" "0,1")
838 (set_attr "mode" "SI")])
840 (define_insn "*cmpsi_minus_1"
841 [(set (reg FLAGS_REG)
842 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
843 (match_operand:SI 1 "general_operand" "ri,mr"))
845 "ix86_match_ccmode (insn, CCGOCmode)"
846 "cmp{l}\t{%1, %0|%0, %1}"
847 [(set_attr "type" "icmp")
848 (set_attr "mode" "SI")])
850 (define_expand "cmpsi_1"
851 [(set (reg:CC FLAGS_REG)
852 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
853 (match_operand:SI 1 "general_operand" "")))]
857 (define_insn "*cmpsi_1_insn"
858 [(set (reg FLAGS_REG)
859 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
860 (match_operand:SI 1 "general_operand" "ri,mr")))]
861 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
862 && ix86_match_ccmode (insn, CCmode)"
863 "cmp{l}\t{%1, %0|%0, %1}"
864 [(set_attr "type" "icmp")
865 (set_attr "mode" "SI")])
867 (define_insn "*cmphi_ccno_1"
868 [(set (reg FLAGS_REG)
869 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
870 (match_operand:HI 1 "const0_operand" "")))]
871 "ix86_match_ccmode (insn, CCNOmode)"
874 cmp{w}\t{%1, %0|%0, %1}"
875 [(set_attr "type" "test,icmp")
876 (set_attr "length_immediate" "0,1")
877 (set_attr "mode" "HI")])
879 (define_insn "*cmphi_minus_1"
880 [(set (reg FLAGS_REG)
881 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
882 (match_operand:HI 1 "general_operand" "rn,mr"))
884 "ix86_match_ccmode (insn, CCGOCmode)"
885 "cmp{w}\t{%1, %0|%0, %1}"
886 [(set_attr "type" "icmp")
887 (set_attr "mode" "HI")])
889 (define_insn "*cmphi_1"
890 [(set (reg FLAGS_REG)
891 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
892 (match_operand:HI 1 "general_operand" "rn,mr")))]
893 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
894 && ix86_match_ccmode (insn, CCmode)"
895 "cmp{w}\t{%1, %0|%0, %1}"
896 [(set_attr "type" "icmp")
897 (set_attr "mode" "HI")])
899 (define_insn "*cmpqi_ccno_1"
900 [(set (reg FLAGS_REG)
901 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
902 (match_operand:QI 1 "const0_operand" "")))]
903 "ix86_match_ccmode (insn, CCNOmode)"
906 cmp{b}\t{$0, %0|%0, 0}"
907 [(set_attr "type" "test,icmp")
908 (set_attr "length_immediate" "0,1")
909 (set_attr "mode" "QI")])
911 (define_insn "*cmpqi_1"
912 [(set (reg FLAGS_REG)
913 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
914 (match_operand:QI 1 "general_operand" "qn,mq")))]
915 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
916 && ix86_match_ccmode (insn, CCmode)"
917 "cmp{b}\t{%1, %0|%0, %1}"
918 [(set_attr "type" "icmp")
919 (set_attr "mode" "QI")])
921 (define_insn "*cmpqi_minus_1"
922 [(set (reg FLAGS_REG)
923 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
924 (match_operand:QI 1 "general_operand" "qn,mq"))
926 "ix86_match_ccmode (insn, CCGOCmode)"
927 "cmp{b}\t{%1, %0|%0, %1}"
928 [(set_attr "type" "icmp")
929 (set_attr "mode" "QI")])
931 (define_insn "*cmpqi_ext_1"
932 [(set (reg FLAGS_REG)
934 (match_operand:QI 0 "general_operand" "Qm")
937 (match_operand 1 "ext_register_operand" "Q")
940 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
941 "cmp{b}\t{%h1, %0|%0, %h1}"
942 [(set_attr "type" "icmp")
943 (set_attr "mode" "QI")])
945 (define_insn "*cmpqi_ext_1_rex64"
946 [(set (reg FLAGS_REG)
948 (match_operand:QI 0 "register_operand" "Q")
951 (match_operand 1 "ext_register_operand" "Q")
954 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
955 "cmp{b}\t{%h1, %0|%0, %h1}"
956 [(set_attr "type" "icmp")
957 (set_attr "mode" "QI")])
959 (define_insn "*cmpqi_ext_2"
960 [(set (reg FLAGS_REG)
964 (match_operand 0 "ext_register_operand" "Q")
967 (match_operand:QI 1 "const0_operand" "")))]
968 "ix86_match_ccmode (insn, CCNOmode)"
970 [(set_attr "type" "test")
971 (set_attr "length_immediate" "0")
972 (set_attr "mode" "QI")])
974 (define_expand "cmpqi_ext_3"
975 [(set (reg:CC FLAGS_REG)
979 (match_operand 0 "ext_register_operand" "")
982 (match_operand:QI 1 "general_operand" "")))]
986 (define_insn "cmpqi_ext_3_insn"
987 [(set (reg FLAGS_REG)
991 (match_operand 0 "ext_register_operand" "Q")
994 (match_operand:QI 1 "general_operand" "Qmn")))]
995 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
996 "cmp{b}\t{%1, %h0|%h0, %1}"
997 [(set_attr "type" "icmp")
998 (set_attr "mode" "QI")])
1000 (define_insn "cmpqi_ext_3_insn_rex64"
1001 [(set (reg FLAGS_REG)
1005 (match_operand 0 "ext_register_operand" "Q")
1008 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1009 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1010 "cmp{b}\t{%1, %h0|%h0, %1}"
1011 [(set_attr "type" "icmp")
1012 (set_attr "mode" "QI")])
1014 (define_insn "*cmpqi_ext_4"
1015 [(set (reg FLAGS_REG)
1019 (match_operand 0 "ext_register_operand" "Q")
1024 (match_operand 1 "ext_register_operand" "Q")
1026 (const_int 8)) 0)))]
1027 "ix86_match_ccmode (insn, CCmode)"
1028 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1029 [(set_attr "type" "icmp")
1030 (set_attr "mode" "QI")])
1032 ;; These implement float point compares.
1033 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1034 ;; which would allow mix and match FP modes on the compares. Which is what
1035 ;; the old patterns did, but with many more of them.
1037 (define_expand "cmpxf"
1038 [(set (reg:CC FLAGS_REG)
1039 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1040 (match_operand:XF 1 "nonmemory_operand" "")))]
1043 ix86_compare_op0 = operands[0];
1044 ix86_compare_op1 = operands[1];
1048 (define_expand "cmp<mode>"
1049 [(set (reg:CC FLAGS_REG)
1050 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1051 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1052 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1054 ix86_compare_op0 = operands[0];
1055 ix86_compare_op1 = operands[1];
1059 ;; FP compares, step 1:
1060 ;; Set the FP condition codes.
1062 ;; CCFPmode compare with exceptions
1063 ;; CCFPUmode compare with no exceptions
1065 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1066 ;; used to manage the reg stack popping would not be preserved.
1068 (define_insn "*cmpfp_0"
1069 [(set (match_operand:HI 0 "register_operand" "=a")
1072 (match_operand 1 "register_operand" "f")
1073 (match_operand 2 "const0_operand" ""))]
1075 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1077 "* return output_fp_compare (insn, operands, 0, 0);"
1078 [(set_attr "type" "multi")
1079 (set_attr "unit" "i387")
1081 (cond [(match_operand:SF 1 "" "")
1083 (match_operand:DF 1 "" "")
1086 (const_string "XF")))])
1088 (define_insn_and_split "*cmpfp_0_cc"
1089 [(set (reg:CCFP FLAGS_REG)
1091 (match_operand 1 "register_operand" "f")
1092 (match_operand 2 "const0_operand" "")))
1093 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1094 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1095 && TARGET_SAHF && !TARGET_CMOVE
1096 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1098 "&& reload_completed"
1101 [(compare:CCFP (match_dup 1)(match_dup 2))]
1103 (set (reg:CC FLAGS_REG)
1104 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1106 [(set_attr "type" "multi")
1107 (set_attr "unit" "i387")
1109 (cond [(match_operand:SF 1 "" "")
1111 (match_operand:DF 1 "" "")
1114 (const_string "XF")))])
1116 (define_insn "*cmpfp_xf"
1117 [(set (match_operand:HI 0 "register_operand" "=a")
1120 (match_operand:XF 1 "register_operand" "f")
1121 (match_operand:XF 2 "register_operand" "f"))]
1124 "* return output_fp_compare (insn, operands, 0, 0);"
1125 [(set_attr "type" "multi")
1126 (set_attr "unit" "i387")
1127 (set_attr "mode" "XF")])
1129 (define_insn_and_split "*cmpfp_xf_cc"
1130 [(set (reg:CCFP FLAGS_REG)
1132 (match_operand:XF 1 "register_operand" "f")
1133 (match_operand:XF 2 "register_operand" "f")))
1134 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1136 && TARGET_SAHF && !TARGET_CMOVE"
1138 "&& reload_completed"
1141 [(compare:CCFP (match_dup 1)(match_dup 2))]
1143 (set (reg:CC FLAGS_REG)
1144 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1146 [(set_attr "type" "multi")
1147 (set_attr "unit" "i387")
1148 (set_attr "mode" "XF")])
1150 (define_insn "*cmpfp_<mode>"
1151 [(set (match_operand:HI 0 "register_operand" "=a")
1154 (match_operand:MODEF 1 "register_operand" "f")
1155 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1158 "* return output_fp_compare (insn, operands, 0, 0);"
1159 [(set_attr "type" "multi")
1160 (set_attr "unit" "i387")
1161 (set_attr "mode" "<MODE>")])
1163 (define_insn_and_split "*cmpfp_<mode>_cc"
1164 [(set (reg:CCFP FLAGS_REG)
1166 (match_operand:MODEF 1 "register_operand" "f")
1167 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1168 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1170 && TARGET_SAHF && !TARGET_CMOVE"
1172 "&& reload_completed"
1175 [(compare:CCFP (match_dup 1)(match_dup 2))]
1177 (set (reg:CC FLAGS_REG)
1178 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1180 [(set_attr "type" "multi")
1181 (set_attr "unit" "i387")
1182 (set_attr "mode" "<MODE>")])
1184 (define_insn "*cmpfp_u"
1185 [(set (match_operand:HI 0 "register_operand" "=a")
1188 (match_operand 1 "register_operand" "f")
1189 (match_operand 2 "register_operand" "f"))]
1191 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1192 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1193 "* return output_fp_compare (insn, operands, 0, 1);"
1194 [(set_attr "type" "multi")
1195 (set_attr "unit" "i387")
1197 (cond [(match_operand:SF 1 "" "")
1199 (match_operand:DF 1 "" "")
1202 (const_string "XF")))])
1204 (define_insn_and_split "*cmpfp_u_cc"
1205 [(set (reg:CCFPU FLAGS_REG)
1207 (match_operand 1 "register_operand" "f")
1208 (match_operand 2 "register_operand" "f")))
1209 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1210 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1211 && TARGET_SAHF && !TARGET_CMOVE
1212 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1214 "&& reload_completed"
1217 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1219 (set (reg:CC FLAGS_REG)
1220 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1222 [(set_attr "type" "multi")
1223 (set_attr "unit" "i387")
1225 (cond [(match_operand:SF 1 "" "")
1227 (match_operand:DF 1 "" "")
1230 (const_string "XF")))])
1232 (define_insn "*cmpfp_<mode>"
1233 [(set (match_operand:HI 0 "register_operand" "=a")
1236 (match_operand 1 "register_operand" "f")
1237 (match_operator 3 "float_operator"
1238 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1240 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1241 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1242 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1243 "* return output_fp_compare (insn, operands, 0, 0);"
1244 [(set_attr "type" "multi")
1245 (set_attr "unit" "i387")
1246 (set_attr "fp_int_src" "true")
1247 (set_attr "mode" "<MODE>")])
1249 (define_insn_and_split "*cmpfp_<mode>_cc"
1250 [(set (reg:CCFP FLAGS_REG)
1252 (match_operand 1 "register_operand" "f")
1253 (match_operator 3 "float_operator"
1254 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1255 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1256 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1257 && TARGET_SAHF && !TARGET_CMOVE
1258 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1259 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1261 "&& reload_completed"
1266 (match_op_dup 3 [(match_dup 2)]))]
1268 (set (reg:CC FLAGS_REG)
1269 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1271 [(set_attr "type" "multi")
1272 (set_attr "unit" "i387")
1273 (set_attr "fp_int_src" "true")
1274 (set_attr "mode" "<MODE>")])
1276 ;; FP compares, step 2
1277 ;; Move the fpsw to ax.
1279 (define_insn "x86_fnstsw_1"
1280 [(set (match_operand:HI 0 "register_operand" "=a")
1281 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1284 [(set_attr "length" "2")
1285 (set_attr "mode" "SI")
1286 (set_attr "unit" "i387")])
1288 ;; FP compares, step 3
1289 ;; Get ax into flags, general case.
1291 (define_insn "x86_sahf_1"
1292 [(set (reg:CC FLAGS_REG)
1293 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1297 #ifdef HAVE_AS_IX86_SAHF
1300 return ".byte\t0x9e";
1303 [(set_attr "length" "1")
1304 (set_attr "athlon_decode" "vector")
1305 (set_attr "amdfam10_decode" "direct")
1306 (set_attr "mode" "SI")])
1308 ;; Pentium Pro can do steps 1 through 3 in one go.
1309 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1310 (define_insn "*cmpfp_i_mixed"
1311 [(set (reg:CCFP FLAGS_REG)
1312 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1313 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1314 "TARGET_MIX_SSE_I387
1315 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1316 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1317 "* return output_fp_compare (insn, operands, 1, 0);"
1318 [(set_attr "type" "fcmp,ssecomi")
1319 (set_attr "prefix" "orig,maybe_vex")
1321 (if_then_else (match_operand:SF 1 "" "")
1323 (const_string "DF")))
1324 (set_attr "athlon_decode" "vector")
1325 (set_attr "amdfam10_decode" "direct")])
1327 (define_insn "*cmpfp_i_sse"
1328 [(set (reg:CCFP FLAGS_REG)
1329 (compare:CCFP (match_operand 0 "register_operand" "x")
1330 (match_operand 1 "nonimmediate_operand" "xm")))]
1332 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1333 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1334 "* return output_fp_compare (insn, operands, 1, 0);"
1335 [(set_attr "type" "ssecomi")
1336 (set_attr "prefix" "maybe_vex")
1338 (if_then_else (match_operand:SF 1 "" "")
1340 (const_string "DF")))
1341 (set_attr "athlon_decode" "vector")
1342 (set_attr "amdfam10_decode" "direct")])
1344 (define_insn "*cmpfp_i_i387"
1345 [(set (reg:CCFP FLAGS_REG)
1346 (compare:CCFP (match_operand 0 "register_operand" "f")
1347 (match_operand 1 "register_operand" "f")))]
1348 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1350 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1351 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1352 "* return output_fp_compare (insn, operands, 1, 0);"
1353 [(set_attr "type" "fcmp")
1355 (cond [(match_operand:SF 1 "" "")
1357 (match_operand:DF 1 "" "")
1360 (const_string "XF")))
1361 (set_attr "athlon_decode" "vector")
1362 (set_attr "amdfam10_decode" "direct")])
1364 (define_insn "*cmpfp_iu_mixed"
1365 [(set (reg:CCFPU FLAGS_REG)
1366 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1367 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1368 "TARGET_MIX_SSE_I387
1369 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1370 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1371 "* return output_fp_compare (insn, operands, 1, 1);"
1372 [(set_attr "type" "fcmp,ssecomi")
1373 (set_attr "prefix" "orig,maybe_vex")
1375 (if_then_else (match_operand:SF 1 "" "")
1377 (const_string "DF")))
1378 (set_attr "athlon_decode" "vector")
1379 (set_attr "amdfam10_decode" "direct")])
1381 (define_insn "*cmpfp_iu_sse"
1382 [(set (reg:CCFPU FLAGS_REG)
1383 (compare:CCFPU (match_operand 0 "register_operand" "x")
1384 (match_operand 1 "nonimmediate_operand" "xm")))]
1386 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1387 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1388 "* return output_fp_compare (insn, operands, 1, 1);"
1389 [(set_attr "type" "ssecomi")
1390 (set_attr "prefix" "maybe_vex")
1392 (if_then_else (match_operand:SF 1 "" "")
1394 (const_string "DF")))
1395 (set_attr "athlon_decode" "vector")
1396 (set_attr "amdfam10_decode" "direct")])
1398 (define_insn "*cmpfp_iu_387"
1399 [(set (reg:CCFPU FLAGS_REG)
1400 (compare:CCFPU (match_operand 0 "register_operand" "f")
1401 (match_operand 1 "register_operand" "f")))]
1402 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1404 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1405 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1406 "* return output_fp_compare (insn, operands, 1, 1);"
1407 [(set_attr "type" "fcmp")
1409 (cond [(match_operand:SF 1 "" "")
1411 (match_operand:DF 1 "" "")
1414 (const_string "XF")))
1415 (set_attr "athlon_decode" "vector")
1416 (set_attr "amdfam10_decode" "direct")])
1418 ;; Move instructions.
1420 ;; General case of fullword move.
1422 (define_expand "movsi"
1423 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1424 (match_operand:SI 1 "general_operand" ""))]
1426 "ix86_expand_move (SImode, operands); DONE;")
1428 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1431 ;; %%% We don't use a post-inc memory reference because x86 is not a
1432 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1433 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1434 ;; targets without our curiosities, and it is just as easy to represent
1435 ;; this differently.
1437 (define_insn "*pushsi2"
1438 [(set (match_operand:SI 0 "push_operand" "=<")
1439 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1442 [(set_attr "type" "push")
1443 (set_attr "mode" "SI")])
1445 ;; For 64BIT abi we always round up to 8 bytes.
1446 (define_insn "*pushsi2_rex64"
1447 [(set (match_operand:SI 0 "push_operand" "=X")
1448 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1451 [(set_attr "type" "push")
1452 (set_attr "mode" "SI")])
1454 (define_insn "*pushsi2_prologue"
1455 [(set (match_operand:SI 0 "push_operand" "=<")
1456 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1457 (clobber (mem:BLK (scratch)))]
1460 [(set_attr "type" "push")
1461 (set_attr "mode" "SI")])
1463 (define_insn "*popsi1_epilogue"
1464 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1465 (mem:SI (reg:SI SP_REG)))
1466 (set (reg:SI SP_REG)
1467 (plus:SI (reg:SI SP_REG) (const_int 4)))
1468 (clobber (mem:BLK (scratch)))]
1471 [(set_attr "type" "pop")
1472 (set_attr "mode" "SI")])
1474 (define_insn "popsi1"
1475 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1476 (mem:SI (reg:SI SP_REG)))
1477 (set (reg:SI SP_REG)
1478 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1481 [(set_attr "type" "pop")
1482 (set_attr "mode" "SI")])
1484 (define_insn "*movsi_xor"
1485 [(set (match_operand:SI 0 "register_operand" "=r")
1486 (match_operand:SI 1 "const0_operand" ""))
1487 (clobber (reg:CC FLAGS_REG))]
1490 [(set_attr "type" "alu1")
1491 (set_attr "mode" "SI")
1492 (set_attr "length_immediate" "0")])
1494 (define_insn "*movsi_or"
1495 [(set (match_operand:SI 0 "register_operand" "=r")
1496 (match_operand:SI 1 "immediate_operand" "i"))
1497 (clobber (reg:CC FLAGS_REG))]
1499 && operands[1] == constm1_rtx"
1501 operands[1] = constm1_rtx;
1502 return "or{l}\t{%1, %0|%0, %1}";
1504 [(set_attr "type" "alu1")
1505 (set_attr "mode" "SI")
1506 (set_attr "length_immediate" "1")])
1508 (define_insn "*movsi_1"
1509 [(set (match_operand:SI 0 "nonimmediate_operand"
1510 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1511 (match_operand:SI 1 "general_operand"
1512 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1513 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1515 switch (get_attr_type (insn))
1518 if (get_attr_mode (insn) == MODE_TI)
1519 return "%vpxor\t%0, %d0";
1520 return "%vxorps\t%0, %d0";
1523 switch (get_attr_mode (insn))
1526 return "%vmovdqa\t{%1, %0|%0, %1}";
1528 return "%vmovaps\t{%1, %0|%0, %1}";
1530 return "%vmovd\t{%1, %0|%0, %1}";
1532 return "%vmovss\t{%1, %0|%0, %1}";
1538 return "pxor\t%0, %0";
1541 if (get_attr_mode (insn) == MODE_DI)
1542 return "movq\t{%1, %0|%0, %1}";
1543 return "movd\t{%1, %0|%0, %1}";
1546 return "lea{l}\t{%1, %0|%0, %1}";
1549 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1550 return "mov{l}\t{%1, %0|%0, %1}";
1554 (cond [(eq_attr "alternative" "2")
1555 (const_string "mmxadd")
1556 (eq_attr "alternative" "3,4,5")
1557 (const_string "mmxmov")
1558 (eq_attr "alternative" "6")
1559 (const_string "sselog1")
1560 (eq_attr "alternative" "7,8,9,10,11")
1561 (const_string "ssemov")
1562 (match_operand:DI 1 "pic_32bit_operand" "")
1563 (const_string "lea")
1565 (const_string "imov")))
1566 (set (attr "prefix")
1567 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1568 (const_string "orig")
1569 (const_string "maybe_vex")))
1571 (cond [(eq_attr "alternative" "2,3")
1573 (eq_attr "alternative" "6,7")
1575 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1576 (const_string "V4SF")
1577 (const_string "TI"))
1578 (and (eq_attr "alternative" "8,9,10,11")
1579 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1582 (const_string "SI")))])
1584 ;; Stores and loads of ax to arbitrary constant address.
1585 ;; We fake an second form of instruction to force reload to load address
1586 ;; into register when rax is not available
1587 (define_insn "*movabssi_1_rex64"
1588 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1589 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1590 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1592 movabs{l}\t{%1, %P0|%P0, %1}
1593 mov{l}\t{%1, %a0|%a0, %1}"
1594 [(set_attr "type" "imov")
1595 (set_attr "modrm" "0,*")
1596 (set_attr "length_address" "8,0")
1597 (set_attr "length_immediate" "0,*")
1598 (set_attr "memory" "store")
1599 (set_attr "mode" "SI")])
1601 (define_insn "*movabssi_2_rex64"
1602 [(set (match_operand:SI 0 "register_operand" "=a,r")
1603 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1604 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1606 movabs{l}\t{%P1, %0|%0, %P1}
1607 mov{l}\t{%a1, %0|%0, %a1}"
1608 [(set_attr "type" "imov")
1609 (set_attr "modrm" "0,*")
1610 (set_attr "length_address" "8,0")
1611 (set_attr "length_immediate" "0")
1612 (set_attr "memory" "load")
1613 (set_attr "mode" "SI")])
1615 (define_insn "*swapsi"
1616 [(set (match_operand:SI 0 "register_operand" "+r")
1617 (match_operand:SI 1 "register_operand" "+r"))
1622 [(set_attr "type" "imov")
1623 (set_attr "mode" "SI")
1624 (set_attr "pent_pair" "np")
1625 (set_attr "athlon_decode" "vector")
1626 (set_attr "amdfam10_decode" "double")])
1628 (define_expand "movhi"
1629 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1630 (match_operand:HI 1 "general_operand" ""))]
1632 "ix86_expand_move (HImode, operands); DONE;")
1634 (define_insn "*pushhi2"
1635 [(set (match_operand:HI 0 "push_operand" "=X")
1636 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1639 [(set_attr "type" "push")
1640 (set_attr "mode" "SI")])
1642 ;; For 64BIT abi we always round up to 8 bytes.
1643 (define_insn "*pushhi2_rex64"
1644 [(set (match_operand:HI 0 "push_operand" "=X")
1645 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1648 [(set_attr "type" "push")
1649 (set_attr "mode" "DI")])
1651 (define_insn "*movhi_1"
1652 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1653 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1654 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1656 switch (get_attr_type (insn))
1659 /* movzwl is faster than movw on p2 due to partial word stalls,
1660 though not as fast as an aligned movl. */
1661 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1663 if (get_attr_mode (insn) == MODE_SI)
1664 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1666 return "mov{w}\t{%1, %0|%0, %1}";
1670 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1671 (const_string "imov")
1672 (and (eq_attr "alternative" "0")
1673 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1675 (eq (symbol_ref "TARGET_HIMODE_MATH")
1677 (const_string "imov")
1678 (and (eq_attr "alternative" "1,2")
1679 (match_operand:HI 1 "aligned_operand" ""))
1680 (const_string "imov")
1681 (and (ne (symbol_ref "TARGET_MOVX")
1683 (eq_attr "alternative" "0,2"))
1684 (const_string "imovx")
1686 (const_string "imov")))
1688 (cond [(eq_attr "type" "imovx")
1690 (and (eq_attr "alternative" "1,2")
1691 (match_operand:HI 1 "aligned_operand" ""))
1693 (and (eq_attr "alternative" "0")
1694 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1696 (eq (symbol_ref "TARGET_HIMODE_MATH")
1700 (const_string "HI")))])
1702 ;; Stores and loads of ax to arbitrary constant address.
1703 ;; We fake an second form of instruction to force reload to load address
1704 ;; into register when rax is not available
1705 (define_insn "*movabshi_1_rex64"
1706 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1707 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1708 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1710 movabs{w}\t{%1, %P0|%P0, %1}
1711 mov{w}\t{%1, %a0|%a0, %1}"
1712 [(set_attr "type" "imov")
1713 (set_attr "modrm" "0,*")
1714 (set_attr "length_address" "8,0")
1715 (set_attr "length_immediate" "0,*")
1716 (set_attr "memory" "store")
1717 (set_attr "mode" "HI")])
1719 (define_insn "*movabshi_2_rex64"
1720 [(set (match_operand:HI 0 "register_operand" "=a,r")
1721 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1722 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1724 movabs{w}\t{%P1, %0|%0, %P1}
1725 mov{w}\t{%a1, %0|%0, %a1}"
1726 [(set_attr "type" "imov")
1727 (set_attr "modrm" "0,*")
1728 (set_attr "length_address" "8,0")
1729 (set_attr "length_immediate" "0")
1730 (set_attr "memory" "load")
1731 (set_attr "mode" "HI")])
1733 (define_insn "*swaphi_1"
1734 [(set (match_operand:HI 0 "register_operand" "+r")
1735 (match_operand:HI 1 "register_operand" "+r"))
1738 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1740 [(set_attr "type" "imov")
1741 (set_attr "mode" "SI")
1742 (set_attr "pent_pair" "np")
1743 (set_attr "athlon_decode" "vector")
1744 (set_attr "amdfam10_decode" "double")])
1746 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1747 (define_insn "*swaphi_2"
1748 [(set (match_operand:HI 0 "register_operand" "+r")
1749 (match_operand:HI 1 "register_operand" "+r"))
1752 "TARGET_PARTIAL_REG_STALL"
1754 [(set_attr "type" "imov")
1755 (set_attr "mode" "HI")
1756 (set_attr "pent_pair" "np")
1757 (set_attr "athlon_decode" "vector")])
1759 (define_expand "movstricthi"
1760 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1761 (match_operand:HI 1 "general_operand" ""))]
1764 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1766 /* Don't generate memory->memory moves, go through a register */
1767 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1768 operands[1] = force_reg (HImode, operands[1]);
1771 (define_insn "*movstricthi_1"
1772 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1773 (match_operand:HI 1 "general_operand" "rn,m"))]
1774 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1776 "mov{w}\t{%1, %0|%0, %1}"
1777 [(set_attr "type" "imov")
1778 (set_attr "mode" "HI")])
1780 (define_insn "*movstricthi_xor"
1781 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1782 (match_operand:HI 1 "const0_operand" ""))
1783 (clobber (reg:CC FLAGS_REG))]
1786 [(set_attr "type" "alu1")
1787 (set_attr "mode" "HI")
1788 (set_attr "length_immediate" "0")])
1790 (define_expand "movqi"
1791 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1792 (match_operand:QI 1 "general_operand" ""))]
1794 "ix86_expand_move (QImode, operands); DONE;")
1796 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1797 ;; "push a byte". But actually we use pushl, which has the effect
1798 ;; of rounding the amount pushed up to a word.
1800 (define_insn "*pushqi2"
1801 [(set (match_operand:QI 0 "push_operand" "=X")
1802 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1805 [(set_attr "type" "push")
1806 (set_attr "mode" "SI")])
1808 ;; For 64BIT abi we always round up to 8 bytes.
1809 (define_insn "*pushqi2_rex64"
1810 [(set (match_operand:QI 0 "push_operand" "=X")
1811 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1814 [(set_attr "type" "push")
1815 (set_attr "mode" "DI")])
1817 ;; Situation is quite tricky about when to choose full sized (SImode) move
1818 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1819 ;; partial register dependency machines (such as AMD Athlon), where QImode
1820 ;; moves issue extra dependency and for partial register stalls machines
1821 ;; that don't use QImode patterns (and QImode move cause stall on the next
1824 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1825 ;; register stall machines with, where we use QImode instructions, since
1826 ;; partial register stall can be caused there. Then we use movzx.
1827 (define_insn "*movqi_1"
1828 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1829 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1830 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1832 switch (get_attr_type (insn))
1835 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1836 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1838 if (get_attr_mode (insn) == MODE_SI)
1839 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1841 return "mov{b}\t{%1, %0|%0, %1}";
1845 (cond [(and (eq_attr "alternative" "5")
1846 (not (match_operand:QI 1 "aligned_operand" "")))
1847 (const_string "imovx")
1848 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1849 (const_string "imov")
1850 (and (eq_attr "alternative" "3")
1851 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1853 (eq (symbol_ref "TARGET_QIMODE_MATH")
1855 (const_string "imov")
1856 (eq_attr "alternative" "3,5")
1857 (const_string "imovx")
1858 (and (ne (symbol_ref "TARGET_MOVX")
1860 (eq_attr "alternative" "2"))
1861 (const_string "imovx")
1863 (const_string "imov")))
1865 (cond [(eq_attr "alternative" "3,4,5")
1867 (eq_attr "alternative" "6")
1869 (eq_attr "type" "imovx")
1871 (and (eq_attr "type" "imov")
1872 (and (eq_attr "alternative" "0,1")
1873 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1875 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1877 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1880 ;; Avoid partial register stalls when not using QImode arithmetic
1881 (and (eq_attr "type" "imov")
1882 (and (eq_attr "alternative" "0,1")
1883 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1885 (eq (symbol_ref "TARGET_QIMODE_MATH")
1889 (const_string "QI")))])
1891 (define_insn "*swapqi_1"
1892 [(set (match_operand:QI 0 "register_operand" "+r")
1893 (match_operand:QI 1 "register_operand" "+r"))
1896 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1898 [(set_attr "type" "imov")
1899 (set_attr "mode" "SI")
1900 (set_attr "pent_pair" "np")
1901 (set_attr "athlon_decode" "vector")
1902 (set_attr "amdfam10_decode" "vector")])
1904 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1905 (define_insn "*swapqi_2"
1906 [(set (match_operand:QI 0 "register_operand" "+q")
1907 (match_operand:QI 1 "register_operand" "+q"))
1910 "TARGET_PARTIAL_REG_STALL"
1912 [(set_attr "type" "imov")
1913 (set_attr "mode" "QI")
1914 (set_attr "pent_pair" "np")
1915 (set_attr "athlon_decode" "vector")])
1917 (define_expand "movstrictqi"
1918 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1919 (match_operand:QI 1 "general_operand" ""))]
1922 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1924 /* Don't generate memory->memory moves, go through a register. */
1925 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1926 operands[1] = force_reg (QImode, operands[1]);
1929 (define_insn "*movstrictqi_1"
1930 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1931 (match_operand:QI 1 "general_operand" "*qn,m"))]
1932 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1934 "mov{b}\t{%1, %0|%0, %1}"
1935 [(set_attr "type" "imov")
1936 (set_attr "mode" "QI")])
1938 (define_insn "*movstrictqi_xor"
1939 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1940 (match_operand:QI 1 "const0_operand" ""))
1941 (clobber (reg:CC FLAGS_REG))]
1944 [(set_attr "type" "alu1")
1945 (set_attr "mode" "QI")
1946 (set_attr "length_immediate" "0")])
1948 (define_insn "*movsi_extv_1"
1949 [(set (match_operand:SI 0 "register_operand" "=R")
1950 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1954 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1955 [(set_attr "type" "imovx")
1956 (set_attr "mode" "SI")])
1958 (define_insn "*movhi_extv_1"
1959 [(set (match_operand:HI 0 "register_operand" "=R")
1960 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1964 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1965 [(set_attr "type" "imovx")
1966 (set_attr "mode" "SI")])
1968 (define_insn "*movqi_extv_1"
1969 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1970 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1975 switch (get_attr_type (insn))
1978 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1980 return "mov{b}\t{%h1, %0|%0, %h1}";
1984 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1985 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1986 (ne (symbol_ref "TARGET_MOVX")
1988 (const_string "imovx")
1989 (const_string "imov")))
1991 (if_then_else (eq_attr "type" "imovx")
1993 (const_string "QI")))])
1995 (define_insn "*movqi_extv_1_rex64"
1996 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1997 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2002 switch (get_attr_type (insn))
2005 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2007 return "mov{b}\t{%h1, %0|%0, %h1}";
2011 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2012 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2013 (ne (symbol_ref "TARGET_MOVX")
2015 (const_string "imovx")
2016 (const_string "imov")))
2018 (if_then_else (eq_attr "type" "imovx")
2020 (const_string "QI")))])
2022 ;; Stores and loads of ax to arbitrary constant address.
2023 ;; We fake an second form of instruction to force reload to load address
2024 ;; into register when rax is not available
2025 (define_insn "*movabsqi_1_rex64"
2026 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2027 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2028 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030 movabs{b}\t{%1, %P0|%P0, %1}
2031 mov{b}\t{%1, %a0|%a0, %1}"
2032 [(set_attr "type" "imov")
2033 (set_attr "modrm" "0,*")
2034 (set_attr "length_address" "8,0")
2035 (set_attr "length_immediate" "0,*")
2036 (set_attr "memory" "store")
2037 (set_attr "mode" "QI")])
2039 (define_insn "*movabsqi_2_rex64"
2040 [(set (match_operand:QI 0 "register_operand" "=a,r")
2041 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2042 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044 movabs{b}\t{%P1, %0|%0, %P1}
2045 mov{b}\t{%a1, %0|%0, %a1}"
2046 [(set_attr "type" "imov")
2047 (set_attr "modrm" "0,*")
2048 (set_attr "length_address" "8,0")
2049 (set_attr "length_immediate" "0")
2050 (set_attr "memory" "load")
2051 (set_attr "mode" "QI")])
2053 (define_insn "*movdi_extzv_1"
2054 [(set (match_operand:DI 0 "register_operand" "=R")
2055 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2059 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2060 [(set_attr "type" "imovx")
2061 (set_attr "mode" "DI")])
2063 (define_insn "*movsi_extzv_1"
2064 [(set (match_operand:SI 0 "register_operand" "=R")
2065 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2069 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2070 [(set_attr "type" "imovx")
2071 (set_attr "mode" "SI")])
2073 (define_insn "*movqi_extzv_2"
2074 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2075 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2080 switch (get_attr_type (insn))
2083 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2085 return "mov{b}\t{%h1, %0|%0, %h1}";
2089 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2090 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2091 (ne (symbol_ref "TARGET_MOVX")
2093 (const_string "imovx")
2094 (const_string "imov")))
2096 (if_then_else (eq_attr "type" "imovx")
2098 (const_string "QI")))])
2100 (define_insn "*movqi_extzv_2_rex64"
2101 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2102 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2107 switch (get_attr_type (insn))
2110 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2112 return "mov{b}\t{%h1, %0|%0, %h1}";
2116 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2117 (ne (symbol_ref "TARGET_MOVX")
2119 (const_string "imovx")
2120 (const_string "imov")))
2122 (if_then_else (eq_attr "type" "imovx")
2124 (const_string "QI")))])
2126 (define_insn "movsi_insv_1"
2127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2130 (match_operand:SI 1 "general_operand" "Qmn"))]
2132 "mov{b}\t{%b1, %h0|%h0, %b1}"
2133 [(set_attr "type" "imov")
2134 (set_attr "mode" "QI")])
2136 (define_insn "*movsi_insv_1_rex64"
2137 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2140 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2142 "mov{b}\t{%b1, %h0|%h0, %b1}"
2143 [(set_attr "type" "imov")
2144 (set_attr "mode" "QI")])
2146 (define_insn "movdi_insv_1_rex64"
2147 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2150 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2152 "mov{b}\t{%b1, %h0|%h0, %b1}"
2153 [(set_attr "type" "imov")
2154 (set_attr "mode" "QI")])
2156 (define_insn "*movqi_insv_2"
2157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2160 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2163 "mov{b}\t{%h1, %h0|%h0, %h1}"
2164 [(set_attr "type" "imov")
2165 (set_attr "mode" "QI")])
2167 (define_expand "movdi"
2168 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2169 (match_operand:DI 1 "general_operand" ""))]
2171 "ix86_expand_move (DImode, operands); DONE;")
2173 (define_insn "*pushdi"
2174 [(set (match_operand:DI 0 "push_operand" "=<")
2175 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2179 (define_insn "*pushdi2_rex64"
2180 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2181 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2186 [(set_attr "type" "push,multi")
2187 (set_attr "mode" "DI")])
2189 ;; Convert impossible pushes of immediate to existing instructions.
2190 ;; First try to get scratch register and go through it. In case this
2191 ;; fails, push sign extended lower part first and then overwrite
2192 ;; upper part by 32bit move.
2194 [(match_scratch:DI 2 "r")
2195 (set (match_operand:DI 0 "push_operand" "")
2196 (match_operand:DI 1 "immediate_operand" ""))]
2197 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2198 && !x86_64_immediate_operand (operands[1], DImode)"
2199 [(set (match_dup 2) (match_dup 1))
2200 (set (match_dup 0) (match_dup 2))]
2203 ;; We need to define this as both peepholer and splitter for case
2204 ;; peephole2 pass is not run.
2205 ;; "&& 1" is needed to keep it from matching the previous pattern.
2207 [(set (match_operand:DI 0 "push_operand" "")
2208 (match_operand:DI 1 "immediate_operand" ""))]
2209 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2210 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2211 [(set (match_dup 0) (match_dup 1))
2212 (set (match_dup 2) (match_dup 3))]
2213 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2214 operands[1] = gen_lowpart (DImode, operands[2]);
2215 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2220 [(set (match_operand:DI 0 "push_operand" "")
2221 (match_operand:DI 1 "immediate_operand" ""))]
2222 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2223 ? epilogue_completed : reload_completed)
2224 && !symbolic_operand (operands[1], DImode)
2225 && !x86_64_immediate_operand (operands[1], DImode)"
2226 [(set (match_dup 0) (match_dup 1))
2227 (set (match_dup 2) (match_dup 3))]
2228 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2229 operands[1] = gen_lowpart (DImode, operands[2]);
2230 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2234 (define_insn "*pushdi2_prologue_rex64"
2235 [(set (match_operand:DI 0 "push_operand" "=<")
2236 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2237 (clobber (mem:BLK (scratch)))]
2240 [(set_attr "type" "push")
2241 (set_attr "mode" "DI")])
2243 (define_insn "*popdi1_epilogue_rex64"
2244 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2245 (mem:DI (reg:DI SP_REG)))
2246 (set (reg:DI SP_REG)
2247 (plus:DI (reg:DI SP_REG) (const_int 8)))
2248 (clobber (mem:BLK (scratch)))]
2251 [(set_attr "type" "pop")
2252 (set_attr "mode" "DI")])
2254 (define_insn "popdi1"
2255 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2256 (mem:DI (reg:DI SP_REG)))
2257 (set (reg:DI SP_REG)
2258 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2261 [(set_attr "type" "pop")
2262 (set_attr "mode" "DI")])
2264 (define_insn "*movdi_xor_rex64"
2265 [(set (match_operand:DI 0 "register_operand" "=r")
2266 (match_operand:DI 1 "const0_operand" ""))
2267 (clobber (reg:CC FLAGS_REG))]
2269 && reload_completed"
2271 [(set_attr "type" "alu1")
2272 (set_attr "mode" "SI")
2273 (set_attr "length_immediate" "0")])
2275 (define_insn "*movdi_or_rex64"
2276 [(set (match_operand:DI 0 "register_operand" "=r")
2277 (match_operand:DI 1 "const_int_operand" "i"))
2278 (clobber (reg:CC FLAGS_REG))]
2281 && operands[1] == constm1_rtx"
2283 operands[1] = constm1_rtx;
2284 return "or{q}\t{%1, %0|%0, %1}";
2286 [(set_attr "type" "alu1")
2287 (set_attr "mode" "DI")
2288 (set_attr "length_immediate" "1")])
2290 (define_insn "*movdi_2"
2291 [(set (match_operand:DI 0 "nonimmediate_operand"
2292 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2293 (match_operand:DI 1 "general_operand"
2294 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2295 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2300 movq\t{%1, %0|%0, %1}
2301 movq\t{%1, %0|%0, %1}
2303 %vmovq\t{%1, %0|%0, %1}
2304 %vmovdqa\t{%1, %0|%0, %1}
2305 %vmovq\t{%1, %0|%0, %1}
2307 movlps\t{%1, %0|%0, %1}
2308 movaps\t{%1, %0|%0, %1}
2309 movlps\t{%1, %0|%0, %1}"
2310 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2311 (set (attr "prefix")
2312 (if_then_else (eq_attr "alternative" "5,6,7,8")
2313 (const_string "vex")
2314 (const_string "orig")))
2315 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2318 [(set (match_operand:DI 0 "push_operand" "")
2319 (match_operand:DI 1 "general_operand" ""))]
2320 "!TARGET_64BIT && reload_completed
2321 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2323 "ix86_split_long_move (operands); DONE;")
2325 ;; %%% This multiword shite has got to go.
2327 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2328 (match_operand:DI 1 "general_operand" ""))]
2329 "!TARGET_64BIT && reload_completed
2330 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2331 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2333 "ix86_split_long_move (operands); DONE;")
2335 (define_insn "*movdi_1_rex64"
2336 [(set (match_operand:DI 0 "nonimmediate_operand"
2337 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2338 (match_operand:DI 1 "general_operand"
2339 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2340 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2342 switch (get_attr_type (insn))
2345 if (SSE_REG_P (operands[0]))
2346 return "movq2dq\t{%1, %0|%0, %1}";
2348 return "movdq2q\t{%1, %0|%0, %1}";
2353 if (get_attr_mode (insn) == MODE_TI)
2354 return "vmovdqa\t{%1, %0|%0, %1}";
2356 return "vmovq\t{%1, %0|%0, %1}";
2359 if (get_attr_mode (insn) == MODE_TI)
2360 return "movdqa\t{%1, %0|%0, %1}";
2364 /* Moves from and into integer register is done using movd
2365 opcode with REX prefix. */
2366 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2367 return "movd\t{%1, %0|%0, %1}";
2368 return "movq\t{%1, %0|%0, %1}";
2371 return "%vpxor\t%0, %d0";
2374 return "pxor\t%0, %0";
2380 return "lea{q}\t{%a1, %0|%0, %a1}";
2383 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2384 if (get_attr_mode (insn) == MODE_SI)
2385 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2386 else if (which_alternative == 2)
2387 return "movabs{q}\t{%1, %0|%0, %1}";
2389 return "mov{q}\t{%1, %0|%0, %1}";
2393 (cond [(eq_attr "alternative" "5")
2394 (const_string "mmxadd")
2395 (eq_attr "alternative" "6,7,8,9,10")
2396 (const_string "mmxmov")
2397 (eq_attr "alternative" "11")
2398 (const_string "sselog1")
2399 (eq_attr "alternative" "12,13,14,15,16")
2400 (const_string "ssemov")
2401 (eq_attr "alternative" "17,18")
2402 (const_string "ssecvt")
2403 (eq_attr "alternative" "4")
2404 (const_string "multi")
2405 (match_operand:DI 1 "pic_32bit_operand" "")
2406 (const_string "lea")
2408 (const_string "imov")))
2409 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2410 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2411 (set (attr "prefix")
2412 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2413 (const_string "maybe_vex")
2414 (const_string "orig")))
2415 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2417 ;; Stores and loads of ax to arbitrary constant address.
2418 ;; We fake an second form of instruction to force reload to load address
2419 ;; into register when rax is not available
2420 (define_insn "*movabsdi_1_rex64"
2421 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2422 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2423 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2425 movabs{q}\t{%1, %P0|%P0, %1}
2426 mov{q}\t{%1, %a0|%a0, %1}"
2427 [(set_attr "type" "imov")
2428 (set_attr "modrm" "0,*")
2429 (set_attr "length_address" "8,0")
2430 (set_attr "length_immediate" "0,*")
2431 (set_attr "memory" "store")
2432 (set_attr "mode" "DI")])
2434 (define_insn "*movabsdi_2_rex64"
2435 [(set (match_operand:DI 0 "register_operand" "=a,r")
2436 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2437 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2439 movabs{q}\t{%P1, %0|%0, %P1}
2440 mov{q}\t{%a1, %0|%0, %a1}"
2441 [(set_attr "type" "imov")
2442 (set_attr "modrm" "0,*")
2443 (set_attr "length_address" "8,0")
2444 (set_attr "length_immediate" "0")
2445 (set_attr "memory" "load")
2446 (set_attr "mode" "DI")])
2448 ;; Convert impossible stores of immediate to existing instructions.
2449 ;; First try to get scratch register and go through it. In case this
2450 ;; fails, move by 32bit parts.
2452 [(match_scratch:DI 2 "r")
2453 (set (match_operand:DI 0 "memory_operand" "")
2454 (match_operand:DI 1 "immediate_operand" ""))]
2455 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2456 && !x86_64_immediate_operand (operands[1], DImode)"
2457 [(set (match_dup 2) (match_dup 1))
2458 (set (match_dup 0) (match_dup 2))]
2461 ;; We need to define this as both peepholer and splitter for case
2462 ;; peephole2 pass is not run.
2463 ;; "&& 1" is needed to keep it from matching the previous pattern.
2465 [(set (match_operand:DI 0 "memory_operand" "")
2466 (match_operand:DI 1 "immediate_operand" ""))]
2467 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2468 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2469 [(set (match_dup 2) (match_dup 3))
2470 (set (match_dup 4) (match_dup 5))]
2471 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2474 [(set (match_operand:DI 0 "memory_operand" "")
2475 (match_operand:DI 1 "immediate_operand" ""))]
2476 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2477 ? epilogue_completed : reload_completed)
2478 && !symbolic_operand (operands[1], DImode)
2479 && !x86_64_immediate_operand (operands[1], DImode)"
2480 [(set (match_dup 2) (match_dup 3))
2481 (set (match_dup 4) (match_dup 5))]
2482 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2484 (define_insn "*swapdi_rex64"
2485 [(set (match_operand:DI 0 "register_operand" "+r")
2486 (match_operand:DI 1 "register_operand" "+r"))
2491 [(set_attr "type" "imov")
2492 (set_attr "mode" "DI")
2493 (set_attr "pent_pair" "np")
2494 (set_attr "athlon_decode" "vector")
2495 (set_attr "amdfam10_decode" "double")])
2497 (define_expand "movoi"
2498 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2499 (match_operand:OI 1 "general_operand" ""))]
2501 "ix86_expand_move (OImode, operands); DONE;")
2503 (define_insn "*movoi_internal"
2504 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2505 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2507 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2509 switch (which_alternative)
2512 return "vxorps\t%0, %0, %0";
2515 if (misaligned_operand (operands[0], OImode)
2516 || misaligned_operand (operands[1], OImode))
2517 return "vmovdqu\t{%1, %0|%0, %1}";
2519 return "vmovdqa\t{%1, %0|%0, %1}";
2524 [(set_attr "type" "sselog1,ssemov,ssemov")
2525 (set_attr "prefix" "vex")
2526 (set_attr "mode" "OI")])
2528 (define_expand "movti"
2529 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2530 (match_operand:TI 1 "nonimmediate_operand" ""))]
2531 "TARGET_SSE || TARGET_64BIT"
2534 ix86_expand_move (TImode, operands);
2535 else if (push_operand (operands[0], TImode))
2536 ix86_expand_push (TImode, operands[1]);
2538 ix86_expand_vector_move (TImode, operands);
2542 (define_insn "*movti_internal"
2543 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2544 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2545 "TARGET_SSE && !TARGET_64BIT
2546 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2548 switch (which_alternative)
2551 if (get_attr_mode (insn) == MODE_V4SF)
2552 return "%vxorps\t%0, %d0";
2554 return "%vpxor\t%0, %d0";
2557 /* TDmode values are passed as TImode on the stack. Moving them
2558 to stack may result in unaligned memory access. */
2559 if (misaligned_operand (operands[0], TImode)
2560 || misaligned_operand (operands[1], TImode))
2562 if (get_attr_mode (insn) == MODE_V4SF)
2563 return "%vmovups\t{%1, %0|%0, %1}";
2565 return "%vmovdqu\t{%1, %0|%0, %1}";
2569 if (get_attr_mode (insn) == MODE_V4SF)
2570 return "%vmovaps\t{%1, %0|%0, %1}";
2572 return "%vmovdqa\t{%1, %0|%0, %1}";
2578 [(set_attr "type" "sselog1,ssemov,ssemov")
2579 (set_attr "prefix" "maybe_vex")
2581 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2582 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2583 (const_string "V4SF")
2584 (and (eq_attr "alternative" "2")
2585 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2587 (const_string "V4SF")]
2588 (const_string "TI")))])
2590 (define_insn "*movti_rex64"
2591 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2592 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2594 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2596 switch (which_alternative)
2602 if (get_attr_mode (insn) == MODE_V4SF)
2603 return "%vxorps\t%0, %d0";
2605 return "%vpxor\t%0, %d0";
2608 /* TDmode values are passed as TImode on the stack. Moving them
2609 to stack may result in unaligned memory access. */
2610 if (misaligned_operand (operands[0], TImode)
2611 || misaligned_operand (operands[1], TImode))
2613 if (get_attr_mode (insn) == MODE_V4SF)
2614 return "%vmovups\t{%1, %0|%0, %1}";
2616 return "%vmovdqu\t{%1, %0|%0, %1}";
2620 if (get_attr_mode (insn) == MODE_V4SF)
2621 return "%vmovaps\t{%1, %0|%0, %1}";
2623 return "%vmovdqa\t{%1, %0|%0, %1}";
2629 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2630 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2632 (cond [(eq_attr "alternative" "2,3")
2634 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2636 (const_string "V4SF")
2637 (const_string "TI"))
2638 (eq_attr "alternative" "4")
2640 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2642 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2644 (const_string "V4SF")
2645 (const_string "TI"))]
2646 (const_string "DI")))])
2649 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2650 (match_operand:TI 1 "general_operand" ""))]
2651 "reload_completed && !SSE_REG_P (operands[0])
2652 && !SSE_REG_P (operands[1])"
2654 "ix86_split_long_move (operands); DONE;")
2656 ;; This expands to what emit_move_complex would generate if we didn't
2657 ;; have a movti pattern. Having this avoids problems with reload on
2658 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2659 ;; to have around all the time.
2660 (define_expand "movcdi"
2661 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2662 (match_operand:CDI 1 "general_operand" ""))]
2665 if (push_operand (operands[0], CDImode))
2666 emit_move_complex_push (CDImode, operands[0], operands[1]);
2668 emit_move_complex_parts (operands[0], operands[1]);
2672 (define_expand "movsf"
2673 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2674 (match_operand:SF 1 "general_operand" ""))]
2676 "ix86_expand_move (SFmode, operands); DONE;")
2678 (define_insn "*pushsf"
2679 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2680 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2683 /* Anything else should be already split before reg-stack. */
2684 gcc_assert (which_alternative == 1);
2685 return "push{l}\t%1";
2687 [(set_attr "type" "multi,push,multi")
2688 (set_attr "unit" "i387,*,*")
2689 (set_attr "mode" "SF,SI,SF")])
2691 (define_insn "*pushsf_rex64"
2692 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2693 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2696 /* Anything else should be already split before reg-stack. */
2697 gcc_assert (which_alternative == 1);
2698 return "push{q}\t%q1";
2700 [(set_attr "type" "multi,push,multi")
2701 (set_attr "unit" "i387,*,*")
2702 (set_attr "mode" "SF,DI,SF")])
2705 [(set (match_operand:SF 0 "push_operand" "")
2706 (match_operand:SF 1 "memory_operand" ""))]
2708 && MEM_P (operands[1])
2709 && (operands[2] = find_constant_src (insn))"
2714 ;; %%% Kill this when call knows how to work this out.
2716 [(set (match_operand:SF 0 "push_operand" "")
2717 (match_operand:SF 1 "any_fp_register_operand" ""))]
2719 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2720 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2723 [(set (match_operand:SF 0 "push_operand" "")
2724 (match_operand:SF 1 "any_fp_register_operand" ""))]
2726 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2727 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2729 (define_insn "*movsf_1"
2730 [(set (match_operand:SF 0 "nonimmediate_operand"
2731 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2732 (match_operand:SF 1 "general_operand"
2733 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2734 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2735 && (reload_in_progress || reload_completed
2736 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2737 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2738 && standard_80387_constant_p (operands[1]))
2739 || GET_CODE (operands[1]) != CONST_DOUBLE
2740 || memory_operand (operands[0], SFmode))"
2742 switch (which_alternative)
2746 return output_387_reg_move (insn, operands);
2749 return standard_80387_constant_opcode (operands[1]);
2753 return "mov{l}\t{%1, %0|%0, %1}";
2755 if (get_attr_mode (insn) == MODE_TI)
2756 return "%vpxor\t%0, %d0";
2758 return "%vxorps\t%0, %d0";
2760 if (get_attr_mode (insn) == MODE_V4SF)
2761 return "%vmovaps\t{%1, %0|%0, %1}";
2763 return "%vmovss\t{%1, %d0|%d0, %1}";
2766 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2767 : "vmovss\t{%1, %0|%0, %1}";
2769 return "movss\t{%1, %0|%0, %1}";
2771 return "%vmovss\t{%1, %0|%0, %1}";
2773 case 9: case 10: case 14: case 15:
2774 return "movd\t{%1, %0|%0, %1}";
2776 return "%vmovd\t{%1, %0|%0, %1}";
2779 return "movq\t{%1, %0|%0, %1}";
2785 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2786 (set (attr "prefix")
2787 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2788 (const_string "maybe_vex")
2789 (const_string "orig")))
2791 (cond [(eq_attr "alternative" "3,4,9,10")
2793 (eq_attr "alternative" "5")
2795 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2797 (ne (symbol_ref "TARGET_SSE2")
2799 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2802 (const_string "V4SF"))
2803 /* For architectures resolving dependencies on
2804 whole SSE registers use APS move to break dependency
2805 chains, otherwise use short move to avoid extra work.
2807 Do the same for architectures resolving dependencies on
2808 the parts. While in DF mode it is better to always handle
2809 just register parts, the SF mode is different due to lack
2810 of instructions to load just part of the register. It is
2811 better to maintain the whole registers in single format
2812 to avoid problems on using packed logical operations. */
2813 (eq_attr "alternative" "6")
2815 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2817 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2819 (const_string "V4SF")
2820 (const_string "SF"))
2821 (eq_attr "alternative" "11")
2822 (const_string "DI")]
2823 (const_string "SF")))])
2825 (define_insn "*swapsf"
2826 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2827 (match_operand:SF 1 "fp_register_operand" "+f"))
2830 "reload_completed || TARGET_80387"
2832 if (STACK_TOP_P (operands[0]))
2837 [(set_attr "type" "fxch")
2838 (set_attr "mode" "SF")])
2840 (define_expand "movdf"
2841 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2842 (match_operand:DF 1 "general_operand" ""))]
2844 "ix86_expand_move (DFmode, operands); DONE;")
2846 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2847 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2848 ;; On the average, pushdf using integers can be still shorter. Allow this
2849 ;; pattern for optimize_size too.
2851 (define_insn "*pushdf_nointeger"
2852 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2853 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2854 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2856 /* This insn should be already split before reg-stack. */
2859 [(set_attr "type" "multi")
2860 (set_attr "unit" "i387,*,*,*")
2861 (set_attr "mode" "DF,SI,SI,DF")])
2863 (define_insn "*pushdf_integer"
2864 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2865 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2866 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2868 /* This insn should be already split before reg-stack. */
2871 [(set_attr "type" "multi")
2872 (set_attr "unit" "i387,*,*")
2873 (set_attr "mode" "DF,SI,DF")])
2875 ;; %%% Kill this when call knows how to work this out.
2877 [(set (match_operand:DF 0 "push_operand" "")
2878 (match_operand:DF 1 "any_fp_register_operand" ""))]
2880 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2881 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2885 [(set (match_operand:DF 0 "push_operand" "")
2886 (match_operand:DF 1 "general_operand" ""))]
2889 "ix86_split_long_move (operands); DONE;")
2891 ;; Moving is usually shorter when only FP registers are used. This separate
2892 ;; movdf pattern avoids the use of integer registers for FP operations
2893 ;; when optimizing for size.
2895 (define_insn "*movdf_nointeger"
2896 [(set (match_operand:DF 0 "nonimmediate_operand"
2897 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2898 (match_operand:DF 1 "general_operand"
2899 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2900 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2901 && ((optimize_function_for_size_p (cfun)
2902 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2903 && (reload_in_progress || reload_completed
2904 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2905 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2906 && optimize_function_for_size_p (cfun)
2907 && !memory_operand (operands[0], DFmode)
2908 && standard_80387_constant_p (operands[1]))
2909 || GET_CODE (operands[1]) != CONST_DOUBLE
2910 || ((optimize_function_for_size_p (cfun)
2911 || !TARGET_MEMORY_MISMATCH_STALL
2912 || reload_in_progress || reload_completed)
2913 && memory_operand (operands[0], DFmode)))"
2915 switch (which_alternative)
2919 return output_387_reg_move (insn, operands);
2922 return standard_80387_constant_opcode (operands[1]);
2928 switch (get_attr_mode (insn))
2931 return "%vxorps\t%0, %d0";
2933 return "%vxorpd\t%0, %d0";
2935 return "%vpxor\t%0, %d0";
2942 switch (get_attr_mode (insn))
2945 return "%vmovaps\t{%1, %0|%0, %1}";
2947 return "%vmovapd\t{%1, %0|%0, %1}";
2949 return "%vmovdqa\t{%1, %0|%0, %1}";
2951 return "%vmovq\t{%1, %0|%0, %1}";
2955 if (REG_P (operands[0]) && REG_P (operands[1]))
2956 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2958 return "vmovsd\t{%1, %0|%0, %1}";
2961 return "movsd\t{%1, %0|%0, %1}";
2965 if (REG_P (operands[0]))
2966 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2968 return "vmovlpd\t{%1, %0|%0, %1}";
2971 return "movlpd\t{%1, %0|%0, %1}";
2975 if (REG_P (operands[0]))
2976 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2978 return "vmovlps\t{%1, %0|%0, %1}";
2981 return "movlps\t{%1, %0|%0, %1}";
2990 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2991 (set (attr "prefix")
2992 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2993 (const_string "orig")
2994 (const_string "maybe_vex")))
2996 (cond [(eq_attr "alternative" "0,1,2")
2998 (eq_attr "alternative" "3,4")
3001 /* For SSE1, we have many fewer alternatives. */
3002 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3003 (cond [(eq_attr "alternative" "5,6")
3004 (const_string "V4SF")
3006 (const_string "V2SF"))
3008 /* xorps is one byte shorter. */
3009 (eq_attr "alternative" "5")
3010 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012 (const_string "V4SF")
3013 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3017 (const_string "V2DF"))
3019 /* For architectures resolving dependencies on
3020 whole SSE registers use APD move to break dependency
3021 chains, otherwise use short move to avoid extra work.
3023 movaps encodes one byte shorter. */
3024 (eq_attr "alternative" "6")
3026 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3028 (const_string "V4SF")
3029 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3031 (const_string "V2DF")
3033 (const_string "DF"))
3034 /* For architectures resolving dependencies on register
3035 parts we may avoid extra work to zero out upper part
3037 (eq_attr "alternative" "7")
3039 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3041 (const_string "V1DF")
3042 (const_string "DF"))
3044 (const_string "DF")))])
3046 (define_insn "*movdf_integer_rex64"
3047 [(set (match_operand:DF 0 "nonimmediate_operand"
3048 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3049 (match_operand:DF 1 "general_operand"
3050 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3051 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3052 && (reload_in_progress || reload_completed
3053 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3054 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3055 && optimize_function_for_size_p (cfun)
3056 && standard_80387_constant_p (operands[1]))
3057 || GET_CODE (operands[1]) != CONST_DOUBLE
3058 || memory_operand (operands[0], DFmode))"
3060 switch (which_alternative)
3064 return output_387_reg_move (insn, operands);
3067 return standard_80387_constant_opcode (operands[1]);
3074 switch (get_attr_mode (insn))
3077 return "%vxorps\t%0, %d0";
3079 return "%vxorpd\t%0, %d0";
3081 return "%vpxor\t%0, %d0";
3088 switch (get_attr_mode (insn))
3091 return "%vmovaps\t{%1, %0|%0, %1}";
3093 return "%vmovapd\t{%1, %0|%0, %1}";
3095 return "%vmovdqa\t{%1, %0|%0, %1}";
3097 return "%vmovq\t{%1, %0|%0, %1}";
3101 if (REG_P (operands[0]) && REG_P (operands[1]))
3102 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104 return "vmovsd\t{%1, %0|%0, %1}";
3107 return "movsd\t{%1, %0|%0, %1}";
3109 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3111 return "%vmovlps\t{%1, %d0|%d0, %1}";
3118 return "%vmovd\t{%1, %0|%0, %1}";
3124 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3125 (set (attr "prefix")
3126 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3127 (const_string "orig")
3128 (const_string "maybe_vex")))
3130 (cond [(eq_attr "alternative" "0,1,2")
3132 (eq_attr "alternative" "3,4,9,10")
3135 /* For SSE1, we have many fewer alternatives. */
3136 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3137 (cond [(eq_attr "alternative" "5,6")
3138 (const_string "V4SF")
3140 (const_string "V2SF"))
3142 /* xorps is one byte shorter. */
3143 (eq_attr "alternative" "5")
3144 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146 (const_string "V4SF")
3147 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3151 (const_string "V2DF"))
3153 /* For architectures resolving dependencies on
3154 whole SSE registers use APD move to break dependency
3155 chains, otherwise use short move to avoid extra work.
3157 movaps encodes one byte shorter. */
3158 (eq_attr "alternative" "6")
3160 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162 (const_string "V4SF")
3163 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165 (const_string "V2DF")
3167 (const_string "DF"))
3168 /* For architectures resolving dependencies on register
3169 parts we may avoid extra work to zero out upper part
3171 (eq_attr "alternative" "7")
3173 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3175 (const_string "V1DF")
3176 (const_string "DF"))
3178 (const_string "DF")))])
3180 (define_insn "*movdf_integer"
3181 [(set (match_operand:DF 0 "nonimmediate_operand"
3182 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3183 (match_operand:DF 1 "general_operand"
3184 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3185 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3186 && optimize_function_for_speed_p (cfun)
3187 && TARGET_INTEGER_DFMODE_MOVES
3188 && (reload_in_progress || reload_completed
3189 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3190 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3191 && optimize_function_for_size_p (cfun)
3192 && standard_80387_constant_p (operands[1]))
3193 || GET_CODE (operands[1]) != CONST_DOUBLE
3194 || memory_operand (operands[0], DFmode))"
3196 switch (which_alternative)
3200 return output_387_reg_move (insn, operands);
3203 return standard_80387_constant_opcode (operands[1]);
3210 switch (get_attr_mode (insn))
3213 return "xorps\t%0, %0";
3215 return "xorpd\t%0, %0";
3217 return "pxor\t%0, %0";
3224 switch (get_attr_mode (insn))
3227 return "movaps\t{%1, %0|%0, %1}";
3229 return "movapd\t{%1, %0|%0, %1}";
3231 return "movdqa\t{%1, %0|%0, %1}";
3233 return "movq\t{%1, %0|%0, %1}";
3235 return "movsd\t{%1, %0|%0, %1}";
3237 return "movlpd\t{%1, %0|%0, %1}";
3239 return "movlps\t{%1, %0|%0, %1}";
3248 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3250 (cond [(eq_attr "alternative" "0,1,2")
3252 (eq_attr "alternative" "3,4")
3255 /* For SSE1, we have many fewer alternatives. */
3256 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3257 (cond [(eq_attr "alternative" "5,6")
3258 (const_string "V4SF")
3260 (const_string "V2SF"))
3262 /* xorps is one byte shorter. */
3263 (eq_attr "alternative" "5")
3264 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3266 (const_string "V4SF")
3267 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3271 (const_string "V2DF"))
3273 /* For architectures resolving dependencies on
3274 whole SSE registers use APD move to break dependency
3275 chains, otherwise use short move to avoid extra work.
3277 movaps encodes one byte shorter. */
3278 (eq_attr "alternative" "6")
3280 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3282 (const_string "V4SF")
3283 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285 (const_string "V2DF")
3287 (const_string "DF"))
3288 /* For architectures resolving dependencies on register
3289 parts we may avoid extra work to zero out upper part
3291 (eq_attr "alternative" "7")
3293 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3295 (const_string "V1DF")
3296 (const_string "DF"))
3298 (const_string "DF")))])
3301 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3302 (match_operand:DF 1 "general_operand" ""))]
3304 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3305 && ! (ANY_FP_REG_P (operands[0]) ||
3306 (GET_CODE (operands[0]) == SUBREG
3307 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3308 && ! (ANY_FP_REG_P (operands[1]) ||
3309 (GET_CODE (operands[1]) == SUBREG
3310 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3312 "ix86_split_long_move (operands); DONE;")
3314 (define_insn "*swapdf"
3315 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3316 (match_operand:DF 1 "fp_register_operand" "+f"))
3319 "reload_completed || TARGET_80387"
3321 if (STACK_TOP_P (operands[0]))
3326 [(set_attr "type" "fxch")
3327 (set_attr "mode" "DF")])
3329 (define_expand "movxf"
3330 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3331 (match_operand:XF 1 "general_operand" ""))]
3333 "ix86_expand_move (XFmode, operands); DONE;")
3335 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3336 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3337 ;; Pushing using integer instructions is longer except for constants
3338 ;; and direct memory references.
3339 ;; (assuming that any given constant is pushed only once, but this ought to be
3340 ;; handled elsewhere).
3342 (define_insn "*pushxf_nointeger"
3343 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3344 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3345 "optimize_function_for_size_p (cfun)"
3347 /* This insn should be already split before reg-stack. */
3350 [(set_attr "type" "multi")
3351 (set_attr "unit" "i387,*,*")
3352 (set_attr "mode" "XF,SI,SI")])
3354 (define_insn "*pushxf_integer"
3355 [(set (match_operand:XF 0 "push_operand" "=<,<")
3356 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3357 "optimize_function_for_speed_p (cfun)"
3359 /* This insn should be already split before reg-stack. */
3362 [(set_attr "type" "multi")
3363 (set_attr "unit" "i387,*")
3364 (set_attr "mode" "XF,SI")])
3367 [(set (match_operand 0 "push_operand" "")
3368 (match_operand 1 "general_operand" ""))]
3370 && (GET_MODE (operands[0]) == XFmode
3371 || GET_MODE (operands[0]) == DFmode)
3372 && !ANY_FP_REG_P (operands[1])"
3374 "ix86_split_long_move (operands); DONE;")
3377 [(set (match_operand:XF 0 "push_operand" "")
3378 (match_operand:XF 1 "any_fp_register_operand" ""))]
3380 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3381 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3382 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3384 ;; Do not use integer registers when optimizing for size
3385 (define_insn "*movxf_nointeger"
3386 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3387 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3388 "optimize_function_for_size_p (cfun)
3389 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3390 && (reload_in_progress || reload_completed
3391 || standard_80387_constant_p (operands[1])
3392 || GET_CODE (operands[1]) != CONST_DOUBLE
3393 || memory_operand (operands[0], XFmode))"
3395 switch (which_alternative)
3399 return output_387_reg_move (insn, operands);
3402 return standard_80387_constant_opcode (operands[1]);
3410 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3411 (set_attr "mode" "XF,XF,XF,SI,SI")])
3413 (define_insn "*movxf_integer"
3414 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3415 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3416 "optimize_function_for_speed_p (cfun)
3417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3418 && (reload_in_progress || reload_completed
3419 || GET_CODE (operands[1]) != CONST_DOUBLE
3420 || memory_operand (operands[0], XFmode))"
3422 switch (which_alternative)
3426 return output_387_reg_move (insn, operands);
3429 return standard_80387_constant_opcode (operands[1]);
3438 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3439 (set_attr "mode" "XF,XF,XF,SI,SI")])
3441 (define_expand "movtf"
3442 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3443 (match_operand:TF 1 "nonimmediate_operand" ""))]
3446 ix86_expand_move (TFmode, operands);
3450 (define_insn "*movtf_internal"
3451 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3452 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3456 switch (which_alternative)
3460 if (get_attr_mode (insn) == MODE_V4SF)
3461 return "%vmovaps\t{%1, %0|%0, %1}";
3463 return "%vmovdqa\t{%1, %0|%0, %1}";
3465 if (get_attr_mode (insn) == MODE_V4SF)
3466 return "%vxorps\t%0, %d0";
3468 return "%vpxor\t%0, %d0";
3476 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3477 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3479 (cond [(eq_attr "alternative" "0,2")
3481 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3483 (const_string "V4SF")
3484 (const_string "TI"))
3485 (eq_attr "alternative" "1")
3487 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3489 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3491 (const_string "V4SF")
3492 (const_string "TI"))]
3493 (const_string "DI")))])
3495 (define_insn "*pushtf_sse"
3496 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3497 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3500 /* This insn should be already split before reg-stack. */
3503 [(set_attr "type" "multi")
3504 (set_attr "unit" "sse,*,*")
3505 (set_attr "mode" "TF,SI,SI")])
3508 [(set (match_operand:TF 0 "push_operand" "")
3509 (match_operand:TF 1 "general_operand" ""))]
3510 "TARGET_SSE2 && reload_completed
3511 && !SSE_REG_P (operands[1])"
3513 "ix86_split_long_move (operands); DONE;")
3516 [(set (match_operand:TF 0 "push_operand" "")
3517 (match_operand:TF 1 "any_fp_register_operand" ""))]
3519 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3520 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3524 [(set (match_operand 0 "nonimmediate_operand" "")
3525 (match_operand 1 "general_operand" ""))]
3527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528 && GET_MODE (operands[0]) == XFmode
3529 && ! (ANY_FP_REG_P (operands[0]) ||
3530 (GET_CODE (operands[0]) == SUBREG
3531 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3532 && ! (ANY_FP_REG_P (operands[1]) ||
3533 (GET_CODE (operands[1]) == SUBREG
3534 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3536 "ix86_split_long_move (operands); DONE;")
3539 [(set (match_operand 0 "register_operand" "")
3540 (match_operand 1 "memory_operand" ""))]
3542 && MEM_P (operands[1])
3543 && (GET_MODE (operands[0]) == TFmode
3544 || GET_MODE (operands[0]) == XFmode
3545 || GET_MODE (operands[0]) == SFmode
3546 || GET_MODE (operands[0]) == DFmode)
3547 && (operands[2] = find_constant_src (insn))"
3548 [(set (match_dup 0) (match_dup 2))]
3550 rtx c = operands[2];
3551 rtx r = operands[0];
3553 if (GET_CODE (r) == SUBREG)
3558 if (!standard_sse_constant_p (c))
3561 else if (FP_REG_P (r))
3563 if (!standard_80387_constant_p (c))
3566 else if (MMX_REG_P (r))
3571 [(set (match_operand 0 "register_operand" "")
3572 (float_extend (match_operand 1 "memory_operand" "")))]
3574 && MEM_P (operands[1])
3575 && (GET_MODE (operands[0]) == TFmode
3576 || GET_MODE (operands[0]) == XFmode
3577 || GET_MODE (operands[0]) == SFmode
3578 || GET_MODE (operands[0]) == DFmode)
3579 && (operands[2] = find_constant_src (insn))"
3580 [(set (match_dup 0) (match_dup 2))]
3582 rtx c = operands[2];
3583 rtx r = operands[0];
3585 if (GET_CODE (r) == SUBREG)
3590 if (!standard_sse_constant_p (c))
3593 else if (FP_REG_P (r))
3595 if (!standard_80387_constant_p (c))
3598 else if (MMX_REG_P (r))
3602 (define_insn "swapxf"
3603 [(set (match_operand:XF 0 "register_operand" "+f")
3604 (match_operand:XF 1 "register_operand" "+f"))
3609 if (STACK_TOP_P (operands[0]))
3614 [(set_attr "type" "fxch")
3615 (set_attr "mode" "XF")])
3617 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3619 [(set (match_operand:X87MODEF 0 "register_operand" "")
3620 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3621 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3622 && (standard_80387_constant_p (operands[1]) == 8
3623 || standard_80387_constant_p (operands[1]) == 9)"
3624 [(set (match_dup 0)(match_dup 1))
3626 (neg:X87MODEF (match_dup 0)))]
3630 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3631 if (real_isnegzero (&r))
3632 operands[1] = CONST0_RTX (<MODE>mode);
3634 operands[1] = CONST1_RTX (<MODE>mode);
3638 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3639 (match_operand:TF 1 "general_operand" ""))]
3641 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3643 "ix86_split_long_move (operands); DONE;")
3645 ;; Zero extension instructions
3647 (define_expand "zero_extendhisi2"
3648 [(set (match_operand:SI 0 "register_operand" "")
3649 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3652 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3654 operands[1] = force_reg (HImode, operands[1]);
3655 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3660 (define_insn "zero_extendhisi2_and"
3661 [(set (match_operand:SI 0 "register_operand" "=r")
3662 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3663 (clobber (reg:CC FLAGS_REG))]
3664 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3666 [(set_attr "type" "alu1")
3667 (set_attr "mode" "SI")])
3670 [(set (match_operand:SI 0 "register_operand" "")
3671 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3672 (clobber (reg:CC FLAGS_REG))]
3673 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3674 && optimize_function_for_speed_p (cfun)"
3675 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3676 (clobber (reg:CC FLAGS_REG))])]
3679 (define_insn "*zero_extendhisi2_movzwl"
3680 [(set (match_operand:SI 0 "register_operand" "=r")
3681 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3682 "!TARGET_ZERO_EXTEND_WITH_AND
3683 || optimize_function_for_size_p (cfun)"
3684 "movz{wl|x}\t{%1, %0|%0, %1}"
3685 [(set_attr "type" "imovx")
3686 (set_attr "mode" "SI")])
3688 (define_expand "zero_extendqihi2"
3690 [(set (match_operand:HI 0 "register_operand" "")
3691 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3692 (clobber (reg:CC FLAGS_REG))])]
3696 (define_insn "*zero_extendqihi2_and"
3697 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3698 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3699 (clobber (reg:CC FLAGS_REG))]
3700 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3702 [(set_attr "type" "alu1")
3703 (set_attr "mode" "HI")])
3705 (define_insn "*zero_extendqihi2_movzbw_and"
3706 [(set (match_operand:HI 0 "register_operand" "=r,r")
3707 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3708 (clobber (reg:CC FLAGS_REG))]
3709 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3711 [(set_attr "type" "imovx,alu1")
3712 (set_attr "mode" "HI")])
3714 ; zero extend to SImode here to avoid partial register stalls
3715 (define_insn "*zero_extendqihi2_movzbl"
3716 [(set (match_operand:HI 0 "register_operand" "=r")
3717 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3718 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3719 && reload_completed"
3720 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3721 [(set_attr "type" "imovx")
3722 (set_attr "mode" "SI")])
3724 ;; For the movzbw case strip only the clobber
3726 [(set (match_operand:HI 0 "register_operand" "")
3727 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3728 (clobber (reg:CC FLAGS_REG))]
3730 && (!TARGET_ZERO_EXTEND_WITH_AND
3731 || optimize_function_for_size_p (cfun))
3732 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3733 [(set (match_operand:HI 0 "register_operand" "")
3734 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3736 ;; When source and destination does not overlap, clear destination
3737 ;; first and then do the movb
3739 [(set (match_operand:HI 0 "register_operand" "")
3740 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3741 (clobber (reg:CC FLAGS_REG))]
3743 && ANY_QI_REG_P (operands[0])
3744 && (TARGET_ZERO_EXTEND_WITH_AND
3745 && optimize_function_for_speed_p (cfun))
3746 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3747 [(set (match_dup 0) (const_int 0))
3748 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3749 "operands[2] = gen_lowpart (QImode, operands[0]);")
3751 ;; Rest is handled by single and.
3753 [(set (match_operand:HI 0 "register_operand" "")
3754 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3755 (clobber (reg:CC FLAGS_REG))]
3757 && true_regnum (operands[0]) == true_regnum (operands[1])"
3758 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3759 (clobber (reg:CC FLAGS_REG))])]
3762 (define_expand "zero_extendqisi2"
3764 [(set (match_operand:SI 0 "register_operand" "")
3765 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3766 (clobber (reg:CC FLAGS_REG))])]
3770 (define_insn "*zero_extendqisi2_and"
3771 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3772 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3773 (clobber (reg:CC FLAGS_REG))]
3774 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3776 [(set_attr "type" "alu1")
3777 (set_attr "mode" "SI")])
3779 (define_insn "*zero_extendqisi2_movzbw_and"
3780 [(set (match_operand:SI 0 "register_operand" "=r,r")
3781 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3782 (clobber (reg:CC FLAGS_REG))]
3783 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3785 [(set_attr "type" "imovx,alu1")
3786 (set_attr "mode" "SI")])
3788 (define_insn "*zero_extendqisi2_movzbw"
3789 [(set (match_operand:SI 0 "register_operand" "=r")
3790 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3791 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3792 && reload_completed"
3793 "movz{bl|x}\t{%1, %0|%0, %1}"
3794 [(set_attr "type" "imovx")
3795 (set_attr "mode" "SI")])
3797 ;; For the movzbl case strip only the clobber
3799 [(set (match_operand:SI 0 "register_operand" "")
3800 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3801 (clobber (reg:CC FLAGS_REG))]
3803 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3804 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3806 (zero_extend:SI (match_dup 1)))])
3808 ;; When source and destination does not overlap, clear destination
3809 ;; first and then do the movb
3811 [(set (match_operand:SI 0 "register_operand" "")
3812 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3813 (clobber (reg:CC FLAGS_REG))]
3815 && ANY_QI_REG_P (operands[0])
3816 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3817 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3818 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3819 [(set (match_dup 0) (const_int 0))
3820 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3821 "operands[2] = gen_lowpart (QImode, operands[0]);")
3823 ;; Rest is handled by single and.
3825 [(set (match_operand:SI 0 "register_operand" "")
3826 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3827 (clobber (reg:CC FLAGS_REG))]
3829 && true_regnum (operands[0]) == true_regnum (operands[1])"
3830 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3831 (clobber (reg:CC FLAGS_REG))])]
3834 ;; %%% Kill me once multi-word ops are sane.
3835 (define_expand "zero_extendsidi2"
3836 [(set (match_operand:DI 0 "register_operand" "")
3837 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3842 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3847 (define_insn "zero_extendsidi2_32"
3848 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3850 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3851 (clobber (reg:CC FLAGS_REG))]
3857 movd\t{%1, %0|%0, %1}
3858 movd\t{%1, %0|%0, %1}
3859 %vmovd\t{%1, %0|%0, %1}
3860 %vmovd\t{%1, %0|%0, %1}"
3861 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3862 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3863 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3865 (define_insn "zero_extendsidi2_rex64"
3866 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3868 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3871 mov\t{%k1, %k0|%k0, %k1}
3873 movd\t{%1, %0|%0, %1}
3874 movd\t{%1, %0|%0, %1}
3875 %vmovd\t{%1, %0|%0, %1}
3876 %vmovd\t{%1, %0|%0, %1}"
3877 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3878 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3879 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3882 [(set (match_operand:DI 0 "memory_operand" "")
3883 (zero_extend:DI (match_dup 0)))]
3885 [(set (match_dup 4) (const_int 0))]
3886 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3889 [(set (match_operand:DI 0 "register_operand" "")
3890 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3891 (clobber (reg:CC FLAGS_REG))]
3892 "!TARGET_64BIT && reload_completed
3893 && true_regnum (operands[0]) == true_regnum (operands[1])"
3894 [(set (match_dup 4) (const_int 0))]
3895 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3898 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3899 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3900 (clobber (reg:CC FLAGS_REG))]
3901 "!TARGET_64BIT && reload_completed
3902 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3903 [(set (match_dup 3) (match_dup 1))
3904 (set (match_dup 4) (const_int 0))]
3905 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3907 (define_insn "zero_extendhidi2"
3908 [(set (match_operand:DI 0 "register_operand" "=r")
3909 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3911 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3912 [(set_attr "type" "imovx")
3913 (set_attr "mode" "DI")])
3915 (define_insn "zero_extendqidi2"
3916 [(set (match_operand:DI 0 "register_operand" "=r")
3917 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3919 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3920 [(set_attr "type" "imovx")
3921 (set_attr "mode" "DI")])
3923 ;; Sign extension instructions
3925 (define_expand "extendsidi2"
3926 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3927 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3928 (clobber (reg:CC FLAGS_REG))
3929 (clobber (match_scratch:SI 2 ""))])]
3934 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3939 (define_insn "*extendsidi2_1"
3940 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3941 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3942 (clobber (reg:CC FLAGS_REG))
3943 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3947 (define_insn "extendsidi2_rex64"
3948 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3949 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3953 movs{lq|x}\t{%1,%0|%0, %1}"
3954 [(set_attr "type" "imovx")
3955 (set_attr "mode" "DI")
3956 (set_attr "prefix_0f" "0")
3957 (set_attr "modrm" "0,1")])
3959 (define_insn "extendhidi2"
3960 [(set (match_operand:DI 0 "register_operand" "=r")
3961 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3963 "movs{wq|x}\t{%1,%0|%0, %1}"
3964 [(set_attr "type" "imovx")
3965 (set_attr "mode" "DI")])
3967 (define_insn "extendqidi2"
3968 [(set (match_operand:DI 0 "register_operand" "=r")
3969 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3971 "movs{bq|x}\t{%1,%0|%0, %1}"
3972 [(set_attr "type" "imovx")
3973 (set_attr "mode" "DI")])
3975 ;; Extend to memory case when source register does die.
3977 [(set (match_operand:DI 0 "memory_operand" "")
3978 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3979 (clobber (reg:CC FLAGS_REG))
3980 (clobber (match_operand:SI 2 "register_operand" ""))]
3982 && dead_or_set_p (insn, operands[1])
3983 && !reg_mentioned_p (operands[1], operands[0]))"
3984 [(set (match_dup 3) (match_dup 1))
3985 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3986 (clobber (reg:CC FLAGS_REG))])
3987 (set (match_dup 4) (match_dup 1))]
3988 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3990 ;; Extend to memory case when source register does not die.
3992 [(set (match_operand:DI 0 "memory_operand" "")
3993 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3994 (clobber (reg:CC FLAGS_REG))
3995 (clobber (match_operand:SI 2 "register_operand" ""))]
3999 split_di (&operands[0], 1, &operands[3], &operands[4]);
4001 emit_move_insn (operands[3], operands[1]);
4003 /* Generate a cltd if possible and doing so it profitable. */
4004 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4005 && true_regnum (operands[1]) == AX_REG
4006 && true_regnum (operands[2]) == DX_REG)
4008 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4012 emit_move_insn (operands[2], operands[1]);
4013 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4015 emit_move_insn (operands[4], operands[2]);
4019 ;; Extend to register case. Optimize case where source and destination
4020 ;; registers match and cases where we can use cltd.
4022 [(set (match_operand:DI 0 "register_operand" "")
4023 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4024 (clobber (reg:CC FLAGS_REG))
4025 (clobber (match_scratch:SI 2 ""))]
4029 split_di (&operands[0], 1, &operands[3], &operands[4]);
4031 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4032 emit_move_insn (operands[3], operands[1]);
4034 /* Generate a cltd if possible and doing so it profitable. */
4035 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4036 && true_regnum (operands[3]) == AX_REG)
4038 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4042 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4043 emit_move_insn (operands[4], operands[1]);
4045 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4049 (define_insn "extendhisi2"
4050 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4051 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4054 switch (get_attr_prefix_0f (insn))
4057 return "{cwtl|cwde}";
4059 return "movs{wl|x}\t{%1,%0|%0, %1}";
4062 [(set_attr "type" "imovx")
4063 (set_attr "mode" "SI")
4064 (set (attr "prefix_0f")
4065 ;; movsx is short decodable while cwtl is vector decoded.
4066 (if_then_else (and (eq_attr "cpu" "!k6")
4067 (eq_attr "alternative" "0"))
4069 (const_string "1")))
4071 (if_then_else (eq_attr "prefix_0f" "0")
4073 (const_string "1")))])
4075 (define_insn "*extendhisi2_zext"
4076 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4078 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4081 switch (get_attr_prefix_0f (insn))
4084 return "{cwtl|cwde}";
4086 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4089 [(set_attr "type" "imovx")
4090 (set_attr "mode" "SI")
4091 (set (attr "prefix_0f")
4092 ;; movsx is short decodable while cwtl is vector decoded.
4093 (if_then_else (and (eq_attr "cpu" "!k6")
4094 (eq_attr "alternative" "0"))
4096 (const_string "1")))
4098 (if_then_else (eq_attr "prefix_0f" "0")
4100 (const_string "1")))])
4102 (define_insn "extendqihi2"
4103 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4104 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4107 switch (get_attr_prefix_0f (insn))
4110 return "{cbtw|cbw}";
4112 return "movs{bw|x}\t{%1,%0|%0, %1}";
4115 [(set_attr "type" "imovx")
4116 (set_attr "mode" "HI")
4117 (set (attr "prefix_0f")
4118 ;; movsx is short decodable while cwtl is vector decoded.
4119 (if_then_else (and (eq_attr "cpu" "!k6")
4120 (eq_attr "alternative" "0"))
4122 (const_string "1")))
4124 (if_then_else (eq_attr "prefix_0f" "0")
4126 (const_string "1")))])
4128 (define_insn "extendqisi2"
4129 [(set (match_operand:SI 0 "register_operand" "=r")
4130 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4132 "movs{bl|x}\t{%1,%0|%0, %1}"
4133 [(set_attr "type" "imovx")
4134 (set_attr "mode" "SI")])
4136 (define_insn "*extendqisi2_zext"
4137 [(set (match_operand:DI 0 "register_operand" "=r")
4139 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4141 "movs{bl|x}\t{%1,%k0|%k0, %1}"
4142 [(set_attr "type" "imovx")
4143 (set_attr "mode" "SI")])
4145 ;; Conversions between float and double.
4147 ;; These are all no-ops in the model used for the 80387. So just
4150 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4151 (define_insn "*dummy_extendsfdf2"
4152 [(set (match_operand:DF 0 "push_operand" "=<")
4153 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4158 [(set (match_operand:DF 0 "push_operand" "")
4159 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4161 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4162 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4164 (define_insn "*dummy_extendsfxf2"
4165 [(set (match_operand:XF 0 "push_operand" "=<")
4166 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4171 [(set (match_operand:XF 0 "push_operand" "")
4172 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4174 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4175 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4176 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4179 [(set (match_operand:XF 0 "push_operand" "")
4180 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4182 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4183 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4184 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4186 (define_expand "extendsfdf2"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4188 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4189 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4191 /* ??? Needed for compress_float_constant since all fp constants
4192 are LEGITIMATE_CONSTANT_P. */
4193 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4195 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4196 && standard_80387_constant_p (operands[1]) > 0)
4198 operands[1] = simplify_const_unary_operation
4199 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4200 emit_move_insn_1 (operands[0], operands[1]);
4203 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4207 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4209 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4211 We do the conversion post reload to avoid producing of 128bit spills
4212 that might lead to ICE on 32bit target. The sequence unlikely combine
4215 [(set (match_operand:DF 0 "register_operand" "")
4217 (match_operand:SF 1 "nonimmediate_operand" "")))]
4218 "TARGET_USE_VECTOR_FP_CONVERTS
4219 && optimize_insn_for_speed_p ()
4220 && reload_completed && SSE_REG_P (operands[0])"
4225 (parallel [(const_int 0) (const_int 1)]))))]
4227 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4228 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4229 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4230 Try to avoid move when unpacking can be done in source. */
4231 if (REG_P (operands[1]))
4233 /* If it is unsafe to overwrite upper half of source, we need
4234 to move to destination and unpack there. */
4235 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4236 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4237 && true_regnum (operands[0]) != true_regnum (operands[1]))
4239 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4240 emit_move_insn (tmp, operands[1]);
4243 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4244 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4247 emit_insn (gen_vec_setv4sf_0 (operands[3],
4248 CONST0_RTX (V4SFmode), operands[1]));
4251 (define_insn "*extendsfdf2_mixed"
4252 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4254 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4255 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4257 switch (which_alternative)
4261 return output_387_reg_move (insn, operands);
4264 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4270 [(set_attr "type" "fmov,fmov,ssecvt")
4271 (set_attr "prefix" "orig,orig,maybe_vex")
4272 (set_attr "mode" "SF,XF,DF")])
4274 (define_insn "*extendsfdf2_sse"
4275 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4276 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4277 "TARGET_SSE2 && TARGET_SSE_MATH"
4278 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4279 [(set_attr "type" "ssecvt")
4280 (set_attr "prefix" "maybe_vex")
4281 (set_attr "mode" "DF")])
4283 (define_insn "*extendsfdf2_i387"
4284 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4285 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4287 "* return output_387_reg_move (insn, operands);"
4288 [(set_attr "type" "fmov")
4289 (set_attr "mode" "SF,XF")])
4291 (define_expand "extend<mode>xf2"
4292 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4293 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4296 /* ??? Needed for compress_float_constant since all fp constants
4297 are LEGITIMATE_CONSTANT_P. */
4298 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4300 if (standard_80387_constant_p (operands[1]) > 0)
4302 operands[1] = simplify_const_unary_operation
4303 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4304 emit_move_insn_1 (operands[0], operands[1]);
4307 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4311 (define_insn "*extend<mode>xf2_i387"
4312 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4314 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4316 "* return output_387_reg_move (insn, operands);"
4317 [(set_attr "type" "fmov")
4318 (set_attr "mode" "<MODE>,XF")])
4320 ;; %%% This seems bad bad news.
4321 ;; This cannot output into an f-reg because there is no way to be sure
4322 ;; of truncating in that case. Otherwise this is just like a simple move
4323 ;; insn. So we pretend we can output to a reg in order to get better
4324 ;; register preferencing, but we really use a stack slot.
4326 ;; Conversion from DFmode to SFmode.
4328 (define_expand "truncdfsf2"
4329 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4331 (match_operand:DF 1 "nonimmediate_operand" "")))]
4332 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4334 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4336 else if (flag_unsafe_math_optimizations)
4340 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4341 rtx temp = assign_386_stack_local (SFmode, slot);
4342 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4347 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4349 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4351 We do the conversion post reload to avoid producing of 128bit spills
4352 that might lead to ICE on 32bit target. The sequence unlikely combine
4355 [(set (match_operand:SF 0 "register_operand" "")
4357 (match_operand:DF 1 "nonimmediate_operand" "")))]
4358 "TARGET_USE_VECTOR_FP_CONVERTS
4359 && optimize_insn_for_speed_p ()
4360 && reload_completed && SSE_REG_P (operands[0])"
4363 (float_truncate:V2SF
4367 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4368 operands[3] = CONST0_RTX (V2SFmode);
4369 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4370 /* Use movsd for loading from memory, unpcklpd for registers.
4371 Try to avoid move when unpacking can be done in source, or SSE3
4372 movddup is available. */
4373 if (REG_P (operands[1]))
4376 && true_regnum (operands[0]) != true_regnum (operands[1])
4377 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4378 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4380 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4381 emit_move_insn (tmp, operands[1]);
4384 else if (!TARGET_SSE3)
4385 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4386 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4389 emit_insn (gen_sse2_loadlpd (operands[4],
4390 CONST0_RTX (V2DFmode), operands[1]));
4393 (define_expand "truncdfsf2_with_temp"
4394 [(parallel [(set (match_operand:SF 0 "" "")
4395 (float_truncate:SF (match_operand:DF 1 "" "")))
4396 (clobber (match_operand:SF 2 "" ""))])]
4399 (define_insn "*truncdfsf_fast_mixed"
4400 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4402 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4403 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4405 switch (which_alternative)
4408 return output_387_reg_move (insn, operands);
4410 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4415 [(set_attr "type" "fmov,ssecvt")
4416 (set_attr "prefix" "orig,maybe_vex")
4417 (set_attr "mode" "SF")])
4419 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4420 ;; because nothing we do here is unsafe.
4421 (define_insn "*truncdfsf_fast_sse"
4422 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4424 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4425 "TARGET_SSE2 && TARGET_SSE_MATH"
4426 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4427 [(set_attr "type" "ssecvt")
4428 (set_attr "prefix" "maybe_vex")
4429 (set_attr "mode" "SF")])
4431 (define_insn "*truncdfsf_fast_i387"
4432 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4434 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4435 "TARGET_80387 && flag_unsafe_math_optimizations"
4436 "* return output_387_reg_move (insn, operands);"
4437 [(set_attr "type" "fmov")
4438 (set_attr "mode" "SF")])
4440 (define_insn "*truncdfsf_mixed"
4441 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4443 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4444 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4445 "TARGET_MIX_SSE_I387"
4447 switch (which_alternative)
4450 return output_387_reg_move (insn, operands);
4455 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4460 [(set_attr "type" "fmov,multi,ssecvt")
4461 (set_attr "unit" "*,i387,*")
4462 (set_attr "prefix" "orig,orig,maybe_vex")
4463 (set_attr "mode" "SF")])
4465 (define_insn "*truncdfsf_i387"
4466 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4468 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4469 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4472 switch (which_alternative)
4475 return output_387_reg_move (insn, operands);
4483 [(set_attr "type" "fmov,multi")
4484 (set_attr "unit" "*,i387")
4485 (set_attr "mode" "SF")])
4487 (define_insn "*truncdfsf2_i387_1"
4488 [(set (match_operand:SF 0 "memory_operand" "=m")
4490 (match_operand:DF 1 "register_operand" "f")))]
4492 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4493 && !TARGET_MIX_SSE_I387"
4494 "* return output_387_reg_move (insn, operands);"
4495 [(set_attr "type" "fmov")
4496 (set_attr "mode" "SF")])
4499 [(set (match_operand:SF 0 "register_operand" "")
4501 (match_operand:DF 1 "fp_register_operand" "")))
4502 (clobber (match_operand 2 "" ""))]
4504 [(set (match_dup 2) (match_dup 1))
4505 (set (match_dup 0) (match_dup 2))]
4507 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4510 ;; Conversion from XFmode to {SF,DF}mode
4512 (define_expand "truncxf<mode>2"
4513 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4514 (float_truncate:MODEF
4515 (match_operand:XF 1 "register_operand" "")))
4516 (clobber (match_dup 2))])]
4519 if (flag_unsafe_math_optimizations)
4521 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4522 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4523 if (reg != operands[0])
4524 emit_move_insn (operands[0], reg);
4529 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4530 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4534 (define_insn "*truncxfsf2_mixed"
4535 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4537 (match_operand:XF 1 "register_operand" "f,f")))
4538 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4541 gcc_assert (!which_alternative);
4542 return output_387_reg_move (insn, operands);
4544 [(set_attr "type" "fmov,multi")
4545 (set_attr "unit" "*,i387")
4546 (set_attr "mode" "SF")])
4548 (define_insn "*truncxfdf2_mixed"
4549 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4551 (match_operand:XF 1 "register_operand" "f,f")))
4552 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4555 gcc_assert (!which_alternative);
4556 return output_387_reg_move (insn, operands);
4558 [(set_attr "type" "fmov,multi")
4559 (set_attr "unit" "*,i387")
4560 (set_attr "mode" "DF")])
4562 (define_insn "truncxf<mode>2_i387_noop"
4563 [(set (match_operand:MODEF 0 "register_operand" "=f")
4564 (float_truncate:MODEF
4565 (match_operand:XF 1 "register_operand" "f")))]
4566 "TARGET_80387 && flag_unsafe_math_optimizations"
4567 "* return output_387_reg_move (insn, operands);"
4568 [(set_attr "type" "fmov")
4569 (set_attr "mode" "<MODE>")])
4571 (define_insn "*truncxf<mode>2_i387"
4572 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4573 (float_truncate:MODEF
4574 (match_operand:XF 1 "register_operand" "f")))]
4576 "* return output_387_reg_move (insn, operands);"
4577 [(set_attr "type" "fmov")
4578 (set_attr "mode" "<MODE>")])
4581 [(set (match_operand:MODEF 0 "register_operand" "")
4582 (float_truncate:MODEF
4583 (match_operand:XF 1 "register_operand" "")))
4584 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4585 "TARGET_80387 && reload_completed"
4586 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4587 (set (match_dup 0) (match_dup 2))]
4591 [(set (match_operand:MODEF 0 "memory_operand" "")
4592 (float_truncate:MODEF
4593 (match_operand:XF 1 "register_operand" "")))
4594 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4596 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4599 ;; Signed conversion to DImode.
4601 (define_expand "fix_truncxfdi2"
4602 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4603 (fix:DI (match_operand:XF 1 "register_operand" "")))
4604 (clobber (reg:CC FLAGS_REG))])]
4609 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4614 (define_expand "fix_trunc<mode>di2"
4615 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4616 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4617 (clobber (reg:CC FLAGS_REG))])]
4618 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4621 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4623 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4626 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4628 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4629 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4630 if (out != operands[0])
4631 emit_move_insn (operands[0], out);
4636 ;; Signed conversion to SImode.
4638 (define_expand "fix_truncxfsi2"
4639 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4640 (fix:SI (match_operand:XF 1 "register_operand" "")))
4641 (clobber (reg:CC FLAGS_REG))])]
4646 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4651 (define_expand "fix_trunc<mode>si2"
4652 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4653 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4654 (clobber (reg:CC FLAGS_REG))])]
4655 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4658 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4660 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4663 if (SSE_FLOAT_MODE_P (<MODE>mode))
4665 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4666 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4667 if (out != operands[0])
4668 emit_move_insn (operands[0], out);
4673 ;; Signed conversion to HImode.
4675 (define_expand "fix_trunc<mode>hi2"
4676 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4677 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4678 (clobber (reg:CC FLAGS_REG))])]
4680 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4684 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4689 ;; Unsigned conversion to SImode.
4691 (define_expand "fixuns_trunc<mode>si2"
4693 [(set (match_operand:SI 0 "register_operand" "")
4695 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4697 (clobber (match_scratch:<ssevecmode> 3 ""))
4698 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4699 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701 enum machine_mode mode = <MODE>mode;
4702 enum machine_mode vecmode = <ssevecmode>mode;
4703 REAL_VALUE_TYPE TWO31r;
4706 if (optimize_insn_for_size_p ())
4709 real_ldexp (&TWO31r, &dconst1, 31);
4710 two31 = const_double_from_real_value (TWO31r, mode);
4711 two31 = ix86_build_const_vector (mode, true, two31);
4712 operands[2] = force_reg (vecmode, two31);
4715 (define_insn_and_split "*fixuns_trunc<mode>_1"
4716 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4718 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4719 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4720 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4721 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4722 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4723 && optimize_function_for_speed_p (cfun)"
4725 "&& reload_completed"
4728 ix86_split_convert_uns_si_sse (operands);
4732 ;; Unsigned conversion to HImode.
4733 ;; Without these patterns, we'll try the unsigned SI conversion which
4734 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4736 (define_expand "fixuns_trunc<mode>hi2"
4738 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4739 (set (match_operand:HI 0 "nonimmediate_operand" "")
4740 (subreg:HI (match_dup 2) 0))]
4741 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4742 "operands[2] = gen_reg_rtx (SImode);")
4744 ;; When SSE is available, it is always faster to use it!
4745 (define_insn "fix_trunc<mode>di_sse"
4746 [(set (match_operand:DI 0 "register_operand" "=r,r")
4747 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4748 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4749 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4750 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4751 [(set_attr "type" "sseicvt")
4752 (set_attr "prefix" "maybe_vex")
4753 (set_attr "mode" "<MODE>")
4754 (set_attr "athlon_decode" "double,vector")
4755 (set_attr "amdfam10_decode" "double,double")])
4757 (define_insn "fix_trunc<mode>si_sse"
4758 [(set (match_operand:SI 0 "register_operand" "=r,r")
4759 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4760 "SSE_FLOAT_MODE_P (<MODE>mode)
4761 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4762 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4763 [(set_attr "type" "sseicvt")
4764 (set_attr "prefix" "maybe_vex")
4765 (set_attr "mode" "<MODE>")
4766 (set_attr "athlon_decode" "double,vector")
4767 (set_attr "amdfam10_decode" "double,double")])
4769 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4771 [(set (match_operand:MODEF 0 "register_operand" "")
4772 (match_operand:MODEF 1 "memory_operand" ""))
4773 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4774 (fix:SSEMODEI24 (match_dup 0)))]
4775 "TARGET_SHORTEN_X87_SSE
4776 && peep2_reg_dead_p (2, operands[0])"
4777 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4780 ;; Avoid vector decoded forms of the instruction.
4782 [(match_scratch:DF 2 "Y2")
4783 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4784 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4785 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4786 [(set (match_dup 2) (match_dup 1))
4787 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4791 [(match_scratch:SF 2 "x")
4792 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4793 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4794 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4795 [(set (match_dup 2) (match_dup 1))
4796 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4799 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4800 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4801 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4802 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4804 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4805 && (TARGET_64BIT || <MODE>mode != DImode))
4807 && !(reload_completed || reload_in_progress)"
4812 if (memory_operand (operands[0], VOIDmode))
4813 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4816 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4817 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4823 [(set_attr "type" "fisttp")
4824 (set_attr "mode" "<MODE>")])
4826 (define_insn "fix_trunc<mode>_i387_fisttp"
4827 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4828 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4829 (clobber (match_scratch:XF 2 "=&1f"))]
4830 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4832 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4833 && (TARGET_64BIT || <MODE>mode != DImode))
4834 && TARGET_SSE_MATH)"
4835 "* return output_fix_trunc (insn, operands, 1);"
4836 [(set_attr "type" "fisttp")
4837 (set_attr "mode" "<MODE>")])
4839 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4840 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4841 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4842 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4843 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4844 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4846 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4847 && (TARGET_64BIT || <MODE>mode != DImode))
4848 && TARGET_SSE_MATH)"
4850 [(set_attr "type" "fisttp")
4851 (set_attr "mode" "<MODE>")])
4854 [(set (match_operand:X87MODEI 0 "register_operand" "")
4855 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4856 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4857 (clobber (match_scratch 3 ""))]
4859 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4860 (clobber (match_dup 3))])
4861 (set (match_dup 0) (match_dup 2))]
4865 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4866 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4867 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4868 (clobber (match_scratch 3 ""))]
4870 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4871 (clobber (match_dup 3))])]
4874 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4875 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4876 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4877 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4878 ;; function in i386.c.
4879 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4880 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4881 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4882 (clobber (reg:CC FLAGS_REG))]
4883 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4885 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4886 && (TARGET_64BIT || <MODE>mode != DImode))
4887 && !(reload_completed || reload_in_progress)"
4892 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4894 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4895 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4896 if (memory_operand (operands[0], VOIDmode))
4897 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4898 operands[2], operands[3]));
4901 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4902 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4903 operands[2], operands[3],
4908 [(set_attr "type" "fistp")
4909 (set_attr "i387_cw" "trunc")
4910 (set_attr "mode" "<MODE>")])
4912 (define_insn "fix_truncdi_i387"
4913 [(set (match_operand:DI 0 "memory_operand" "=m")
4914 (fix:DI (match_operand 1 "register_operand" "f")))
4915 (use (match_operand:HI 2 "memory_operand" "m"))
4916 (use (match_operand:HI 3 "memory_operand" "m"))
4917 (clobber (match_scratch:XF 4 "=&1f"))]
4918 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4920 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4921 "* return output_fix_trunc (insn, operands, 0);"
4922 [(set_attr "type" "fistp")
4923 (set_attr "i387_cw" "trunc")
4924 (set_attr "mode" "DI")])
4926 (define_insn "fix_truncdi_i387_with_temp"
4927 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4928 (fix:DI (match_operand 1 "register_operand" "f,f")))
4929 (use (match_operand:HI 2 "memory_operand" "m,m"))
4930 (use (match_operand:HI 3 "memory_operand" "m,m"))
4931 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4932 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4933 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4935 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937 [(set_attr "type" "fistp")
4938 (set_attr "i387_cw" "trunc")
4939 (set_attr "mode" "DI")])
4942 [(set (match_operand:DI 0 "register_operand" "")
4943 (fix:DI (match_operand 1 "register_operand" "")))
4944 (use (match_operand:HI 2 "memory_operand" ""))
4945 (use (match_operand:HI 3 "memory_operand" ""))
4946 (clobber (match_operand:DI 4 "memory_operand" ""))
4947 (clobber (match_scratch 5 ""))]
4949 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4952 (clobber (match_dup 5))])
4953 (set (match_dup 0) (match_dup 4))]
4957 [(set (match_operand:DI 0 "memory_operand" "")
4958 (fix:DI (match_operand 1 "register_operand" "")))
4959 (use (match_operand:HI 2 "memory_operand" ""))
4960 (use (match_operand:HI 3 "memory_operand" ""))
4961 (clobber (match_operand:DI 4 "memory_operand" ""))
4962 (clobber (match_scratch 5 ""))]
4964 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4967 (clobber (match_dup 5))])]
4970 (define_insn "fix_trunc<mode>_i387"
4971 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4972 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4973 (use (match_operand:HI 2 "memory_operand" "m"))
4974 (use (match_operand:HI 3 "memory_operand" "m"))]
4975 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4978 "* return output_fix_trunc (insn, operands, 0);"
4979 [(set_attr "type" "fistp")
4980 (set_attr "i387_cw" "trunc")
4981 (set_attr "mode" "<MODE>")])
4983 (define_insn "fix_trunc<mode>_i387_with_temp"
4984 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4985 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4986 (use (match_operand:HI 2 "memory_operand" "m,m"))
4987 (use (match_operand:HI 3 "memory_operand" "m,m"))
4988 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4989 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4991 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4993 [(set_attr "type" "fistp")
4994 (set_attr "i387_cw" "trunc")
4995 (set_attr "mode" "<MODE>")])
4998 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4999 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5000 (use (match_operand:HI 2 "memory_operand" ""))
5001 (use (match_operand:HI 3 "memory_operand" ""))
5002 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5004 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5006 (use (match_dup 3))])
5007 (set (match_dup 0) (match_dup 4))]
5011 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5012 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5013 (use (match_operand:HI 2 "memory_operand" ""))
5014 (use (match_operand:HI 3 "memory_operand" ""))
5015 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5017 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5019 (use (match_dup 3))])]
5022 (define_insn "x86_fnstcw_1"
5023 [(set (match_operand:HI 0 "memory_operand" "=m")
5024 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5027 [(set_attr "length" "2")
5028 (set_attr "mode" "HI")
5029 (set_attr "unit" "i387")])
5031 (define_insn "x86_fldcw_1"
5032 [(set (reg:HI FPCR_REG)
5033 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5036 [(set_attr "length" "2")
5037 (set_attr "mode" "HI")
5038 (set_attr "unit" "i387")
5039 (set_attr "athlon_decode" "vector")
5040 (set_attr "amdfam10_decode" "vector")])
5042 ;; Conversion between fixed point and floating point.
5044 ;; Even though we only accept memory inputs, the backend _really_
5045 ;; wants to be able to do this between registers.
5047 (define_expand "floathi<mode>2"
5048 [(set (match_operand:X87MODEF 0 "register_operand" "")
5049 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5052 || TARGET_MIX_SSE_I387)"
5055 ;; Pre-reload splitter to add memory clobber to the pattern.
5056 (define_insn_and_split "*floathi<mode>2_1"
5057 [(set (match_operand:X87MODEF 0 "register_operand" "")
5058 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5061 || TARGET_MIX_SSE_I387)
5062 && !(reload_completed || reload_in_progress)"
5065 [(parallel [(set (match_dup 0)
5066 (float:X87MODEF (match_dup 1)))
5067 (clobber (match_dup 2))])]
5068 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5070 (define_insn "*floathi<mode>2_i387_with_temp"
5071 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5072 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5073 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5076 || TARGET_MIX_SSE_I387)"
5078 [(set_attr "type" "fmov,multi")
5079 (set_attr "mode" "<MODE>")
5080 (set_attr "unit" "*,i387")
5081 (set_attr "fp_int_src" "true")])
5083 (define_insn "*floathi<mode>2_i387"
5084 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5085 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5087 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5088 || TARGET_MIX_SSE_I387)"
5090 [(set_attr "type" "fmov")
5091 (set_attr "mode" "<MODE>")
5092 (set_attr "fp_int_src" "true")])
5095 [(set (match_operand:X87MODEF 0 "register_operand" "")
5096 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5097 (clobber (match_operand:HI 2 "memory_operand" ""))]
5099 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5100 || TARGET_MIX_SSE_I387)
5101 && reload_completed"
5102 [(set (match_dup 2) (match_dup 1))
5103 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5107 [(set (match_operand:X87MODEF 0 "register_operand" "")
5108 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5109 (clobber (match_operand:HI 2 "memory_operand" ""))]
5111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5112 || TARGET_MIX_SSE_I387)
5113 && reload_completed"
5114 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5117 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5118 [(set (match_operand:X87MODEF 0 "register_operand" "")
5120 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5122 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5123 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5126 ;; Pre-reload splitter to add memory clobber to the pattern.
5127 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5128 [(set (match_operand:X87MODEF 0 "register_operand" "")
5129 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5131 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5132 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5133 || TARGET_MIX_SSE_I387))
5134 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5135 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5136 && ((<SSEMODEI24:MODE>mode == SImode
5137 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5138 && optimize_function_for_speed_p (cfun)
5139 && flag_trapping_math)
5140 || !(TARGET_INTER_UNIT_CONVERSIONS
5141 || optimize_function_for_size_p (cfun)))))
5142 && !(reload_completed || reload_in_progress)"
5145 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5146 (clobber (match_dup 2))])]
5148 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5150 /* Avoid store forwarding (partial memory) stall penalty
5151 by passing DImode value through XMM registers. */
5152 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5153 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5154 && optimize_function_for_speed_p (cfun))
5156 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5163 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5164 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5166 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5167 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5168 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5169 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5171 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5172 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5173 (set_attr "unit" "*,i387,*,*,*")
5174 (set_attr "athlon_decode" "*,*,double,direct,double")
5175 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5176 (set_attr "fp_int_src" "true")])
5178 (define_insn "*floatsi<mode>2_vector_mixed"
5179 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5180 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5181 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5182 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5186 [(set_attr "type" "fmov,sseicvt")
5187 (set_attr "mode" "<MODE>,<ssevecmode>")
5188 (set_attr "unit" "i387,*")
5189 (set_attr "athlon_decode" "*,direct")
5190 (set_attr "amdfam10_decode" "*,double")
5191 (set_attr "fp_int_src" "true")])
5193 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5194 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5196 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5197 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5198 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5199 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5201 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5202 (set_attr "mode" "<MODEF:MODE>")
5203 (set_attr "unit" "*,i387,*,*")
5204 (set_attr "athlon_decode" "*,*,double,direct")
5205 (set_attr "amdfam10_decode" "*,*,vector,double")
5206 (set_attr "fp_int_src" "true")])
5209 [(set (match_operand:MODEF 0 "register_operand" "")
5210 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5211 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5212 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5214 && TARGET_INTER_UNIT_CONVERSIONS
5216 && (SSE_REG_P (operands[0])
5217 || (GET_CODE (operands[0]) == SUBREG
5218 && SSE_REG_P (operands[0])))"
5219 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5223 [(set (match_operand:MODEF 0 "register_operand" "")
5224 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5225 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5226 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5227 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5228 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5230 && (SSE_REG_P (operands[0])
5231 || (GET_CODE (operands[0]) == SUBREG
5232 && SSE_REG_P (operands[0])))"
5233 [(set (match_dup 2) (match_dup 1))
5234 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5237 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5238 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5240 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5241 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5242 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5243 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5246 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5247 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5248 [(set_attr "type" "fmov,sseicvt,sseicvt")
5249 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5250 (set_attr "mode" "<MODEF:MODE>")
5251 (set_attr "unit" "i387,*,*")
5252 (set_attr "athlon_decode" "*,double,direct")
5253 (set_attr "amdfam10_decode" "*,vector,double")
5254 (set_attr "fp_int_src" "true")])
5256 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5257 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5259 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5260 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5261 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5262 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5265 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5266 [(set_attr "type" "fmov,sseicvt")
5267 (set_attr "prefix" "orig,maybe_vex")
5268 (set_attr "mode" "<MODEF:MODE>")
5269 (set_attr "athlon_decode" "*,direct")
5270 (set_attr "amdfam10_decode" "*,double")
5271 (set_attr "fp_int_src" "true")])
5273 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5274 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5276 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5277 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5278 "TARGET_SSE2 && TARGET_SSE_MATH
5279 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5281 [(set_attr "type" "sseicvt")
5282 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5283 (set_attr "athlon_decode" "double,direct,double")
5284 (set_attr "amdfam10_decode" "vector,double,double")
5285 (set_attr "fp_int_src" "true")])
5287 (define_insn "*floatsi<mode>2_vector_sse"
5288 [(set (match_operand:MODEF 0 "register_operand" "=x")
5289 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5290 "TARGET_SSE2 && TARGET_SSE_MATH
5291 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5293 [(set_attr "type" "sseicvt")
5294 (set_attr "mode" "<MODE>")
5295 (set_attr "athlon_decode" "direct")
5296 (set_attr "amdfam10_decode" "double")
5297 (set_attr "fp_int_src" "true")])
5300 [(set (match_operand:MODEF 0 "register_operand" "")
5301 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5302 (clobber (match_operand:SI 2 "memory_operand" ""))]
5303 "TARGET_SSE2 && TARGET_SSE_MATH
5304 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5306 && (SSE_REG_P (operands[0])
5307 || (GET_CODE (operands[0]) == SUBREG
5308 && SSE_REG_P (operands[0])))"
5311 rtx op1 = operands[1];
5313 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5315 if (GET_CODE (op1) == SUBREG)
5316 op1 = SUBREG_REG (op1);
5318 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5320 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5321 emit_insn (gen_sse2_loadld (operands[4],
5322 CONST0_RTX (V4SImode), operands[1]));
5324 /* We can ignore possible trapping value in the
5325 high part of SSE register for non-trapping math. */
5326 else if (SSE_REG_P (op1) && !flag_trapping_math)
5327 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5330 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5331 emit_move_insn (operands[2], operands[1]);
5332 emit_insn (gen_sse2_loadld (operands[4],
5333 CONST0_RTX (V4SImode), operands[2]));
5336 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5341 [(set (match_operand:MODEF 0 "register_operand" "")
5342 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5343 (clobber (match_operand:SI 2 "memory_operand" ""))]
5344 "TARGET_SSE2 && TARGET_SSE_MATH
5345 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5347 && (SSE_REG_P (operands[0])
5348 || (GET_CODE (operands[0]) == SUBREG
5349 && SSE_REG_P (operands[0])))"
5352 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5354 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5356 emit_insn (gen_sse2_loadld (operands[4],
5357 CONST0_RTX (V4SImode), operands[1]));
5359 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5364 [(set (match_operand:MODEF 0 "register_operand" "")
5365 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5366 "TARGET_SSE2 && TARGET_SSE_MATH
5367 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5369 && (SSE_REG_P (operands[0])
5370 || (GET_CODE (operands[0]) == SUBREG
5371 && SSE_REG_P (operands[0])))"
5374 rtx op1 = operands[1];
5376 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5378 if (GET_CODE (op1) == SUBREG)
5379 op1 = SUBREG_REG (op1);
5381 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5383 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5384 emit_insn (gen_sse2_loadld (operands[4],
5385 CONST0_RTX (V4SImode), operands[1]));
5387 /* We can ignore possible trapping value in the
5388 high part of SSE register for non-trapping math. */
5389 else if (SSE_REG_P (op1) && !flag_trapping_math)
5390 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5394 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5399 [(set (match_operand:MODEF 0 "register_operand" "")
5400 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5401 "TARGET_SSE2 && TARGET_SSE_MATH
5402 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5404 && (SSE_REG_P (operands[0])
5405 || (GET_CODE (operands[0]) == SUBREG
5406 && SSE_REG_P (operands[0])))"
5409 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5411 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5413 emit_insn (gen_sse2_loadld (operands[4],
5414 CONST0_RTX (V4SImode), operands[1]));
5416 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5420 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5421 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5423 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5424 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5425 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5426 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5428 [(set_attr "type" "sseicvt")
5429 (set_attr "mode" "<MODEF:MODE>")
5430 (set_attr "athlon_decode" "double,direct")
5431 (set_attr "amdfam10_decode" "vector,double")
5432 (set_attr "fp_int_src" "true")])
5434 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5435 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5437 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5438 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5439 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5440 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5441 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5442 [(set_attr "type" "sseicvt")
5443 (set_attr "prefix" "maybe_vex")
5444 (set_attr "mode" "<MODEF:MODE>")
5445 (set_attr "athlon_decode" "double,direct")
5446 (set_attr "amdfam10_decode" "vector,double")
5447 (set_attr "fp_int_src" "true")])
5450 [(set (match_operand:MODEF 0 "register_operand" "")
5451 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5452 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5453 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5454 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5455 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5457 && (SSE_REG_P (operands[0])
5458 || (GET_CODE (operands[0]) == SUBREG
5459 && SSE_REG_P (operands[0])))"
5460 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5463 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5464 [(set (match_operand:MODEF 0 "register_operand" "=x")
5466 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5467 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5468 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5469 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5470 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5471 [(set_attr "type" "sseicvt")
5472 (set_attr "prefix" "maybe_vex")
5473 (set_attr "mode" "<MODEF:MODE>")
5474 (set_attr "athlon_decode" "direct")
5475 (set_attr "amdfam10_decode" "double")
5476 (set_attr "fp_int_src" "true")])
5479 [(set (match_operand:MODEF 0 "register_operand" "")
5480 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5481 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5482 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5483 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5484 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5486 && (SSE_REG_P (operands[0])
5487 || (GET_CODE (operands[0]) == SUBREG
5488 && SSE_REG_P (operands[0])))"
5489 [(set (match_dup 2) (match_dup 1))
5490 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5494 [(set (match_operand:MODEF 0 "register_operand" "")
5495 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5496 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5497 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5498 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500 && (SSE_REG_P (operands[0])
5501 || (GET_CODE (operands[0]) == SUBREG
5502 && SSE_REG_P (operands[0])))"
5503 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5506 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5507 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5509 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5510 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5515 [(set_attr "type" "fmov,multi")
5516 (set_attr "mode" "<X87MODEF:MODE>")
5517 (set_attr "unit" "*,i387")
5518 (set_attr "fp_int_src" "true")])
5520 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5521 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5523 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5526 [(set_attr "type" "fmov")
5527 (set_attr "mode" "<X87MODEF:MODE>")
5528 (set_attr "fp_int_src" "true")])
5531 [(set (match_operand:X87MODEF 0 "register_operand" "")
5532 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5533 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5536 && FP_REG_P (operands[0])"
5537 [(set (match_dup 2) (match_dup 1))
5538 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5542 [(set (match_operand:X87MODEF 0 "register_operand" "")
5543 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5544 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5547 && FP_REG_P (operands[0])"
5548 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5551 ;; Avoid store forwarding (partial memory) stall penalty
5552 ;; by passing DImode value through XMM registers. */
5554 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5555 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5557 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5558 (clobber (match_scratch:V4SI 3 "=X,x"))
5559 (clobber (match_scratch:V4SI 4 "=X,x"))
5560 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5561 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5562 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5564 [(set_attr "type" "multi")
5565 (set_attr "mode" "<X87MODEF:MODE>")
5566 (set_attr "unit" "i387")
5567 (set_attr "fp_int_src" "true")])
5570 [(set (match_operand:X87MODEF 0 "register_operand" "")
5571 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5572 (clobber (match_scratch:V4SI 3 ""))
5573 (clobber (match_scratch:V4SI 4 ""))
5574 (clobber (match_operand:DI 2 "memory_operand" ""))]
5575 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5576 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5578 && FP_REG_P (operands[0])"
5579 [(set (match_dup 2) (match_dup 3))
5580 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5582 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5583 Assemble the 64-bit DImode value in an xmm register. */
5584 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5585 gen_rtx_SUBREG (SImode, operands[1], 0)));
5586 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5587 gen_rtx_SUBREG (SImode, operands[1], 4)));
5588 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5590 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5594 [(set (match_operand:X87MODEF 0 "register_operand" "")
5595 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5596 (clobber (match_scratch:V4SI 3 ""))
5597 (clobber (match_scratch:V4SI 4 ""))
5598 (clobber (match_operand:DI 2 "memory_operand" ""))]
5599 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5600 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5602 && FP_REG_P (operands[0])"
5603 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5606 ;; Avoid store forwarding (partial memory) stall penalty by extending
5607 ;; SImode value to DImode through XMM register instead of pushing two
5608 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5609 ;; targets benefit from this optimization. Also note that fild
5610 ;; loads from memory only.
5612 (define_insn "*floatunssi<mode>2_1"
5613 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5614 (unsigned_float:X87MODEF
5615 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5616 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5617 (clobber (match_scratch:SI 3 "=X,x"))]
5619 && TARGET_80387 && TARGET_SSE"
5621 [(set_attr "type" "multi")
5622 (set_attr "mode" "<MODE>")])
5625 [(set (match_operand:X87MODEF 0 "register_operand" "")
5626 (unsigned_float:X87MODEF
5627 (match_operand:SI 1 "register_operand" "")))
5628 (clobber (match_operand:DI 2 "memory_operand" ""))
5629 (clobber (match_scratch:SI 3 ""))]
5631 && TARGET_80387 && TARGET_SSE
5632 && reload_completed"
5633 [(set (match_dup 2) (match_dup 1))
5635 (float:X87MODEF (match_dup 2)))]
5636 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5639 [(set (match_operand:X87MODEF 0 "register_operand" "")
5640 (unsigned_float:X87MODEF
5641 (match_operand:SI 1 "memory_operand" "")))
5642 (clobber (match_operand:DI 2 "memory_operand" ""))
5643 (clobber (match_scratch:SI 3 ""))]
5645 && TARGET_80387 && TARGET_SSE
5646 && reload_completed"
5647 [(set (match_dup 2) (match_dup 3))
5649 (float:X87MODEF (match_dup 2)))]
5651 emit_move_insn (operands[3], operands[1]);
5652 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5655 (define_expand "floatunssi<mode>2"
5657 [(set (match_operand:X87MODEF 0 "register_operand" "")
5658 (unsigned_float:X87MODEF
5659 (match_operand:SI 1 "nonimmediate_operand" "")))
5660 (clobber (match_dup 2))
5661 (clobber (match_scratch:SI 3 ""))])]
5663 && ((TARGET_80387 && TARGET_SSE)
5664 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5666 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5668 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5673 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5674 operands[2] = assign_386_stack_local (DImode, slot);
5678 (define_expand "floatunsdisf2"
5679 [(use (match_operand:SF 0 "register_operand" ""))
5680 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5681 "TARGET_64BIT && TARGET_SSE_MATH"
5682 "x86_emit_floatuns (operands); DONE;")
5684 (define_expand "floatunsdidf2"
5685 [(use (match_operand:DF 0 "register_operand" ""))
5686 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5687 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5688 && TARGET_SSE2 && TARGET_SSE_MATH"
5691 x86_emit_floatuns (operands);
5693 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5699 ;; %%% splits for addditi3
5701 (define_expand "addti3"
5702 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5703 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5704 (match_operand:TI 2 "x86_64_general_operand" "")))]
5706 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5708 (define_insn "*addti3_1"
5709 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5710 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5711 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5712 (clobber (reg:CC FLAGS_REG))]
5713 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5717 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5718 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5719 (match_operand:TI 2 "x86_64_general_operand" "")))
5720 (clobber (reg:CC FLAGS_REG))]
5721 "TARGET_64BIT && reload_completed"
5722 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5724 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5725 (parallel [(set (match_dup 3)
5726 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5729 (clobber (reg:CC FLAGS_REG))])]
5730 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5732 ;; %%% splits for addsidi3
5733 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5734 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5735 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5737 (define_expand "adddi3"
5738 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5739 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5740 (match_operand:DI 2 "x86_64_general_operand" "")))]
5742 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5744 (define_insn "*adddi3_1"
5745 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5746 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5747 (match_operand:DI 2 "general_operand" "roiF,riF")))
5748 (clobber (reg:CC FLAGS_REG))]
5749 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5753 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5754 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5755 (match_operand:DI 2 "general_operand" "")))
5756 (clobber (reg:CC FLAGS_REG))]
5757 "!TARGET_64BIT && reload_completed"
5758 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5760 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5761 (parallel [(set (match_dup 3)
5762 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5765 (clobber (reg:CC FLAGS_REG))])]
5766 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5768 (define_insn "adddi3_carry_rex64"
5769 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5770 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5771 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5772 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5773 (clobber (reg:CC FLAGS_REG))]
5774 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5775 "adc{q}\t{%2, %0|%0, %2}"
5776 [(set_attr "type" "alu")
5777 (set_attr "pent_pair" "pu")
5778 (set_attr "mode" "DI")])
5780 (define_insn "*adddi3_cc_rex64"
5781 [(set (reg:CC FLAGS_REG)
5782 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5783 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5785 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5786 (plus:DI (match_dup 1) (match_dup 2)))]
5787 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5788 "add{q}\t{%2, %0|%0, %2}"
5789 [(set_attr "type" "alu")
5790 (set_attr "mode" "DI")])
5792 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5793 [(set (reg:CCC FLAGS_REG)
5796 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5797 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5799 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5800 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5801 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5802 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5803 [(set_attr "type" "alu")
5804 (set_attr "mode" "<MODE>")])
5806 (define_insn "*add<mode>3_cconly_overflow"
5807 [(set (reg:CCC FLAGS_REG)
5809 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5810 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5812 (clobber (match_scratch:SWI 0 "=<r>"))]
5813 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5814 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5815 [(set_attr "type" "alu")
5816 (set_attr "mode" "<MODE>")])
5818 (define_insn "*sub<mode>3_cconly_overflow"
5819 [(set (reg:CCC FLAGS_REG)
5821 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5822 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5825 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5826 [(set_attr "type" "icmp")
5827 (set_attr "mode" "<MODE>")])
5829 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5830 [(set (reg:CCC FLAGS_REG)
5832 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5833 (match_operand:SI 2 "general_operand" "g"))
5835 (set (match_operand:DI 0 "register_operand" "=r")
5836 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5837 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5838 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5839 [(set_attr "type" "alu")
5840 (set_attr "mode" "SI")])
5842 (define_insn "addqi3_carry"
5843 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5844 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5845 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5846 (match_operand:QI 2 "general_operand" "qn,qm")))
5847 (clobber (reg:CC FLAGS_REG))]
5848 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5849 "adc{b}\t{%2, %0|%0, %2}"
5850 [(set_attr "type" "alu")
5851 (set_attr "pent_pair" "pu")
5852 (set_attr "mode" "QI")])
5854 (define_insn "addhi3_carry"
5855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5856 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5857 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5858 (match_operand:HI 2 "general_operand" "rn,rm")))
5859 (clobber (reg:CC FLAGS_REG))]
5860 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5861 "adc{w}\t{%2, %0|%0, %2}"
5862 [(set_attr "type" "alu")
5863 (set_attr "pent_pair" "pu")
5864 (set_attr "mode" "HI")])
5866 (define_insn "addsi3_carry"
5867 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5868 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5869 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5870 (match_operand:SI 2 "general_operand" "ri,rm")))
5871 (clobber (reg:CC FLAGS_REG))]
5872 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5873 "adc{l}\t{%2, %0|%0, %2}"
5874 [(set_attr "type" "alu")
5875 (set_attr "pent_pair" "pu")
5876 (set_attr "mode" "SI")])
5878 (define_insn "*addsi3_carry_zext"
5879 [(set (match_operand:DI 0 "register_operand" "=r")
5881 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5882 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5883 (match_operand:SI 2 "general_operand" "g"))))
5884 (clobber (reg:CC FLAGS_REG))]
5885 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5886 "adc{l}\t{%2, %k0|%k0, %2}"
5887 [(set_attr "type" "alu")
5888 (set_attr "pent_pair" "pu")
5889 (set_attr "mode" "SI")])
5891 (define_insn "*addsi3_cc"
5892 [(set (reg:CC FLAGS_REG)
5893 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5894 (match_operand:SI 2 "general_operand" "ri,rm")]
5896 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5897 (plus:SI (match_dup 1) (match_dup 2)))]
5898 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5899 "add{l}\t{%2, %0|%0, %2}"
5900 [(set_attr "type" "alu")
5901 (set_attr "mode" "SI")])
5903 (define_insn "addqi3_cc"
5904 [(set (reg:CC FLAGS_REG)
5905 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5906 (match_operand:QI 2 "general_operand" "qn,qm")]
5908 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5909 (plus:QI (match_dup 1) (match_dup 2)))]
5910 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5911 "add{b}\t{%2, %0|%0, %2}"
5912 [(set_attr "type" "alu")
5913 (set_attr "mode" "QI")])
5915 (define_expand "addsi3"
5916 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5917 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5918 (match_operand:SI 2 "general_operand" "")))]
5920 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5922 (define_insn "*lea_1"
5923 [(set (match_operand:SI 0 "register_operand" "=r")
5924 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5926 "lea{l}\t{%a1, %0|%0, %a1}"
5927 [(set_attr "type" "lea")
5928 (set_attr "mode" "SI")])
5930 (define_insn "*lea_1_rex64"
5931 [(set (match_operand:SI 0 "register_operand" "=r")
5932 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5934 "lea{l}\t{%a1, %0|%0, %a1}"
5935 [(set_attr "type" "lea")
5936 (set_attr "mode" "SI")])
5938 (define_insn "*lea_1_zext"
5939 [(set (match_operand:DI 0 "register_operand" "=r")
5941 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5943 "lea{l}\t{%a1, %k0|%k0, %a1}"
5944 [(set_attr "type" "lea")
5945 (set_attr "mode" "SI")])
5947 (define_insn "*lea_2_rex64"
5948 [(set (match_operand:DI 0 "register_operand" "=r")
5949 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5951 "lea{q}\t{%a1, %0|%0, %a1}"
5952 [(set_attr "type" "lea")
5953 (set_attr "mode" "DI")])
5955 ;; The lea patterns for non-Pmodes needs to be matched by several
5956 ;; insns converted to real lea by splitters.
5958 (define_insn_and_split "*lea_general_1"
5959 [(set (match_operand 0 "register_operand" "=r")
5960 (plus (plus (match_operand 1 "index_register_operand" "l")
5961 (match_operand 2 "register_operand" "r"))
5962 (match_operand 3 "immediate_operand" "i")))]
5963 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5964 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5965 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5966 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5967 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5968 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5969 || GET_MODE (operands[3]) == VOIDmode)"
5971 "&& reload_completed"
5975 operands[0] = gen_lowpart (SImode, operands[0]);
5976 operands[1] = gen_lowpart (Pmode, operands[1]);
5977 operands[2] = gen_lowpart (Pmode, operands[2]);
5978 operands[3] = gen_lowpart (Pmode, operands[3]);
5979 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5981 if (Pmode != SImode)
5982 pat = gen_rtx_SUBREG (SImode, pat, 0);
5983 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5986 [(set_attr "type" "lea")
5987 (set_attr "mode" "SI")])
5989 (define_insn_and_split "*lea_general_1_zext"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5992 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5993 (match_operand:SI 2 "register_operand" "r"))
5994 (match_operand:SI 3 "immediate_operand" "i"))))]
5997 "&& reload_completed"
5999 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6001 (match_dup 3)) 0)))]
6003 operands[1] = gen_lowpart (Pmode, operands[1]);
6004 operands[2] = gen_lowpart (Pmode, operands[2]);
6005 operands[3] = gen_lowpart (Pmode, operands[3]);
6007 [(set_attr "type" "lea")
6008 (set_attr "mode" "SI")])
6010 (define_insn_and_split "*lea_general_2"
6011 [(set (match_operand 0 "register_operand" "=r")
6012 (plus (mult (match_operand 1 "index_register_operand" "l")
6013 (match_operand 2 "const248_operand" "i"))
6014 (match_operand 3 "nonmemory_operand" "ri")))]
6015 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6016 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6017 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6018 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6019 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6020 || GET_MODE (operands[3]) == VOIDmode)"
6022 "&& reload_completed"
6026 operands[0] = gen_lowpart (SImode, operands[0]);
6027 operands[1] = gen_lowpart (Pmode, operands[1]);
6028 operands[3] = gen_lowpart (Pmode, operands[3]);
6029 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6031 if (Pmode != SImode)
6032 pat = gen_rtx_SUBREG (SImode, pat, 0);
6033 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6036 [(set_attr "type" "lea")
6037 (set_attr "mode" "SI")])
6039 (define_insn_and_split "*lea_general_2_zext"
6040 [(set (match_operand:DI 0 "register_operand" "=r")
6042 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6043 (match_operand:SI 2 "const248_operand" "n"))
6044 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6047 "&& reload_completed"
6049 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6051 (match_dup 3)) 0)))]
6053 operands[1] = gen_lowpart (Pmode, operands[1]);
6054 operands[3] = gen_lowpart (Pmode, operands[3]);
6056 [(set_attr "type" "lea")
6057 (set_attr "mode" "SI")])
6059 (define_insn_and_split "*lea_general_3"
6060 [(set (match_operand 0 "register_operand" "=r")
6061 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6062 (match_operand 2 "const248_operand" "i"))
6063 (match_operand 3 "register_operand" "r"))
6064 (match_operand 4 "immediate_operand" "i")))]
6065 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6066 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6067 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6068 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6069 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6071 "&& reload_completed"
6075 operands[0] = gen_lowpart (SImode, operands[0]);
6076 operands[1] = gen_lowpart (Pmode, operands[1]);
6077 operands[3] = gen_lowpart (Pmode, operands[3]);
6078 operands[4] = gen_lowpart (Pmode, operands[4]);
6079 pat = gen_rtx_PLUS (Pmode,
6080 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6084 if (Pmode != SImode)
6085 pat = gen_rtx_SUBREG (SImode, pat, 0);
6086 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6089 [(set_attr "type" "lea")
6090 (set_attr "mode" "SI")])
6092 (define_insn_and_split "*lea_general_3_zext"
6093 [(set (match_operand:DI 0 "register_operand" "=r")
6095 (plus:SI (plus:SI (mult:SI
6096 (match_operand:SI 1 "index_register_operand" "l")
6097 (match_operand:SI 2 "const248_operand" "n"))
6098 (match_operand:SI 3 "register_operand" "r"))
6099 (match_operand:SI 4 "immediate_operand" "i"))))]
6102 "&& reload_completed"
6104 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6107 (match_dup 4)) 0)))]
6109 operands[1] = gen_lowpart (Pmode, operands[1]);
6110 operands[3] = gen_lowpart (Pmode, operands[3]);
6111 operands[4] = gen_lowpart (Pmode, operands[4]);
6113 [(set_attr "type" "lea")
6114 (set_attr "mode" "SI")])
6116 (define_insn "*adddi_1_rex64"
6117 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6118 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6119 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6120 (clobber (reg:CC FLAGS_REG))]
6121 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6123 switch (get_attr_type (insn))
6126 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6127 return "lea{q}\t{%a2, %0|%0, %a2}";
6130 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6131 if (operands[2] == const1_rtx)
6132 return "inc{q}\t%0";
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return "dec{q}\t%0";
6140 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6142 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6143 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6144 if (CONST_INT_P (operands[2])
6145 /* Avoid overflows. */
6146 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6147 && (INTVAL (operands[2]) == 128
6148 || (INTVAL (operands[2]) < 0
6149 && INTVAL (operands[2]) != -128)))
6151 operands[2] = GEN_INT (-INTVAL (operands[2]));
6152 return "sub{q}\t{%2, %0|%0, %2}";
6154 return "add{q}\t{%2, %0|%0, %2}";
6158 (cond [(eq_attr "alternative" "2")
6159 (const_string "lea")
6160 ; Current assemblers are broken and do not allow @GOTOFF in
6161 ; ought but a memory context.
6162 (match_operand:DI 2 "pic_symbolic_operand" "")
6163 (const_string "lea")
6164 (match_operand:DI 2 "incdec_operand" "")
6165 (const_string "incdec")
6167 (const_string "alu")))
6168 (set_attr "mode" "DI")])
6170 ;; Convert lea to the lea pattern to avoid flags dependency.
6172 [(set (match_operand:DI 0 "register_operand" "")
6173 (plus:DI (match_operand:DI 1 "register_operand" "")
6174 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6175 (clobber (reg:CC FLAGS_REG))]
6176 "TARGET_64BIT && reload_completed
6177 && true_regnum (operands[0]) != true_regnum (operands[1])"
6179 (plus:DI (match_dup 1)
6183 (define_insn "*adddi_2_rex64"
6184 [(set (reg FLAGS_REG)
6186 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6187 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6189 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6190 (plus:DI (match_dup 1) (match_dup 2)))]
6191 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6192 && ix86_binary_operator_ok (PLUS, DImode, operands)
6193 /* Current assemblers are broken and do not allow @GOTOFF in
6194 ought but a memory context. */
6195 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6197 switch (get_attr_type (insn))
6200 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6201 if (operands[2] == const1_rtx)
6202 return "inc{q}\t%0";
6205 gcc_assert (operands[2] == constm1_rtx);
6206 return "dec{q}\t%0";
6210 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6211 /* ???? We ought to handle there the 32bit case too
6212 - do we need new constraint? */
6213 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6214 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6215 if (CONST_INT_P (operands[2])
6216 /* Avoid overflows. */
6217 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6218 && (INTVAL (operands[2]) == 128
6219 || (INTVAL (operands[2]) < 0
6220 && INTVAL (operands[2]) != -128)))
6222 operands[2] = GEN_INT (-INTVAL (operands[2]));
6223 return "sub{q}\t{%2, %0|%0, %2}";
6225 return "add{q}\t{%2, %0|%0, %2}";
6229 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6230 (const_string "incdec")
6231 (const_string "alu")))
6232 (set_attr "mode" "DI")])
6234 (define_insn "*adddi_3_rex64"
6235 [(set (reg FLAGS_REG)
6236 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6237 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6238 (clobber (match_scratch:DI 0 "=r"))]
6240 && ix86_match_ccmode (insn, CCZmode)
6241 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6242 /* Current assemblers are broken and do not allow @GOTOFF in
6243 ought but a memory context. */
6244 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6246 switch (get_attr_type (insn))
6249 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6250 if (operands[2] == const1_rtx)
6251 return "inc{q}\t%0";
6254 gcc_assert (operands[2] == constm1_rtx);
6255 return "dec{q}\t%0";
6259 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6260 /* ???? We ought to handle there the 32bit case too
6261 - do we need new constraint? */
6262 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6263 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6264 if (CONST_INT_P (operands[2])
6265 /* Avoid overflows. */
6266 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6267 && (INTVAL (operands[2]) == 128
6268 || (INTVAL (operands[2]) < 0
6269 && INTVAL (operands[2]) != -128)))
6271 operands[2] = GEN_INT (-INTVAL (operands[2]));
6272 return "sub{q}\t{%2, %0|%0, %2}";
6274 return "add{q}\t{%2, %0|%0, %2}";
6278 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6279 (const_string "incdec")
6280 (const_string "alu")))
6281 (set_attr "mode" "DI")])
6283 ; For comparisons against 1, -1 and 128, we may generate better code
6284 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6285 ; is matched then. We can't accept general immediate, because for
6286 ; case of overflows, the result is messed up.
6287 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6289 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6290 ; only for comparisons not depending on it.
6291 (define_insn "*adddi_4_rex64"
6292 [(set (reg FLAGS_REG)
6293 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6294 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6295 (clobber (match_scratch:DI 0 "=rm"))]
6297 && ix86_match_ccmode (insn, CCGCmode)"
6299 switch (get_attr_type (insn))
6302 if (operands[2] == constm1_rtx)
6303 return "inc{q}\t%0";
6306 gcc_assert (operands[2] == const1_rtx);
6307 return "dec{q}\t%0";
6311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6312 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6313 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6314 if ((INTVAL (operands[2]) == -128
6315 || (INTVAL (operands[2]) > 0
6316 && INTVAL (operands[2]) != 128))
6317 /* Avoid overflows. */
6318 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6319 return "sub{q}\t{%2, %0|%0, %2}";
6320 operands[2] = GEN_INT (-INTVAL (operands[2]));
6321 return "add{q}\t{%2, %0|%0, %2}";
6325 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6326 (const_string "incdec")
6327 (const_string "alu")))
6328 (set_attr "mode" "DI")])
6330 (define_insn "*adddi_5_rex64"
6331 [(set (reg FLAGS_REG)
6333 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6334 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6336 (clobber (match_scratch:DI 0 "=r"))]
6338 && ix86_match_ccmode (insn, CCGOCmode)
6339 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6340 /* Current assemblers are broken and do not allow @GOTOFF in
6341 ought but a memory context. */
6342 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6344 switch (get_attr_type (insn))
6347 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6348 if (operands[2] == const1_rtx)
6349 return "inc{q}\t%0";
6352 gcc_assert (operands[2] == constm1_rtx);
6353 return "dec{q}\t%0";
6357 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6358 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6359 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6360 if (CONST_INT_P (operands[2])
6361 /* Avoid overflows. */
6362 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6363 && (INTVAL (operands[2]) == 128
6364 || (INTVAL (operands[2]) < 0
6365 && INTVAL (operands[2]) != -128)))
6367 operands[2] = GEN_INT (-INTVAL (operands[2]));
6368 return "sub{q}\t{%2, %0|%0, %2}";
6370 return "add{q}\t{%2, %0|%0, %2}";
6374 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6375 (const_string "incdec")
6376 (const_string "alu")))
6377 (set_attr "mode" "DI")])
6380 (define_insn "*addsi_1"
6381 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6382 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6383 (match_operand:SI 2 "general_operand" "g,ri,li")))
6384 (clobber (reg:CC FLAGS_REG))]
6385 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6387 switch (get_attr_type (insn))
6390 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6391 return "lea{l}\t{%a2, %0|%0, %a2}";
6394 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6395 if (operands[2] == const1_rtx)
6396 return "inc{l}\t%0";
6399 gcc_assert (operands[2] == constm1_rtx);
6400 return "dec{l}\t%0";
6404 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6406 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6407 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6408 if (CONST_INT_P (operands[2])
6409 && (INTVAL (operands[2]) == 128
6410 || (INTVAL (operands[2]) < 0
6411 && INTVAL (operands[2]) != -128)))
6413 operands[2] = GEN_INT (-INTVAL (operands[2]));
6414 return "sub{l}\t{%2, %0|%0, %2}";
6416 return "add{l}\t{%2, %0|%0, %2}";
6420 (cond [(eq_attr "alternative" "2")
6421 (const_string "lea")
6422 ; Current assemblers are broken and do not allow @GOTOFF in
6423 ; ought but a memory context.
6424 (match_operand:SI 2 "pic_symbolic_operand" "")
6425 (const_string "lea")
6426 (match_operand:SI 2 "incdec_operand" "")
6427 (const_string "incdec")
6429 (const_string "alu")))
6430 (set_attr "mode" "SI")])
6432 ;; Convert lea to the lea pattern to avoid flags dependency.
6434 [(set (match_operand 0 "register_operand" "")
6435 (plus (match_operand 1 "register_operand" "")
6436 (match_operand 2 "nonmemory_operand" "")))
6437 (clobber (reg:CC FLAGS_REG))]
6439 && true_regnum (operands[0]) != true_regnum (operands[1])"
6443 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6444 may confuse gen_lowpart. */
6445 if (GET_MODE (operands[0]) != Pmode)
6447 operands[1] = gen_lowpart (Pmode, operands[1]);
6448 operands[2] = gen_lowpart (Pmode, operands[2]);
6450 operands[0] = gen_lowpart (SImode, operands[0]);
6451 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6452 if (Pmode != SImode)
6453 pat = gen_rtx_SUBREG (SImode, pat, 0);
6454 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6458 ;; It may seem that nonimmediate operand is proper one for operand 1.
6459 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6460 ;; we take care in ix86_binary_operator_ok to not allow two memory
6461 ;; operands so proper swapping will be done in reload. This allow
6462 ;; patterns constructed from addsi_1 to match.
6463 (define_insn "addsi_1_zext"
6464 [(set (match_operand:DI 0 "register_operand" "=r,r")
6466 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6467 (match_operand:SI 2 "general_operand" "g,li"))))
6468 (clobber (reg:CC FLAGS_REG))]
6469 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6471 switch (get_attr_type (insn))
6474 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6475 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6478 if (operands[2] == const1_rtx)
6479 return "inc{l}\t%k0";
6482 gcc_assert (operands[2] == constm1_rtx);
6483 return "dec{l}\t%k0";
6487 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6488 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6489 if (CONST_INT_P (operands[2])
6490 && (INTVAL (operands[2]) == 128
6491 || (INTVAL (operands[2]) < 0
6492 && INTVAL (operands[2]) != -128)))
6494 operands[2] = GEN_INT (-INTVAL (operands[2]));
6495 return "sub{l}\t{%2, %k0|%k0, %2}";
6497 return "add{l}\t{%2, %k0|%k0, %2}";
6501 (cond [(eq_attr "alternative" "1")
6502 (const_string "lea")
6503 ; Current assemblers are broken and do not allow @GOTOFF in
6504 ; ought but a memory context.
6505 (match_operand:SI 2 "pic_symbolic_operand" "")
6506 (const_string "lea")
6507 (match_operand:SI 2 "incdec_operand" "")
6508 (const_string "incdec")
6510 (const_string "alu")))
6511 (set_attr "mode" "SI")])
6513 ;; Convert lea to the lea pattern to avoid flags dependency.
6515 [(set (match_operand:DI 0 "register_operand" "")
6517 (plus:SI (match_operand:SI 1 "register_operand" "")
6518 (match_operand:SI 2 "nonmemory_operand" ""))))
6519 (clobber (reg:CC FLAGS_REG))]
6520 "TARGET_64BIT && reload_completed
6521 && true_regnum (operands[0]) != true_regnum (operands[1])"
6523 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6525 operands[1] = gen_lowpart (Pmode, operands[1]);
6526 operands[2] = gen_lowpart (Pmode, operands[2]);
6529 (define_insn "*addsi_2"
6530 [(set (reg FLAGS_REG)
6532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6533 (match_operand:SI 2 "general_operand" "g,ri"))
6535 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6536 (plus:SI (match_dup 1) (match_dup 2)))]
6537 "ix86_match_ccmode (insn, CCGOCmode)
6538 && ix86_binary_operator_ok (PLUS, SImode, operands)
6539 /* Current assemblers are broken and do not allow @GOTOFF in
6540 ought but a memory context. */
6541 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6543 switch (get_attr_type (insn))
6546 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6547 if (operands[2] == const1_rtx)
6548 return "inc{l}\t%0";
6551 gcc_assert (operands[2] == constm1_rtx);
6552 return "dec{l}\t%0";
6556 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6557 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6558 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6559 if (CONST_INT_P (operands[2])
6560 && (INTVAL (operands[2]) == 128
6561 || (INTVAL (operands[2]) < 0
6562 && INTVAL (operands[2]) != -128)))
6564 operands[2] = GEN_INT (-INTVAL (operands[2]));
6565 return "sub{l}\t{%2, %0|%0, %2}";
6567 return "add{l}\t{%2, %0|%0, %2}";
6571 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6572 (const_string "incdec")
6573 (const_string "alu")))
6574 (set_attr "mode" "SI")])
6576 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6577 (define_insn "*addsi_2_zext"
6578 [(set (reg FLAGS_REG)
6580 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6581 (match_operand:SI 2 "general_operand" "g"))
6583 (set (match_operand:DI 0 "register_operand" "=r")
6584 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6585 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6586 && ix86_binary_operator_ok (PLUS, SImode, operands)
6587 /* Current assemblers are broken and do not allow @GOTOFF in
6588 ought but a memory context. */
6589 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6591 switch (get_attr_type (insn))
6594 if (operands[2] == const1_rtx)
6595 return "inc{l}\t%k0";
6598 gcc_assert (operands[2] == constm1_rtx);
6599 return "dec{l}\t%k0";
6603 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6604 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6605 if (CONST_INT_P (operands[2])
6606 && (INTVAL (operands[2]) == 128
6607 || (INTVAL (operands[2]) < 0
6608 && INTVAL (operands[2]) != -128)))
6610 operands[2] = GEN_INT (-INTVAL (operands[2]));
6611 return "sub{l}\t{%2, %k0|%k0, %2}";
6613 return "add{l}\t{%2, %k0|%k0, %2}";
6617 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6618 (const_string "incdec")
6619 (const_string "alu")))
6620 (set_attr "mode" "SI")])
6622 (define_insn "*addsi_3"
6623 [(set (reg FLAGS_REG)
6624 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6625 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6626 (clobber (match_scratch:SI 0 "=r"))]
6627 "ix86_match_ccmode (insn, CCZmode)
6628 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6629 /* Current assemblers are broken and do not allow @GOTOFF in
6630 ought but a memory context. */
6631 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6633 switch (get_attr_type (insn))
6636 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6637 if (operands[2] == const1_rtx)
6638 return "inc{l}\t%0";
6641 gcc_assert (operands[2] == constm1_rtx);
6642 return "dec{l}\t%0";
6646 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6647 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6648 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6649 if (CONST_INT_P (operands[2])
6650 && (INTVAL (operands[2]) == 128
6651 || (INTVAL (operands[2]) < 0
6652 && INTVAL (operands[2]) != -128)))
6654 operands[2] = GEN_INT (-INTVAL (operands[2]));
6655 return "sub{l}\t{%2, %0|%0, %2}";
6657 return "add{l}\t{%2, %0|%0, %2}";
6661 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6662 (const_string "incdec")
6663 (const_string "alu")))
6664 (set_attr "mode" "SI")])
6666 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6667 (define_insn "*addsi_3_zext"
6668 [(set (reg FLAGS_REG)
6669 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6670 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6671 (set (match_operand:DI 0 "register_operand" "=r")
6672 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6673 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6674 && ix86_binary_operator_ok (PLUS, SImode, operands)
6675 /* Current assemblers are broken and do not allow @GOTOFF in
6676 ought but a memory context. */
6677 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6679 switch (get_attr_type (insn))
6682 if (operands[2] == const1_rtx)
6683 return "inc{l}\t%k0";
6686 gcc_assert (operands[2] == constm1_rtx);
6687 return "dec{l}\t%k0";
6691 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6692 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6693 if (CONST_INT_P (operands[2])
6694 && (INTVAL (operands[2]) == 128
6695 || (INTVAL (operands[2]) < 0
6696 && INTVAL (operands[2]) != -128)))
6698 operands[2] = GEN_INT (-INTVAL (operands[2]));
6699 return "sub{l}\t{%2, %k0|%k0, %2}";
6701 return "add{l}\t{%2, %k0|%k0, %2}";
6705 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6706 (const_string "incdec")
6707 (const_string "alu")))
6708 (set_attr "mode" "SI")])
6710 ; For comparisons against 1, -1 and 128, we may generate better code
6711 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6712 ; is matched then. We can't accept general immediate, because for
6713 ; case of overflows, the result is messed up.
6714 ; This pattern also don't hold of 0x80000000, since the value overflows
6716 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6717 ; only for comparisons not depending on it.
6718 (define_insn "*addsi_4"
6719 [(set (reg FLAGS_REG)
6720 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6721 (match_operand:SI 2 "const_int_operand" "n")))
6722 (clobber (match_scratch:SI 0 "=rm"))]
6723 "ix86_match_ccmode (insn, CCGCmode)
6724 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6726 switch (get_attr_type (insn))
6729 if (operands[2] == constm1_rtx)
6730 return "inc{l}\t%0";
6733 gcc_assert (operands[2] == const1_rtx);
6734 return "dec{l}\t%0";
6738 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6739 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6740 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6741 if ((INTVAL (operands[2]) == -128
6742 || (INTVAL (operands[2]) > 0
6743 && INTVAL (operands[2]) != 128)))
6744 return "sub{l}\t{%2, %0|%0, %2}";
6745 operands[2] = GEN_INT (-INTVAL (operands[2]));
6746 return "add{l}\t{%2, %0|%0, %2}";
6750 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6751 (const_string "incdec")
6752 (const_string "alu")))
6753 (set_attr "mode" "SI")])
6755 (define_insn "*addsi_5"
6756 [(set (reg FLAGS_REG)
6758 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6759 (match_operand:SI 2 "general_operand" "g"))
6761 (clobber (match_scratch:SI 0 "=r"))]
6762 "ix86_match_ccmode (insn, CCGOCmode)
6763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6764 /* Current assemblers are broken and do not allow @GOTOFF in
6765 ought but a memory context. */
6766 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6768 switch (get_attr_type (insn))
6771 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772 if (operands[2] == const1_rtx)
6773 return "inc{l}\t%0";
6776 gcc_assert (operands[2] == constm1_rtx);
6777 return "dec{l}\t%0";
6781 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6782 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6783 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6784 if (CONST_INT_P (operands[2])
6785 && (INTVAL (operands[2]) == 128
6786 || (INTVAL (operands[2]) < 0
6787 && INTVAL (operands[2]) != -128)))
6789 operands[2] = GEN_INT (-INTVAL (operands[2]));
6790 return "sub{l}\t{%2, %0|%0, %2}";
6792 return "add{l}\t{%2, %0|%0, %2}";
6796 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6797 (const_string "incdec")
6798 (const_string "alu")))
6799 (set_attr "mode" "SI")])
6801 (define_expand "addhi3"
6802 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6803 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6804 (match_operand:HI 2 "general_operand" "")))]
6805 "TARGET_HIMODE_MATH"
6806 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6808 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6809 ;; type optimizations enabled by define-splits. This is not important
6810 ;; for PII, and in fact harmful because of partial register stalls.
6812 (define_insn "*addhi_1_lea"
6813 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6814 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6815 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6816 (clobber (reg:CC FLAGS_REG))]
6817 "!TARGET_PARTIAL_REG_STALL
6818 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6820 switch (get_attr_type (insn))
6825 if (operands[2] == const1_rtx)
6826 return "inc{w}\t%0";
6829 gcc_assert (operands[2] == constm1_rtx);
6830 return "dec{w}\t%0";
6834 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6835 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6836 if (CONST_INT_P (operands[2])
6837 && (INTVAL (operands[2]) == 128
6838 || (INTVAL (operands[2]) < 0
6839 && INTVAL (operands[2]) != -128)))
6841 operands[2] = GEN_INT (-INTVAL (operands[2]));
6842 return "sub{w}\t{%2, %0|%0, %2}";
6844 return "add{w}\t{%2, %0|%0, %2}";
6848 (if_then_else (eq_attr "alternative" "2")
6849 (const_string "lea")
6850 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6851 (const_string "incdec")
6852 (const_string "alu"))))
6853 (set_attr "mode" "HI,HI,SI")])
6855 (define_insn "*addhi_1"
6856 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6857 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6858 (match_operand:HI 2 "general_operand" "rn,rm")))
6859 (clobber (reg:CC FLAGS_REG))]
6860 "TARGET_PARTIAL_REG_STALL
6861 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6863 switch (get_attr_type (insn))
6866 if (operands[2] == const1_rtx)
6867 return "inc{w}\t%0";
6870 gcc_assert (operands[2] == constm1_rtx);
6871 return "dec{w}\t%0";
6875 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6876 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6877 if (CONST_INT_P (operands[2])
6878 && (INTVAL (operands[2]) == 128
6879 || (INTVAL (operands[2]) < 0
6880 && INTVAL (operands[2]) != -128)))
6882 operands[2] = GEN_INT (-INTVAL (operands[2]));
6883 return "sub{w}\t{%2, %0|%0, %2}";
6885 return "add{w}\t{%2, %0|%0, %2}";
6889 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6890 (const_string "incdec")
6891 (const_string "alu")))
6892 (set_attr "mode" "HI")])
6894 (define_insn "*addhi_2"
6895 [(set (reg FLAGS_REG)
6897 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6898 (match_operand:HI 2 "general_operand" "rmn,rn"))
6900 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6901 (plus:HI (match_dup 1) (match_dup 2)))]
6902 "ix86_match_ccmode (insn, CCGOCmode)
6903 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6905 switch (get_attr_type (insn))
6908 if (operands[2] == const1_rtx)
6909 return "inc{w}\t%0";
6912 gcc_assert (operands[2] == constm1_rtx);
6913 return "dec{w}\t%0";
6917 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6918 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6919 if (CONST_INT_P (operands[2])
6920 && (INTVAL (operands[2]) == 128
6921 || (INTVAL (operands[2]) < 0
6922 && INTVAL (operands[2]) != -128)))
6924 operands[2] = GEN_INT (-INTVAL (operands[2]));
6925 return "sub{w}\t{%2, %0|%0, %2}";
6927 return "add{w}\t{%2, %0|%0, %2}";
6931 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6932 (const_string "incdec")
6933 (const_string "alu")))
6934 (set_attr "mode" "HI")])
6936 (define_insn "*addhi_3"
6937 [(set (reg FLAGS_REG)
6938 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6939 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6940 (clobber (match_scratch:HI 0 "=r"))]
6941 "ix86_match_ccmode (insn, CCZmode)
6942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944 switch (get_attr_type (insn))
6947 if (operands[2] == const1_rtx)
6948 return "inc{w}\t%0";
6951 gcc_assert (operands[2] == constm1_rtx);
6952 return "dec{w}\t%0";
6956 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6957 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6958 if (CONST_INT_P (operands[2])
6959 && (INTVAL (operands[2]) == 128
6960 || (INTVAL (operands[2]) < 0
6961 && INTVAL (operands[2]) != -128)))
6963 operands[2] = GEN_INT (-INTVAL (operands[2]));
6964 return "sub{w}\t{%2, %0|%0, %2}";
6966 return "add{w}\t{%2, %0|%0, %2}";
6970 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6971 (const_string "incdec")
6972 (const_string "alu")))
6973 (set_attr "mode" "HI")])
6975 ; See comments above addsi_4 for details.
6976 (define_insn "*addhi_4"
6977 [(set (reg FLAGS_REG)
6978 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6979 (match_operand:HI 2 "const_int_operand" "n")))
6980 (clobber (match_scratch:HI 0 "=rm"))]
6981 "ix86_match_ccmode (insn, CCGCmode)
6982 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6984 switch (get_attr_type (insn))
6987 if (operands[2] == constm1_rtx)
6988 return "inc{w}\t%0";
6991 gcc_assert (operands[2] == const1_rtx);
6992 return "dec{w}\t%0";
6996 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6997 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6998 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6999 if ((INTVAL (operands[2]) == -128
7000 || (INTVAL (operands[2]) > 0
7001 && INTVAL (operands[2]) != 128)))
7002 return "sub{w}\t{%2, %0|%0, %2}";
7003 operands[2] = GEN_INT (-INTVAL (operands[2]));
7004 return "add{w}\t{%2, %0|%0, %2}";
7008 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7009 (const_string "incdec")
7010 (const_string "alu")))
7011 (set_attr "mode" "SI")])
7014 (define_insn "*addhi_5"
7015 [(set (reg FLAGS_REG)
7017 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7018 (match_operand:HI 2 "general_operand" "rmn"))
7020 (clobber (match_scratch:HI 0 "=r"))]
7021 "ix86_match_ccmode (insn, CCGOCmode)
7022 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024 switch (get_attr_type (insn))
7027 if (operands[2] == const1_rtx)
7028 return "inc{w}\t%0";
7031 gcc_assert (operands[2] == constm1_rtx);
7032 return "dec{w}\t%0";
7036 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7037 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7038 if (CONST_INT_P (operands[2])
7039 && (INTVAL (operands[2]) == 128
7040 || (INTVAL (operands[2]) < 0
7041 && INTVAL (operands[2]) != -128)))
7043 operands[2] = GEN_INT (-INTVAL (operands[2]));
7044 return "sub{w}\t{%2, %0|%0, %2}";
7046 return "add{w}\t{%2, %0|%0, %2}";
7050 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7051 (const_string "incdec")
7052 (const_string "alu")))
7053 (set_attr "mode" "HI")])
7055 (define_expand "addqi3"
7056 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058 (match_operand:QI 2 "general_operand" "")))]
7059 "TARGET_QIMODE_MATH"
7060 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7062 ;; %%% Potential partial reg stall on alternative 2. What to do?
7063 (define_insn "*addqi_1_lea"
7064 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7065 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7066 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "!TARGET_PARTIAL_REG_STALL
7069 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7071 int widen = (which_alternative == 2);
7072 switch (get_attr_type (insn))
7077 if (operands[2] == const1_rtx)
7078 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7081 gcc_assert (operands[2] == constm1_rtx);
7082 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7086 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7087 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7088 if (CONST_INT_P (operands[2])
7089 && (INTVAL (operands[2]) == 128
7090 || (INTVAL (operands[2]) < 0
7091 && INTVAL (operands[2]) != -128)))
7093 operands[2] = GEN_INT (-INTVAL (operands[2]));
7095 return "sub{l}\t{%2, %k0|%k0, %2}";
7097 return "sub{b}\t{%2, %0|%0, %2}";
7100 return "add{l}\t{%k2, %k0|%k0, %k2}";
7102 return "add{b}\t{%2, %0|%0, %2}";
7106 (if_then_else (eq_attr "alternative" "3")
7107 (const_string "lea")
7108 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7109 (const_string "incdec")
7110 (const_string "alu"))))
7111 (set_attr "mode" "QI,QI,SI,SI")])
7113 (define_insn "*addqi_1"
7114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7115 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7116 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7117 (clobber (reg:CC FLAGS_REG))]
7118 "TARGET_PARTIAL_REG_STALL
7119 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7121 int widen = (which_alternative == 2);
7122 switch (get_attr_type (insn))
7125 if (operands[2] == const1_rtx)
7126 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7129 gcc_assert (operands[2] == constm1_rtx);
7130 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7134 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7135 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7136 if (CONST_INT_P (operands[2])
7137 && (INTVAL (operands[2]) == 128
7138 || (INTVAL (operands[2]) < 0
7139 && INTVAL (operands[2]) != -128)))
7141 operands[2] = GEN_INT (-INTVAL (operands[2]));
7143 return "sub{l}\t{%2, %k0|%k0, %2}";
7145 return "sub{b}\t{%2, %0|%0, %2}";
7148 return "add{l}\t{%k2, %k0|%k0, %k2}";
7150 return "add{b}\t{%2, %0|%0, %2}";
7154 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7155 (const_string "incdec")
7156 (const_string "alu")))
7157 (set_attr "mode" "QI,QI,SI")])
7159 (define_insn "*addqi_1_slp"
7160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7161 (plus:QI (match_dup 0)
7162 (match_operand:QI 1 "general_operand" "qn,qnm")))
7163 (clobber (reg:CC FLAGS_REG))]
7164 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7165 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7167 switch (get_attr_type (insn))
7170 if (operands[1] == const1_rtx)
7171 return "inc{b}\t%0";
7174 gcc_assert (operands[1] == constm1_rtx);
7175 return "dec{b}\t%0";
7179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7180 if (CONST_INT_P (operands[1])
7181 && INTVAL (operands[1]) < 0)
7183 operands[1] = GEN_INT (-INTVAL (operands[1]));
7184 return "sub{b}\t{%1, %0|%0, %1}";
7186 return "add{b}\t{%1, %0|%0, %1}";
7190 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7191 (const_string "incdec")
7192 (const_string "alu1")))
7193 (set (attr "memory")
7194 (if_then_else (match_operand 1 "memory_operand" "")
7195 (const_string "load")
7196 (const_string "none")))
7197 (set_attr "mode" "QI")])
7199 (define_insn "*addqi_2"
7200 [(set (reg FLAGS_REG)
7202 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7203 (match_operand:QI 2 "general_operand" "qmn,qn"))
7205 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7206 (plus:QI (match_dup 1) (match_dup 2)))]
7207 "ix86_match_ccmode (insn, CCGOCmode)
7208 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7210 switch (get_attr_type (insn))
7213 if (operands[2] == const1_rtx)
7214 return "inc{b}\t%0";
7217 gcc_assert (operands[2] == constm1_rtx
7218 || (CONST_INT_P (operands[2])
7219 && INTVAL (operands[2]) == 255));
7220 return "dec{b}\t%0";
7224 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7225 if (CONST_INT_P (operands[2])
7226 && INTVAL (operands[2]) < 0)
7228 operands[2] = GEN_INT (-INTVAL (operands[2]));
7229 return "sub{b}\t{%2, %0|%0, %2}";
7231 return "add{b}\t{%2, %0|%0, %2}";
7235 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7236 (const_string "incdec")
7237 (const_string "alu")))
7238 (set_attr "mode" "QI")])
7240 (define_insn "*addqi_3"
7241 [(set (reg FLAGS_REG)
7242 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7243 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7244 (clobber (match_scratch:QI 0 "=q"))]
7245 "ix86_match_ccmode (insn, CCZmode)
7246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7248 switch (get_attr_type (insn))
7251 if (operands[2] == const1_rtx)
7252 return "inc{b}\t%0";
7255 gcc_assert (operands[2] == constm1_rtx
7256 || (CONST_INT_P (operands[2])
7257 && INTVAL (operands[2]) == 255));
7258 return "dec{b}\t%0";
7262 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7263 if (CONST_INT_P (operands[2])
7264 && INTVAL (operands[2]) < 0)
7266 operands[2] = GEN_INT (-INTVAL (operands[2]));
7267 return "sub{b}\t{%2, %0|%0, %2}";
7269 return "add{b}\t{%2, %0|%0, %2}";
7273 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7274 (const_string "incdec")
7275 (const_string "alu")))
7276 (set_attr "mode" "QI")])
7278 ; See comments above addsi_4 for details.
7279 (define_insn "*addqi_4"
7280 [(set (reg FLAGS_REG)
7281 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7282 (match_operand:QI 2 "const_int_operand" "n")))
7283 (clobber (match_scratch:QI 0 "=qm"))]
7284 "ix86_match_ccmode (insn, CCGCmode)
7285 && (INTVAL (operands[2]) & 0xff) != 0x80"
7287 switch (get_attr_type (insn))
7290 if (operands[2] == constm1_rtx
7291 || (CONST_INT_P (operands[2])
7292 && INTVAL (operands[2]) == 255))
7293 return "inc{b}\t%0";
7296 gcc_assert (operands[2] == const1_rtx);
7297 return "dec{b}\t%0";
7301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7302 if (INTVAL (operands[2]) < 0)
7304 operands[2] = GEN_INT (-INTVAL (operands[2]));
7305 return "add{b}\t{%2, %0|%0, %2}";
7307 return "sub{b}\t{%2, %0|%0, %2}";
7311 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7312 (const_string "incdec")
7313 (const_string "alu")))
7314 (set_attr "mode" "QI")])
7317 (define_insn "*addqi_5"
7318 [(set (reg FLAGS_REG)
7320 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7321 (match_operand:QI 2 "general_operand" "qmn"))
7323 (clobber (match_scratch:QI 0 "=q"))]
7324 "ix86_match_ccmode (insn, CCGOCmode)
7325 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7327 switch (get_attr_type (insn))
7330 if (operands[2] == const1_rtx)
7331 return "inc{b}\t%0";
7334 gcc_assert (operands[2] == constm1_rtx
7335 || (CONST_INT_P (operands[2])
7336 && INTVAL (operands[2]) == 255));
7337 return "dec{b}\t%0";
7341 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7342 if (CONST_INT_P (operands[2])
7343 && INTVAL (operands[2]) < 0)
7345 operands[2] = GEN_INT (-INTVAL (operands[2]));
7346 return "sub{b}\t{%2, %0|%0, %2}";
7348 return "add{b}\t{%2, %0|%0, %2}";
7352 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7353 (const_string "incdec")
7354 (const_string "alu")))
7355 (set_attr "mode" "QI")])
7358 (define_insn "addqi_ext_1"
7359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7364 (match_operand 1 "ext_register_operand" "0")
7367 (match_operand:QI 2 "general_operand" "Qmn")))
7368 (clobber (reg:CC FLAGS_REG))]
7371 switch (get_attr_type (insn))
7374 if (operands[2] == const1_rtx)
7375 return "inc{b}\t%h0";
7378 gcc_assert (operands[2] == constm1_rtx
7379 || (CONST_INT_P (operands[2])
7380 && INTVAL (operands[2]) == 255));
7381 return "dec{b}\t%h0";
7385 return "add{b}\t{%2, %h0|%h0, %2}";
7389 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7390 (const_string "incdec")
7391 (const_string "alu")))
7392 (set_attr "mode" "QI")])
7394 (define_insn "*addqi_ext_1_rex64"
7395 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7400 (match_operand 1 "ext_register_operand" "0")
7403 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7404 (clobber (reg:CC FLAGS_REG))]
7407 switch (get_attr_type (insn))
7410 if (operands[2] == const1_rtx)
7411 return "inc{b}\t%h0";
7414 gcc_assert (operands[2] == constm1_rtx
7415 || (CONST_INT_P (operands[2])
7416 && INTVAL (operands[2]) == 255));
7417 return "dec{b}\t%h0";
7421 return "add{b}\t{%2, %h0|%h0, %2}";
7425 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7426 (const_string "incdec")
7427 (const_string "alu")))
7428 (set_attr "mode" "QI")])
7430 (define_insn "*addqi_ext_2"
7431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7436 (match_operand 1 "ext_register_operand" "%0")
7440 (match_operand 2 "ext_register_operand" "Q")
7443 (clobber (reg:CC FLAGS_REG))]
7445 "add{b}\t{%h2, %h0|%h0, %h2}"
7446 [(set_attr "type" "alu")
7447 (set_attr "mode" "QI")])
7449 ;; The patterns that match these are at the end of this file.
7451 (define_expand "addxf3"
7452 [(set (match_operand:XF 0 "register_operand" "")
7453 (plus:XF (match_operand:XF 1 "register_operand" "")
7454 (match_operand:XF 2 "register_operand" "")))]
7458 (define_expand "add<mode>3"
7459 [(set (match_operand:MODEF 0 "register_operand" "")
7460 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7461 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7462 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7465 ;; Subtract instructions
7467 ;; %%% splits for subditi3
7469 (define_expand "subti3"
7470 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7471 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7472 (match_operand:TI 2 "x86_64_general_operand" "")))]
7474 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7476 (define_insn "*subti3_1"
7477 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7478 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7479 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7480 (clobber (reg:CC FLAGS_REG))]
7481 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7485 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7486 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7487 (match_operand:TI 2 "x86_64_general_operand" "")))
7488 (clobber (reg:CC FLAGS_REG))]
7489 "TARGET_64BIT && reload_completed"
7490 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7491 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7492 (parallel [(set (match_dup 3)
7493 (minus:DI (match_dup 4)
7494 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7496 (clobber (reg:CC FLAGS_REG))])]
7497 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7499 ;; %%% splits for subsidi3
7501 (define_expand "subdi3"
7502 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7503 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7504 (match_operand:DI 2 "x86_64_general_operand" "")))]
7506 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7508 (define_insn "*subdi3_1"
7509 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7510 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7511 (match_operand:DI 2 "general_operand" "roiF,riF")))
7512 (clobber (reg:CC FLAGS_REG))]
7513 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7517 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7518 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7519 (match_operand:DI 2 "general_operand" "")))
7520 (clobber (reg:CC FLAGS_REG))]
7521 "!TARGET_64BIT && reload_completed"
7522 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7523 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7524 (parallel [(set (match_dup 3)
7525 (minus:SI (match_dup 4)
7526 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7528 (clobber (reg:CC FLAGS_REG))])]
7529 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7531 (define_insn "subdi3_carry_rex64"
7532 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7533 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7534 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7535 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7536 (clobber (reg:CC FLAGS_REG))]
7537 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7538 "sbb{q}\t{%2, %0|%0, %2}"
7539 [(set_attr "type" "alu")
7540 (set_attr "pent_pair" "pu")
7541 (set_attr "mode" "DI")])
7543 (define_insn "*subdi_1_rex64"
7544 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7545 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7546 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7547 (clobber (reg:CC FLAGS_REG))]
7548 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7549 "sub{q}\t{%2, %0|%0, %2}"
7550 [(set_attr "type" "alu")
7551 (set_attr "mode" "DI")])
7553 (define_insn "*subdi_2_rex64"
7554 [(set (reg FLAGS_REG)
7556 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7557 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7559 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7560 (minus:DI (match_dup 1) (match_dup 2)))]
7561 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7562 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7563 "sub{q}\t{%2, %0|%0, %2}"
7564 [(set_attr "type" "alu")
7565 (set_attr "mode" "DI")])
7567 (define_insn "*subdi_3_rex63"
7568 [(set (reg FLAGS_REG)
7569 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7570 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7571 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7572 (minus:DI (match_dup 1) (match_dup 2)))]
7573 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7574 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7575 "sub{q}\t{%2, %0|%0, %2}"
7576 [(set_attr "type" "alu")
7577 (set_attr "mode" "DI")])
7579 (define_insn "subqi3_carry"
7580 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7581 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7582 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7583 (match_operand:QI 2 "general_operand" "qn,qm"))))
7584 (clobber (reg:CC FLAGS_REG))]
7585 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7586 "sbb{b}\t{%2, %0|%0, %2}"
7587 [(set_attr "type" "alu")
7588 (set_attr "pent_pair" "pu")
7589 (set_attr "mode" "QI")])
7591 (define_insn "subhi3_carry"
7592 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7593 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7594 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7595 (match_operand:HI 2 "general_operand" "rn,rm"))))
7596 (clobber (reg:CC FLAGS_REG))]
7597 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7598 "sbb{w}\t{%2, %0|%0, %2}"
7599 [(set_attr "type" "alu")
7600 (set_attr "pent_pair" "pu")
7601 (set_attr "mode" "HI")])
7603 (define_insn "subsi3_carry"
7604 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7605 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7606 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7607 (match_operand:SI 2 "general_operand" "ri,rm"))))
7608 (clobber (reg:CC FLAGS_REG))]
7609 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7610 "sbb{l}\t{%2, %0|%0, %2}"
7611 [(set_attr "type" "alu")
7612 (set_attr "pent_pair" "pu")
7613 (set_attr "mode" "SI")])
7615 (define_insn "subsi3_carry_zext"
7616 [(set (match_operand:DI 0 "register_operand" "=r")
7618 (minus:SI (match_operand:SI 1 "register_operand" "0")
7619 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7620 (match_operand:SI 2 "general_operand" "g")))))
7621 (clobber (reg:CC FLAGS_REG))]
7622 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7623 "sbb{l}\t{%2, %k0|%k0, %2}"
7624 [(set_attr "type" "alu")
7625 (set_attr "pent_pair" "pu")
7626 (set_attr "mode" "SI")])
7628 (define_expand "subsi3"
7629 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7630 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7631 (match_operand:SI 2 "general_operand" "")))]
7633 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7635 (define_insn "*subsi_1"
7636 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7637 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7638 (match_operand:SI 2 "general_operand" "ri,rm")))
7639 (clobber (reg:CC FLAGS_REG))]
7640 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7641 "sub{l}\t{%2, %0|%0, %2}"
7642 [(set_attr "type" "alu")
7643 (set_attr "mode" "SI")])
7645 (define_insn "*subsi_1_zext"
7646 [(set (match_operand:DI 0 "register_operand" "=r")
7648 (minus:SI (match_operand:SI 1 "register_operand" "0")
7649 (match_operand:SI 2 "general_operand" "g"))))
7650 (clobber (reg:CC FLAGS_REG))]
7651 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7652 "sub{l}\t{%2, %k0|%k0, %2}"
7653 [(set_attr "type" "alu")
7654 (set_attr "mode" "SI")])
7656 (define_insn "*subsi_2"
7657 [(set (reg FLAGS_REG)
7659 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7660 (match_operand:SI 2 "general_operand" "ri,rm"))
7662 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7663 (minus:SI (match_dup 1) (match_dup 2)))]
7664 "ix86_match_ccmode (insn, CCGOCmode)
7665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7666 "sub{l}\t{%2, %0|%0, %2}"
7667 [(set_attr "type" "alu")
7668 (set_attr "mode" "SI")])
7670 (define_insn "*subsi_2_zext"
7671 [(set (reg FLAGS_REG)
7673 (minus:SI (match_operand:SI 1 "register_operand" "0")
7674 (match_operand:SI 2 "general_operand" "g"))
7676 (set (match_operand:DI 0 "register_operand" "=r")
7678 (minus:SI (match_dup 1)
7680 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7681 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682 "sub{l}\t{%2, %k0|%k0, %2}"
7683 [(set_attr "type" "alu")
7684 (set_attr "mode" "SI")])
7686 (define_insn "*subsi_3"
7687 [(set (reg FLAGS_REG)
7688 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7689 (match_operand:SI 2 "general_operand" "ri,rm")))
7690 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7691 (minus:SI (match_dup 1) (match_dup 2)))]
7692 "ix86_match_ccmode (insn, CCmode)
7693 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7694 "sub{l}\t{%2, %0|%0, %2}"
7695 [(set_attr "type" "alu")
7696 (set_attr "mode" "SI")])
7698 (define_insn "*subsi_3_zext"
7699 [(set (reg FLAGS_REG)
7700 (compare (match_operand:SI 1 "register_operand" "0")
7701 (match_operand:SI 2 "general_operand" "g")))
7702 (set (match_operand:DI 0 "register_operand" "=r")
7704 (minus:SI (match_dup 1)
7706 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7707 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7708 "sub{l}\t{%2, %1|%1, %2}"
7709 [(set_attr "type" "alu")
7710 (set_attr "mode" "DI")])
7712 (define_expand "subhi3"
7713 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7714 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7715 (match_operand:HI 2 "general_operand" "")))]
7716 "TARGET_HIMODE_MATH"
7717 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7719 (define_insn "*subhi_1"
7720 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7721 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7722 (match_operand:HI 2 "general_operand" "rn,rm")))
7723 (clobber (reg:CC FLAGS_REG))]
7724 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7725 "sub{w}\t{%2, %0|%0, %2}"
7726 [(set_attr "type" "alu")
7727 (set_attr "mode" "HI")])
7729 (define_insn "*subhi_2"
7730 [(set (reg FLAGS_REG)
7732 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7733 (match_operand:HI 2 "general_operand" "rn,rm"))
7735 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7736 (minus:HI (match_dup 1) (match_dup 2)))]
7737 "ix86_match_ccmode (insn, CCGOCmode)
7738 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7739 "sub{w}\t{%2, %0|%0, %2}"
7740 [(set_attr "type" "alu")
7741 (set_attr "mode" "HI")])
7743 (define_insn "*subhi_3"
7744 [(set (reg FLAGS_REG)
7745 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7746 (match_operand:HI 2 "general_operand" "rn,rm")))
7747 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7748 (minus:HI (match_dup 1) (match_dup 2)))]
7749 "ix86_match_ccmode (insn, CCmode)
7750 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7751 "sub{w}\t{%2, %0|%0, %2}"
7752 [(set_attr "type" "alu")
7753 (set_attr "mode" "HI")])
7755 (define_expand "subqi3"
7756 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7757 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7758 (match_operand:QI 2 "general_operand" "")))]
7759 "TARGET_QIMODE_MATH"
7760 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7762 (define_insn "*subqi_1"
7763 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7764 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7765 (match_operand:QI 2 "general_operand" "qn,qm")))
7766 (clobber (reg:CC FLAGS_REG))]
7767 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7768 "sub{b}\t{%2, %0|%0, %2}"
7769 [(set_attr "type" "alu")
7770 (set_attr "mode" "QI")])
7772 (define_insn "*subqi_1_slp"
7773 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7774 (minus:QI (match_dup 0)
7775 (match_operand:QI 1 "general_operand" "qn,qm")))
7776 (clobber (reg:CC FLAGS_REG))]
7777 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7778 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7779 "sub{b}\t{%1, %0|%0, %1}"
7780 [(set_attr "type" "alu1")
7781 (set_attr "mode" "QI")])
7783 (define_insn "*subqi_2"
7784 [(set (reg FLAGS_REG)
7786 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7787 (match_operand:QI 2 "general_operand" "qn,qm"))
7789 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7790 (minus:QI (match_dup 1) (match_dup 2)))]
7791 "ix86_match_ccmode (insn, CCGOCmode)
7792 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7793 "sub{b}\t{%2, %0|%0, %2}"
7794 [(set_attr "type" "alu")
7795 (set_attr "mode" "QI")])
7797 (define_insn "*subqi_3"
7798 [(set (reg FLAGS_REG)
7799 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7800 (match_operand:QI 2 "general_operand" "qn,qm")))
7801 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7802 (minus:QI (match_dup 1) (match_dup 2)))]
7803 "ix86_match_ccmode (insn, CCmode)
7804 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7805 "sub{b}\t{%2, %0|%0, %2}"
7806 [(set_attr "type" "alu")
7807 (set_attr "mode" "QI")])
7809 ;; The patterns that match these are at the end of this file.
7811 (define_expand "subxf3"
7812 [(set (match_operand:XF 0 "register_operand" "")
7813 (minus:XF (match_operand:XF 1 "register_operand" "")
7814 (match_operand:XF 2 "register_operand" "")))]
7818 (define_expand "sub<mode>3"
7819 [(set (match_operand:MODEF 0 "register_operand" "")
7820 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7821 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7822 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7825 ;; Multiply instructions
7827 (define_expand "muldi3"
7828 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7829 (mult:DI (match_operand:DI 1 "register_operand" "")
7830 (match_operand:DI 2 "x86_64_general_operand" "")))
7831 (clobber (reg:CC FLAGS_REG))])]
7836 ;; IMUL reg64, reg64, imm8 Direct
7837 ;; IMUL reg64, mem64, imm8 VectorPath
7838 ;; IMUL reg64, reg64, imm32 Direct
7839 ;; IMUL reg64, mem64, imm32 VectorPath
7840 ;; IMUL reg64, reg64 Direct
7841 ;; IMUL reg64, mem64 Direct
7843 (define_insn "*muldi3_1_rex64"
7844 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7845 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7846 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7847 (clobber (reg:CC FLAGS_REG))]
7849 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7851 imul{q}\t{%2, %1, %0|%0, %1, %2}
7852 imul{q}\t{%2, %1, %0|%0, %1, %2}
7853 imul{q}\t{%2, %0|%0, %2}"
7854 [(set_attr "type" "imul")
7855 (set_attr "prefix_0f" "0,0,1")
7856 (set (attr "athlon_decode")
7857 (cond [(eq_attr "cpu" "athlon")
7858 (const_string "vector")
7859 (eq_attr "alternative" "1")
7860 (const_string "vector")
7861 (and (eq_attr "alternative" "2")
7862 (match_operand 1 "memory_operand" ""))
7863 (const_string "vector")]
7864 (const_string "direct")))
7865 (set (attr "amdfam10_decode")
7866 (cond [(and (eq_attr "alternative" "0,1")
7867 (match_operand 1 "memory_operand" ""))
7868 (const_string "vector")]
7869 (const_string "direct")))
7870 (set_attr "mode" "DI")])
7872 (define_expand "mulsi3"
7873 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7874 (mult:SI (match_operand:SI 1 "register_operand" "")
7875 (match_operand:SI 2 "general_operand" "")))
7876 (clobber (reg:CC FLAGS_REG))])]
7881 ;; IMUL reg32, reg32, imm8 Direct
7882 ;; IMUL reg32, mem32, imm8 VectorPath
7883 ;; IMUL reg32, reg32, imm32 Direct
7884 ;; IMUL reg32, mem32, imm32 VectorPath
7885 ;; IMUL reg32, reg32 Direct
7886 ;; IMUL reg32, mem32 Direct
7888 (define_insn "*mulsi3_1"
7889 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7890 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7891 (match_operand:SI 2 "general_operand" "K,i,mr")))
7892 (clobber (reg:CC FLAGS_REG))]
7893 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7895 imul{l}\t{%2, %1, %0|%0, %1, %2}
7896 imul{l}\t{%2, %1, %0|%0, %1, %2}
7897 imul{l}\t{%2, %0|%0, %2}"
7898 [(set_attr "type" "imul")
7899 (set_attr "prefix_0f" "0,0,1")
7900 (set (attr "athlon_decode")
7901 (cond [(eq_attr "cpu" "athlon")
7902 (const_string "vector")
7903 (eq_attr "alternative" "1")
7904 (const_string "vector")
7905 (and (eq_attr "alternative" "2")
7906 (match_operand 1 "memory_operand" ""))
7907 (const_string "vector")]
7908 (const_string "direct")))
7909 (set (attr "amdfam10_decode")
7910 (cond [(and (eq_attr "alternative" "0,1")
7911 (match_operand 1 "memory_operand" ""))
7912 (const_string "vector")]
7913 (const_string "direct")))
7914 (set_attr "mode" "SI")])
7916 (define_insn "*mulsi3_1_zext"
7917 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7919 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7920 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7921 (clobber (reg:CC FLAGS_REG))]
7923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7926 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7927 imul{l}\t{%2, %k0|%k0, %2}"
7928 [(set_attr "type" "imul")
7929 (set_attr "prefix_0f" "0,0,1")
7930 (set (attr "athlon_decode")
7931 (cond [(eq_attr "cpu" "athlon")
7932 (const_string "vector")
7933 (eq_attr "alternative" "1")
7934 (const_string "vector")
7935 (and (eq_attr "alternative" "2")
7936 (match_operand 1 "memory_operand" ""))
7937 (const_string "vector")]
7938 (const_string "direct")))
7939 (set (attr "amdfam10_decode")
7940 (cond [(and (eq_attr "alternative" "0,1")
7941 (match_operand 1 "memory_operand" ""))
7942 (const_string "vector")]
7943 (const_string "direct")))
7944 (set_attr "mode" "SI")])
7946 (define_expand "mulhi3"
7947 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7948 (mult:HI (match_operand:HI 1 "register_operand" "")
7949 (match_operand:HI 2 "general_operand" "")))
7950 (clobber (reg:CC FLAGS_REG))])]
7951 "TARGET_HIMODE_MATH"
7955 ;; IMUL reg16, reg16, imm8 VectorPath
7956 ;; IMUL reg16, mem16, imm8 VectorPath
7957 ;; IMUL reg16, reg16, imm16 VectorPath
7958 ;; IMUL reg16, mem16, imm16 VectorPath
7959 ;; IMUL reg16, reg16 Direct
7960 ;; IMUL reg16, mem16 Direct
7961 (define_insn "*mulhi3_1"
7962 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7963 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7964 (match_operand:HI 2 "general_operand" "K,n,mr")))
7965 (clobber (reg:CC FLAGS_REG))]
7966 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7968 imul{w}\t{%2, %1, %0|%0, %1, %2}
7969 imul{w}\t{%2, %1, %0|%0, %1, %2}
7970 imul{w}\t{%2, %0|%0, %2}"
7971 [(set_attr "type" "imul")
7972 (set_attr "prefix_0f" "0,0,1")
7973 (set (attr "athlon_decode")
7974 (cond [(eq_attr "cpu" "athlon")
7975 (const_string "vector")
7976 (eq_attr "alternative" "1,2")
7977 (const_string "vector")]
7978 (const_string "direct")))
7979 (set (attr "amdfam10_decode")
7980 (cond [(eq_attr "alternative" "0,1")
7981 (const_string "vector")]
7982 (const_string "direct")))
7983 (set_attr "mode" "HI")])
7985 (define_expand "mulqi3"
7986 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7987 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7988 (match_operand:QI 2 "register_operand" "")))
7989 (clobber (reg:CC FLAGS_REG))])]
7990 "TARGET_QIMODE_MATH"
7997 (define_insn "*mulqi3_1"
7998 [(set (match_operand:QI 0 "register_operand" "=a")
7999 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8000 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8001 (clobber (reg:CC FLAGS_REG))]
8003 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005 [(set_attr "type" "imul")
8006 (set_attr "length_immediate" "0")
8007 (set (attr "athlon_decode")
8008 (if_then_else (eq_attr "cpu" "athlon")
8009 (const_string "vector")
8010 (const_string "direct")))
8011 (set_attr "amdfam10_decode" "direct")
8012 (set_attr "mode" "QI")])
8014 (define_expand "umulqihi3"
8015 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8016 (mult:HI (zero_extend:HI
8017 (match_operand:QI 1 "nonimmediate_operand" ""))
8019 (match_operand:QI 2 "register_operand" ""))))
8020 (clobber (reg:CC FLAGS_REG))])]
8021 "TARGET_QIMODE_MATH"
8024 (define_insn "*umulqihi3_1"
8025 [(set (match_operand:HI 0 "register_operand" "=a")
8026 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8027 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8028 (clobber (reg:CC FLAGS_REG))]
8030 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8032 [(set_attr "type" "imul")
8033 (set_attr "length_immediate" "0")
8034 (set (attr "athlon_decode")
8035 (if_then_else (eq_attr "cpu" "athlon")
8036 (const_string "vector")
8037 (const_string "direct")))
8038 (set_attr "amdfam10_decode" "direct")
8039 (set_attr "mode" "QI")])
8041 (define_expand "mulqihi3"
8042 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8043 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8044 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8045 (clobber (reg:CC FLAGS_REG))])]
8046 "TARGET_QIMODE_MATH"
8049 (define_insn "*mulqihi3_insn"
8050 [(set (match_operand:HI 0 "register_operand" "=a")
8051 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8052 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8053 (clobber (reg:CC FLAGS_REG))]
8055 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8057 [(set_attr "type" "imul")
8058 (set_attr "length_immediate" "0")
8059 (set (attr "athlon_decode")
8060 (if_then_else (eq_attr "cpu" "athlon")
8061 (const_string "vector")
8062 (const_string "direct")))
8063 (set_attr "amdfam10_decode" "direct")
8064 (set_attr "mode" "QI")])
8066 (define_expand "umulditi3"
8067 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8068 (mult:TI (zero_extend:TI
8069 (match_operand:DI 1 "nonimmediate_operand" ""))
8071 (match_operand:DI 2 "register_operand" ""))))
8072 (clobber (reg:CC FLAGS_REG))])]
8076 (define_insn "*umulditi3_insn"
8077 [(set (match_operand:TI 0 "register_operand" "=A")
8078 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8079 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8080 (clobber (reg:CC FLAGS_REG))]
8082 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8084 [(set_attr "type" "imul")
8085 (set_attr "length_immediate" "0")
8086 (set (attr "athlon_decode")
8087 (if_then_else (eq_attr "cpu" "athlon")
8088 (const_string "vector")
8089 (const_string "double")))
8090 (set_attr "amdfam10_decode" "double")
8091 (set_attr "mode" "DI")])
8093 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8094 (define_expand "umulsidi3"
8095 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8096 (mult:DI (zero_extend:DI
8097 (match_operand:SI 1 "nonimmediate_operand" ""))
8099 (match_operand:SI 2 "register_operand" ""))))
8100 (clobber (reg:CC FLAGS_REG))])]
8104 (define_insn "*umulsidi3_insn"
8105 [(set (match_operand:DI 0 "register_operand" "=A")
8106 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8107 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8108 (clobber (reg:CC FLAGS_REG))]
8110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8112 [(set_attr "type" "imul")
8113 (set_attr "length_immediate" "0")
8114 (set (attr "athlon_decode")
8115 (if_then_else (eq_attr "cpu" "athlon")
8116 (const_string "vector")
8117 (const_string "double")))
8118 (set_attr "amdfam10_decode" "double")
8119 (set_attr "mode" "SI")])
8121 (define_expand "mulditi3"
8122 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8123 (mult:TI (sign_extend:TI
8124 (match_operand:DI 1 "nonimmediate_operand" ""))
8126 (match_operand:DI 2 "register_operand" ""))))
8127 (clobber (reg:CC FLAGS_REG))])]
8131 (define_insn "*mulditi3_insn"
8132 [(set (match_operand:TI 0 "register_operand" "=A")
8133 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8134 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8135 (clobber (reg:CC FLAGS_REG))]
8137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8139 [(set_attr "type" "imul")
8140 (set_attr "length_immediate" "0")
8141 (set (attr "athlon_decode")
8142 (if_then_else (eq_attr "cpu" "athlon")
8143 (const_string "vector")
8144 (const_string "double")))
8145 (set_attr "amdfam10_decode" "double")
8146 (set_attr "mode" "DI")])
8148 (define_expand "mulsidi3"
8149 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8150 (mult:DI (sign_extend:DI
8151 (match_operand:SI 1 "nonimmediate_operand" ""))
8153 (match_operand:SI 2 "register_operand" ""))))
8154 (clobber (reg:CC FLAGS_REG))])]
8158 (define_insn "*mulsidi3_insn"
8159 [(set (match_operand:DI 0 "register_operand" "=A")
8160 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8161 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8162 (clobber (reg:CC FLAGS_REG))]
8164 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8166 [(set_attr "type" "imul")
8167 (set_attr "length_immediate" "0")
8168 (set (attr "athlon_decode")
8169 (if_then_else (eq_attr "cpu" "athlon")
8170 (const_string "vector")
8171 (const_string "double")))
8172 (set_attr "amdfam10_decode" "double")
8173 (set_attr "mode" "SI")])
8175 (define_expand "umuldi3_highpart"
8176 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8179 (mult:TI (zero_extend:TI
8180 (match_operand:DI 1 "nonimmediate_operand" ""))
8182 (match_operand:DI 2 "register_operand" "")))
8184 (clobber (match_scratch:DI 3 ""))
8185 (clobber (reg:CC FLAGS_REG))])]
8189 (define_insn "*umuldi3_highpart_rex64"
8190 [(set (match_operand:DI 0 "register_operand" "=d")
8193 (mult:TI (zero_extend:TI
8194 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8196 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8198 (clobber (match_scratch:DI 3 "=1"))
8199 (clobber (reg:CC FLAGS_REG))]
8201 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8203 [(set_attr "type" "imul")
8204 (set_attr "length_immediate" "0")
8205 (set (attr "athlon_decode")
8206 (if_then_else (eq_attr "cpu" "athlon")
8207 (const_string "vector")
8208 (const_string "double")))
8209 (set_attr "amdfam10_decode" "double")
8210 (set_attr "mode" "DI")])
8212 (define_expand "umulsi3_highpart"
8213 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8216 (mult:DI (zero_extend:DI
8217 (match_operand:SI 1 "nonimmediate_operand" ""))
8219 (match_operand:SI 2 "register_operand" "")))
8221 (clobber (match_scratch:SI 3 ""))
8222 (clobber (reg:CC FLAGS_REG))])]
8226 (define_insn "*umulsi3_highpart_insn"
8227 [(set (match_operand:SI 0 "register_operand" "=d")
8230 (mult:DI (zero_extend:DI
8231 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8233 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8235 (clobber (match_scratch:SI 3 "=1"))
8236 (clobber (reg:CC FLAGS_REG))]
8237 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8239 [(set_attr "type" "imul")
8240 (set_attr "length_immediate" "0")
8241 (set (attr "athlon_decode")
8242 (if_then_else (eq_attr "cpu" "athlon")
8243 (const_string "vector")
8244 (const_string "double")))
8245 (set_attr "amdfam10_decode" "double")
8246 (set_attr "mode" "SI")])
8248 (define_insn "*umulsi3_highpart_zext"
8249 [(set (match_operand:DI 0 "register_operand" "=d")
8250 (zero_extend:DI (truncate:SI
8252 (mult:DI (zero_extend:DI
8253 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8255 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8257 (clobber (match_scratch:SI 3 "=1"))
8258 (clobber (reg:CC FLAGS_REG))]
8260 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8262 [(set_attr "type" "imul")
8263 (set_attr "length_immediate" "0")
8264 (set (attr "athlon_decode")
8265 (if_then_else (eq_attr "cpu" "athlon")
8266 (const_string "vector")
8267 (const_string "double")))
8268 (set_attr "amdfam10_decode" "double")
8269 (set_attr "mode" "SI")])
8271 (define_expand "smuldi3_highpart"
8272 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8275 (mult:TI (sign_extend:TI
8276 (match_operand:DI 1 "nonimmediate_operand" ""))
8278 (match_operand:DI 2 "register_operand" "")))
8280 (clobber (match_scratch:DI 3 ""))
8281 (clobber (reg:CC FLAGS_REG))])]
8285 (define_insn "*smuldi3_highpart_rex64"
8286 [(set (match_operand:DI 0 "register_operand" "=d")
8289 (mult:TI (sign_extend:TI
8290 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8292 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8294 (clobber (match_scratch:DI 3 "=1"))
8295 (clobber (reg:CC FLAGS_REG))]
8297 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8299 [(set_attr "type" "imul")
8300 (set (attr "athlon_decode")
8301 (if_then_else (eq_attr "cpu" "athlon")
8302 (const_string "vector")
8303 (const_string "double")))
8304 (set_attr "amdfam10_decode" "double")
8305 (set_attr "mode" "DI")])
8307 (define_expand "smulsi3_highpart"
8308 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8311 (mult:DI (sign_extend:DI
8312 (match_operand:SI 1 "nonimmediate_operand" ""))
8314 (match_operand:SI 2 "register_operand" "")))
8316 (clobber (match_scratch:SI 3 ""))
8317 (clobber (reg:CC FLAGS_REG))])]
8321 (define_insn "*smulsi3_highpart_insn"
8322 [(set (match_operand:SI 0 "register_operand" "=d")
8325 (mult:DI (sign_extend:DI
8326 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8328 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8330 (clobber (match_scratch:SI 3 "=1"))
8331 (clobber (reg:CC FLAGS_REG))]
8332 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8334 [(set_attr "type" "imul")
8335 (set (attr "athlon_decode")
8336 (if_then_else (eq_attr "cpu" "athlon")
8337 (const_string "vector")
8338 (const_string "double")))
8339 (set_attr "amdfam10_decode" "double")
8340 (set_attr "mode" "SI")])
8342 (define_insn "*smulsi3_highpart_zext"
8343 [(set (match_operand:DI 0 "register_operand" "=d")
8344 (zero_extend:DI (truncate:SI
8346 (mult:DI (sign_extend:DI
8347 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8349 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8351 (clobber (match_scratch:SI 3 "=1"))
8352 (clobber (reg:CC FLAGS_REG))]
8354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8356 [(set_attr "type" "imul")
8357 (set (attr "athlon_decode")
8358 (if_then_else (eq_attr "cpu" "athlon")
8359 (const_string "vector")
8360 (const_string "double")))
8361 (set_attr "amdfam10_decode" "double")
8362 (set_attr "mode" "SI")])
8364 ;; The patterns that match these are at the end of this file.
8366 (define_expand "mulxf3"
8367 [(set (match_operand:XF 0 "register_operand" "")
8368 (mult:XF (match_operand:XF 1 "register_operand" "")
8369 (match_operand:XF 2 "register_operand" "")))]
8373 (define_expand "mul<mode>3"
8374 [(set (match_operand:MODEF 0 "register_operand" "")
8375 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8376 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8377 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8380 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8383 ;; Divide instructions
8385 (define_insn "divqi3"
8386 [(set (match_operand:QI 0 "register_operand" "=a")
8387 (div:QI (match_operand:HI 1 "register_operand" "0")
8388 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8389 (clobber (reg:CC FLAGS_REG))]
8390 "TARGET_QIMODE_MATH"
8392 [(set_attr "type" "idiv")
8393 (set_attr "mode" "QI")])
8395 (define_insn "udivqi3"
8396 [(set (match_operand:QI 0 "register_operand" "=a")
8397 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8398 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8399 (clobber (reg:CC FLAGS_REG))]
8400 "TARGET_QIMODE_MATH"
8402 [(set_attr "type" "idiv")
8403 (set_attr "mode" "QI")])
8405 ;; The patterns that match these are at the end of this file.
8407 (define_expand "divxf3"
8408 [(set (match_operand:XF 0 "register_operand" "")
8409 (div:XF (match_operand:XF 1 "register_operand" "")
8410 (match_operand:XF 2 "register_operand" "")))]
8414 (define_expand "divdf3"
8415 [(set (match_operand:DF 0 "register_operand" "")
8416 (div:DF (match_operand:DF 1 "register_operand" "")
8417 (match_operand:DF 2 "nonimmediate_operand" "")))]
8418 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8421 (define_expand "divsf3"
8422 [(set (match_operand:SF 0 "register_operand" "")
8423 (div:SF (match_operand:SF 1 "register_operand" "")
8424 (match_operand:SF 2 "nonimmediate_operand" "")))]
8425 "TARGET_80387 || TARGET_SSE_MATH"
8427 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8428 && flag_finite_math_only && !flag_trapping_math
8429 && flag_unsafe_math_optimizations)
8431 ix86_emit_swdivsf (operands[0], operands[1],
8432 operands[2], SFmode);
8437 ;; Remainder instructions.
8439 (define_expand "divmoddi4"
8440 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8441 (div:DI (match_operand:DI 1 "register_operand" "")
8442 (match_operand:DI 2 "nonimmediate_operand" "")))
8443 (set (match_operand:DI 3 "register_operand" "")
8444 (mod:DI (match_dup 1) (match_dup 2)))
8445 (clobber (reg:CC FLAGS_REG))])]
8449 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8450 ;; Penalize eax case slightly because it results in worse scheduling
8452 (define_insn "*divmoddi4_nocltd_rex64"
8453 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8454 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8455 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8456 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8457 (mod:DI (match_dup 2) (match_dup 3)))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8461 [(set_attr "type" "multi")])
8463 (define_insn "*divmoddi4_cltd_rex64"
8464 [(set (match_operand:DI 0 "register_operand" "=a")
8465 (div:DI (match_operand:DI 2 "register_operand" "a")
8466 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8467 (set (match_operand:DI 1 "register_operand" "=&d")
8468 (mod:DI (match_dup 2) (match_dup 3)))
8469 (clobber (reg:CC FLAGS_REG))]
8470 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8472 [(set_attr "type" "multi")])
8474 (define_insn "*divmoddi_noext_rex64"
8475 [(set (match_operand:DI 0 "register_operand" "=a")
8476 (div:DI (match_operand:DI 1 "register_operand" "0")
8477 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8478 (set (match_operand:DI 3 "register_operand" "=d")
8479 (mod:DI (match_dup 1) (match_dup 2)))
8480 (use (match_operand:DI 4 "register_operand" "3"))
8481 (clobber (reg:CC FLAGS_REG))]
8484 [(set_attr "type" "idiv")
8485 (set_attr "mode" "DI")])
8488 [(set (match_operand:DI 0 "register_operand" "")
8489 (div:DI (match_operand:DI 1 "register_operand" "")
8490 (match_operand:DI 2 "nonimmediate_operand" "")))
8491 (set (match_operand:DI 3 "register_operand" "")
8492 (mod:DI (match_dup 1) (match_dup 2)))
8493 (clobber (reg:CC FLAGS_REG))]
8494 "TARGET_64BIT && reload_completed"
8495 [(parallel [(set (match_dup 3)
8496 (ashiftrt:DI (match_dup 4) (const_int 63)))
8497 (clobber (reg:CC FLAGS_REG))])
8498 (parallel [(set (match_dup 0)
8499 (div:DI (reg:DI 0) (match_dup 2)))
8501 (mod:DI (reg:DI 0) (match_dup 2)))
8503 (clobber (reg:CC FLAGS_REG))])]
8505 /* Avoid use of cltd in favor of a mov+shift. */
8506 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8508 if (true_regnum (operands[1]))
8509 emit_move_insn (operands[0], operands[1]);
8511 emit_move_insn (operands[3], operands[1]);
8512 operands[4] = operands[3];
8516 gcc_assert (!true_regnum (operands[1]));
8517 operands[4] = operands[1];
8522 (define_expand "divmodsi4"
8523 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8524 (div:SI (match_operand:SI 1 "register_operand" "")
8525 (match_operand:SI 2 "nonimmediate_operand" "")))
8526 (set (match_operand:SI 3 "register_operand" "")
8527 (mod:SI (match_dup 1) (match_dup 2)))
8528 (clobber (reg:CC FLAGS_REG))])]
8532 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8533 ;; Penalize eax case slightly because it results in worse scheduling
8535 (define_insn "*divmodsi4_nocltd"
8536 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8537 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8538 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8539 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8540 (mod:SI (match_dup 2) (match_dup 3)))
8541 (clobber (reg:CC FLAGS_REG))]
8542 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8544 [(set_attr "type" "multi")])
8546 (define_insn "*divmodsi4_cltd"
8547 [(set (match_operand:SI 0 "register_operand" "=a")
8548 (div:SI (match_operand:SI 2 "register_operand" "a")
8549 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8550 (set (match_operand:SI 1 "register_operand" "=&d")
8551 (mod:SI (match_dup 2) (match_dup 3)))
8552 (clobber (reg:CC FLAGS_REG))]
8553 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8555 [(set_attr "type" "multi")])
8557 (define_insn "*divmodsi_noext"
8558 [(set (match_operand:SI 0 "register_operand" "=a")
8559 (div:SI (match_operand:SI 1 "register_operand" "0")
8560 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8561 (set (match_operand:SI 3 "register_operand" "=d")
8562 (mod:SI (match_dup 1) (match_dup 2)))
8563 (use (match_operand:SI 4 "register_operand" "3"))
8564 (clobber (reg:CC FLAGS_REG))]
8567 [(set_attr "type" "idiv")
8568 (set_attr "mode" "SI")])
8571 [(set (match_operand:SI 0 "register_operand" "")
8572 (div:SI (match_operand:SI 1 "register_operand" "")
8573 (match_operand:SI 2 "nonimmediate_operand" "")))
8574 (set (match_operand:SI 3 "register_operand" "")
8575 (mod:SI (match_dup 1) (match_dup 2)))
8576 (clobber (reg:CC FLAGS_REG))]
8578 [(parallel [(set (match_dup 3)
8579 (ashiftrt:SI (match_dup 4) (const_int 31)))
8580 (clobber (reg:CC FLAGS_REG))])
8581 (parallel [(set (match_dup 0)
8582 (div:SI (reg:SI 0) (match_dup 2)))
8584 (mod:SI (reg:SI 0) (match_dup 2)))
8586 (clobber (reg:CC FLAGS_REG))])]
8588 /* Avoid use of cltd in favor of a mov+shift. */
8589 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8591 if (true_regnum (operands[1]))
8592 emit_move_insn (operands[0], operands[1]);
8594 emit_move_insn (operands[3], operands[1]);
8595 operands[4] = operands[3];
8599 gcc_assert (!true_regnum (operands[1]));
8600 operands[4] = operands[1];
8604 (define_insn "divmodhi4"
8605 [(set (match_operand:HI 0 "register_operand" "=a")
8606 (div:HI (match_operand:HI 1 "register_operand" "0")
8607 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8608 (set (match_operand:HI 3 "register_operand" "=&d")
8609 (mod:HI (match_dup 1) (match_dup 2)))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "TARGET_HIMODE_MATH"
8613 [(set_attr "type" "multi")
8614 (set_attr "length_immediate" "0")
8615 (set_attr "mode" "SI")])
8617 (define_insn "udivmoddi4"
8618 [(set (match_operand:DI 0 "register_operand" "=a")
8619 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8620 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8621 (set (match_operand:DI 3 "register_operand" "=&d")
8622 (umod:DI (match_dup 1) (match_dup 2)))
8623 (clobber (reg:CC FLAGS_REG))]
8625 "xor{q}\t%3, %3\;div{q}\t%2"
8626 [(set_attr "type" "multi")
8627 (set_attr "length_immediate" "0")
8628 (set_attr "mode" "DI")])
8630 (define_insn "*udivmoddi4_noext"
8631 [(set (match_operand:DI 0 "register_operand" "=a")
8632 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8633 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8634 (set (match_operand:DI 3 "register_operand" "=d")
8635 (umod:DI (match_dup 1) (match_dup 2)))
8637 (clobber (reg:CC FLAGS_REG))]
8640 [(set_attr "type" "idiv")
8641 (set_attr "mode" "DI")])
8644 [(set (match_operand:DI 0 "register_operand" "")
8645 (udiv:DI (match_operand:DI 1 "register_operand" "")
8646 (match_operand:DI 2 "nonimmediate_operand" "")))
8647 (set (match_operand:DI 3 "register_operand" "")
8648 (umod:DI (match_dup 1) (match_dup 2)))
8649 (clobber (reg:CC FLAGS_REG))]
8650 "TARGET_64BIT && reload_completed"
8651 [(set (match_dup 3) (const_int 0))
8652 (parallel [(set (match_dup 0)
8653 (udiv:DI (match_dup 1) (match_dup 2)))
8655 (umod:DI (match_dup 1) (match_dup 2)))
8657 (clobber (reg:CC FLAGS_REG))])]
8660 (define_insn "udivmodsi4"
8661 [(set (match_operand:SI 0 "register_operand" "=a")
8662 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8663 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8664 (set (match_operand:SI 3 "register_operand" "=&d")
8665 (umod:SI (match_dup 1) (match_dup 2)))
8666 (clobber (reg:CC FLAGS_REG))]
8668 "xor{l}\t%3, %3\;div{l}\t%2"
8669 [(set_attr "type" "multi")
8670 (set_attr "length_immediate" "0")
8671 (set_attr "mode" "SI")])
8673 (define_insn "*udivmodsi4_noext"
8674 [(set (match_operand:SI 0 "register_operand" "=a")
8675 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8676 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8677 (set (match_operand:SI 3 "register_operand" "=d")
8678 (umod:SI (match_dup 1) (match_dup 2)))
8680 (clobber (reg:CC FLAGS_REG))]
8683 [(set_attr "type" "idiv")
8684 (set_attr "mode" "SI")])
8687 [(set (match_operand:SI 0 "register_operand" "")
8688 (udiv:SI (match_operand:SI 1 "register_operand" "")
8689 (match_operand:SI 2 "nonimmediate_operand" "")))
8690 (set (match_operand:SI 3 "register_operand" "")
8691 (umod:SI (match_dup 1) (match_dup 2)))
8692 (clobber (reg:CC FLAGS_REG))]
8694 [(set (match_dup 3) (const_int 0))
8695 (parallel [(set (match_dup 0)
8696 (udiv:SI (match_dup 1) (match_dup 2)))
8698 (umod:SI (match_dup 1) (match_dup 2)))
8700 (clobber (reg:CC FLAGS_REG))])]
8703 (define_expand "udivmodhi4"
8704 [(set (match_dup 4) (const_int 0))
8705 (parallel [(set (match_operand:HI 0 "register_operand" "")
8706 (udiv:HI (match_operand:HI 1 "register_operand" "")
8707 (match_operand:HI 2 "nonimmediate_operand" "")))
8708 (set (match_operand:HI 3 "register_operand" "")
8709 (umod:HI (match_dup 1) (match_dup 2)))
8711 (clobber (reg:CC FLAGS_REG))])]
8712 "TARGET_HIMODE_MATH"
8713 "operands[4] = gen_reg_rtx (HImode);")
8715 (define_insn "*udivmodhi_noext"
8716 [(set (match_operand:HI 0 "register_operand" "=a")
8717 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8718 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8719 (set (match_operand:HI 3 "register_operand" "=d")
8720 (umod:HI (match_dup 1) (match_dup 2)))
8721 (use (match_operand:HI 4 "register_operand" "3"))
8722 (clobber (reg:CC FLAGS_REG))]
8725 [(set_attr "type" "idiv")
8726 (set_attr "mode" "HI")])
8728 ;; We cannot use div/idiv for double division, because it causes
8729 ;; "division by zero" on the overflow and that's not what we expect
8730 ;; from truncate. Because true (non truncating) double division is
8731 ;; never generated, we can't create this insn anyway.
8734 ; [(set (match_operand:SI 0 "register_operand" "=a")
8736 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8738 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8739 ; (set (match_operand:SI 3 "register_operand" "=d")
8741 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8742 ; (clobber (reg:CC FLAGS_REG))]
8744 ; "div{l}\t{%2, %0|%0, %2}"
8745 ; [(set_attr "type" "idiv")])
8747 ;;- Logical AND instructions
8749 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8750 ;; Note that this excludes ah.
8752 (define_insn "*testdi_1_rex64"
8753 [(set (reg FLAGS_REG)
8755 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8756 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8758 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8759 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8761 test{l}\t{%k1, %k0|%k0, %k1}
8762 test{l}\t{%k1, %k0|%k0, %k1}
8763 test{q}\t{%1, %0|%0, %1}
8764 test{q}\t{%1, %0|%0, %1}
8765 test{q}\t{%1, %0|%0, %1}"
8766 [(set_attr "type" "test")
8767 (set_attr "modrm" "0,1,0,1,1")
8768 (set_attr "mode" "SI,SI,DI,DI,DI")
8769 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8771 (define_insn "testsi_1"
8772 [(set (reg FLAGS_REG)
8774 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8775 (match_operand:SI 1 "general_operand" "i,i,ri"))
8777 "ix86_match_ccmode (insn, CCNOmode)
8778 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8779 "test{l}\t{%1, %0|%0, %1}"
8780 [(set_attr "type" "test")
8781 (set_attr "modrm" "0,1,1")
8782 (set_attr "mode" "SI")
8783 (set_attr "pent_pair" "uv,np,uv")])
8785 (define_expand "testsi_ccno_1"
8786 [(set (reg:CCNO FLAGS_REG)
8788 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8789 (match_operand:SI 1 "nonmemory_operand" ""))
8794 (define_insn "*testhi_1"
8795 [(set (reg FLAGS_REG)
8796 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8797 (match_operand:HI 1 "general_operand" "n,n,rn"))
8799 "ix86_match_ccmode (insn, CCNOmode)
8800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8801 "test{w}\t{%1, %0|%0, %1}"
8802 [(set_attr "type" "test")
8803 (set_attr "modrm" "0,1,1")
8804 (set_attr "mode" "HI")
8805 (set_attr "pent_pair" "uv,np,uv")])
8807 (define_expand "testqi_ccz_1"
8808 [(set (reg:CCZ FLAGS_REG)
8809 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8810 (match_operand:QI 1 "nonmemory_operand" ""))
8815 (define_insn "*testqi_1_maybe_si"
8816 [(set (reg FLAGS_REG)
8819 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8820 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8822 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8823 && ix86_match_ccmode (insn,
8824 CONST_INT_P (operands[1])
8825 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8827 if (which_alternative == 3)
8829 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8830 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8831 return "test{l}\t{%1, %k0|%k0, %1}";
8833 return "test{b}\t{%1, %0|%0, %1}";
8835 [(set_attr "type" "test")
8836 (set_attr "modrm" "0,1,1,1")
8837 (set_attr "mode" "QI,QI,QI,SI")
8838 (set_attr "pent_pair" "uv,np,uv,np")])
8840 (define_insn "*testqi_1"
8841 [(set (reg FLAGS_REG)
8844 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8845 (match_operand:QI 1 "general_operand" "n,n,qn"))
8847 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8848 && ix86_match_ccmode (insn, CCNOmode)"
8849 "test{b}\t{%1, %0|%0, %1}"
8850 [(set_attr "type" "test")
8851 (set_attr "modrm" "0,1,1")
8852 (set_attr "mode" "QI")
8853 (set_attr "pent_pair" "uv,np,uv")])
8855 (define_expand "testqi_ext_ccno_0"
8856 [(set (reg:CCNO FLAGS_REG)
8860 (match_operand 0 "ext_register_operand" "")
8863 (match_operand 1 "const_int_operand" ""))
8868 (define_insn "*testqi_ext_0"
8869 [(set (reg FLAGS_REG)
8873 (match_operand 0 "ext_register_operand" "Q")
8876 (match_operand 1 "const_int_operand" "n"))
8878 "ix86_match_ccmode (insn, CCNOmode)"
8879 "test{b}\t{%1, %h0|%h0, %1}"
8880 [(set_attr "type" "test")
8881 (set_attr "mode" "QI")
8882 (set_attr "length_immediate" "1")
8883 (set_attr "pent_pair" "np")])
8885 (define_insn "*testqi_ext_1"
8886 [(set (reg FLAGS_REG)
8890 (match_operand 0 "ext_register_operand" "Q")
8894 (match_operand:QI 1 "general_operand" "Qm")))
8896 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8897 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8898 "test{b}\t{%1, %h0|%h0, %1}"
8899 [(set_attr "type" "test")
8900 (set_attr "mode" "QI")])
8902 (define_insn "*testqi_ext_1_rex64"
8903 [(set (reg FLAGS_REG)
8907 (match_operand 0 "ext_register_operand" "Q")
8911 (match_operand:QI 1 "register_operand" "Q")))
8913 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8914 "test{b}\t{%1, %h0|%h0, %1}"
8915 [(set_attr "type" "test")
8916 (set_attr "mode" "QI")])
8918 (define_insn "*testqi_ext_2"
8919 [(set (reg FLAGS_REG)
8923 (match_operand 0 "ext_register_operand" "Q")
8927 (match_operand 1 "ext_register_operand" "Q")
8931 "ix86_match_ccmode (insn, CCNOmode)"
8932 "test{b}\t{%h1, %h0|%h0, %h1}"
8933 [(set_attr "type" "test")
8934 (set_attr "mode" "QI")])
8936 ;; Combine likes to form bit extractions for some tests. Humor it.
8937 (define_insn "*testqi_ext_3"
8938 [(set (reg FLAGS_REG)
8939 (compare (zero_extract:SI
8940 (match_operand 0 "nonimmediate_operand" "rm")
8941 (match_operand:SI 1 "const_int_operand" "")
8942 (match_operand:SI 2 "const_int_operand" ""))
8944 "ix86_match_ccmode (insn, CCNOmode)
8945 && INTVAL (operands[1]) > 0
8946 && INTVAL (operands[2]) >= 0
8947 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8948 && (GET_MODE (operands[0]) == SImode
8949 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8950 || GET_MODE (operands[0]) == HImode
8951 || GET_MODE (operands[0]) == QImode)"
8954 (define_insn "*testqi_ext_3_rex64"
8955 [(set (reg FLAGS_REG)
8956 (compare (zero_extract:DI
8957 (match_operand 0 "nonimmediate_operand" "rm")
8958 (match_operand:DI 1 "const_int_operand" "")
8959 (match_operand:DI 2 "const_int_operand" ""))
8962 && ix86_match_ccmode (insn, CCNOmode)
8963 && INTVAL (operands[1]) > 0
8964 && INTVAL (operands[2]) >= 0
8965 /* Ensure that resulting mask is zero or sign extended operand. */
8966 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8967 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8968 && INTVAL (operands[1]) > 32))
8969 && (GET_MODE (operands[0]) == SImode
8970 || GET_MODE (operands[0]) == DImode
8971 || GET_MODE (operands[0]) == HImode
8972 || GET_MODE (operands[0]) == QImode)"
8976 [(set (match_operand 0 "flags_reg_operand" "")
8977 (match_operator 1 "compare_operator"
8979 (match_operand 2 "nonimmediate_operand" "")
8980 (match_operand 3 "const_int_operand" "")
8981 (match_operand 4 "const_int_operand" ""))
8983 "ix86_match_ccmode (insn, CCNOmode)"
8984 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8986 rtx val = operands[2];
8987 HOST_WIDE_INT len = INTVAL (operands[3]);
8988 HOST_WIDE_INT pos = INTVAL (operands[4]);
8990 enum machine_mode mode, submode;
8992 mode = GET_MODE (val);
8995 /* ??? Combine likes to put non-volatile mem extractions in QImode
8996 no matter the size of the test. So find a mode that works. */
8997 if (! MEM_VOLATILE_P (val))
8999 mode = smallest_mode_for_size (pos + len, MODE_INT);
9000 val = adjust_address (val, mode, 0);
9003 else if (GET_CODE (val) == SUBREG
9004 && (submode = GET_MODE (SUBREG_REG (val)),
9005 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9006 && pos + len <= GET_MODE_BITSIZE (submode))
9008 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9010 val = SUBREG_REG (val);
9012 else if (mode == HImode && pos + len <= 8)
9014 /* Small HImode tests can be converted to QImode. */
9016 val = gen_lowpart (QImode, val);
9019 if (len == HOST_BITS_PER_WIDE_INT)
9022 mask = ((HOST_WIDE_INT)1 << len) - 1;
9025 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9028 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9029 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9030 ;; this is relatively important trick.
9031 ;; Do the conversion only post-reload to avoid limiting of the register class
9034 [(set (match_operand 0 "flags_reg_operand" "")
9035 (match_operator 1 "compare_operator"
9036 [(and (match_operand 2 "register_operand" "")
9037 (match_operand 3 "const_int_operand" ""))
9040 && QI_REG_P (operands[2])
9041 && GET_MODE (operands[2]) != QImode
9042 && ((ix86_match_ccmode (insn, CCZmode)
9043 && !(INTVAL (operands[3]) & ~(255 << 8)))
9044 || (ix86_match_ccmode (insn, CCNOmode)
9045 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9048 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9051 "operands[2] = gen_lowpart (SImode, operands[2]);
9052 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9055 [(set (match_operand 0 "flags_reg_operand" "")
9056 (match_operator 1 "compare_operator"
9057 [(and (match_operand 2 "nonimmediate_operand" "")
9058 (match_operand 3 "const_int_operand" ""))
9061 && GET_MODE (operands[2]) != QImode
9062 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9063 && ((ix86_match_ccmode (insn, CCZmode)
9064 && !(INTVAL (operands[3]) & ~255))
9065 || (ix86_match_ccmode (insn, CCNOmode)
9066 && !(INTVAL (operands[3]) & ~127)))"
9068 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9070 "operands[2] = gen_lowpart (QImode, operands[2]);
9071 operands[3] = gen_lowpart (QImode, operands[3]);")
9074 ;; %%% This used to optimize known byte-wide and operations to memory,
9075 ;; and sometimes to QImode registers. If this is considered useful,
9076 ;; it should be done with splitters.
9078 (define_expand "anddi3"
9079 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9080 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9081 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9083 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9085 (define_insn "*anddi_1_rex64"
9086 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9087 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9088 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9089 (clobber (reg:CC FLAGS_REG))]
9090 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9092 switch (get_attr_type (insn))
9096 enum machine_mode mode;
9098 gcc_assert (CONST_INT_P (operands[2]));
9099 if (INTVAL (operands[2]) == 0xff)
9103 gcc_assert (INTVAL (operands[2]) == 0xffff);
9107 operands[1] = gen_lowpart (mode, operands[1]);
9109 return "movz{bq|x}\t{%1,%0|%0, %1}";
9111 return "movz{wq|x}\t{%1,%0|%0, %1}";
9115 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9116 if (get_attr_mode (insn) == MODE_SI)
9117 return "and{l}\t{%k2, %k0|%k0, %k2}";
9119 return "and{q}\t{%2, %0|%0, %2}";
9122 [(set_attr "type" "alu,alu,alu,imovx")
9123 (set_attr "length_immediate" "*,*,*,0")
9124 (set_attr "mode" "SI,DI,DI,DI")])
9126 (define_insn "*anddi_2"
9127 [(set (reg FLAGS_REG)
9128 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9129 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9131 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9132 (and:DI (match_dup 1) (match_dup 2)))]
9133 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9134 && ix86_binary_operator_ok (AND, DImode, operands)"
9136 and{l}\t{%k2, %k0|%k0, %k2}
9137 and{q}\t{%2, %0|%0, %2}
9138 and{q}\t{%2, %0|%0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "mode" "SI,DI,DI")])
9142 (define_expand "andsi3"
9143 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9144 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9145 (match_operand:SI 2 "general_operand" "")))]
9147 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9149 (define_insn "*andsi_1"
9150 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9151 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9152 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9153 (clobber (reg:CC FLAGS_REG))]
9154 "ix86_binary_operator_ok (AND, SImode, operands)"
9156 switch (get_attr_type (insn))
9160 enum machine_mode mode;
9162 gcc_assert (CONST_INT_P (operands[2]));
9163 if (INTVAL (operands[2]) == 0xff)
9167 gcc_assert (INTVAL (operands[2]) == 0xffff);
9171 operands[1] = gen_lowpart (mode, operands[1]);
9173 return "movz{bl|x}\t{%1,%0|%0, %1}";
9175 return "movz{wl|x}\t{%1,%0|%0, %1}";
9179 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9180 return "and{l}\t{%2, %0|%0, %2}";
9183 [(set_attr "type" "alu,alu,imovx")
9184 (set_attr "length_immediate" "*,*,0")
9185 (set_attr "mode" "SI")])
9188 [(set (match_operand 0 "register_operand" "")
9190 (const_int -65536)))
9191 (clobber (reg:CC FLAGS_REG))]
9192 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9193 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9194 "operands[1] = gen_lowpart (HImode, operands[0]);")
9197 [(set (match_operand 0 "ext_register_operand" "")
9200 (clobber (reg:CC FLAGS_REG))]
9201 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9202 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9203 "operands[1] = gen_lowpart (QImode, operands[0]);")
9206 [(set (match_operand 0 "ext_register_operand" "")
9208 (const_int -65281)))
9209 (clobber (reg:CC FLAGS_REG))]
9210 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9211 [(parallel [(set (zero_extract:SI (match_dup 0)
9215 (zero_extract:SI (match_dup 0)
9218 (zero_extract:SI (match_dup 0)
9221 (clobber (reg:CC FLAGS_REG))])]
9222 "operands[0] = gen_lowpart (SImode, operands[0]);")
9224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9225 (define_insn "*andsi_1_zext"
9226 [(set (match_operand:DI 0 "register_operand" "=r")
9228 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9229 (match_operand:SI 2 "general_operand" "g"))))
9230 (clobber (reg:CC FLAGS_REG))]
9231 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9232 "and{l}\t{%2, %k0|%k0, %2}"
9233 [(set_attr "type" "alu")
9234 (set_attr "mode" "SI")])
9236 (define_insn "*andsi_2"
9237 [(set (reg FLAGS_REG)
9238 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9239 (match_operand:SI 2 "general_operand" "g,ri"))
9241 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9242 (and:SI (match_dup 1) (match_dup 2)))]
9243 "ix86_match_ccmode (insn, CCNOmode)
9244 && ix86_binary_operator_ok (AND, SImode, operands)"
9245 "and{l}\t{%2, %0|%0, %2}"
9246 [(set_attr "type" "alu")
9247 (set_attr "mode" "SI")])
9249 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9250 (define_insn "*andsi_2_zext"
9251 [(set (reg FLAGS_REG)
9252 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9253 (match_operand:SI 2 "general_operand" "g"))
9255 (set (match_operand:DI 0 "register_operand" "=r")
9256 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9257 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9258 && ix86_binary_operator_ok (AND, SImode, operands)"
9259 "and{l}\t{%2, %k0|%k0, %2}"
9260 [(set_attr "type" "alu")
9261 (set_attr "mode" "SI")])
9263 (define_expand "andhi3"
9264 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9265 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9266 (match_operand:HI 2 "general_operand" "")))]
9267 "TARGET_HIMODE_MATH"
9268 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9270 (define_insn "*andhi_1"
9271 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9272 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9273 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9274 (clobber (reg:CC FLAGS_REG))]
9275 "ix86_binary_operator_ok (AND, HImode, operands)"
9277 switch (get_attr_type (insn))
9280 gcc_assert (CONST_INT_P (operands[2]));
9281 gcc_assert (INTVAL (operands[2]) == 0xff);
9282 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9285 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9287 return "and{w}\t{%2, %0|%0, %2}";
9290 [(set_attr "type" "alu,alu,imovx")
9291 (set_attr "length_immediate" "*,*,0")
9292 (set_attr "mode" "HI,HI,SI")])
9294 (define_insn "*andhi_2"
9295 [(set (reg FLAGS_REG)
9296 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9297 (match_operand:HI 2 "general_operand" "rmn,rn"))
9299 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9300 (and:HI (match_dup 1) (match_dup 2)))]
9301 "ix86_match_ccmode (insn, CCNOmode)
9302 && ix86_binary_operator_ok (AND, HImode, operands)"
9303 "and{w}\t{%2, %0|%0, %2}"
9304 [(set_attr "type" "alu")
9305 (set_attr "mode" "HI")])
9307 (define_expand "andqi3"
9308 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9309 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9310 (match_operand:QI 2 "general_operand" "")))]
9311 "TARGET_QIMODE_MATH"
9312 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9314 ;; %%% Potential partial reg stall on alternative 2. What to do?
9315 (define_insn "*andqi_1"
9316 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9317 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9318 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "ix86_binary_operator_ok (AND, QImode, operands)"
9322 and{b}\t{%2, %0|%0, %2}
9323 and{b}\t{%2, %0|%0, %2}
9324 and{l}\t{%k2, %k0|%k0, %k2}"
9325 [(set_attr "type" "alu")
9326 (set_attr "mode" "QI,QI,SI")])
9328 (define_insn "*andqi_1_slp"
9329 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9330 (and:QI (match_dup 0)
9331 (match_operand:QI 1 "general_operand" "qn,qmn")))
9332 (clobber (reg:CC FLAGS_REG))]
9333 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9334 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9335 "and{b}\t{%1, %0|%0, %1}"
9336 [(set_attr "type" "alu1")
9337 (set_attr "mode" "QI")])
9339 (define_insn "*andqi_2_maybe_si"
9340 [(set (reg FLAGS_REG)
9342 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9343 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9345 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9346 (and:QI (match_dup 1) (match_dup 2)))]
9347 "ix86_binary_operator_ok (AND, QImode, operands)
9348 && ix86_match_ccmode (insn,
9349 CONST_INT_P (operands[2])
9350 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9352 if (which_alternative == 2)
9354 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9355 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9356 return "and{l}\t{%2, %k0|%k0, %2}";
9358 return "and{b}\t{%2, %0|%0, %2}";
9360 [(set_attr "type" "alu")
9361 (set_attr "mode" "QI,QI,SI")])
9363 (define_insn "*andqi_2"
9364 [(set (reg FLAGS_REG)
9366 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9367 (match_operand:QI 2 "general_operand" "qmn,qn"))
9369 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9370 (and:QI (match_dup 1) (match_dup 2)))]
9371 "ix86_match_ccmode (insn, CCNOmode)
9372 && ix86_binary_operator_ok (AND, QImode, operands)"
9373 "and{b}\t{%2, %0|%0, %2}"
9374 [(set_attr "type" "alu")
9375 (set_attr "mode" "QI")])
9377 (define_insn "*andqi_2_slp"
9378 [(set (reg FLAGS_REG)
9380 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9381 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9383 (set (strict_low_part (match_dup 0))
9384 (and:QI (match_dup 0) (match_dup 1)))]
9385 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9386 && ix86_match_ccmode (insn, CCNOmode)
9387 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9388 "and{b}\t{%1, %0|%0, %1}"
9389 [(set_attr "type" "alu1")
9390 (set_attr "mode" "QI")])
9392 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9393 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9394 ;; for a QImode operand, which of course failed.
9396 (define_insn "andqi_ext_0"
9397 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9402 (match_operand 1 "ext_register_operand" "0")
9405 (match_operand 2 "const_int_operand" "n")))
9406 (clobber (reg:CC FLAGS_REG))]
9408 "and{b}\t{%2, %h0|%h0, %2}"
9409 [(set_attr "type" "alu")
9410 (set_attr "length_immediate" "1")
9411 (set_attr "mode" "QI")])
9413 ;; Generated by peephole translating test to and. This shows up
9414 ;; often in fp comparisons.
9416 (define_insn "*andqi_ext_0_cc"
9417 [(set (reg FLAGS_REG)
9421 (match_operand 1 "ext_register_operand" "0")
9424 (match_operand 2 "const_int_operand" "n"))
9426 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9435 "ix86_match_ccmode (insn, CCNOmode)"
9436 "and{b}\t{%2, %h0|%h0, %2}"
9437 [(set_attr "type" "alu")
9438 (set_attr "length_immediate" "1")
9439 (set_attr "mode" "QI")])
9441 (define_insn "*andqi_ext_1"
9442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9447 (match_operand 1 "ext_register_operand" "0")
9451 (match_operand:QI 2 "general_operand" "Qm"))))
9452 (clobber (reg:CC FLAGS_REG))]
9454 "and{b}\t{%2, %h0|%h0, %2}"
9455 [(set_attr "type" "alu")
9456 (set_attr "length_immediate" "0")
9457 (set_attr "mode" "QI")])
9459 (define_insn "*andqi_ext_1_rex64"
9460 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9465 (match_operand 1 "ext_register_operand" "0")
9469 (match_operand 2 "ext_register_operand" "Q"))))
9470 (clobber (reg:CC FLAGS_REG))]
9472 "and{b}\t{%2, %h0|%h0, %2}"
9473 [(set_attr "type" "alu")
9474 (set_attr "length_immediate" "0")
9475 (set_attr "mode" "QI")])
9477 (define_insn "*andqi_ext_2"
9478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483 (match_operand 1 "ext_register_operand" "%0")
9487 (match_operand 2 "ext_register_operand" "Q")
9490 (clobber (reg:CC FLAGS_REG))]
9492 "and{b}\t{%h2, %h0|%h0, %h2}"
9493 [(set_attr "type" "alu")
9494 (set_attr "length_immediate" "0")
9495 (set_attr "mode" "QI")])
9497 ;; Convert wide AND instructions with immediate operand to shorter QImode
9498 ;; equivalents when possible.
9499 ;; Don't do the splitting with memory operands, since it introduces risk
9500 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9501 ;; for size, but that can (should?) be handled by generic code instead.
9503 [(set (match_operand 0 "register_operand" "")
9504 (and (match_operand 1 "register_operand" "")
9505 (match_operand 2 "const_int_operand" "")))
9506 (clobber (reg:CC FLAGS_REG))]
9508 && QI_REG_P (operands[0])
9509 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9510 && !(~INTVAL (operands[2]) & ~(255 << 8))
9511 && GET_MODE (operands[0]) != QImode"
9512 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9513 (and:SI (zero_extract:SI (match_dup 1)
9514 (const_int 8) (const_int 8))
9516 (clobber (reg:CC FLAGS_REG))])]
9517 "operands[0] = gen_lowpart (SImode, operands[0]);
9518 operands[1] = gen_lowpart (SImode, operands[1]);
9519 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9521 ;; Since AND can be encoded with sign extended immediate, this is only
9522 ;; profitable when 7th bit is not set.
9524 [(set (match_operand 0 "register_operand" "")
9525 (and (match_operand 1 "general_operand" "")
9526 (match_operand 2 "const_int_operand" "")))
9527 (clobber (reg:CC FLAGS_REG))]
9529 && ANY_QI_REG_P (operands[0])
9530 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9531 && !(~INTVAL (operands[2]) & ~255)
9532 && !(INTVAL (operands[2]) & 128)
9533 && GET_MODE (operands[0]) != QImode"
9534 [(parallel [(set (strict_low_part (match_dup 0))
9535 (and:QI (match_dup 1)
9537 (clobber (reg:CC FLAGS_REG))])]
9538 "operands[0] = gen_lowpart (QImode, operands[0]);
9539 operands[1] = gen_lowpart (QImode, operands[1]);
9540 operands[2] = gen_lowpart (QImode, operands[2]);")
9542 ;; Logical inclusive OR instructions
9544 ;; %%% This used to optimize known byte-wide and operations to memory.
9545 ;; If this is considered useful, it should be done with splitters.
9547 (define_expand "iordi3"
9548 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9549 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9550 (match_operand:DI 2 "x86_64_general_operand" "")))]
9552 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9554 (define_insn "*iordi_1_rex64"
9555 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9556 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9557 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9558 (clobber (reg:CC FLAGS_REG))]
9560 && ix86_binary_operator_ok (IOR, DImode, operands)"
9561 "or{q}\t{%2, %0|%0, %2}"
9562 [(set_attr "type" "alu")
9563 (set_attr "mode" "DI")])
9565 (define_insn "*iordi_2_rex64"
9566 [(set (reg FLAGS_REG)
9567 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9568 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9570 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9571 (ior:DI (match_dup 1) (match_dup 2)))]
9573 && ix86_match_ccmode (insn, CCNOmode)
9574 && ix86_binary_operator_ok (IOR, DImode, operands)"
9575 "or{q}\t{%2, %0|%0, %2}"
9576 [(set_attr "type" "alu")
9577 (set_attr "mode" "DI")])
9579 (define_insn "*iordi_3_rex64"
9580 [(set (reg FLAGS_REG)
9581 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9582 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9584 (clobber (match_scratch:DI 0 "=r"))]
9586 && ix86_match_ccmode (insn, CCNOmode)
9587 && ix86_binary_operator_ok (IOR, DImode, operands)"
9588 "or{q}\t{%2, %0|%0, %2}"
9589 [(set_attr "type" "alu")
9590 (set_attr "mode" "DI")])
9593 (define_expand "iorsi3"
9594 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9595 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9596 (match_operand:SI 2 "general_operand" "")))]
9598 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9600 (define_insn "*iorsi_1"
9601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9602 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9603 (match_operand:SI 2 "general_operand" "ri,g")))
9604 (clobber (reg:CC FLAGS_REG))]
9605 "ix86_binary_operator_ok (IOR, SImode, operands)"
9606 "or{l}\t{%2, %0|%0, %2}"
9607 [(set_attr "type" "alu")
9608 (set_attr "mode" "SI")])
9610 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9611 (define_insn "*iorsi_1_zext"
9612 [(set (match_operand:DI 0 "register_operand" "=r")
9614 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9615 (match_operand:SI 2 "general_operand" "g"))))
9616 (clobber (reg:CC FLAGS_REG))]
9617 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9618 "or{l}\t{%2, %k0|%k0, %2}"
9619 [(set_attr "type" "alu")
9620 (set_attr "mode" "SI")])
9622 (define_insn "*iorsi_1_zext_imm"
9623 [(set (match_operand:DI 0 "register_operand" "=r")
9624 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9625 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9626 (clobber (reg:CC FLAGS_REG))]
9628 "or{l}\t{%2, %k0|%k0, %2}"
9629 [(set_attr "type" "alu")
9630 (set_attr "mode" "SI")])
9632 (define_insn "*iorsi_2"
9633 [(set (reg FLAGS_REG)
9634 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9635 (match_operand:SI 2 "general_operand" "g,ri"))
9637 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9638 (ior:SI (match_dup 1) (match_dup 2)))]
9639 "ix86_match_ccmode (insn, CCNOmode)
9640 && ix86_binary_operator_ok (IOR, SImode, operands)"
9641 "or{l}\t{%2, %0|%0, %2}"
9642 [(set_attr "type" "alu")
9643 (set_attr "mode" "SI")])
9645 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9646 ;; ??? Special case for immediate operand is missing - it is tricky.
9647 (define_insn "*iorsi_2_zext"
9648 [(set (reg FLAGS_REG)
9649 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9650 (match_operand:SI 2 "general_operand" "g"))
9652 (set (match_operand:DI 0 "register_operand" "=r")
9653 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9654 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9655 && ix86_binary_operator_ok (IOR, SImode, operands)"
9656 "or{l}\t{%2, %k0|%k0, %2}"
9657 [(set_attr "type" "alu")
9658 (set_attr "mode" "SI")])
9660 (define_insn "*iorsi_2_zext_imm"
9661 [(set (reg FLAGS_REG)
9662 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9663 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9665 (set (match_operand:DI 0 "register_operand" "=r")
9666 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9667 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9668 && ix86_binary_operator_ok (IOR, SImode, operands)"
9669 "or{l}\t{%2, %k0|%k0, %2}"
9670 [(set_attr "type" "alu")
9671 (set_attr "mode" "SI")])
9673 (define_insn "*iorsi_3"
9674 [(set (reg FLAGS_REG)
9675 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9676 (match_operand:SI 2 "general_operand" "g"))
9678 (clobber (match_scratch:SI 0 "=r"))]
9679 "ix86_match_ccmode (insn, CCNOmode)
9680 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9681 "or{l}\t{%2, %0|%0, %2}"
9682 [(set_attr "type" "alu")
9683 (set_attr "mode" "SI")])
9685 (define_expand "iorhi3"
9686 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9687 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9688 (match_operand:HI 2 "general_operand" "")))]
9689 "TARGET_HIMODE_MATH"
9690 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9692 (define_insn "*iorhi_1"
9693 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9694 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9695 (match_operand:HI 2 "general_operand" "rmn,rn")))
9696 (clobber (reg:CC FLAGS_REG))]
9697 "ix86_binary_operator_ok (IOR, HImode, operands)"
9698 "or{w}\t{%2, %0|%0, %2}"
9699 [(set_attr "type" "alu")
9700 (set_attr "mode" "HI")])
9702 (define_insn "*iorhi_2"
9703 [(set (reg FLAGS_REG)
9704 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9705 (match_operand:HI 2 "general_operand" "rmn,rn"))
9707 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9708 (ior:HI (match_dup 1) (match_dup 2)))]
9709 "ix86_match_ccmode (insn, CCNOmode)
9710 && ix86_binary_operator_ok (IOR, HImode, operands)"
9711 "or{w}\t{%2, %0|%0, %2}"
9712 [(set_attr "type" "alu")
9713 (set_attr "mode" "HI")])
9715 (define_insn "*iorhi_3"
9716 [(set (reg FLAGS_REG)
9717 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9718 (match_operand:HI 2 "general_operand" "rmn"))
9720 (clobber (match_scratch:HI 0 "=r"))]
9721 "ix86_match_ccmode (insn, CCNOmode)
9722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9723 "or{w}\t{%2, %0|%0, %2}"
9724 [(set_attr "type" "alu")
9725 (set_attr "mode" "HI")])
9727 (define_expand "iorqi3"
9728 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9729 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9730 (match_operand:QI 2 "general_operand" "")))]
9731 "TARGET_QIMODE_MATH"
9732 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9734 ;; %%% Potential partial reg stall on alternative 2. What to do?
9735 (define_insn "*iorqi_1"
9736 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9737 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9738 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9739 (clobber (reg:CC FLAGS_REG))]
9740 "ix86_binary_operator_ok (IOR, QImode, operands)"
9742 or{b}\t{%2, %0|%0, %2}
9743 or{b}\t{%2, %0|%0, %2}
9744 or{l}\t{%k2, %k0|%k0, %k2}"
9745 [(set_attr "type" "alu")
9746 (set_attr "mode" "QI,QI,SI")])
9748 (define_insn "*iorqi_1_slp"
9749 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9750 (ior:QI (match_dup 0)
9751 (match_operand:QI 1 "general_operand" "qmn,qn")))
9752 (clobber (reg:CC FLAGS_REG))]
9753 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9754 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9755 "or{b}\t{%1, %0|%0, %1}"
9756 [(set_attr "type" "alu1")
9757 (set_attr "mode" "QI")])
9759 (define_insn "*iorqi_2"
9760 [(set (reg FLAGS_REG)
9761 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9762 (match_operand:QI 2 "general_operand" "qmn,qn"))
9764 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9765 (ior:QI (match_dup 1) (match_dup 2)))]
9766 "ix86_match_ccmode (insn, CCNOmode)
9767 && ix86_binary_operator_ok (IOR, QImode, operands)"
9768 "or{b}\t{%2, %0|%0, %2}"
9769 [(set_attr "type" "alu")
9770 (set_attr "mode" "QI")])
9772 (define_insn "*iorqi_2_slp"
9773 [(set (reg FLAGS_REG)
9774 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9775 (match_operand:QI 1 "general_operand" "qmn,qn"))
9777 (set (strict_low_part (match_dup 0))
9778 (ior:QI (match_dup 0) (match_dup 1)))]
9779 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9780 && ix86_match_ccmode (insn, CCNOmode)
9781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9782 "or{b}\t{%1, %0|%0, %1}"
9783 [(set_attr "type" "alu1")
9784 (set_attr "mode" "QI")])
9786 (define_insn "*iorqi_3"
9787 [(set (reg FLAGS_REG)
9788 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9789 (match_operand:QI 2 "general_operand" "qmn"))
9791 (clobber (match_scratch:QI 0 "=q"))]
9792 "ix86_match_ccmode (insn, CCNOmode)
9793 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9794 "or{b}\t{%2, %0|%0, %2}"
9795 [(set_attr "type" "alu")
9796 (set_attr "mode" "QI")])
9798 (define_insn "*iorqi_ext_0"
9799 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9804 (match_operand 1 "ext_register_operand" "0")
9807 (match_operand 2 "const_int_operand" "n")))
9808 (clobber (reg:CC FLAGS_REG))]
9809 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9810 "or{b}\t{%2, %h0|%h0, %2}"
9811 [(set_attr "type" "alu")
9812 (set_attr "length_immediate" "1")
9813 (set_attr "mode" "QI")])
9815 (define_insn "*iorqi_ext_1"
9816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9821 (match_operand 1 "ext_register_operand" "0")
9825 (match_operand:QI 2 "general_operand" "Qm"))))
9826 (clobber (reg:CC FLAGS_REG))]
9828 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9829 "or{b}\t{%2, %h0|%h0, %2}"
9830 [(set_attr "type" "alu")
9831 (set_attr "length_immediate" "0")
9832 (set_attr "mode" "QI")])
9834 (define_insn "*iorqi_ext_1_rex64"
9835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9840 (match_operand 1 "ext_register_operand" "0")
9844 (match_operand 2 "ext_register_operand" "Q"))))
9845 (clobber (reg:CC FLAGS_REG))]
9847 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9848 "or{b}\t{%2, %h0|%h0, %2}"
9849 [(set_attr "type" "alu")
9850 (set_attr "length_immediate" "0")
9851 (set_attr "mode" "QI")])
9853 (define_insn "*iorqi_ext_2"
9854 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9858 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9861 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9864 (clobber (reg:CC FLAGS_REG))]
9865 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9866 "ior{b}\t{%h2, %h0|%h0, %h2}"
9867 [(set_attr "type" "alu")
9868 (set_attr "length_immediate" "0")
9869 (set_attr "mode" "QI")])
9872 [(set (match_operand 0 "register_operand" "")
9873 (ior (match_operand 1 "register_operand" "")
9874 (match_operand 2 "const_int_operand" "")))
9875 (clobber (reg:CC FLAGS_REG))]
9877 && QI_REG_P (operands[0])
9878 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9879 && !(INTVAL (operands[2]) & ~(255 << 8))
9880 && GET_MODE (operands[0]) != QImode"
9881 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9882 (ior:SI (zero_extract:SI (match_dup 1)
9883 (const_int 8) (const_int 8))
9885 (clobber (reg:CC FLAGS_REG))])]
9886 "operands[0] = gen_lowpart (SImode, operands[0]);
9887 operands[1] = gen_lowpart (SImode, operands[1]);
9888 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9890 ;; Since OR can be encoded with sign extended immediate, this is only
9891 ;; profitable when 7th bit is set.
9893 [(set (match_operand 0 "register_operand" "")
9894 (ior (match_operand 1 "general_operand" "")
9895 (match_operand 2 "const_int_operand" "")))
9896 (clobber (reg:CC FLAGS_REG))]
9898 && ANY_QI_REG_P (operands[0])
9899 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9900 && !(INTVAL (operands[2]) & ~255)
9901 && (INTVAL (operands[2]) & 128)
9902 && GET_MODE (operands[0]) != QImode"
9903 [(parallel [(set (strict_low_part (match_dup 0))
9904 (ior:QI (match_dup 1)
9906 (clobber (reg:CC FLAGS_REG))])]
9907 "operands[0] = gen_lowpart (QImode, operands[0]);
9908 operands[1] = gen_lowpart (QImode, operands[1]);
9909 operands[2] = gen_lowpart (QImode, operands[2]);")
9911 ;; Logical XOR instructions
9913 ;; %%% This used to optimize known byte-wide and operations to memory.
9914 ;; If this is considered useful, it should be done with splitters.
9916 (define_expand "xordi3"
9917 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9918 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9919 (match_operand:DI 2 "x86_64_general_operand" "")))]
9921 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9923 (define_insn "*xordi_1_rex64"
9924 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9925 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9926 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9927 (clobber (reg:CC FLAGS_REG))]
9929 && ix86_binary_operator_ok (XOR, DImode, operands)"
9930 "xor{q}\t{%2, %0|%0, %2}"
9931 [(set_attr "type" "alu")
9932 (set_attr "mode" "DI")])
9934 (define_insn "*xordi_2_rex64"
9935 [(set (reg FLAGS_REG)
9936 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9937 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9939 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9940 (xor:DI (match_dup 1) (match_dup 2)))]
9942 && ix86_match_ccmode (insn, CCNOmode)
9943 && ix86_binary_operator_ok (XOR, DImode, operands)"
9944 "xor{q}\t{%2, %0|%0, %2}"
9945 [(set_attr "type" "alu")
9946 (set_attr "mode" "DI")])
9948 (define_insn "*xordi_3_rex64"
9949 [(set (reg FLAGS_REG)
9950 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9951 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9953 (clobber (match_scratch:DI 0 "=r"))]
9955 && ix86_match_ccmode (insn, CCNOmode)
9956 && ix86_binary_operator_ok (XOR, DImode, operands)"
9957 "xor{q}\t{%2, %0|%0, %2}"
9958 [(set_attr "type" "alu")
9959 (set_attr "mode" "DI")])
9961 (define_expand "xorsi3"
9962 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9963 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9964 (match_operand:SI 2 "general_operand" "")))]
9966 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9968 (define_insn "*xorsi_1"
9969 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9970 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9971 (match_operand:SI 2 "general_operand" "ri,rm")))
9972 (clobber (reg:CC FLAGS_REG))]
9973 "ix86_binary_operator_ok (XOR, SImode, operands)"
9974 "xor{l}\t{%2, %0|%0, %2}"
9975 [(set_attr "type" "alu")
9976 (set_attr "mode" "SI")])
9978 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9979 ;; Add speccase for immediates
9980 (define_insn "*xorsi_1_zext"
9981 [(set (match_operand:DI 0 "register_operand" "=r")
9983 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9984 (match_operand:SI 2 "general_operand" "g"))))
9985 (clobber (reg:CC FLAGS_REG))]
9986 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9987 "xor{l}\t{%2, %k0|%k0, %2}"
9988 [(set_attr "type" "alu")
9989 (set_attr "mode" "SI")])
9991 (define_insn "*xorsi_1_zext_imm"
9992 [(set (match_operand:DI 0 "register_operand" "=r")
9993 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9994 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9995 (clobber (reg:CC FLAGS_REG))]
9996 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9997 "xor{l}\t{%2, %k0|%k0, %2}"
9998 [(set_attr "type" "alu")
9999 (set_attr "mode" "SI")])
10001 (define_insn "*xorsi_2"
10002 [(set (reg FLAGS_REG)
10003 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10004 (match_operand:SI 2 "general_operand" "g,ri"))
10006 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10007 (xor:SI (match_dup 1) (match_dup 2)))]
10008 "ix86_match_ccmode (insn, CCNOmode)
10009 && ix86_binary_operator_ok (XOR, SImode, operands)"
10010 "xor{l}\t{%2, %0|%0, %2}"
10011 [(set_attr "type" "alu")
10012 (set_attr "mode" "SI")])
10014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10015 ;; ??? Special case for immediate operand is missing - it is tricky.
10016 (define_insn "*xorsi_2_zext"
10017 [(set (reg FLAGS_REG)
10018 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10019 (match_operand:SI 2 "general_operand" "g"))
10021 (set (match_operand:DI 0 "register_operand" "=r")
10022 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10023 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10024 && ix86_binary_operator_ok (XOR, SImode, operands)"
10025 "xor{l}\t{%2, %k0|%k0, %2}"
10026 [(set_attr "type" "alu")
10027 (set_attr "mode" "SI")])
10029 (define_insn "*xorsi_2_zext_imm"
10030 [(set (reg FLAGS_REG)
10031 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10032 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10034 (set (match_operand:DI 0 "register_operand" "=r")
10035 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10036 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10037 && ix86_binary_operator_ok (XOR, SImode, operands)"
10038 "xor{l}\t{%2, %k0|%k0, %2}"
10039 [(set_attr "type" "alu")
10040 (set_attr "mode" "SI")])
10042 (define_insn "*xorsi_3"
10043 [(set (reg FLAGS_REG)
10044 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10045 (match_operand:SI 2 "general_operand" "g"))
10047 (clobber (match_scratch:SI 0 "=r"))]
10048 "ix86_match_ccmode (insn, CCNOmode)
10049 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10050 "xor{l}\t{%2, %0|%0, %2}"
10051 [(set_attr "type" "alu")
10052 (set_attr "mode" "SI")])
10054 (define_expand "xorhi3"
10055 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10056 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10057 (match_operand:HI 2 "general_operand" "")))]
10058 "TARGET_HIMODE_MATH"
10059 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10061 (define_insn "*xorhi_1"
10062 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10063 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10064 (match_operand:HI 2 "general_operand" "rmn,rn")))
10065 (clobber (reg:CC FLAGS_REG))]
10066 "ix86_binary_operator_ok (XOR, HImode, operands)"
10067 "xor{w}\t{%2, %0|%0, %2}"
10068 [(set_attr "type" "alu")
10069 (set_attr "mode" "HI")])
10071 (define_insn "*xorhi_2"
10072 [(set (reg FLAGS_REG)
10073 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10074 (match_operand:HI 2 "general_operand" "rmn,rn"))
10076 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10077 (xor:HI (match_dup 1) (match_dup 2)))]
10078 "ix86_match_ccmode (insn, CCNOmode)
10079 && ix86_binary_operator_ok (XOR, HImode, operands)"
10080 "xor{w}\t{%2, %0|%0, %2}"
10081 [(set_attr "type" "alu")
10082 (set_attr "mode" "HI")])
10084 (define_insn "*xorhi_3"
10085 [(set (reg FLAGS_REG)
10086 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10087 (match_operand:HI 2 "general_operand" "rmn"))
10089 (clobber (match_scratch:HI 0 "=r"))]
10090 "ix86_match_ccmode (insn, CCNOmode)
10091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10092 "xor{w}\t{%2, %0|%0, %2}"
10093 [(set_attr "type" "alu")
10094 (set_attr "mode" "HI")])
10096 (define_expand "xorqi3"
10097 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10098 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10099 (match_operand:QI 2 "general_operand" "")))]
10100 "TARGET_QIMODE_MATH"
10101 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10103 ;; %%% Potential partial reg stall on alternative 2. What to do?
10104 (define_insn "*xorqi_1"
10105 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10106 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10107 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10108 (clobber (reg:CC FLAGS_REG))]
10109 "ix86_binary_operator_ok (XOR, QImode, operands)"
10111 xor{b}\t{%2, %0|%0, %2}
10112 xor{b}\t{%2, %0|%0, %2}
10113 xor{l}\t{%k2, %k0|%k0, %k2}"
10114 [(set_attr "type" "alu")
10115 (set_attr "mode" "QI,QI,SI")])
10117 (define_insn "*xorqi_1_slp"
10118 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10119 (xor:QI (match_dup 0)
10120 (match_operand:QI 1 "general_operand" "qn,qmn")))
10121 (clobber (reg:CC FLAGS_REG))]
10122 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10123 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10124 "xor{b}\t{%1, %0|%0, %1}"
10125 [(set_attr "type" "alu1")
10126 (set_attr "mode" "QI")])
10128 (define_insn "*xorqi_ext_0"
10129 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10134 (match_operand 1 "ext_register_operand" "0")
10137 (match_operand 2 "const_int_operand" "n")))
10138 (clobber (reg:CC FLAGS_REG))]
10139 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10140 "xor{b}\t{%2, %h0|%h0, %2}"
10141 [(set_attr "type" "alu")
10142 (set_attr "length_immediate" "1")
10143 (set_attr "mode" "QI")])
10145 (define_insn "*xorqi_ext_1"
10146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10151 (match_operand 1 "ext_register_operand" "0")
10155 (match_operand:QI 2 "general_operand" "Qm"))))
10156 (clobber (reg:CC FLAGS_REG))]
10158 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10159 "xor{b}\t{%2, %h0|%h0, %2}"
10160 [(set_attr "type" "alu")
10161 (set_attr "length_immediate" "0")
10162 (set_attr "mode" "QI")])
10164 (define_insn "*xorqi_ext_1_rex64"
10165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10170 (match_operand 1 "ext_register_operand" "0")
10174 (match_operand 2 "ext_register_operand" "Q"))))
10175 (clobber (reg:CC FLAGS_REG))]
10177 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10178 "xor{b}\t{%2, %h0|%h0, %2}"
10179 [(set_attr "type" "alu")
10180 (set_attr "length_immediate" "0")
10181 (set_attr "mode" "QI")])
10183 (define_insn "*xorqi_ext_2"
10184 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10188 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10191 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10194 (clobber (reg:CC FLAGS_REG))]
10195 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10196 "xor{b}\t{%h2, %h0|%h0, %h2}"
10197 [(set_attr "type" "alu")
10198 (set_attr "length_immediate" "0")
10199 (set_attr "mode" "QI")])
10201 (define_insn "*xorqi_cc_1"
10202 [(set (reg FLAGS_REG)
10204 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10205 (match_operand:QI 2 "general_operand" "qmn,qn"))
10207 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10208 (xor:QI (match_dup 1) (match_dup 2)))]
10209 "ix86_match_ccmode (insn, CCNOmode)
10210 && ix86_binary_operator_ok (XOR, QImode, operands)"
10211 "xor{b}\t{%2, %0|%0, %2}"
10212 [(set_attr "type" "alu")
10213 (set_attr "mode" "QI")])
10215 (define_insn "*xorqi_2_slp"
10216 [(set (reg FLAGS_REG)
10217 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10218 (match_operand:QI 1 "general_operand" "qmn,qn"))
10220 (set (strict_low_part (match_dup 0))
10221 (xor:QI (match_dup 0) (match_dup 1)))]
10222 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10223 && ix86_match_ccmode (insn, CCNOmode)
10224 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10225 "xor{b}\t{%1, %0|%0, %1}"
10226 [(set_attr "type" "alu1")
10227 (set_attr "mode" "QI")])
10229 (define_insn "*xorqi_cc_2"
10230 [(set (reg FLAGS_REG)
10232 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10233 (match_operand:QI 2 "general_operand" "qmn"))
10235 (clobber (match_scratch:QI 0 "=q"))]
10236 "ix86_match_ccmode (insn, CCNOmode)
10237 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10238 "xor{b}\t{%2, %0|%0, %2}"
10239 [(set_attr "type" "alu")
10240 (set_attr "mode" "QI")])
10242 (define_insn "*xorqi_cc_ext_1"
10243 [(set (reg FLAGS_REG)
10247 (match_operand 1 "ext_register_operand" "0")
10250 (match_operand:QI 2 "general_operand" "qmn"))
10252 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10256 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10258 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10259 "xor{b}\t{%2, %h0|%h0, %2}"
10260 [(set_attr "type" "alu")
10261 (set_attr "mode" "QI")])
10263 (define_insn "*xorqi_cc_ext_1_rex64"
10264 [(set (reg FLAGS_REG)
10268 (match_operand 1 "ext_register_operand" "0")
10271 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10273 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10277 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10279 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10280 "xor{b}\t{%2, %h0|%h0, %2}"
10281 [(set_attr "type" "alu")
10282 (set_attr "mode" "QI")])
10284 (define_expand "xorqi_cc_ext_1"
10286 (set (reg:CCNO FLAGS_REG)
10290 (match_operand 1 "ext_register_operand" "")
10293 (match_operand:QI 2 "general_operand" ""))
10295 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10299 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10305 [(set (match_operand 0 "register_operand" "")
10306 (xor (match_operand 1 "register_operand" "")
10307 (match_operand 2 "const_int_operand" "")))
10308 (clobber (reg:CC FLAGS_REG))]
10310 && QI_REG_P (operands[0])
10311 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10312 && !(INTVAL (operands[2]) & ~(255 << 8))
10313 && GET_MODE (operands[0]) != QImode"
10314 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10315 (xor:SI (zero_extract:SI (match_dup 1)
10316 (const_int 8) (const_int 8))
10318 (clobber (reg:CC FLAGS_REG))])]
10319 "operands[0] = gen_lowpart (SImode, operands[0]);
10320 operands[1] = gen_lowpart (SImode, operands[1]);
10321 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10323 ;; Since XOR can be encoded with sign extended immediate, this is only
10324 ;; profitable when 7th bit is set.
10326 [(set (match_operand 0 "register_operand" "")
10327 (xor (match_operand 1 "general_operand" "")
10328 (match_operand 2 "const_int_operand" "")))
10329 (clobber (reg:CC FLAGS_REG))]
10331 && ANY_QI_REG_P (operands[0])
10332 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10333 && !(INTVAL (operands[2]) & ~255)
10334 && (INTVAL (operands[2]) & 128)
10335 && GET_MODE (operands[0]) != QImode"
10336 [(parallel [(set (strict_low_part (match_dup 0))
10337 (xor:QI (match_dup 1)
10339 (clobber (reg:CC FLAGS_REG))])]
10340 "operands[0] = gen_lowpart (QImode, operands[0]);
10341 operands[1] = gen_lowpart (QImode, operands[1]);
10342 operands[2] = gen_lowpart (QImode, operands[2]);")
10344 ;; Negation instructions
10346 (define_expand "negti2"
10347 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10348 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10350 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10352 (define_insn "*negti2_1"
10353 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10354 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10355 (clobber (reg:CC FLAGS_REG))]
10357 && ix86_unary_operator_ok (NEG, TImode, operands)"
10361 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10362 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "TARGET_64BIT && reload_completed"
10366 [(set (reg:CCZ FLAGS_REG)
10367 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10368 (set (match_dup 0) (neg:DI (match_dup 1)))])
10370 [(set (match_dup 2)
10371 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10374 (clobber (reg:CC FLAGS_REG))])
10376 [(set (match_dup 2)
10377 (neg:DI (match_dup 2)))
10378 (clobber (reg:CC FLAGS_REG))])]
10379 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10381 (define_expand "negdi2"
10382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10385 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10387 (define_insn "*negdi2_1"
10388 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10389 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10390 (clobber (reg:CC FLAGS_REG))]
10392 && ix86_unary_operator_ok (NEG, DImode, operands)"
10396 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10397 (neg:DI (match_operand:DI 1 "general_operand" "")))
10398 (clobber (reg:CC FLAGS_REG))]
10399 "!TARGET_64BIT && reload_completed"
10401 [(set (reg:CCZ FLAGS_REG)
10402 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10403 (set (match_dup 0) (neg:SI (match_dup 1)))])
10405 [(set (match_dup 2)
10406 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10409 (clobber (reg:CC FLAGS_REG))])
10411 [(set (match_dup 2)
10412 (neg:SI (match_dup 2)))
10413 (clobber (reg:CC FLAGS_REG))])]
10414 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10416 (define_insn "*negdi2_1_rex64"
10417 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10418 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10422 [(set_attr "type" "negnot")
10423 (set_attr "mode" "DI")])
10425 ;; The problem with neg is that it does not perform (compare x 0),
10426 ;; it really performs (compare 0 x), which leaves us with the zero
10427 ;; flag being the only useful item.
10429 (define_insn "*negdi2_cmpz_rex64"
10430 [(set (reg:CCZ FLAGS_REG)
10431 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10433 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434 (neg:DI (match_dup 1)))]
10435 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10437 [(set_attr "type" "negnot")
10438 (set_attr "mode" "DI")])
10441 (define_expand "negsi2"
10442 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10443 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10445 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10447 (define_insn "*negsi2_1"
10448 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10449 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10450 (clobber (reg:CC FLAGS_REG))]
10451 "ix86_unary_operator_ok (NEG, SImode, operands)"
10453 [(set_attr "type" "negnot")
10454 (set_attr "mode" "SI")])
10456 ;; Combine is quite creative about this pattern.
10457 (define_insn "*negsi2_1_zext"
10458 [(set (match_operand:DI 0 "register_operand" "=r")
10459 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10462 (clobber (reg:CC FLAGS_REG))]
10463 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10465 [(set_attr "type" "negnot")
10466 (set_attr "mode" "SI")])
10468 ;; The problem with neg is that it does not perform (compare x 0),
10469 ;; it really performs (compare 0 x), which leaves us with the zero
10470 ;; flag being the only useful item.
10472 (define_insn "*negsi2_cmpz"
10473 [(set (reg:CCZ FLAGS_REG)
10474 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10476 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10477 (neg:SI (match_dup 1)))]
10478 "ix86_unary_operator_ok (NEG, SImode, operands)"
10480 [(set_attr "type" "negnot")
10481 (set_attr "mode" "SI")])
10483 (define_insn "*negsi2_cmpz_zext"
10484 [(set (reg:CCZ FLAGS_REG)
10485 (compare:CCZ (lshiftrt:DI
10487 (match_operand:DI 1 "register_operand" "0")
10491 (set (match_operand:DI 0 "register_operand" "=r")
10492 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10495 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10497 [(set_attr "type" "negnot")
10498 (set_attr "mode" "SI")])
10500 (define_expand "neghi2"
10501 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10502 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10503 "TARGET_HIMODE_MATH"
10504 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10506 (define_insn "*neghi2_1"
10507 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10508 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10509 (clobber (reg:CC FLAGS_REG))]
10510 "ix86_unary_operator_ok (NEG, HImode, operands)"
10512 [(set_attr "type" "negnot")
10513 (set_attr "mode" "HI")])
10515 (define_insn "*neghi2_cmpz"
10516 [(set (reg:CCZ FLAGS_REG)
10517 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10519 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10520 (neg:HI (match_dup 1)))]
10521 "ix86_unary_operator_ok (NEG, HImode, operands)"
10523 [(set_attr "type" "negnot")
10524 (set_attr "mode" "HI")])
10526 (define_expand "negqi2"
10527 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10528 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10529 "TARGET_QIMODE_MATH"
10530 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10532 (define_insn "*negqi2_1"
10533 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10534 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10535 (clobber (reg:CC FLAGS_REG))]
10536 "ix86_unary_operator_ok (NEG, QImode, operands)"
10538 [(set_attr "type" "negnot")
10539 (set_attr "mode" "QI")])
10541 (define_insn "*negqi2_cmpz"
10542 [(set (reg:CCZ FLAGS_REG)
10543 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10545 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10546 (neg:QI (match_dup 1)))]
10547 "ix86_unary_operator_ok (NEG, QImode, operands)"
10549 [(set_attr "type" "negnot")
10550 (set_attr "mode" "QI")])
10552 ;; Changing of sign for FP values is doable using integer unit too.
10554 (define_expand "<code><mode>2"
10555 [(set (match_operand:X87MODEF 0 "register_operand" "")
10556 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10557 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10558 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10560 (define_insn "*absneg<mode>2_mixed"
10561 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10562 (match_operator:MODEF 3 "absneg_operator"
10563 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10564 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10565 (clobber (reg:CC FLAGS_REG))]
10566 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10569 (define_insn "*absneg<mode>2_sse"
10570 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10571 (match_operator:MODEF 3 "absneg_operator"
10572 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10573 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10574 (clobber (reg:CC FLAGS_REG))]
10575 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10578 (define_insn "*absneg<mode>2_i387"
10579 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10580 (match_operator:X87MODEF 3 "absneg_operator"
10581 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10582 (use (match_operand 2 "" ""))
10583 (clobber (reg:CC FLAGS_REG))]
10584 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10587 (define_expand "<code>tf2"
10588 [(set (match_operand:TF 0 "register_operand" "")
10589 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10591 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10593 (define_insn "*absnegtf2_sse"
10594 [(set (match_operand:TF 0 "register_operand" "=x,x")
10595 (match_operator:TF 3 "absneg_operator"
10596 [(match_operand:TF 1 "register_operand" "0,x")]))
10597 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10598 (clobber (reg:CC FLAGS_REG))]
10602 ;; Splitters for fp abs and neg.
10605 [(set (match_operand 0 "fp_register_operand" "")
10606 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10607 (use (match_operand 2 "" ""))
10608 (clobber (reg:CC FLAGS_REG))]
10610 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10613 [(set (match_operand 0 "register_operand" "")
10614 (match_operator 3 "absneg_operator"
10615 [(match_operand 1 "register_operand" "")]))
10616 (use (match_operand 2 "nonimmediate_operand" ""))
10617 (clobber (reg:CC FLAGS_REG))]
10618 "reload_completed && SSE_REG_P (operands[0])"
10619 [(set (match_dup 0) (match_dup 3))]
10621 enum machine_mode mode = GET_MODE (operands[0]);
10622 enum machine_mode vmode = GET_MODE (operands[2]);
10625 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10626 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10627 if (operands_match_p (operands[0], operands[2]))
10630 operands[1] = operands[2];
10633 if (GET_CODE (operands[3]) == ABS)
10634 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10636 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10641 [(set (match_operand:SF 0 "register_operand" "")
10642 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10643 (use (match_operand:V4SF 2 "" ""))
10644 (clobber (reg:CC FLAGS_REG))]
10646 [(parallel [(set (match_dup 0) (match_dup 1))
10647 (clobber (reg:CC FLAGS_REG))])]
10650 operands[0] = gen_lowpart (SImode, operands[0]);
10651 if (GET_CODE (operands[1]) == ABS)
10653 tmp = gen_int_mode (0x7fffffff, SImode);
10654 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10658 tmp = gen_int_mode (0x80000000, SImode);
10659 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10665 [(set (match_operand:DF 0 "register_operand" "")
10666 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10667 (use (match_operand 2 "" ""))
10668 (clobber (reg:CC FLAGS_REG))]
10670 [(parallel [(set (match_dup 0) (match_dup 1))
10671 (clobber (reg:CC FLAGS_REG))])]
10676 tmp = gen_lowpart (DImode, operands[0]);
10677 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10680 if (GET_CODE (operands[1]) == ABS)
10683 tmp = gen_rtx_NOT (DImode, tmp);
10687 operands[0] = gen_highpart (SImode, operands[0]);
10688 if (GET_CODE (operands[1]) == ABS)
10690 tmp = gen_int_mode (0x7fffffff, SImode);
10691 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10695 tmp = gen_int_mode (0x80000000, SImode);
10696 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10703 [(set (match_operand:XF 0 "register_operand" "")
10704 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10705 (use (match_operand 2 "" ""))
10706 (clobber (reg:CC FLAGS_REG))]
10708 [(parallel [(set (match_dup 0) (match_dup 1))
10709 (clobber (reg:CC FLAGS_REG))])]
10712 operands[0] = gen_rtx_REG (SImode,
10713 true_regnum (operands[0])
10714 + (TARGET_64BIT ? 1 : 2));
10715 if (GET_CODE (operands[1]) == ABS)
10717 tmp = GEN_INT (0x7fff);
10718 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10722 tmp = GEN_INT (0x8000);
10723 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10728 ;; Conditionalize these after reload. If they match before reload, we
10729 ;; lose the clobber and ability to use integer instructions.
10731 (define_insn "*<code><mode>2_1"
10732 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10733 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10735 && (reload_completed
10736 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10738 [(set_attr "type" "fsgn")
10739 (set_attr "mode" "<MODE>")])
10741 (define_insn "*<code>extendsfdf2"
10742 [(set (match_operand:DF 0 "register_operand" "=f")
10743 (absneg:DF (float_extend:DF
10744 (match_operand:SF 1 "register_operand" "0"))))]
10745 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10747 [(set_attr "type" "fsgn")
10748 (set_attr "mode" "DF")])
10750 (define_insn "*<code>extendsfxf2"
10751 [(set (match_operand:XF 0 "register_operand" "=f")
10752 (absneg:XF (float_extend:XF
10753 (match_operand:SF 1 "register_operand" "0"))))]
10756 [(set_attr "type" "fsgn")
10757 (set_attr "mode" "XF")])
10759 (define_insn "*<code>extenddfxf2"
10760 [(set (match_operand:XF 0 "register_operand" "=f")
10761 (absneg:XF (float_extend:XF
10762 (match_operand:DF 1 "register_operand" "0"))))]
10765 [(set_attr "type" "fsgn")
10766 (set_attr "mode" "XF")])
10768 ;; Copysign instructions
10770 (define_mode_iterator CSGNMODE [SF DF TF])
10771 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10773 (define_expand "copysign<mode>3"
10774 [(match_operand:CSGNMODE 0 "register_operand" "")
10775 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10776 (match_operand:CSGNMODE 2 "register_operand" "")]
10777 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10778 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10780 ix86_expand_copysign (operands);
10784 (define_insn_and_split "copysign<mode>3_const"
10785 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10787 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10788 (match_operand:CSGNMODE 2 "register_operand" "0")
10789 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10791 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10792 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10794 "&& reload_completed"
10797 ix86_split_copysign_const (operands);
10801 (define_insn "copysign<mode>3_var"
10802 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10804 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10805 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10806 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10807 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10809 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10810 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10811 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10815 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10817 [(match_operand:CSGNMODE 2 "register_operand" "")
10818 (match_operand:CSGNMODE 3 "register_operand" "")
10819 (match_operand:<CSGNVMODE> 4 "" "")
10820 (match_operand:<CSGNVMODE> 5 "" "")]
10822 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10823 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10824 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10825 && reload_completed"
10828 ix86_split_copysign_var (operands);
10832 ;; One complement instructions
10834 (define_expand "one_cmpldi2"
10835 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10836 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10838 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10840 (define_insn "*one_cmpldi2_1_rex64"
10841 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10842 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10843 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10845 [(set_attr "type" "negnot")
10846 (set_attr "mode" "DI")])
10848 (define_insn "*one_cmpldi2_2_rex64"
10849 [(set (reg FLAGS_REG)
10850 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10852 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10853 (not:DI (match_dup 1)))]
10854 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10855 && ix86_unary_operator_ok (NOT, DImode, operands)"
10857 [(set_attr "type" "alu1")
10858 (set_attr "mode" "DI")])
10861 [(set (match_operand 0 "flags_reg_operand" "")
10862 (match_operator 2 "compare_operator"
10863 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10865 (set (match_operand:DI 1 "nonimmediate_operand" "")
10866 (not:DI (match_dup 3)))]
10867 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10868 [(parallel [(set (match_dup 0)
10870 [(xor:DI (match_dup 3) (const_int -1))
10873 (xor:DI (match_dup 3) (const_int -1)))])]
10876 (define_expand "one_cmplsi2"
10877 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10878 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10880 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10882 (define_insn "*one_cmplsi2_1"
10883 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10884 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10885 "ix86_unary_operator_ok (NOT, SImode, operands)"
10887 [(set_attr "type" "negnot")
10888 (set_attr "mode" "SI")])
10890 ;; ??? Currently never generated - xor is used instead.
10891 (define_insn "*one_cmplsi2_1_zext"
10892 [(set (match_operand:DI 0 "register_operand" "=r")
10893 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10894 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10896 [(set_attr "type" "negnot")
10897 (set_attr "mode" "SI")])
10899 (define_insn "*one_cmplsi2_2"
10900 [(set (reg FLAGS_REG)
10901 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10903 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10904 (not:SI (match_dup 1)))]
10905 "ix86_match_ccmode (insn, CCNOmode)
10906 && ix86_unary_operator_ok (NOT, SImode, operands)"
10908 [(set_attr "type" "alu1")
10909 (set_attr "mode" "SI")])
10912 [(set (match_operand 0 "flags_reg_operand" "")
10913 (match_operator 2 "compare_operator"
10914 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10916 (set (match_operand:SI 1 "nonimmediate_operand" "")
10917 (not:SI (match_dup 3)))]
10918 "ix86_match_ccmode (insn, CCNOmode)"
10919 [(parallel [(set (match_dup 0)
10920 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10923 (xor:SI (match_dup 3) (const_int -1)))])]
10926 ;; ??? Currently never generated - xor is used instead.
10927 (define_insn "*one_cmplsi2_2_zext"
10928 [(set (reg FLAGS_REG)
10929 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10931 (set (match_operand:DI 0 "register_operand" "=r")
10932 (zero_extend:DI (not:SI (match_dup 1))))]
10933 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10934 && ix86_unary_operator_ok (NOT, SImode, operands)"
10936 [(set_attr "type" "alu1")
10937 (set_attr "mode" "SI")])
10940 [(set (match_operand 0 "flags_reg_operand" "")
10941 (match_operator 2 "compare_operator"
10942 [(not:SI (match_operand:SI 3 "register_operand" ""))
10944 (set (match_operand:DI 1 "register_operand" "")
10945 (zero_extend:DI (not:SI (match_dup 3))))]
10946 "ix86_match_ccmode (insn, CCNOmode)"
10947 [(parallel [(set (match_dup 0)
10948 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10951 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10954 (define_expand "one_cmplhi2"
10955 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10956 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10957 "TARGET_HIMODE_MATH"
10958 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10960 (define_insn "*one_cmplhi2_1"
10961 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10962 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10963 "ix86_unary_operator_ok (NOT, HImode, operands)"
10965 [(set_attr "type" "negnot")
10966 (set_attr "mode" "HI")])
10968 (define_insn "*one_cmplhi2_2"
10969 [(set (reg FLAGS_REG)
10970 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10972 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10973 (not:HI (match_dup 1)))]
10974 "ix86_match_ccmode (insn, CCNOmode)
10975 && ix86_unary_operator_ok (NEG, HImode, operands)"
10977 [(set_attr "type" "alu1")
10978 (set_attr "mode" "HI")])
10981 [(set (match_operand 0 "flags_reg_operand" "")
10982 (match_operator 2 "compare_operator"
10983 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10985 (set (match_operand:HI 1 "nonimmediate_operand" "")
10986 (not:HI (match_dup 3)))]
10987 "ix86_match_ccmode (insn, CCNOmode)"
10988 [(parallel [(set (match_dup 0)
10989 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10992 (xor:HI (match_dup 3) (const_int -1)))])]
10995 ;; %%% Potential partial reg stall on alternative 1. What to do?
10996 (define_expand "one_cmplqi2"
10997 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10998 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10999 "TARGET_QIMODE_MATH"
11000 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11002 (define_insn "*one_cmplqi2_1"
11003 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11004 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11005 "ix86_unary_operator_ok (NOT, QImode, operands)"
11009 [(set_attr "type" "negnot")
11010 (set_attr "mode" "QI,SI")])
11012 (define_insn "*one_cmplqi2_2"
11013 [(set (reg FLAGS_REG)
11014 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11016 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11017 (not:QI (match_dup 1)))]
11018 "ix86_match_ccmode (insn, CCNOmode)
11019 && ix86_unary_operator_ok (NOT, QImode, operands)"
11021 [(set_attr "type" "alu1")
11022 (set_attr "mode" "QI")])
11025 [(set (match_operand 0 "flags_reg_operand" "")
11026 (match_operator 2 "compare_operator"
11027 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11029 (set (match_operand:QI 1 "nonimmediate_operand" "")
11030 (not:QI (match_dup 3)))]
11031 "ix86_match_ccmode (insn, CCNOmode)"
11032 [(parallel [(set (match_dup 0)
11033 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11036 (xor:QI (match_dup 3) (const_int -1)))])]
11039 ;; Arithmetic shift instructions
11041 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11042 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11043 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11044 ;; from the assembler input.
11046 ;; This instruction shifts the target reg/mem as usual, but instead of
11047 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11048 ;; is a left shift double, bits are taken from the high order bits of
11049 ;; reg, else if the insn is a shift right double, bits are taken from the
11050 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11051 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11053 ;; Since sh[lr]d does not change the `reg' operand, that is done
11054 ;; separately, making all shifts emit pairs of shift double and normal
11055 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11056 ;; support a 63 bit shift, each shift where the count is in a reg expands
11057 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11059 ;; If the shift count is a constant, we need never emit more than one
11060 ;; shift pair, instead using moves and sign extension for counts greater
11063 (define_expand "ashlti3"
11064 [(set (match_operand:TI 0 "register_operand" "")
11065 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11066 (match_operand:QI 2 "nonmemory_operand" "")))]
11068 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11070 ;; This pattern must be defined before *ashlti3_1 to prevent
11071 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11073 (define_insn "*avx_ashlti3"
11074 [(set (match_operand:TI 0 "register_operand" "=x")
11075 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11076 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11079 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11080 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11082 [(set_attr "type" "sseishft")
11083 (set_attr "prefix" "vex")
11084 (set_attr "mode" "TI")])
11086 (define_insn "sse2_ashlti3"
11087 [(set (match_operand:TI 0 "register_operand" "=x")
11088 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11089 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11092 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11093 return "pslldq\t{%2, %0|%0, %2}";
11095 [(set_attr "type" "sseishft")
11096 (set_attr "prefix_data16" "1")
11097 (set_attr "mode" "TI")])
11099 (define_insn "*ashlti3_1"
11100 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11101 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11102 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11103 (clobber (reg:CC FLAGS_REG))]
11106 [(set_attr "type" "multi")])
11109 [(match_scratch:DI 3 "r")
11110 (parallel [(set (match_operand:TI 0 "register_operand" "")
11111 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11112 (match_operand:QI 2 "nonmemory_operand" "")))
11113 (clobber (reg:CC FLAGS_REG))])
11117 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11120 [(set (match_operand:TI 0 "register_operand" "")
11121 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11122 (match_operand:QI 2 "nonmemory_operand" "")))
11123 (clobber (reg:CC FLAGS_REG))]
11124 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11125 ? epilogue_completed : reload_completed)"
11127 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11129 (define_insn "x86_64_shld"
11130 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11131 (ior:DI (ashift:DI (match_dup 0)
11132 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11133 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11134 (minus:QI (const_int 64) (match_dup 2)))))
11135 (clobber (reg:CC FLAGS_REG))]
11137 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11138 [(set_attr "type" "ishift")
11139 (set_attr "prefix_0f" "1")
11140 (set_attr "mode" "DI")
11141 (set_attr "athlon_decode" "vector")
11142 (set_attr "amdfam10_decode" "vector")])
11144 (define_expand "x86_64_shift_adj_1"
11145 [(set (reg:CCZ FLAGS_REG)
11146 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11149 (set (match_operand:DI 0 "register_operand" "")
11150 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11151 (match_operand:DI 1 "register_operand" "")
11154 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11155 (match_operand:DI 3 "register_operand" "r")
11160 (define_expand "x86_64_shift_adj_2"
11161 [(use (match_operand:DI 0 "register_operand" ""))
11162 (use (match_operand:DI 1 "register_operand" ""))
11163 (use (match_operand:QI 2 "register_operand" ""))]
11166 rtx label = gen_label_rtx ();
11169 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11171 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11172 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11173 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11174 gen_rtx_LABEL_REF (VOIDmode, label),
11176 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11177 JUMP_LABEL (tmp) = label;
11179 emit_move_insn (operands[0], operands[1]);
11180 ix86_expand_clear (operands[1]);
11182 emit_label (label);
11183 LABEL_NUSES (label) = 1;
11188 (define_expand "ashldi3"
11189 [(set (match_operand:DI 0 "shiftdi_operand" "")
11190 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11191 (match_operand:QI 2 "nonmemory_operand" "")))]
11193 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11195 (define_insn "*ashldi3_1_rex64"
11196 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11197 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11198 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11199 (clobber (reg:CC FLAGS_REG))]
11200 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11202 switch (get_attr_type (insn))
11205 gcc_assert (operands[2] == const1_rtx);
11206 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11207 return "add{q}\t%0, %0";
11210 gcc_assert (CONST_INT_P (operands[2]));
11211 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11212 operands[1] = gen_rtx_MULT (DImode, operands[1],
11213 GEN_INT (1 << INTVAL (operands[2])));
11214 return "lea{q}\t{%a1, %0|%0, %a1}";
11217 if (REG_P (operands[2]))
11218 return "sal{q}\t{%b2, %0|%0, %b2}";
11219 else if (operands[2] == const1_rtx
11220 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11221 return "sal{q}\t%0";
11223 return "sal{q}\t{%2, %0|%0, %2}";
11226 [(set (attr "type")
11227 (cond [(eq_attr "alternative" "1")
11228 (const_string "lea")
11229 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11231 (match_operand 0 "register_operand" ""))
11232 (match_operand 2 "const1_operand" ""))
11233 (const_string "alu")
11235 (const_string "ishift")))
11236 (set_attr "mode" "DI")])
11238 ;; Convert lea to the lea pattern to avoid flags dependency.
11240 [(set (match_operand:DI 0 "register_operand" "")
11241 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11242 (match_operand:QI 2 "immediate_operand" "")))
11243 (clobber (reg:CC FLAGS_REG))]
11244 "TARGET_64BIT && reload_completed
11245 && true_regnum (operands[0]) != true_regnum (operands[1])"
11246 [(set (match_dup 0)
11247 (mult:DI (match_dup 1)
11249 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11251 ;; This pattern can't accept a variable shift count, since shifts by
11252 ;; zero don't affect the flags. We assume that shifts by constant
11253 ;; zero are optimized away.
11254 (define_insn "*ashldi3_cmp_rex64"
11255 [(set (reg FLAGS_REG)
11257 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11258 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11260 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11261 (ashift:DI (match_dup 1) (match_dup 2)))]
11263 && (optimize_function_for_size_p (cfun)
11264 || !TARGET_PARTIAL_FLAG_REG_STALL
11265 || (operands[2] == const1_rtx
11267 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11268 && ix86_match_ccmode (insn, CCGOCmode)
11269 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11271 switch (get_attr_type (insn))
11274 gcc_assert (operands[2] == const1_rtx);
11275 return "add{q}\t%0, %0";
11278 if (REG_P (operands[2]))
11279 return "sal{q}\t{%b2, %0|%0, %b2}";
11280 else if (operands[2] == const1_rtx
11281 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11282 return "sal{q}\t%0";
11284 return "sal{q}\t{%2, %0|%0, %2}";
11287 [(set (attr "type")
11288 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11290 (match_operand 0 "register_operand" ""))
11291 (match_operand 2 "const1_operand" ""))
11292 (const_string "alu")
11294 (const_string "ishift")))
11295 (set_attr "mode" "DI")])
11297 (define_insn "*ashldi3_cconly_rex64"
11298 [(set (reg FLAGS_REG)
11300 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11301 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11303 (clobber (match_scratch:DI 0 "=r"))]
11305 && (optimize_function_for_size_p (cfun)
11306 || !TARGET_PARTIAL_FLAG_REG_STALL
11307 || (operands[2] == const1_rtx
11309 || TARGET_DOUBLE_WITH_ADD)))
11310 && ix86_match_ccmode (insn, CCGOCmode)
11311 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11313 switch (get_attr_type (insn))
11316 gcc_assert (operands[2] == const1_rtx);
11317 return "add{q}\t%0, %0";
11320 if (REG_P (operands[2]))
11321 return "sal{q}\t{%b2, %0|%0, %b2}";
11322 else if (operands[2] == const1_rtx
11323 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11324 return "sal{q}\t%0";
11326 return "sal{q}\t{%2, %0|%0, %2}";
11329 [(set (attr "type")
11330 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332 (match_operand 0 "register_operand" ""))
11333 (match_operand 2 "const1_operand" ""))
11334 (const_string "alu")
11336 (const_string "ishift")))
11337 (set_attr "mode" "DI")])
11339 (define_insn "*ashldi3_1"
11340 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11341 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11342 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11343 (clobber (reg:CC FLAGS_REG))]
11346 [(set_attr "type" "multi")])
11348 ;; By default we don't ask for a scratch register, because when DImode
11349 ;; values are manipulated, registers are already at a premium. But if
11350 ;; we have one handy, we won't turn it away.
11352 [(match_scratch:SI 3 "r")
11353 (parallel [(set (match_operand:DI 0 "register_operand" "")
11354 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11355 (match_operand:QI 2 "nonmemory_operand" "")))
11356 (clobber (reg:CC FLAGS_REG))])
11358 "!TARGET_64BIT && TARGET_CMOVE"
11360 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11363 [(set (match_operand:DI 0 "register_operand" "")
11364 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11365 (match_operand:QI 2 "nonmemory_operand" "")))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11368 ? epilogue_completed : reload_completed)"
11370 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11372 (define_insn "x86_shld"
11373 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11374 (ior:SI (ashift:SI (match_dup 0)
11375 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11376 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11377 (minus:QI (const_int 32) (match_dup 2)))))
11378 (clobber (reg:CC FLAGS_REG))]
11380 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11381 [(set_attr "type" "ishift")
11382 (set_attr "prefix_0f" "1")
11383 (set_attr "mode" "SI")
11384 (set_attr "pent_pair" "np")
11385 (set_attr "athlon_decode" "vector")
11386 (set_attr "amdfam10_decode" "vector")])
11388 (define_expand "x86_shift_adj_1"
11389 [(set (reg:CCZ FLAGS_REG)
11390 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11393 (set (match_operand:SI 0 "register_operand" "")
11394 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11395 (match_operand:SI 1 "register_operand" "")
11398 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11399 (match_operand:SI 3 "register_operand" "r")
11404 (define_expand "x86_shift_adj_2"
11405 [(use (match_operand:SI 0 "register_operand" ""))
11406 (use (match_operand:SI 1 "register_operand" ""))
11407 (use (match_operand:QI 2 "register_operand" ""))]
11410 rtx label = gen_label_rtx ();
11413 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11415 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11416 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11417 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11418 gen_rtx_LABEL_REF (VOIDmode, label),
11420 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11421 JUMP_LABEL (tmp) = label;
11423 emit_move_insn (operands[0], operands[1]);
11424 ix86_expand_clear (operands[1]);
11426 emit_label (label);
11427 LABEL_NUSES (label) = 1;
11432 (define_expand "ashlsi3"
11433 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11434 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11435 (match_operand:QI 2 "nonmemory_operand" "")))]
11437 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11439 (define_insn "*ashlsi3_1"
11440 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11441 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11442 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11443 (clobber (reg:CC FLAGS_REG))]
11444 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11446 switch (get_attr_type (insn))
11449 gcc_assert (operands[2] == const1_rtx);
11450 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11451 return "add{l}\t%0, %0";
11457 if (REG_P (operands[2]))
11458 return "sal{l}\t{%b2, %0|%0, %b2}";
11459 else if (operands[2] == const1_rtx
11460 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11461 return "sal{l}\t%0";
11463 return "sal{l}\t{%2, %0|%0, %2}";
11466 [(set (attr "type")
11467 (cond [(eq_attr "alternative" "1")
11468 (const_string "lea")
11469 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11471 (match_operand 0 "register_operand" ""))
11472 (match_operand 2 "const1_operand" ""))
11473 (const_string "alu")
11475 (const_string "ishift")))
11476 (set_attr "mode" "SI")])
11478 ;; Convert lea to the lea pattern to avoid flags dependency.
11480 [(set (match_operand 0 "register_operand" "")
11481 (ashift (match_operand 1 "index_register_operand" "")
11482 (match_operand:QI 2 "const_int_operand" "")))
11483 (clobber (reg:CC FLAGS_REG))]
11485 && true_regnum (operands[0]) != true_regnum (operands[1])
11486 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11490 enum machine_mode mode = GET_MODE (operands[0]);
11492 if (GET_MODE_SIZE (mode) < 4)
11493 operands[0] = gen_lowpart (SImode, operands[0]);
11495 operands[1] = gen_lowpart (Pmode, operands[1]);
11496 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11498 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11499 if (Pmode != SImode)
11500 pat = gen_rtx_SUBREG (SImode, pat, 0);
11501 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11505 ;; Rare case of shifting RSP is handled by generating move and shift
11507 [(set (match_operand 0 "register_operand" "")
11508 (ashift (match_operand 1 "register_operand" "")
11509 (match_operand:QI 2 "const_int_operand" "")))
11510 (clobber (reg:CC FLAGS_REG))]
11512 && true_regnum (operands[0]) != true_regnum (operands[1])"
11516 emit_move_insn (operands[0], operands[1]);
11517 pat = gen_rtx_SET (VOIDmode, operands[0],
11518 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11519 operands[0], operands[2]));
11520 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11521 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11525 (define_insn "*ashlsi3_1_zext"
11526 [(set (match_operand:DI 0 "register_operand" "=r,r")
11527 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11528 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11529 (clobber (reg:CC FLAGS_REG))]
11530 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11532 switch (get_attr_type (insn))
11535 gcc_assert (operands[2] == const1_rtx);
11536 return "add{l}\t%k0, %k0";
11542 if (REG_P (operands[2]))
11543 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11544 else if (operands[2] == const1_rtx
11545 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11546 return "sal{l}\t%k0";
11548 return "sal{l}\t{%2, %k0|%k0, %2}";
11551 [(set (attr "type")
11552 (cond [(eq_attr "alternative" "1")
11553 (const_string "lea")
11554 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11556 (match_operand 2 "const1_operand" ""))
11557 (const_string "alu")
11559 (const_string "ishift")))
11560 (set_attr "mode" "SI")])
11562 ;; Convert lea to the lea pattern to avoid flags dependency.
11564 [(set (match_operand:DI 0 "register_operand" "")
11565 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11566 (match_operand:QI 2 "const_int_operand" ""))))
11567 (clobber (reg:CC FLAGS_REG))]
11568 "TARGET_64BIT && reload_completed
11569 && true_regnum (operands[0]) != true_regnum (operands[1])"
11570 [(set (match_dup 0) (zero_extend:DI
11571 (subreg:SI (mult:SI (match_dup 1)
11572 (match_dup 2)) 0)))]
11574 operands[1] = gen_lowpart (Pmode, operands[1]);
11575 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11578 ;; This pattern can't accept a variable shift count, since shifts by
11579 ;; zero don't affect the flags. We assume that shifts by constant
11580 ;; zero are optimized away.
11581 (define_insn "*ashlsi3_cmp"
11582 [(set (reg FLAGS_REG)
11584 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11585 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11587 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11588 (ashift:SI (match_dup 1) (match_dup 2)))]
11589 "(optimize_function_for_size_p (cfun)
11590 || !TARGET_PARTIAL_FLAG_REG_STALL
11591 || (operands[2] == const1_rtx
11593 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11594 && ix86_match_ccmode (insn, CCGOCmode)
11595 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11597 switch (get_attr_type (insn))
11600 gcc_assert (operands[2] == const1_rtx);
11601 return "add{l}\t%0, %0";
11604 if (REG_P (operands[2]))
11605 return "sal{l}\t{%b2, %0|%0, %b2}";
11606 else if (operands[2] == const1_rtx
11607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11608 return "sal{l}\t%0";
11610 return "sal{l}\t{%2, %0|%0, %2}";
11613 [(set (attr "type")
11614 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11616 (match_operand 0 "register_operand" ""))
11617 (match_operand 2 "const1_operand" ""))
11618 (const_string "alu")
11620 (const_string "ishift")))
11621 (set_attr "mode" "SI")])
11623 (define_insn "*ashlsi3_cconly"
11624 [(set (reg FLAGS_REG)
11626 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11627 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11629 (clobber (match_scratch:SI 0 "=r"))]
11630 "(optimize_function_for_size_p (cfun)
11631 || !TARGET_PARTIAL_FLAG_REG_STALL
11632 || (operands[2] == const1_rtx
11634 || TARGET_DOUBLE_WITH_ADD)))
11635 && ix86_match_ccmode (insn, CCGOCmode)
11636 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11638 switch (get_attr_type (insn))
11641 gcc_assert (operands[2] == const1_rtx);
11642 return "add{l}\t%0, %0";
11645 if (REG_P (operands[2]))
11646 return "sal{l}\t{%b2, %0|%0, %b2}";
11647 else if (operands[2] == const1_rtx
11648 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11649 return "sal{l}\t%0";
11651 return "sal{l}\t{%2, %0|%0, %2}";
11654 [(set (attr "type")
11655 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11657 (match_operand 0 "register_operand" ""))
11658 (match_operand 2 "const1_operand" ""))
11659 (const_string "alu")
11661 (const_string "ishift")))
11662 (set_attr "mode" "SI")])
11664 (define_insn "*ashlsi3_cmp_zext"
11665 [(set (reg FLAGS_REG)
11667 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11668 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11670 (set (match_operand:DI 0 "register_operand" "=r")
11671 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11673 && (optimize_function_for_size_p (cfun)
11674 || !TARGET_PARTIAL_FLAG_REG_STALL
11675 || (operands[2] == const1_rtx
11677 || TARGET_DOUBLE_WITH_ADD)))
11678 && ix86_match_ccmode (insn, CCGOCmode)
11679 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11681 switch (get_attr_type (insn))
11684 gcc_assert (operands[2] == const1_rtx);
11685 return "add{l}\t%k0, %k0";
11688 if (REG_P (operands[2]))
11689 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11690 else if (operands[2] == const1_rtx
11691 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11692 return "sal{l}\t%k0";
11694 return "sal{l}\t{%2, %k0|%k0, %2}";
11697 [(set (attr "type")
11698 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700 (match_operand 2 "const1_operand" ""))
11701 (const_string "alu")
11703 (const_string "ishift")))
11704 (set_attr "mode" "SI")])
11706 (define_expand "ashlhi3"
11707 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709 (match_operand:QI 2 "nonmemory_operand" "")))]
11710 "TARGET_HIMODE_MATH"
11711 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11713 (define_insn "*ashlhi3_1_lea"
11714 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11715 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11716 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11717 (clobber (reg:CC FLAGS_REG))]
11718 "!TARGET_PARTIAL_REG_STALL
11719 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11721 switch (get_attr_type (insn))
11726 gcc_assert (operands[2] == const1_rtx);
11727 return "add{w}\t%0, %0";
11730 if (REG_P (operands[2]))
11731 return "sal{w}\t{%b2, %0|%0, %b2}";
11732 else if (operands[2] == const1_rtx
11733 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11734 return "sal{w}\t%0";
11736 return "sal{w}\t{%2, %0|%0, %2}";
11739 [(set (attr "type")
11740 (cond [(eq_attr "alternative" "1")
11741 (const_string "lea")
11742 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11744 (match_operand 0 "register_operand" ""))
11745 (match_operand 2 "const1_operand" ""))
11746 (const_string "alu")
11748 (const_string "ishift")))
11749 (set_attr "mode" "HI,SI")])
11751 (define_insn "*ashlhi3_1"
11752 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11753 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11754 (match_operand:QI 2 "nonmemory_operand" "cI")))
11755 (clobber (reg:CC FLAGS_REG))]
11756 "TARGET_PARTIAL_REG_STALL
11757 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11759 switch (get_attr_type (insn))
11762 gcc_assert (operands[2] == const1_rtx);
11763 return "add{w}\t%0, %0";
11766 if (REG_P (operands[2]))
11767 return "sal{w}\t{%b2, %0|%0, %b2}";
11768 else if (operands[2] == const1_rtx
11769 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11770 return "sal{w}\t%0";
11772 return "sal{w}\t{%2, %0|%0, %2}";
11775 [(set (attr "type")
11776 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778 (match_operand 0 "register_operand" ""))
11779 (match_operand 2 "const1_operand" ""))
11780 (const_string "alu")
11782 (const_string "ishift")))
11783 (set_attr "mode" "HI")])
11785 ;; This pattern can't accept a variable shift count, since shifts by
11786 ;; zero don't affect the flags. We assume that shifts by constant
11787 ;; zero are optimized away.
11788 (define_insn "*ashlhi3_cmp"
11789 [(set (reg FLAGS_REG)
11791 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11792 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11794 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11795 (ashift:HI (match_dup 1) (match_dup 2)))]
11796 "(optimize_function_for_size_p (cfun)
11797 || !TARGET_PARTIAL_FLAG_REG_STALL
11798 || (operands[2] == const1_rtx
11800 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11801 && ix86_match_ccmode (insn, CCGOCmode)
11802 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11804 switch (get_attr_type (insn))
11807 gcc_assert (operands[2] == const1_rtx);
11808 return "add{w}\t%0, %0";
11811 if (REG_P (operands[2]))
11812 return "sal{w}\t{%b2, %0|%0, %b2}";
11813 else if (operands[2] == const1_rtx
11814 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11815 return "sal{w}\t%0";
11817 return "sal{w}\t{%2, %0|%0, %2}";
11820 [(set (attr "type")
11821 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11823 (match_operand 0 "register_operand" ""))
11824 (match_operand 2 "const1_operand" ""))
11825 (const_string "alu")
11827 (const_string "ishift")))
11828 (set_attr "mode" "HI")])
11830 (define_insn "*ashlhi3_cconly"
11831 [(set (reg FLAGS_REG)
11833 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11834 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11836 (clobber (match_scratch:HI 0 "=r"))]
11837 "(optimize_function_for_size_p (cfun)
11838 || !TARGET_PARTIAL_FLAG_REG_STALL
11839 || (operands[2] == const1_rtx
11841 || TARGET_DOUBLE_WITH_ADD)))
11842 && ix86_match_ccmode (insn, CCGOCmode)
11843 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11845 switch (get_attr_type (insn))
11848 gcc_assert (operands[2] == const1_rtx);
11849 return "add{w}\t%0, %0";
11852 if (REG_P (operands[2]))
11853 return "sal{w}\t{%b2, %0|%0, %b2}";
11854 else if (operands[2] == const1_rtx
11855 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11856 return "sal{w}\t%0";
11858 return "sal{w}\t{%2, %0|%0, %2}";
11861 [(set (attr "type")
11862 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11864 (match_operand 0 "register_operand" ""))
11865 (match_operand 2 "const1_operand" ""))
11866 (const_string "alu")
11868 (const_string "ishift")))
11869 (set_attr "mode" "HI")])
11871 (define_expand "ashlqi3"
11872 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11873 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11874 (match_operand:QI 2 "nonmemory_operand" "")))]
11875 "TARGET_QIMODE_MATH"
11876 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11878 ;; %%% Potential partial reg stall on alternative 2. What to do?
11880 (define_insn "*ashlqi3_1_lea"
11881 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11882 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11883 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11884 (clobber (reg:CC FLAGS_REG))]
11885 "!TARGET_PARTIAL_REG_STALL
11886 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11888 switch (get_attr_type (insn))
11893 gcc_assert (operands[2] == const1_rtx);
11894 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11895 return "add{l}\t%k0, %k0";
11897 return "add{b}\t%0, %0";
11900 if (REG_P (operands[2]))
11902 if (get_attr_mode (insn) == MODE_SI)
11903 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11905 return "sal{b}\t{%b2, %0|%0, %b2}";
11907 else if (operands[2] == const1_rtx
11908 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11910 if (get_attr_mode (insn) == MODE_SI)
11911 return "sal{l}\t%0";
11913 return "sal{b}\t%0";
11917 if (get_attr_mode (insn) == MODE_SI)
11918 return "sal{l}\t{%2, %k0|%k0, %2}";
11920 return "sal{b}\t{%2, %0|%0, %2}";
11924 [(set (attr "type")
11925 (cond [(eq_attr "alternative" "2")
11926 (const_string "lea")
11927 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11929 (match_operand 0 "register_operand" ""))
11930 (match_operand 2 "const1_operand" ""))
11931 (const_string "alu")
11933 (const_string "ishift")))
11934 (set_attr "mode" "QI,SI,SI")])
11936 (define_insn "*ashlqi3_1"
11937 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11938 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11939 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11940 (clobber (reg:CC FLAGS_REG))]
11941 "TARGET_PARTIAL_REG_STALL
11942 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11944 switch (get_attr_type (insn))
11947 gcc_assert (operands[2] == const1_rtx);
11948 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11949 return "add{l}\t%k0, %k0";
11951 return "add{b}\t%0, %0";
11954 if (REG_P (operands[2]))
11956 if (get_attr_mode (insn) == MODE_SI)
11957 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11959 return "sal{b}\t{%b2, %0|%0, %b2}";
11961 else if (operands[2] == const1_rtx
11962 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11964 if (get_attr_mode (insn) == MODE_SI)
11965 return "sal{l}\t%0";
11967 return "sal{b}\t%0";
11971 if (get_attr_mode (insn) == MODE_SI)
11972 return "sal{l}\t{%2, %k0|%k0, %2}";
11974 return "sal{b}\t{%2, %0|%0, %2}";
11978 [(set (attr "type")
11979 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11981 (match_operand 0 "register_operand" ""))
11982 (match_operand 2 "const1_operand" ""))
11983 (const_string "alu")
11985 (const_string "ishift")))
11986 (set_attr "mode" "QI,SI")])
11988 ;; This pattern can't accept a variable shift count, since shifts by
11989 ;; zero don't affect the flags. We assume that shifts by constant
11990 ;; zero are optimized away.
11991 (define_insn "*ashlqi3_cmp"
11992 [(set (reg FLAGS_REG)
11994 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11995 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11997 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11998 (ashift:QI (match_dup 1) (match_dup 2)))]
11999 "(optimize_function_for_size_p (cfun)
12000 || !TARGET_PARTIAL_FLAG_REG_STALL
12001 || (operands[2] == const1_rtx
12003 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12004 && ix86_match_ccmode (insn, CCGOCmode)
12005 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12007 switch (get_attr_type (insn))
12010 gcc_assert (operands[2] == const1_rtx);
12011 return "add{b}\t%0, %0";
12014 if (REG_P (operands[2]))
12015 return "sal{b}\t{%b2, %0|%0, %b2}";
12016 else if (operands[2] == const1_rtx
12017 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12018 return "sal{b}\t%0";
12020 return "sal{b}\t{%2, %0|%0, %2}";
12023 [(set (attr "type")
12024 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12026 (match_operand 0 "register_operand" ""))
12027 (match_operand 2 "const1_operand" ""))
12028 (const_string "alu")
12030 (const_string "ishift")))
12031 (set_attr "mode" "QI")])
12033 (define_insn "*ashlqi3_cconly"
12034 [(set (reg FLAGS_REG)
12036 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12037 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12039 (clobber (match_scratch:QI 0 "=q"))]
12040 "(optimize_function_for_size_p (cfun)
12041 || !TARGET_PARTIAL_FLAG_REG_STALL
12042 || (operands[2] == const1_rtx
12044 || TARGET_DOUBLE_WITH_ADD)))
12045 && ix86_match_ccmode (insn, CCGOCmode)
12046 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12048 switch (get_attr_type (insn))
12051 gcc_assert (operands[2] == const1_rtx);
12052 return "add{b}\t%0, %0";
12055 if (REG_P (operands[2]))
12056 return "sal{b}\t{%b2, %0|%0, %b2}";
12057 else if (operands[2] == const1_rtx
12058 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12059 return "sal{b}\t%0";
12061 return "sal{b}\t{%2, %0|%0, %2}";
12064 [(set (attr "type")
12065 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12067 (match_operand 0 "register_operand" ""))
12068 (match_operand 2 "const1_operand" ""))
12069 (const_string "alu")
12071 (const_string "ishift")))
12072 (set_attr "mode" "QI")])
12074 ;; See comment above `ashldi3' about how this works.
12076 (define_expand "ashrti3"
12077 [(set (match_operand:TI 0 "register_operand" "")
12078 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12079 (match_operand:QI 2 "nonmemory_operand" "")))]
12081 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12083 (define_insn "*ashrti3_1"
12084 [(set (match_operand:TI 0 "register_operand" "=r")
12085 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12086 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12087 (clobber (reg:CC FLAGS_REG))]
12090 [(set_attr "type" "multi")])
12093 [(match_scratch:DI 3 "r")
12094 (parallel [(set (match_operand:TI 0 "register_operand" "")
12095 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12096 (match_operand:QI 2 "nonmemory_operand" "")))
12097 (clobber (reg:CC FLAGS_REG))])
12101 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12104 [(set (match_operand:TI 0 "register_operand" "")
12105 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12106 (match_operand:QI 2 "nonmemory_operand" "")))
12107 (clobber (reg:CC FLAGS_REG))]
12108 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12109 ? epilogue_completed : reload_completed)"
12111 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12113 (define_insn "x86_64_shrd"
12114 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12115 (ior:DI (ashiftrt:DI (match_dup 0)
12116 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12117 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12118 (minus:QI (const_int 64) (match_dup 2)))))
12119 (clobber (reg:CC FLAGS_REG))]
12121 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12122 [(set_attr "type" "ishift")
12123 (set_attr "prefix_0f" "1")
12124 (set_attr "mode" "DI")
12125 (set_attr "athlon_decode" "vector")
12126 (set_attr "amdfam10_decode" "vector")])
12128 (define_expand "ashrdi3"
12129 [(set (match_operand:DI 0 "shiftdi_operand" "")
12130 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12131 (match_operand:QI 2 "nonmemory_operand" "")))]
12133 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12135 (define_expand "x86_64_shift_adj_3"
12136 [(use (match_operand:DI 0 "register_operand" ""))
12137 (use (match_operand:DI 1 "register_operand" ""))
12138 (use (match_operand:QI 2 "register_operand" ""))]
12141 rtx label = gen_label_rtx ();
12144 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12146 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12147 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12148 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12149 gen_rtx_LABEL_REF (VOIDmode, label),
12151 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12152 JUMP_LABEL (tmp) = label;
12154 emit_move_insn (operands[0], operands[1]);
12155 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12157 emit_label (label);
12158 LABEL_NUSES (label) = 1;
12163 (define_insn "ashrdi3_63_rex64"
12164 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12165 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12166 (match_operand:DI 2 "const_int_operand" "i,i")))
12167 (clobber (reg:CC FLAGS_REG))]
12168 "TARGET_64BIT && INTVAL (operands[2]) == 63
12169 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12170 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12173 sar{q}\t{%2, %0|%0, %2}"
12174 [(set_attr "type" "imovx,ishift")
12175 (set_attr "prefix_0f" "0,*")
12176 (set_attr "length_immediate" "0,*")
12177 (set_attr "modrm" "0,1")
12178 (set_attr "mode" "DI")])
12180 (define_insn "*ashrdi3_1_one_bit_rex64"
12181 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12182 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12183 (match_operand:QI 2 "const1_operand" "")))
12184 (clobber (reg:CC FLAGS_REG))]
12186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12187 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12189 [(set_attr "type" "ishift")
12190 (set (attr "length")
12191 (if_then_else (match_operand:DI 0 "register_operand" "")
12193 (const_string "*")))])
12195 (define_insn "*ashrdi3_1_rex64"
12196 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12197 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12198 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12199 (clobber (reg:CC FLAGS_REG))]
12200 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12202 sar{q}\t{%2, %0|%0, %2}
12203 sar{q}\t{%b2, %0|%0, %b2}"
12204 [(set_attr "type" "ishift")
12205 (set_attr "mode" "DI")])
12207 ;; This pattern can't accept a variable shift count, since shifts by
12208 ;; zero don't affect the flags. We assume that shifts by constant
12209 ;; zero are optimized away.
12210 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12211 [(set (reg FLAGS_REG)
12213 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12214 (match_operand:QI 2 "const1_operand" ""))
12216 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12217 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12219 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12220 && ix86_match_ccmode (insn, CCGOCmode)
12221 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12223 [(set_attr "type" "ishift")
12224 (set (attr "length")
12225 (if_then_else (match_operand:DI 0 "register_operand" "")
12227 (const_string "*")))])
12229 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12230 [(set (reg FLAGS_REG)
12232 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12233 (match_operand:QI 2 "const1_operand" ""))
12235 (clobber (match_scratch:DI 0 "=r"))]
12237 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12238 && ix86_match_ccmode (insn, CCGOCmode)
12239 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12241 [(set_attr "type" "ishift")
12242 (set_attr "length" "2")])
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags. We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrdi3_cmp_rex64"
12248 [(set (reg FLAGS_REG)
12250 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12251 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12253 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12254 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12256 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12257 && ix86_match_ccmode (insn, CCGOCmode)
12258 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12259 "sar{q}\t{%2, %0|%0, %2}"
12260 [(set_attr "type" "ishift")
12261 (set_attr "mode" "DI")])
12263 (define_insn "*ashrdi3_cconly_rex64"
12264 [(set (reg FLAGS_REG)
12266 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12269 (clobber (match_scratch:DI 0 "=r"))]
12271 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12272 && ix86_match_ccmode (insn, CCGOCmode)
12273 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12274 "sar{q}\t{%2, %0|%0, %2}"
12275 [(set_attr "type" "ishift")
12276 (set_attr "mode" "DI")])
12278 (define_insn "*ashrdi3_1"
12279 [(set (match_operand:DI 0 "register_operand" "=r")
12280 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12281 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12282 (clobber (reg:CC FLAGS_REG))]
12285 [(set_attr "type" "multi")])
12287 ;; By default we don't ask for a scratch register, because when DImode
12288 ;; values are manipulated, registers are already at a premium. But if
12289 ;; we have one handy, we won't turn it away.
12291 [(match_scratch:SI 3 "r")
12292 (parallel [(set (match_operand:DI 0 "register_operand" "")
12293 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12294 (match_operand:QI 2 "nonmemory_operand" "")))
12295 (clobber (reg:CC FLAGS_REG))])
12297 "!TARGET_64BIT && TARGET_CMOVE"
12299 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12302 [(set (match_operand:DI 0 "register_operand" "")
12303 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12304 (match_operand:QI 2 "nonmemory_operand" "")))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12307 ? epilogue_completed : reload_completed)"
12309 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12311 (define_insn "x86_shrd"
12312 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12313 (ior:SI (ashiftrt:SI (match_dup 0)
12314 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12315 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12316 (minus:QI (const_int 32) (match_dup 2)))))
12317 (clobber (reg:CC FLAGS_REG))]
12319 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12320 [(set_attr "type" "ishift")
12321 (set_attr "prefix_0f" "1")
12322 (set_attr "pent_pair" "np")
12323 (set_attr "mode" "SI")])
12325 (define_expand "x86_shift_adj_3"
12326 [(use (match_operand:SI 0 "register_operand" ""))
12327 (use (match_operand:SI 1 "register_operand" ""))
12328 (use (match_operand:QI 2 "register_operand" ""))]
12331 rtx label = gen_label_rtx ();
12334 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12336 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12337 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12338 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12339 gen_rtx_LABEL_REF (VOIDmode, label),
12341 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12342 JUMP_LABEL (tmp) = label;
12344 emit_move_insn (operands[0], operands[1]);
12345 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12347 emit_label (label);
12348 LABEL_NUSES (label) = 1;
12353 (define_expand "ashrsi3_31"
12354 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12355 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12356 (match_operand:SI 2 "const_int_operand" "i,i")))
12357 (clobber (reg:CC FLAGS_REG))])]
12360 (define_insn "*ashrsi3_31"
12361 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12362 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12363 (match_operand:SI 2 "const_int_operand" "i,i")))
12364 (clobber (reg:CC FLAGS_REG))]
12365 "INTVAL (operands[2]) == 31
12366 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12367 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12370 sar{l}\t{%2, %0|%0, %2}"
12371 [(set_attr "type" "imovx,ishift")
12372 (set_attr "prefix_0f" "0,*")
12373 (set_attr "length_immediate" "0,*")
12374 (set_attr "modrm" "0,1")
12375 (set_attr "mode" "SI")])
12377 (define_insn "*ashrsi3_31_zext"
12378 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12379 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12380 (match_operand:SI 2 "const_int_operand" "i,i"))))
12381 (clobber (reg:CC FLAGS_REG))]
12382 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12383 && INTVAL (operands[2]) == 31
12384 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12387 sar{l}\t{%2, %k0|%k0, %2}"
12388 [(set_attr "type" "imovx,ishift")
12389 (set_attr "prefix_0f" "0,*")
12390 (set_attr "length_immediate" "0,*")
12391 (set_attr "modrm" "0,1")
12392 (set_attr "mode" "SI")])
12394 (define_expand "ashrsi3"
12395 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12396 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12397 (match_operand:QI 2 "nonmemory_operand" "")))]
12399 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12401 (define_insn "*ashrsi3_1_one_bit"
12402 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12403 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12404 (match_operand:QI 2 "const1_operand" "")))
12405 (clobber (reg:CC FLAGS_REG))]
12406 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12407 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12409 [(set_attr "type" "ishift")
12410 (set (attr "length")
12411 (if_then_else (match_operand:SI 0 "register_operand" "")
12413 (const_string "*")))])
12415 (define_insn "*ashrsi3_1_one_bit_zext"
12416 [(set (match_operand:DI 0 "register_operand" "=r")
12417 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12418 (match_operand:QI 2 "const1_operand" ""))))
12419 (clobber (reg:CC FLAGS_REG))]
12421 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12422 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12424 [(set_attr "type" "ishift")
12425 (set_attr "length" "2")])
12427 (define_insn "*ashrsi3_1"
12428 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12429 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12430 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12431 (clobber (reg:CC FLAGS_REG))]
12432 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12434 sar{l}\t{%2, %0|%0, %2}
12435 sar{l}\t{%b2, %0|%0, %b2}"
12436 [(set_attr "type" "ishift")
12437 (set_attr "mode" "SI")])
12439 (define_insn "*ashrsi3_1_zext"
12440 [(set (match_operand:DI 0 "register_operand" "=r,r")
12441 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12442 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12446 sar{l}\t{%2, %k0|%k0, %2}
12447 sar{l}\t{%b2, %k0|%k0, %b2}"
12448 [(set_attr "type" "ishift")
12449 (set_attr "mode" "SI")])
12451 ;; This pattern can't accept a variable shift count, since shifts by
12452 ;; zero don't affect the flags. We assume that shifts by constant
12453 ;; zero are optimized away.
12454 (define_insn "*ashrsi3_one_bit_cmp"
12455 [(set (reg FLAGS_REG)
12457 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12458 (match_operand:QI 2 "const1_operand" ""))
12460 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12461 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12462 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12463 && ix86_match_ccmode (insn, CCGOCmode)
12464 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12466 [(set_attr "type" "ishift")
12467 (set (attr "length")
12468 (if_then_else (match_operand:SI 0 "register_operand" "")
12470 (const_string "*")))])
12472 (define_insn "*ashrsi3_one_bit_cconly"
12473 [(set (reg FLAGS_REG)
12475 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12476 (match_operand:QI 2 "const1_operand" ""))
12478 (clobber (match_scratch:SI 0 "=r"))]
12479 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12480 && ix86_match_ccmode (insn, CCGOCmode)
12481 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12483 [(set_attr "type" "ishift")
12484 (set_attr "length" "2")])
12486 (define_insn "*ashrsi3_one_bit_cmp_zext"
12487 [(set (reg FLAGS_REG)
12489 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12490 (match_operand:QI 2 "const1_operand" ""))
12492 (set (match_operand:DI 0 "register_operand" "=r")
12493 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12496 && ix86_match_ccmode (insn, CCmode)
12497 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12499 [(set_attr "type" "ishift")
12500 (set_attr "length" "2")])
12502 ;; This pattern can't accept a variable shift count, since shifts by
12503 ;; zero don't affect the flags. We assume that shifts by constant
12504 ;; zero are optimized away.
12505 (define_insn "*ashrsi3_cmp"
12506 [(set (reg FLAGS_REG)
12508 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12509 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12511 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12512 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12513 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12514 && ix86_match_ccmode (insn, CCGOCmode)
12515 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12516 "sar{l}\t{%2, %0|%0, %2}"
12517 [(set_attr "type" "ishift")
12518 (set_attr "mode" "SI")])
12520 (define_insn "*ashrsi3_cconly"
12521 [(set (reg FLAGS_REG)
12523 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12524 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12526 (clobber (match_scratch:SI 0 "=r"))]
12527 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12528 && ix86_match_ccmode (insn, CCGOCmode)
12529 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12530 "sar{l}\t{%2, %0|%0, %2}"
12531 [(set_attr "type" "ishift")
12532 (set_attr "mode" "SI")])
12534 (define_insn "*ashrsi3_cmp_zext"
12535 [(set (reg FLAGS_REG)
12537 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12538 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12540 (set (match_operand:DI 0 "register_operand" "=r")
12541 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12543 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12544 && ix86_match_ccmode (insn, CCGOCmode)
12545 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12546 "sar{l}\t{%2, %k0|%k0, %2}"
12547 [(set_attr "type" "ishift")
12548 (set_attr "mode" "SI")])
12550 (define_expand "ashrhi3"
12551 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12552 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12553 (match_operand:QI 2 "nonmemory_operand" "")))]
12554 "TARGET_HIMODE_MATH"
12555 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12557 (define_insn "*ashrhi3_1_one_bit"
12558 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12559 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12560 (match_operand:QI 2 "const1_operand" "")))
12561 (clobber (reg:CC FLAGS_REG))]
12562 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12563 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12565 [(set_attr "type" "ishift")
12566 (set (attr "length")
12567 (if_then_else (match_operand 0 "register_operand" "")
12569 (const_string "*")))])
12571 (define_insn "*ashrhi3_1"
12572 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12573 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12574 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12578 sar{w}\t{%2, %0|%0, %2}
12579 sar{w}\t{%b2, %0|%0, %b2}"
12580 [(set_attr "type" "ishift")
12581 (set_attr "mode" "HI")])
12583 ;; This pattern can't accept a variable shift count, since shifts by
12584 ;; zero don't affect the flags. We assume that shifts by constant
12585 ;; zero are optimized away.
12586 (define_insn "*ashrhi3_one_bit_cmp"
12587 [(set (reg FLAGS_REG)
12589 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12590 (match_operand:QI 2 "const1_operand" ""))
12592 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12593 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12594 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12595 && ix86_match_ccmode (insn, CCGOCmode)
12596 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12598 [(set_attr "type" "ishift")
12599 (set (attr "length")
12600 (if_then_else (match_operand 0 "register_operand" "")
12602 (const_string "*")))])
12604 (define_insn "*ashrhi3_one_bit_cconly"
12605 [(set (reg FLAGS_REG)
12607 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12608 (match_operand:QI 2 "const1_operand" ""))
12610 (clobber (match_scratch:HI 0 "=r"))]
12611 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12612 && ix86_match_ccmode (insn, CCGOCmode)
12613 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12615 [(set_attr "type" "ishift")
12616 (set_attr "length" "2")])
12618 ;; This pattern can't accept a variable shift count, since shifts by
12619 ;; zero don't affect the flags. We assume that shifts by constant
12620 ;; zero are optimized away.
12621 (define_insn "*ashrhi3_cmp"
12622 [(set (reg FLAGS_REG)
12624 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12625 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12627 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12628 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12629 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12630 && ix86_match_ccmode (insn, CCGOCmode)
12631 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12632 "sar{w}\t{%2, %0|%0, %2}"
12633 [(set_attr "type" "ishift")
12634 (set_attr "mode" "HI")])
12636 (define_insn "*ashrhi3_cconly"
12637 [(set (reg FLAGS_REG)
12639 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12640 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12642 (clobber (match_scratch:HI 0 "=r"))]
12643 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12644 && ix86_match_ccmode (insn, CCGOCmode)
12645 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12646 "sar{w}\t{%2, %0|%0, %2}"
12647 [(set_attr "type" "ishift")
12648 (set_attr "mode" "HI")])
12650 (define_expand "ashrqi3"
12651 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12652 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12653 (match_operand:QI 2 "nonmemory_operand" "")))]
12654 "TARGET_QIMODE_MATH"
12655 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12657 (define_insn "*ashrqi3_1_one_bit"
12658 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12659 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12660 (match_operand:QI 2 "const1_operand" "")))
12661 (clobber (reg:CC FLAGS_REG))]
12662 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12663 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12665 [(set_attr "type" "ishift")
12666 (set (attr "length")
12667 (if_then_else (match_operand 0 "register_operand" "")
12669 (const_string "*")))])
12671 (define_insn "*ashrqi3_1_one_bit_slp"
12672 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12673 (ashiftrt:QI (match_dup 0)
12674 (match_operand:QI 1 "const1_operand" "")))
12675 (clobber (reg:CC FLAGS_REG))]
12676 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12677 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12678 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12680 [(set_attr "type" "ishift1")
12681 (set (attr "length")
12682 (if_then_else (match_operand 0 "register_operand" "")
12684 (const_string "*")))])
12686 (define_insn "*ashrqi3_1"
12687 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12688 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12689 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12690 (clobber (reg:CC FLAGS_REG))]
12691 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12693 sar{b}\t{%2, %0|%0, %2}
12694 sar{b}\t{%b2, %0|%0, %b2}"
12695 [(set_attr "type" "ishift")
12696 (set_attr "mode" "QI")])
12698 (define_insn "*ashrqi3_1_slp"
12699 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12700 (ashiftrt:QI (match_dup 0)
12701 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12702 (clobber (reg:CC FLAGS_REG))]
12703 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12704 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12706 sar{b}\t{%1, %0|%0, %1}
12707 sar{b}\t{%b1, %0|%0, %b1}"
12708 [(set_attr "type" "ishift1")
12709 (set_attr "mode" "QI")])
12711 ;; This pattern can't accept a variable shift count, since shifts by
12712 ;; zero don't affect the flags. We assume that shifts by constant
12713 ;; zero are optimized away.
12714 (define_insn "*ashrqi3_one_bit_cmp"
12715 [(set (reg FLAGS_REG)
12717 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12718 (match_operand:QI 2 "const1_operand" "I"))
12720 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12721 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12722 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12723 && ix86_match_ccmode (insn, CCGOCmode)
12724 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12726 [(set_attr "type" "ishift")
12727 (set (attr "length")
12728 (if_then_else (match_operand 0 "register_operand" "")
12730 (const_string "*")))])
12732 (define_insn "*ashrqi3_one_bit_cconly"
12733 [(set (reg FLAGS_REG)
12735 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12736 (match_operand:QI 2 "const1_operand" ""))
12738 (clobber (match_scratch:QI 0 "=q"))]
12739 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12740 && ix86_match_ccmode (insn, CCGOCmode)
12741 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12743 [(set_attr "type" "ishift")
12744 (set_attr "length" "2")])
12746 ;; This pattern can't accept a variable shift count, since shifts by
12747 ;; zero don't affect the flags. We assume that shifts by constant
12748 ;; zero are optimized away.
12749 (define_insn "*ashrqi3_cmp"
12750 [(set (reg FLAGS_REG)
12752 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12753 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12755 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12756 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12757 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12758 && ix86_match_ccmode (insn, CCGOCmode)
12759 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12760 "sar{b}\t{%2, %0|%0, %2}"
12761 [(set_attr "type" "ishift")
12762 (set_attr "mode" "QI")])
12764 (define_insn "*ashrqi3_cconly"
12765 [(set (reg FLAGS_REG)
12767 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12768 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12770 (clobber (match_scratch:QI 0 "=q"))]
12771 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12772 && ix86_match_ccmode (insn, CCGOCmode)
12773 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12774 "sar{b}\t{%2, %0|%0, %2}"
12775 [(set_attr "type" "ishift")
12776 (set_attr "mode" "QI")])
12779 ;; Logical shift instructions
12781 ;; See comment above `ashldi3' about how this works.
12783 (define_expand "lshrti3"
12784 [(set (match_operand:TI 0 "register_operand" "")
12785 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12786 (match_operand:QI 2 "nonmemory_operand" "")))]
12788 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12790 ;; This pattern must be defined before *lshrti3_1 to prevent
12791 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12793 (define_insn "*avx_lshrti3"
12794 [(set (match_operand:TI 0 "register_operand" "=x")
12795 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12796 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12799 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12800 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12802 [(set_attr "type" "sseishft")
12803 (set_attr "prefix" "vex")
12804 (set_attr "mode" "TI")])
12806 (define_insn "sse2_lshrti3"
12807 [(set (match_operand:TI 0 "register_operand" "=x")
12808 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12809 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12812 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12813 return "psrldq\t{%2, %0|%0, %2}";
12815 [(set_attr "type" "sseishft")
12816 (set_attr "prefix_data16" "1")
12817 (set_attr "mode" "TI")])
12819 (define_insn "*lshrti3_1"
12820 [(set (match_operand:TI 0 "register_operand" "=r")
12821 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12822 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12823 (clobber (reg:CC FLAGS_REG))]
12826 [(set_attr "type" "multi")])
12829 [(match_scratch:DI 3 "r")
12830 (parallel [(set (match_operand:TI 0 "register_operand" "")
12831 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12832 (match_operand:QI 2 "nonmemory_operand" "")))
12833 (clobber (reg:CC FLAGS_REG))])
12837 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12840 [(set (match_operand:TI 0 "register_operand" "")
12841 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12842 (match_operand:QI 2 "nonmemory_operand" "")))
12843 (clobber (reg:CC FLAGS_REG))]
12844 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12845 ? epilogue_completed : reload_completed)"
12847 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12849 (define_expand "lshrdi3"
12850 [(set (match_operand:DI 0 "shiftdi_operand" "")
12851 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12852 (match_operand:QI 2 "nonmemory_operand" "")))]
12854 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12856 (define_insn "*lshrdi3_1_one_bit_rex64"
12857 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12858 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12859 (match_operand:QI 2 "const1_operand" "")))
12860 (clobber (reg:CC FLAGS_REG))]
12862 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12863 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12865 [(set_attr "type" "ishift")
12866 (set (attr "length")
12867 (if_then_else (match_operand:DI 0 "register_operand" "")
12869 (const_string "*")))])
12871 (define_insn "*lshrdi3_1_rex64"
12872 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12873 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12874 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12875 (clobber (reg:CC FLAGS_REG))]
12876 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878 shr{q}\t{%2, %0|%0, %2}
12879 shr{q}\t{%b2, %0|%0, %b2}"
12880 [(set_attr "type" "ishift")
12881 (set_attr "mode" "DI")])
12883 ;; This pattern can't accept a variable shift count, since shifts by
12884 ;; zero don't affect the flags. We assume that shifts by constant
12885 ;; zero are optimized away.
12886 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12887 [(set (reg FLAGS_REG)
12889 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12890 (match_operand:QI 2 "const1_operand" ""))
12892 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12893 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12895 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12896 && ix86_match_ccmode (insn, CCGOCmode)
12897 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12899 [(set_attr "type" "ishift")
12900 (set (attr "length")
12901 (if_then_else (match_operand:DI 0 "register_operand" "")
12903 (const_string "*")))])
12905 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12906 [(set (reg FLAGS_REG)
12908 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12909 (match_operand:QI 2 "const1_operand" ""))
12911 (clobber (match_scratch:DI 0 "=r"))]
12913 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12914 && ix86_match_ccmode (insn, CCGOCmode)
12915 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12917 [(set_attr "type" "ishift")
12918 (set_attr "length" "2")])
12920 ;; This pattern can't accept a variable shift count, since shifts by
12921 ;; zero don't affect the flags. We assume that shifts by constant
12922 ;; zero are optimized away.
12923 (define_insn "*lshrdi3_cmp_rex64"
12924 [(set (reg FLAGS_REG)
12926 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12927 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12929 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12930 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12932 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12933 && ix86_match_ccmode (insn, CCGOCmode)
12934 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12935 "shr{q}\t{%2, %0|%0, %2}"
12936 [(set_attr "type" "ishift")
12937 (set_attr "mode" "DI")])
12939 (define_insn "*lshrdi3_cconly_rex64"
12940 [(set (reg FLAGS_REG)
12942 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12945 (clobber (match_scratch:DI 0 "=r"))]
12947 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12948 && ix86_match_ccmode (insn, CCGOCmode)
12949 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12950 "shr{q}\t{%2, %0|%0, %2}"
12951 [(set_attr "type" "ishift")
12952 (set_attr "mode" "DI")])
12954 (define_insn "*lshrdi3_1"
12955 [(set (match_operand:DI 0 "register_operand" "=r")
12956 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12957 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12958 (clobber (reg:CC FLAGS_REG))]
12961 [(set_attr "type" "multi")])
12963 ;; By default we don't ask for a scratch register, because when DImode
12964 ;; values are manipulated, registers are already at a premium. But if
12965 ;; we have one handy, we won't turn it away.
12967 [(match_scratch:SI 3 "r")
12968 (parallel [(set (match_operand:DI 0 "register_operand" "")
12969 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12970 (match_operand:QI 2 "nonmemory_operand" "")))
12971 (clobber (reg:CC FLAGS_REG))])
12973 "!TARGET_64BIT && TARGET_CMOVE"
12975 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12978 [(set (match_operand:DI 0 "register_operand" "")
12979 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12980 (match_operand:QI 2 "nonmemory_operand" "")))
12981 (clobber (reg:CC FLAGS_REG))]
12982 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12983 ? epilogue_completed : reload_completed)"
12985 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12987 (define_expand "lshrsi3"
12988 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12989 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12990 (match_operand:QI 2 "nonmemory_operand" "")))]
12992 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12994 (define_insn "*lshrsi3_1_one_bit"
12995 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12996 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12997 (match_operand:QI 2 "const1_operand" "")))
12998 (clobber (reg:CC FLAGS_REG))]
12999 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13000 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13002 [(set_attr "type" "ishift")
13003 (set (attr "length")
13004 (if_then_else (match_operand:SI 0 "register_operand" "")
13006 (const_string "*")))])
13008 (define_insn "*lshrsi3_1_one_bit_zext"
13009 [(set (match_operand:DI 0 "register_operand" "=r")
13010 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13011 (match_operand:QI 2 "const1_operand" "")))
13012 (clobber (reg:CC FLAGS_REG))]
13014 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13015 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13017 [(set_attr "type" "ishift")
13018 (set_attr "length" "2")])
13020 (define_insn "*lshrsi3_1"
13021 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13022 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13023 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024 (clobber (reg:CC FLAGS_REG))]
13025 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027 shr{l}\t{%2, %0|%0, %2}
13028 shr{l}\t{%b2, %0|%0, %b2}"
13029 [(set_attr "type" "ishift")
13030 (set_attr "mode" "SI")])
13032 (define_insn "*lshrsi3_1_zext"
13033 [(set (match_operand:DI 0 "register_operand" "=r,r")
13035 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13036 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13037 (clobber (reg:CC FLAGS_REG))]
13038 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13040 shr{l}\t{%2, %k0|%k0, %2}
13041 shr{l}\t{%b2, %k0|%k0, %b2}"
13042 [(set_attr "type" "ishift")
13043 (set_attr "mode" "SI")])
13045 ;; This pattern can't accept a variable shift count, since shifts by
13046 ;; zero don't affect the flags. We assume that shifts by constant
13047 ;; zero are optimized away.
13048 (define_insn "*lshrsi3_one_bit_cmp"
13049 [(set (reg FLAGS_REG)
13051 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13052 (match_operand:QI 2 "const1_operand" ""))
13054 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13055 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13056 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13057 && ix86_match_ccmode (insn, CCGOCmode)
13058 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060 [(set_attr "type" "ishift")
13061 (set (attr "length")
13062 (if_then_else (match_operand:SI 0 "register_operand" "")
13064 (const_string "*")))])
13066 (define_insn "*lshrsi3_one_bit_cconly"
13067 [(set (reg FLAGS_REG)
13069 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13070 (match_operand:QI 2 "const1_operand" ""))
13072 (clobber (match_scratch:SI 0 "=r"))]
13073 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13074 && ix86_match_ccmode (insn, CCGOCmode)
13075 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13077 [(set_attr "type" "ishift")
13078 (set_attr "length" "2")])
13080 (define_insn "*lshrsi3_cmp_one_bit_zext"
13081 [(set (reg FLAGS_REG)
13083 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13084 (match_operand:QI 2 "const1_operand" ""))
13086 (set (match_operand:DI 0 "register_operand" "=r")
13087 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13089 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13090 && ix86_match_ccmode (insn, CCGOCmode)
13091 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13093 [(set_attr "type" "ishift")
13094 (set_attr "length" "2")])
13096 ;; This pattern can't accept a variable shift count, since shifts by
13097 ;; zero don't affect the flags. We assume that shifts by constant
13098 ;; zero are optimized away.
13099 (define_insn "*lshrsi3_cmp"
13100 [(set (reg FLAGS_REG)
13102 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13103 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13105 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13106 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13107 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13108 && ix86_match_ccmode (insn, CCGOCmode)
13109 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13110 "shr{l}\t{%2, %0|%0, %2}"
13111 [(set_attr "type" "ishift")
13112 (set_attr "mode" "SI")])
13114 (define_insn "*lshrsi3_cconly"
13115 [(set (reg FLAGS_REG)
13117 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13118 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13120 (clobber (match_scratch:SI 0 "=r"))]
13121 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13122 && ix86_match_ccmode (insn, CCGOCmode)
13123 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13124 "shr{l}\t{%2, %0|%0, %2}"
13125 [(set_attr "type" "ishift")
13126 (set_attr "mode" "SI")])
13128 (define_insn "*lshrsi3_cmp_zext"
13129 [(set (reg FLAGS_REG)
13131 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13132 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13134 (set (match_operand:DI 0 "register_operand" "=r")
13135 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13137 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13138 && ix86_match_ccmode (insn, CCGOCmode)
13139 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13140 "shr{l}\t{%2, %k0|%k0, %2}"
13141 [(set_attr "type" "ishift")
13142 (set_attr "mode" "SI")])
13144 (define_expand "lshrhi3"
13145 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13146 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13147 (match_operand:QI 2 "nonmemory_operand" "")))]
13148 "TARGET_HIMODE_MATH"
13149 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13151 (define_insn "*lshrhi3_1_one_bit"
13152 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13153 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13154 (match_operand:QI 2 "const1_operand" "")))
13155 (clobber (reg:CC FLAGS_REG))]
13156 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13157 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13159 [(set_attr "type" "ishift")
13160 (set (attr "length")
13161 (if_then_else (match_operand 0 "register_operand" "")
13163 (const_string "*")))])
13165 (define_insn "*lshrhi3_1"
13166 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13167 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13168 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13169 (clobber (reg:CC FLAGS_REG))]
13170 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13172 shr{w}\t{%2, %0|%0, %2}
13173 shr{w}\t{%b2, %0|%0, %b2}"
13174 [(set_attr "type" "ishift")
13175 (set_attr "mode" "HI")])
13177 ;; This pattern can't accept a variable shift count, since shifts by
13178 ;; zero don't affect the flags. We assume that shifts by constant
13179 ;; zero are optimized away.
13180 (define_insn "*lshrhi3_one_bit_cmp"
13181 [(set (reg FLAGS_REG)
13183 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13184 (match_operand:QI 2 "const1_operand" ""))
13186 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13187 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13188 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13189 && ix86_match_ccmode (insn, CCGOCmode)
13190 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13192 [(set_attr "type" "ishift")
13193 (set (attr "length")
13194 (if_then_else (match_operand:SI 0 "register_operand" "")
13196 (const_string "*")))])
13198 (define_insn "*lshrhi3_one_bit_cconly"
13199 [(set (reg FLAGS_REG)
13201 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13202 (match_operand:QI 2 "const1_operand" ""))
13204 (clobber (match_scratch:HI 0 "=r"))]
13205 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13206 && ix86_match_ccmode (insn, CCGOCmode)
13207 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13209 [(set_attr "type" "ishift")
13210 (set_attr "length" "2")])
13212 ;; This pattern can't accept a variable shift count, since shifts by
13213 ;; zero don't affect the flags. We assume that shifts by constant
13214 ;; zero are optimized away.
13215 (define_insn "*lshrhi3_cmp"
13216 [(set (reg FLAGS_REG)
13218 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13219 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13221 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13222 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13223 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13224 && ix86_match_ccmode (insn, CCGOCmode)
13225 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13226 "shr{w}\t{%2, %0|%0, %2}"
13227 [(set_attr "type" "ishift")
13228 (set_attr "mode" "HI")])
13230 (define_insn "*lshrhi3_cconly"
13231 [(set (reg FLAGS_REG)
13233 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13234 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13236 (clobber (match_scratch:HI 0 "=r"))]
13237 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13238 && ix86_match_ccmode (insn, CCGOCmode)
13239 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13240 "shr{w}\t{%2, %0|%0, %2}"
13241 [(set_attr "type" "ishift")
13242 (set_attr "mode" "HI")])
13244 (define_expand "lshrqi3"
13245 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13246 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13247 (match_operand:QI 2 "nonmemory_operand" "")))]
13248 "TARGET_QIMODE_MATH"
13249 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13251 (define_insn "*lshrqi3_1_one_bit"
13252 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13253 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13254 (match_operand:QI 2 "const1_operand" "")))
13255 (clobber (reg:CC FLAGS_REG))]
13256 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13257 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13259 [(set_attr "type" "ishift")
13260 (set (attr "length")
13261 (if_then_else (match_operand 0 "register_operand" "")
13263 (const_string "*")))])
13265 (define_insn "*lshrqi3_1_one_bit_slp"
13266 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13267 (lshiftrt:QI (match_dup 0)
13268 (match_operand:QI 1 "const1_operand" "")))
13269 (clobber (reg:CC FLAGS_REG))]
13270 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13271 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13273 [(set_attr "type" "ishift1")
13274 (set (attr "length")
13275 (if_then_else (match_operand 0 "register_operand" "")
13277 (const_string "*")))])
13279 (define_insn "*lshrqi3_1"
13280 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13281 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13282 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13283 (clobber (reg:CC FLAGS_REG))]
13284 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13286 shr{b}\t{%2, %0|%0, %2}
13287 shr{b}\t{%b2, %0|%0, %b2}"
13288 [(set_attr "type" "ishift")
13289 (set_attr "mode" "QI")])
13291 (define_insn "*lshrqi3_1_slp"
13292 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13293 (lshiftrt:QI (match_dup 0)
13294 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13295 (clobber (reg:CC FLAGS_REG))]
13296 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13297 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13299 shr{b}\t{%1, %0|%0, %1}
13300 shr{b}\t{%b1, %0|%0, %b1}"
13301 [(set_attr "type" "ishift1")
13302 (set_attr "mode" "QI")])
13304 ;; This pattern can't accept a variable shift count, since shifts by
13305 ;; zero don't affect the flags. We assume that shifts by constant
13306 ;; zero are optimized away.
13307 (define_insn "*lshrqi2_one_bit_cmp"
13308 [(set (reg FLAGS_REG)
13310 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13311 (match_operand:QI 2 "const1_operand" ""))
13313 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13314 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13315 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13316 && ix86_match_ccmode (insn, CCGOCmode)
13317 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13319 [(set_attr "type" "ishift")
13320 (set (attr "length")
13321 (if_then_else (match_operand:SI 0 "register_operand" "")
13323 (const_string "*")))])
13325 (define_insn "*lshrqi2_one_bit_cconly"
13326 [(set (reg FLAGS_REG)
13328 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13329 (match_operand:QI 2 "const1_operand" ""))
13331 (clobber (match_scratch:QI 0 "=q"))]
13332 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13333 && ix86_match_ccmode (insn, CCGOCmode)
13334 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13336 [(set_attr "type" "ishift")
13337 (set_attr "length" "2")])
13339 ;; This pattern can't accept a variable shift count, since shifts by
13340 ;; zero don't affect the flags. We assume that shifts by constant
13341 ;; zero are optimized away.
13342 (define_insn "*lshrqi2_cmp"
13343 [(set (reg FLAGS_REG)
13345 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13346 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13348 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13349 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13350 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13351 && ix86_match_ccmode (insn, CCGOCmode)
13352 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13353 "shr{b}\t{%2, %0|%0, %2}"
13354 [(set_attr "type" "ishift")
13355 (set_attr "mode" "QI")])
13357 (define_insn "*lshrqi2_cconly"
13358 [(set (reg FLAGS_REG)
13360 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13361 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13363 (clobber (match_scratch:QI 0 "=q"))]
13364 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13365 && ix86_match_ccmode (insn, CCGOCmode)
13366 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13367 "shr{b}\t{%2, %0|%0, %2}"
13368 [(set_attr "type" "ishift")
13369 (set_attr "mode" "QI")])
13371 ;; Rotate instructions
13373 (define_expand "rotldi3"
13374 [(set (match_operand:DI 0 "shiftdi_operand" "")
13375 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13376 (match_operand:QI 2 "nonmemory_operand" "")))]
13381 ix86_expand_binary_operator (ROTATE, DImode, operands);
13384 if (!const_1_to_31_operand (operands[2], VOIDmode))
13386 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13390 ;; Implement rotation using two double-precision shift instructions
13391 ;; and a scratch register.
13392 (define_insn_and_split "ix86_rotldi3"
13393 [(set (match_operand:DI 0 "register_operand" "=r")
13394 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13395 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13396 (clobber (reg:CC FLAGS_REG))
13397 (clobber (match_scratch:SI 3 "=&r"))]
13400 "&& reload_completed"
13401 [(set (match_dup 3) (match_dup 4))
13403 [(set (match_dup 4)
13404 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13405 (lshiftrt:SI (match_dup 5)
13406 (minus:QI (const_int 32) (match_dup 2)))))
13407 (clobber (reg:CC FLAGS_REG))])
13409 [(set (match_dup 5)
13410 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13411 (lshiftrt:SI (match_dup 3)
13412 (minus:QI (const_int 32) (match_dup 2)))))
13413 (clobber (reg:CC FLAGS_REG))])]
13414 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13416 (define_insn "*rotlsi3_1_one_bit_rex64"
13417 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13418 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13419 (match_operand:QI 2 "const1_operand" "")))
13420 (clobber (reg:CC FLAGS_REG))]
13422 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13423 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13425 [(set_attr "type" "rotate")
13426 (set (attr "length")
13427 (if_then_else (match_operand:DI 0 "register_operand" "")
13429 (const_string "*")))])
13431 (define_insn "*rotldi3_1_rex64"
13432 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13433 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13434 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13435 (clobber (reg:CC FLAGS_REG))]
13436 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13438 rol{q}\t{%2, %0|%0, %2}
13439 rol{q}\t{%b2, %0|%0, %b2}"
13440 [(set_attr "type" "rotate")
13441 (set_attr "mode" "DI")])
13443 (define_expand "rotlsi3"
13444 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13445 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13446 (match_operand:QI 2 "nonmemory_operand" "")))]
13448 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13450 (define_insn "*rotlsi3_1_one_bit"
13451 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13452 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13453 (match_operand:QI 2 "const1_operand" "")))
13454 (clobber (reg:CC FLAGS_REG))]
13455 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13456 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13458 [(set_attr "type" "rotate")
13459 (set (attr "length")
13460 (if_then_else (match_operand:SI 0 "register_operand" "")
13462 (const_string "*")))])
13464 (define_insn "*rotlsi3_1_one_bit_zext"
13465 [(set (match_operand:DI 0 "register_operand" "=r")
13467 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13468 (match_operand:QI 2 "const1_operand" ""))))
13469 (clobber (reg:CC FLAGS_REG))]
13471 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13472 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13474 [(set_attr "type" "rotate")
13475 (set_attr "length" "2")])
13477 (define_insn "*rotlsi3_1"
13478 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13479 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13480 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13481 (clobber (reg:CC FLAGS_REG))]
13482 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13484 rol{l}\t{%2, %0|%0, %2}
13485 rol{l}\t{%b2, %0|%0, %b2}"
13486 [(set_attr "type" "rotate")
13487 (set_attr "mode" "SI")])
13489 (define_insn "*rotlsi3_1_zext"
13490 [(set (match_operand:DI 0 "register_operand" "=r,r")
13492 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13493 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13494 (clobber (reg:CC FLAGS_REG))]
13495 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13497 rol{l}\t{%2, %k0|%k0, %2}
13498 rol{l}\t{%b2, %k0|%k0, %b2}"
13499 [(set_attr "type" "rotate")
13500 (set_attr "mode" "SI")])
13502 (define_expand "rotlhi3"
13503 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13504 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13505 (match_operand:QI 2 "nonmemory_operand" "")))]
13506 "TARGET_HIMODE_MATH"
13507 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13509 (define_insn "*rotlhi3_1_one_bit"
13510 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13511 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13512 (match_operand:QI 2 "const1_operand" "")))
13513 (clobber (reg:CC FLAGS_REG))]
13514 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13515 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13517 [(set_attr "type" "rotate")
13518 (set (attr "length")
13519 (if_then_else (match_operand 0 "register_operand" "")
13521 (const_string "*")))])
13523 (define_insn "*rotlhi3_1"
13524 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13525 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13526 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13527 (clobber (reg:CC FLAGS_REG))]
13528 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13530 rol{w}\t{%2, %0|%0, %2}
13531 rol{w}\t{%b2, %0|%0, %b2}"
13532 [(set_attr "type" "rotate")
13533 (set_attr "mode" "HI")])
13536 [(set (match_operand:HI 0 "register_operand" "")
13537 (rotate:HI (match_dup 0) (const_int 8)))
13538 (clobber (reg:CC FLAGS_REG))]
13540 [(parallel [(set (strict_low_part (match_dup 0))
13541 (bswap:HI (match_dup 0)))
13542 (clobber (reg:CC FLAGS_REG))])]
13545 (define_expand "rotlqi3"
13546 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13547 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13548 (match_operand:QI 2 "nonmemory_operand" "")))]
13549 "TARGET_QIMODE_MATH"
13550 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13552 (define_insn "*rotlqi3_1_one_bit_slp"
13553 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13554 (rotate:QI (match_dup 0)
13555 (match_operand:QI 1 "const1_operand" "")))
13556 (clobber (reg:CC FLAGS_REG))]
13557 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13558 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13560 [(set_attr "type" "rotate1")
13561 (set (attr "length")
13562 (if_then_else (match_operand 0 "register_operand" "")
13564 (const_string "*")))])
13566 (define_insn "*rotlqi3_1_one_bit"
13567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13568 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13569 (match_operand:QI 2 "const1_operand" "")))
13570 (clobber (reg:CC FLAGS_REG))]
13571 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13572 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13574 [(set_attr "type" "rotate")
13575 (set (attr "length")
13576 (if_then_else (match_operand 0 "register_operand" "")
13578 (const_string "*")))])
13580 (define_insn "*rotlqi3_1_slp"
13581 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13582 (rotate:QI (match_dup 0)
13583 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13584 (clobber (reg:CC FLAGS_REG))]
13585 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13586 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13588 rol{b}\t{%1, %0|%0, %1}
13589 rol{b}\t{%b1, %0|%0, %b1}"
13590 [(set_attr "type" "rotate1")
13591 (set_attr "mode" "QI")])
13593 (define_insn "*rotlqi3_1"
13594 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13595 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13596 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13597 (clobber (reg:CC FLAGS_REG))]
13598 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13600 rol{b}\t{%2, %0|%0, %2}
13601 rol{b}\t{%b2, %0|%0, %b2}"
13602 [(set_attr "type" "rotate")
13603 (set_attr "mode" "QI")])
13605 (define_expand "rotrdi3"
13606 [(set (match_operand:DI 0 "shiftdi_operand" "")
13607 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13608 (match_operand:QI 2 "nonmemory_operand" "")))]
13613 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13616 if (!const_1_to_31_operand (operands[2], VOIDmode))
13618 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13622 ;; Implement rotation using two double-precision shift instructions
13623 ;; and a scratch register.
13624 (define_insn_and_split "ix86_rotrdi3"
13625 [(set (match_operand:DI 0 "register_operand" "=r")
13626 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13627 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13628 (clobber (reg:CC FLAGS_REG))
13629 (clobber (match_scratch:SI 3 "=&r"))]
13632 "&& reload_completed"
13633 [(set (match_dup 3) (match_dup 4))
13635 [(set (match_dup 4)
13636 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13637 (ashift:SI (match_dup 5)
13638 (minus:QI (const_int 32) (match_dup 2)))))
13639 (clobber (reg:CC FLAGS_REG))])
13641 [(set (match_dup 5)
13642 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13643 (ashift:SI (match_dup 3)
13644 (minus:QI (const_int 32) (match_dup 2)))))
13645 (clobber (reg:CC FLAGS_REG))])]
13646 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13648 (define_insn "*rotrdi3_1_one_bit_rex64"
13649 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13650 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13651 (match_operand:QI 2 "const1_operand" "")))
13652 (clobber (reg:CC FLAGS_REG))]
13654 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13655 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13657 [(set_attr "type" "rotate")
13658 (set (attr "length")
13659 (if_then_else (match_operand:DI 0 "register_operand" "")
13661 (const_string "*")))])
13663 (define_insn "*rotrdi3_1_rex64"
13664 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13665 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13666 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13667 (clobber (reg:CC FLAGS_REG))]
13668 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13670 ror{q}\t{%2, %0|%0, %2}
13671 ror{q}\t{%b2, %0|%0, %b2}"
13672 [(set_attr "type" "rotate")
13673 (set_attr "mode" "DI")])
13675 (define_expand "rotrsi3"
13676 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13677 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13678 (match_operand:QI 2 "nonmemory_operand" "")))]
13680 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13682 (define_insn "*rotrsi3_1_one_bit"
13683 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13684 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13685 (match_operand:QI 2 "const1_operand" "")))
13686 (clobber (reg:CC FLAGS_REG))]
13687 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13688 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13690 [(set_attr "type" "rotate")
13691 (set (attr "length")
13692 (if_then_else (match_operand:SI 0 "register_operand" "")
13694 (const_string "*")))])
13696 (define_insn "*rotrsi3_1_one_bit_zext"
13697 [(set (match_operand:DI 0 "register_operand" "=r")
13699 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13700 (match_operand:QI 2 "const1_operand" ""))))
13701 (clobber (reg:CC FLAGS_REG))]
13703 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13706 [(set_attr "type" "rotate")
13707 (set (attr "length")
13708 (if_then_else (match_operand:SI 0 "register_operand" "")
13710 (const_string "*")))])
13712 (define_insn "*rotrsi3_1"
13713 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13714 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13715 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13716 (clobber (reg:CC FLAGS_REG))]
13717 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13719 ror{l}\t{%2, %0|%0, %2}
13720 ror{l}\t{%b2, %0|%0, %b2}"
13721 [(set_attr "type" "rotate")
13722 (set_attr "mode" "SI")])
13724 (define_insn "*rotrsi3_1_zext"
13725 [(set (match_operand:DI 0 "register_operand" "=r,r")
13727 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13728 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13729 (clobber (reg:CC FLAGS_REG))]
13730 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13732 ror{l}\t{%2, %k0|%k0, %2}
13733 ror{l}\t{%b2, %k0|%k0, %b2}"
13734 [(set_attr "type" "rotate")
13735 (set_attr "mode" "SI")])
13737 (define_expand "rotrhi3"
13738 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13739 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13740 (match_operand:QI 2 "nonmemory_operand" "")))]
13741 "TARGET_HIMODE_MATH"
13742 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13744 (define_insn "*rotrhi3_one_bit"
13745 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13746 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13747 (match_operand:QI 2 "const1_operand" "")))
13748 (clobber (reg:CC FLAGS_REG))]
13749 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13750 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13752 [(set_attr "type" "rotate")
13753 (set (attr "length")
13754 (if_then_else (match_operand 0 "register_operand" "")
13756 (const_string "*")))])
13758 (define_insn "*rotrhi3_1"
13759 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13760 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13761 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13762 (clobber (reg:CC FLAGS_REG))]
13763 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13765 ror{w}\t{%2, %0|%0, %2}
13766 ror{w}\t{%b2, %0|%0, %b2}"
13767 [(set_attr "type" "rotate")
13768 (set_attr "mode" "HI")])
13771 [(set (match_operand:HI 0 "register_operand" "")
13772 (rotatert:HI (match_dup 0) (const_int 8)))
13773 (clobber (reg:CC FLAGS_REG))]
13775 [(parallel [(set (strict_low_part (match_dup 0))
13776 (bswap:HI (match_dup 0)))
13777 (clobber (reg:CC FLAGS_REG))])]
13780 (define_expand "rotrqi3"
13781 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13782 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13783 (match_operand:QI 2 "nonmemory_operand" "")))]
13784 "TARGET_QIMODE_MATH"
13785 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13787 (define_insn "*rotrqi3_1_one_bit"
13788 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13789 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13790 (match_operand:QI 2 "const1_operand" "")))
13791 (clobber (reg:CC FLAGS_REG))]
13792 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13793 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13795 [(set_attr "type" "rotate")
13796 (set (attr "length")
13797 (if_then_else (match_operand 0 "register_operand" "")
13799 (const_string "*")))])
13801 (define_insn "*rotrqi3_1_one_bit_slp"
13802 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13803 (rotatert:QI (match_dup 0)
13804 (match_operand:QI 1 "const1_operand" "")))
13805 (clobber (reg:CC FLAGS_REG))]
13806 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13807 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13809 [(set_attr "type" "rotate1")
13810 (set (attr "length")
13811 (if_then_else (match_operand 0 "register_operand" "")
13813 (const_string "*")))])
13815 (define_insn "*rotrqi3_1"
13816 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13817 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13818 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13819 (clobber (reg:CC FLAGS_REG))]
13820 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13822 ror{b}\t{%2, %0|%0, %2}
13823 ror{b}\t{%b2, %0|%0, %b2}"
13824 [(set_attr "type" "rotate")
13825 (set_attr "mode" "QI")])
13827 (define_insn "*rotrqi3_1_slp"
13828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13829 (rotatert:QI (match_dup 0)
13830 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13831 (clobber (reg:CC FLAGS_REG))]
13832 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13833 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13835 ror{b}\t{%1, %0|%0, %1}
13836 ror{b}\t{%b1, %0|%0, %b1}"
13837 [(set_attr "type" "rotate1")
13838 (set_attr "mode" "QI")])
13840 ;; Bit set / bit test instructions
13842 (define_expand "extv"
13843 [(set (match_operand:SI 0 "register_operand" "")
13844 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13845 (match_operand:SI 2 "const8_operand" "")
13846 (match_operand:SI 3 "const8_operand" "")))]
13849 /* Handle extractions from %ah et al. */
13850 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13853 /* From mips.md: extract_bit_field doesn't verify that our source
13854 matches the predicate, so check it again here. */
13855 if (! ext_register_operand (operands[1], VOIDmode))
13859 (define_expand "extzv"
13860 [(set (match_operand:SI 0 "register_operand" "")
13861 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13862 (match_operand:SI 2 "const8_operand" "")
13863 (match_operand:SI 3 "const8_operand" "")))]
13866 /* Handle extractions from %ah et al. */
13867 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13870 /* From mips.md: extract_bit_field doesn't verify that our source
13871 matches the predicate, so check it again here. */
13872 if (! ext_register_operand (operands[1], VOIDmode))
13876 (define_expand "insv"
13877 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13878 (match_operand 1 "const8_operand" "")
13879 (match_operand 2 "const8_operand" ""))
13880 (match_operand 3 "register_operand" ""))]
13883 /* Handle insertions to %ah et al. */
13884 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13887 /* From mips.md: insert_bit_field doesn't verify that our source
13888 matches the predicate, so check it again here. */
13889 if (! ext_register_operand (operands[0], VOIDmode))
13893 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13895 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13900 ;; %%% bts, btr, btc, bt.
13901 ;; In general these instructions are *slow* when applied to memory,
13902 ;; since they enforce atomic operation. When applied to registers,
13903 ;; it depends on the cpu implementation. They're never faster than
13904 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13905 ;; no point. But in 64-bit, we can't hold the relevant immediates
13906 ;; within the instruction itself, so operating on bits in the high
13907 ;; 32-bits of a register becomes easier.
13909 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13910 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13911 ;; negdf respectively, so they can never be disabled entirely.
13913 (define_insn "*btsq"
13914 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13916 (match_operand:DI 1 "const_0_to_63_operand" ""))
13918 (clobber (reg:CC FLAGS_REG))]
13919 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13920 "bts{q}\t{%1, %0|%0, %1}"
13921 [(set_attr "type" "alu1")])
13923 (define_insn "*btrq"
13924 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13926 (match_operand:DI 1 "const_0_to_63_operand" ""))
13928 (clobber (reg:CC FLAGS_REG))]
13929 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13930 "btr{q}\t{%1, %0|%0, %1}"
13931 [(set_attr "type" "alu1")])
13933 (define_insn "*btcq"
13934 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13936 (match_operand:DI 1 "const_0_to_63_operand" ""))
13937 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13938 (clobber (reg:CC FLAGS_REG))]
13939 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13940 "btc{q}\t{%1, %0|%0, %1}"
13941 [(set_attr "type" "alu1")])
13943 ;; Allow Nocona to avoid these instructions if a register is available.
13946 [(match_scratch:DI 2 "r")
13947 (parallel [(set (zero_extract:DI
13948 (match_operand:DI 0 "register_operand" "")
13950 (match_operand:DI 1 "const_0_to_63_operand" ""))
13952 (clobber (reg:CC FLAGS_REG))])]
13953 "TARGET_64BIT && !TARGET_USE_BT"
13956 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13959 if (HOST_BITS_PER_WIDE_INT >= 64)
13960 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13961 else if (i < HOST_BITS_PER_WIDE_INT)
13962 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13964 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13966 op1 = immed_double_const (lo, hi, DImode);
13969 emit_move_insn (operands[2], op1);
13973 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13978 [(match_scratch:DI 2 "r")
13979 (parallel [(set (zero_extract:DI
13980 (match_operand:DI 0 "register_operand" "")
13982 (match_operand:DI 1 "const_0_to_63_operand" ""))
13984 (clobber (reg:CC FLAGS_REG))])]
13985 "TARGET_64BIT && !TARGET_USE_BT"
13988 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13991 if (HOST_BITS_PER_WIDE_INT >= 64)
13992 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13993 else if (i < HOST_BITS_PER_WIDE_INT)
13994 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13996 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13998 op1 = immed_double_const (~lo, ~hi, DImode);
14001 emit_move_insn (operands[2], op1);
14005 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14010 [(match_scratch:DI 2 "r")
14011 (parallel [(set (zero_extract:DI
14012 (match_operand:DI 0 "register_operand" "")
14014 (match_operand:DI 1 "const_0_to_63_operand" ""))
14015 (not:DI (zero_extract:DI
14016 (match_dup 0) (const_int 1) (match_dup 1))))
14017 (clobber (reg:CC FLAGS_REG))])]
14018 "TARGET_64BIT && !TARGET_USE_BT"
14021 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14024 if (HOST_BITS_PER_WIDE_INT >= 64)
14025 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14026 else if (i < HOST_BITS_PER_WIDE_INT)
14027 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14029 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14031 op1 = immed_double_const (lo, hi, DImode);
14034 emit_move_insn (operands[2], op1);
14038 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14042 (define_insn "*btdi_rex64"
14043 [(set (reg:CCC FLAGS_REG)
14046 (match_operand:DI 0 "register_operand" "r")
14048 (match_operand:DI 1 "nonmemory_operand" "rN"))
14050 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14051 "bt{q}\t{%1, %0|%0, %1}"
14052 [(set_attr "type" "alu1")])
14054 (define_insn "*btsi"
14055 [(set (reg:CCC FLAGS_REG)
14058 (match_operand:SI 0 "register_operand" "r")
14060 (match_operand:SI 1 "nonmemory_operand" "rN"))
14062 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14063 "bt{l}\t{%1, %0|%0, %1}"
14064 [(set_attr "type" "alu1")])
14066 ;; Store-flag instructions.
14068 ;; For all sCOND expanders, also expand the compare or test insn that
14069 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14071 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14072 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14073 ;; way, which can later delete the movzx if only QImode is needed.
14075 (define_expand "s<code>"
14076 [(set (match_operand:QI 0 "register_operand" "")
14077 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14079 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14081 (define_expand "s<code>"
14082 [(set (match_operand:QI 0 "register_operand" "")
14083 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14084 "TARGET_80387 || TARGET_SSE"
14085 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14087 (define_insn "*setcc_1"
14088 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14089 (match_operator:QI 1 "ix86_comparison_operator"
14090 [(reg FLAGS_REG) (const_int 0)]))]
14093 [(set_attr "type" "setcc")
14094 (set_attr "mode" "QI")])
14096 (define_insn "*setcc_2"
14097 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14098 (match_operator:QI 1 "ix86_comparison_operator"
14099 [(reg FLAGS_REG) (const_int 0)]))]
14102 [(set_attr "type" "setcc")
14103 (set_attr "mode" "QI")])
14105 ;; In general it is not safe to assume too much about CCmode registers,
14106 ;; so simplify-rtx stops when it sees a second one. Under certain
14107 ;; conditions this is safe on x86, so help combine not create
14114 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14115 (ne:QI (match_operator 1 "ix86_comparison_operator"
14116 [(reg FLAGS_REG) (const_int 0)])
14119 [(set (match_dup 0) (match_dup 1))]
14121 PUT_MODE (operands[1], QImode);
14125 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14126 (ne:QI (match_operator 1 "ix86_comparison_operator"
14127 [(reg FLAGS_REG) (const_int 0)])
14130 [(set (match_dup 0) (match_dup 1))]
14132 PUT_MODE (operands[1], QImode);
14136 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14137 (eq:QI (match_operator 1 "ix86_comparison_operator"
14138 [(reg FLAGS_REG) (const_int 0)])
14141 [(set (match_dup 0) (match_dup 1))]
14143 rtx new_op1 = copy_rtx (operands[1]);
14144 operands[1] = new_op1;
14145 PUT_MODE (new_op1, QImode);
14146 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14147 GET_MODE (XEXP (new_op1, 0))));
14149 /* Make sure that (a) the CCmode we have for the flags is strong
14150 enough for the reversed compare or (b) we have a valid FP compare. */
14151 if (! ix86_comparison_operator (new_op1, VOIDmode))
14156 [(set (strict_low_part (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))
14175 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14176 ;; subsequent logical operations are used to imitate conditional moves.
14177 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14180 (define_insn "*avx_setcc<mode>"
14181 [(set (match_operand:MODEF 0 "register_operand" "=x")
14182 (match_operator:MODEF 1 "avx_comparison_float_operator"
14183 [(match_operand:MODEF 2 "register_operand" "x")
14184 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14186 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14187 [(set_attr "type" "ssecmp")
14188 (set_attr "prefix" "vex")
14189 (set_attr "mode" "<MODE>")])
14191 (define_insn "*sse_setcc<mode>"
14192 [(set (match_operand:MODEF 0 "register_operand" "=x")
14193 (match_operator:MODEF 1 "sse_comparison_operator"
14194 [(match_operand:MODEF 2 "register_operand" "0")
14195 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14196 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14197 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14198 [(set_attr "type" "ssecmp")
14199 (set_attr "mode" "<MODE>")])
14201 (define_insn "*sse5_setcc<mode>"
14202 [(set (match_operand:MODEF 0 "register_operand" "=x")
14203 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14204 [(match_operand:MODEF 2 "register_operand" "x")
14205 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14207 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14208 [(set_attr "type" "sse4arg")
14209 (set_attr "mode" "<MODE>")])
14212 ;; Basic conditional jump instructions.
14213 ;; We ignore the overflow flag for signed branch instructions.
14215 ;; For all bCOND expanders, also expand the compare or test insn that
14216 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14218 (define_expand "b<code>"
14220 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14222 (label_ref (match_operand 0 ""))
14225 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14227 (define_expand "b<code>"
14229 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14231 (label_ref (match_operand 0 ""))
14233 "TARGET_80387 || TARGET_SSE_MATH"
14234 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14236 (define_insn "*jcc_1"
14238 (if_then_else (match_operator 1 "ix86_comparison_operator"
14239 [(reg FLAGS_REG) (const_int 0)])
14240 (label_ref (match_operand 0 "" ""))
14244 [(set_attr "type" "ibr")
14245 (set_attr "modrm" "0")
14246 (set (attr "length")
14247 (if_then_else (and (ge (minus (match_dup 0) (pc))
14249 (lt (minus (match_dup 0) (pc))
14254 (define_insn "*jcc_2"
14256 (if_then_else (match_operator 1 "ix86_comparison_operator"
14257 [(reg FLAGS_REG) (const_int 0)])
14259 (label_ref (match_operand 0 "" ""))))]
14262 [(set_attr "type" "ibr")
14263 (set_attr "modrm" "0")
14264 (set (attr "length")
14265 (if_then_else (and (ge (minus (match_dup 0) (pc))
14267 (lt (minus (match_dup 0) (pc))
14272 ;; In general it is not safe to assume too much about CCmode registers,
14273 ;; so simplify-rtx stops when it sees a second one. Under certain
14274 ;; conditions this is safe on x86, so help combine not create
14282 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14283 [(reg FLAGS_REG) (const_int 0)])
14285 (label_ref (match_operand 1 "" ""))
14289 (if_then_else (match_dup 0)
14290 (label_ref (match_dup 1))
14293 PUT_MODE (operands[0], VOIDmode);
14298 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14299 [(reg FLAGS_REG) (const_int 0)])
14301 (label_ref (match_operand 1 "" ""))
14305 (if_then_else (match_dup 0)
14306 (label_ref (match_dup 1))
14309 rtx new_op0 = copy_rtx (operands[0]);
14310 operands[0] = new_op0;
14311 PUT_MODE (new_op0, VOIDmode);
14312 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14313 GET_MODE (XEXP (new_op0, 0))));
14315 /* Make sure that (a) the CCmode we have for the flags is strong
14316 enough for the reversed compare or (b) we have a valid FP compare. */
14317 if (! ix86_comparison_operator (new_op0, VOIDmode))
14321 ;; zero_extend in SImode is correct, since this is what combine pass
14322 ;; generates from shift insn with QImode operand. Actually, the mode of
14323 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14324 ;; appropriate modulo of the bit offset value.
14326 (define_insn_and_split "*jcc_btdi_rex64"
14328 (if_then_else (match_operator 0 "bt_comparison_operator"
14330 (match_operand:DI 1 "register_operand" "r")
14333 (match_operand:QI 2 "register_operand" "r")))
14335 (label_ref (match_operand 3 "" ""))
14337 (clobber (reg:CC FLAGS_REG))]
14338 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14341 [(set (reg:CCC FLAGS_REG)
14349 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14350 (label_ref (match_dup 3))
14353 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14355 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14358 ;; avoid useless masking of bit offset operand
14359 (define_insn_and_split "*jcc_btdi_mask_rex64"
14361 (if_then_else (match_operator 0 "bt_comparison_operator"
14363 (match_operand:DI 1 "register_operand" "r")
14366 (match_operand:SI 2 "register_operand" "r")
14367 (match_operand:SI 3 "const_int_operand" "n")))])
14368 (label_ref (match_operand 4 "" ""))
14370 (clobber (reg:CC FLAGS_REG))]
14371 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14372 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14375 [(set (reg:CCC FLAGS_REG)
14383 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14384 (label_ref (match_dup 4))
14387 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14389 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14392 (define_insn_and_split "*jcc_btsi"
14394 (if_then_else (match_operator 0 "bt_comparison_operator"
14396 (match_operand:SI 1 "register_operand" "r")
14399 (match_operand:QI 2 "register_operand" "r")))
14401 (label_ref (match_operand 3 "" ""))
14403 (clobber (reg:CC FLAGS_REG))]
14404 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14407 [(set (reg:CCC FLAGS_REG)
14415 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14416 (label_ref (match_dup 3))
14419 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14421 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14424 ;; avoid useless masking of bit offset operand
14425 (define_insn_and_split "*jcc_btsi_mask"
14427 (if_then_else (match_operator 0 "bt_comparison_operator"
14429 (match_operand:SI 1 "register_operand" "r")
14432 (match_operand:SI 2 "register_operand" "r")
14433 (match_operand:SI 3 "const_int_operand" "n")))])
14434 (label_ref (match_operand 4 "" ""))
14436 (clobber (reg:CC FLAGS_REG))]
14437 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14438 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14441 [(set (reg:CCC FLAGS_REG)
14449 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14450 (label_ref (match_dup 4))
14452 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14454 (define_insn_and_split "*jcc_btsi_1"
14456 (if_then_else (match_operator 0 "bt_comparison_operator"
14459 (match_operand:SI 1 "register_operand" "r")
14460 (match_operand:QI 2 "register_operand" "r"))
14463 (label_ref (match_operand 3 "" ""))
14465 (clobber (reg:CC FLAGS_REG))]
14466 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14469 [(set (reg:CCC FLAGS_REG)
14477 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14478 (label_ref (match_dup 3))
14481 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14483 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14486 ;; avoid useless masking of bit offset operand
14487 (define_insn_and_split "*jcc_btsi_mask_1"
14490 (match_operator 0 "bt_comparison_operator"
14493 (match_operand:SI 1 "register_operand" "r")
14496 (match_operand:SI 2 "register_operand" "r")
14497 (match_operand:SI 3 "const_int_operand" "n")) 0))
14500 (label_ref (match_operand 4 "" ""))
14502 (clobber (reg:CC FLAGS_REG))]
14503 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14504 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14507 [(set (reg:CCC FLAGS_REG)
14515 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14516 (label_ref (match_dup 4))
14518 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14520 ;; Define combination compare-and-branch fp compare instructions to use
14521 ;; during early optimization. Splitting the operation apart early makes
14522 ;; for bad code when we want to reverse the operation.
14524 (define_insn "*fp_jcc_1_mixed"
14526 (if_then_else (match_operator 0 "comparison_operator"
14527 [(match_operand 1 "register_operand" "f,x")
14528 (match_operand 2 "nonimmediate_operand" "f,xm")])
14529 (label_ref (match_operand 3 "" ""))
14531 (clobber (reg:CCFP FPSR_REG))
14532 (clobber (reg:CCFP FLAGS_REG))]
14533 "TARGET_MIX_SSE_I387
14534 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14535 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14536 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14539 (define_insn "*fp_jcc_1_sse"
14541 (if_then_else (match_operator 0 "comparison_operator"
14542 [(match_operand 1 "register_operand" "x")
14543 (match_operand 2 "nonimmediate_operand" "xm")])
14544 (label_ref (match_operand 3 "" ""))
14546 (clobber (reg:CCFP FPSR_REG))
14547 (clobber (reg:CCFP FLAGS_REG))]
14549 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14550 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14551 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14554 (define_insn "*fp_jcc_1_387"
14556 (if_then_else (match_operator 0 "comparison_operator"
14557 [(match_operand 1 "register_operand" "f")
14558 (match_operand 2 "register_operand" "f")])
14559 (label_ref (match_operand 3 "" ""))
14561 (clobber (reg:CCFP FPSR_REG))
14562 (clobber (reg:CCFP FLAGS_REG))]
14563 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14565 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14566 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14569 (define_insn "*fp_jcc_2_mixed"
14571 (if_then_else (match_operator 0 "comparison_operator"
14572 [(match_operand 1 "register_operand" "f,x")
14573 (match_operand 2 "nonimmediate_operand" "f,xm")])
14575 (label_ref (match_operand 3 "" ""))))
14576 (clobber (reg:CCFP FPSR_REG))
14577 (clobber (reg:CCFP FLAGS_REG))]
14578 "TARGET_MIX_SSE_I387
14579 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14580 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14581 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14584 (define_insn "*fp_jcc_2_sse"
14586 (if_then_else (match_operator 0 "comparison_operator"
14587 [(match_operand 1 "register_operand" "x")
14588 (match_operand 2 "nonimmediate_operand" "xm")])
14590 (label_ref (match_operand 3 "" ""))))
14591 (clobber (reg:CCFP FPSR_REG))
14592 (clobber (reg:CCFP FLAGS_REG))]
14594 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14595 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14596 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14599 (define_insn "*fp_jcc_2_387"
14601 (if_then_else (match_operator 0 "comparison_operator"
14602 [(match_operand 1 "register_operand" "f")
14603 (match_operand 2 "register_operand" "f")])
14605 (label_ref (match_operand 3 "" ""))))
14606 (clobber (reg:CCFP FPSR_REG))
14607 (clobber (reg:CCFP FLAGS_REG))]
14608 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14610 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14611 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14614 (define_insn "*fp_jcc_3_387"
14616 (if_then_else (match_operator 0 "comparison_operator"
14617 [(match_operand 1 "register_operand" "f")
14618 (match_operand 2 "nonimmediate_operand" "fm")])
14619 (label_ref (match_operand 3 "" ""))
14621 (clobber (reg:CCFP FPSR_REG))
14622 (clobber (reg:CCFP FLAGS_REG))
14623 (clobber (match_scratch:HI 4 "=a"))]
14625 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14626 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14627 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14628 && SELECT_CC_MODE (GET_CODE (operands[0]),
14629 operands[1], operands[2]) == CCFPmode
14630 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14633 (define_insn "*fp_jcc_4_387"
14635 (if_then_else (match_operator 0 "comparison_operator"
14636 [(match_operand 1 "register_operand" "f")
14637 (match_operand 2 "nonimmediate_operand" "fm")])
14639 (label_ref (match_operand 3 "" ""))))
14640 (clobber (reg:CCFP FPSR_REG))
14641 (clobber (reg:CCFP FLAGS_REG))
14642 (clobber (match_scratch:HI 4 "=a"))]
14644 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14645 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14646 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14647 && SELECT_CC_MODE (GET_CODE (operands[0]),
14648 operands[1], operands[2]) == CCFPmode
14649 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14652 (define_insn "*fp_jcc_5_387"
14654 (if_then_else (match_operator 0 "comparison_operator"
14655 [(match_operand 1 "register_operand" "f")
14656 (match_operand 2 "register_operand" "f")])
14657 (label_ref (match_operand 3 "" ""))
14659 (clobber (reg:CCFP FPSR_REG))
14660 (clobber (reg:CCFP FLAGS_REG))
14661 (clobber (match_scratch:HI 4 "=a"))]
14662 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14663 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14664 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14667 (define_insn "*fp_jcc_6_387"
14669 (if_then_else (match_operator 0 "comparison_operator"
14670 [(match_operand 1 "register_operand" "f")
14671 (match_operand 2 "register_operand" "f")])
14673 (label_ref (match_operand 3 "" ""))))
14674 (clobber (reg:CCFP FPSR_REG))
14675 (clobber (reg:CCFP FLAGS_REG))
14676 (clobber (match_scratch:HI 4 "=a"))]
14677 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14678 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14679 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14682 (define_insn "*fp_jcc_7_387"
14684 (if_then_else (match_operator 0 "comparison_operator"
14685 [(match_operand 1 "register_operand" "f")
14686 (match_operand 2 "const0_operand" "")])
14687 (label_ref (match_operand 3 "" ""))
14689 (clobber (reg:CCFP FPSR_REG))
14690 (clobber (reg:CCFP FLAGS_REG))
14691 (clobber (match_scratch:HI 4 "=a"))]
14692 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14693 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14694 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14695 && SELECT_CC_MODE (GET_CODE (operands[0]),
14696 operands[1], operands[2]) == CCFPmode
14697 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14700 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14701 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14702 ;; with a precedence over other operators and is always put in the first
14703 ;; place. Swap condition and operands to match ficom instruction.
14705 (define_insn "*fp_jcc_8<mode>_387"
14707 (if_then_else (match_operator 0 "comparison_operator"
14708 [(match_operator 1 "float_operator"
14709 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14710 (match_operand 3 "register_operand" "f,f")])
14711 (label_ref (match_operand 4 "" ""))
14713 (clobber (reg:CCFP FPSR_REG))
14714 (clobber (reg:CCFP FLAGS_REG))
14715 (clobber (match_scratch:HI 5 "=a,a"))]
14716 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14717 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14718 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14719 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14720 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14721 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14726 (if_then_else (match_operator 0 "comparison_operator"
14727 [(match_operand 1 "register_operand" "")
14728 (match_operand 2 "nonimmediate_operand" "")])
14729 (match_operand 3 "" "")
14730 (match_operand 4 "" "")))
14731 (clobber (reg:CCFP FPSR_REG))
14732 (clobber (reg:CCFP FLAGS_REG))]
14736 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14737 operands[3], operands[4], NULL_RTX, NULL_RTX);
14743 (if_then_else (match_operator 0 "comparison_operator"
14744 [(match_operand 1 "register_operand" "")
14745 (match_operand 2 "general_operand" "")])
14746 (match_operand 3 "" "")
14747 (match_operand 4 "" "")))
14748 (clobber (reg:CCFP FPSR_REG))
14749 (clobber (reg:CCFP FLAGS_REG))
14750 (clobber (match_scratch:HI 5 "=a"))]
14754 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14755 operands[3], operands[4], operands[5], NULL_RTX);
14761 (if_then_else (match_operator 0 "comparison_operator"
14762 [(match_operator 1 "float_operator"
14763 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14764 (match_operand 3 "register_operand" "")])
14765 (match_operand 4 "" "")
14766 (match_operand 5 "" "")))
14767 (clobber (reg:CCFP FPSR_REG))
14768 (clobber (reg:CCFP FLAGS_REG))
14769 (clobber (match_scratch:HI 6 "=a"))]
14773 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14774 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14775 operands[3], operands[7],
14776 operands[4], operands[5], operands[6], NULL_RTX);
14780 ;; %%% Kill this when reload knows how to do it.
14783 (if_then_else (match_operator 0 "comparison_operator"
14784 [(match_operator 1 "float_operator"
14785 [(match_operand:X87MODEI12 2 "register_operand" "")])
14786 (match_operand 3 "register_operand" "")])
14787 (match_operand 4 "" "")
14788 (match_operand 5 "" "")))
14789 (clobber (reg:CCFP FPSR_REG))
14790 (clobber (reg:CCFP FLAGS_REG))
14791 (clobber (match_scratch:HI 6 "=a"))]
14795 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14796 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14797 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14798 operands[3], operands[7],
14799 operands[4], operands[5], operands[6], operands[2]);
14803 ;; Unconditional and other jump instructions
14805 (define_insn "jump"
14807 (label_ref (match_operand 0 "" "")))]
14810 [(set_attr "type" "ibr")
14811 (set (attr "length")
14812 (if_then_else (and (ge (minus (match_dup 0) (pc))
14814 (lt (minus (match_dup 0) (pc))
14818 (set_attr "modrm" "0")])
14820 (define_expand "indirect_jump"
14821 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14825 (define_insn "*indirect_jump"
14826 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14829 [(set_attr "type" "ibr")
14830 (set_attr "length_immediate" "0")])
14832 (define_expand "tablejump"
14833 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14834 (use (label_ref (match_operand 1 "" "")))])]
14837 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14838 relative. Convert the relative address to an absolute address. */
14842 enum rtx_code code;
14844 /* We can't use @GOTOFF for text labels on VxWorks;
14845 see gotoff_operand. */
14846 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14850 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14852 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14856 op1 = pic_offset_table_rtx;
14861 op0 = pic_offset_table_rtx;
14865 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14870 (define_insn "*tablejump_1"
14871 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14872 (use (label_ref (match_operand 1 "" "")))]
14875 [(set_attr "type" "ibr")
14876 (set_attr "length_immediate" "0")])
14878 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14881 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14882 (set (match_operand:QI 1 "register_operand" "")
14883 (match_operator:QI 2 "ix86_comparison_operator"
14884 [(reg FLAGS_REG) (const_int 0)]))
14885 (set (match_operand 3 "q_regs_operand" "")
14886 (zero_extend (match_dup 1)))]
14887 "(peep2_reg_dead_p (3, operands[1])
14888 || operands_match_p (operands[1], operands[3]))
14889 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14890 [(set (match_dup 4) (match_dup 0))
14891 (set (strict_low_part (match_dup 5))
14894 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14895 operands[5] = gen_lowpart (QImode, operands[3]);
14896 ix86_expand_clear (operands[3]);
14899 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14902 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14903 (set (match_operand:QI 1 "register_operand" "")
14904 (match_operator:QI 2 "ix86_comparison_operator"
14905 [(reg FLAGS_REG) (const_int 0)]))
14906 (parallel [(set (match_operand 3 "q_regs_operand" "")
14907 (zero_extend (match_dup 1)))
14908 (clobber (reg:CC FLAGS_REG))])]
14909 "(peep2_reg_dead_p (3, operands[1])
14910 || operands_match_p (operands[1], operands[3]))
14911 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14912 [(set (match_dup 4) (match_dup 0))
14913 (set (strict_low_part (match_dup 5))
14916 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14917 operands[5] = gen_lowpart (QImode, operands[3]);
14918 ix86_expand_clear (operands[3]);
14921 ;; Call instructions.
14923 ;; The predicates normally associated with named expanders are not properly
14924 ;; checked for calls. This is a bug in the generic code, but it isn't that
14925 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14927 ;; Call subroutine returning no value.
14929 (define_expand "call_pop"
14930 [(parallel [(call (match_operand:QI 0 "" "")
14931 (match_operand:SI 1 "" ""))
14932 (set (reg:SI SP_REG)
14933 (plus:SI (reg:SI SP_REG)
14934 (match_operand:SI 3 "" "")))])]
14937 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14941 (define_insn "*call_pop_0"
14942 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14943 (match_operand:SI 1 "" ""))
14944 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14945 (match_operand:SI 2 "immediate_operand" "")))]
14948 if (SIBLING_CALL_P (insn))
14951 return "call\t%P0";
14953 [(set_attr "type" "call")])
14955 (define_insn "*call_pop_1"
14956 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14957 (match_operand:SI 1 "" ""))
14958 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14959 (match_operand:SI 2 "immediate_operand" "i")))]
14962 if (constant_call_address_operand (operands[0], Pmode))
14964 if (SIBLING_CALL_P (insn))
14967 return "call\t%P0";
14969 if (SIBLING_CALL_P (insn))
14972 return "call\t%A0";
14974 [(set_attr "type" "call")])
14976 (define_expand "call"
14977 [(call (match_operand:QI 0 "" "")
14978 (match_operand 1 "" ""))
14979 (use (match_operand 2 "" ""))]
14982 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14986 (define_expand "sibcall"
14987 [(call (match_operand:QI 0 "" "")
14988 (match_operand 1 "" ""))
14989 (use (match_operand 2 "" ""))]
14992 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14996 (define_insn "*call_0"
14997 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14998 (match_operand 1 "" ""))]
15001 if (SIBLING_CALL_P (insn))
15004 return "call\t%P0";
15006 [(set_attr "type" "call")])
15008 (define_insn "*call_1"
15009 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15010 (match_operand 1 "" ""))]
15011 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15013 if (constant_call_address_operand (operands[0], Pmode))
15014 return "call\t%P0";
15015 return "call\t%A0";
15017 [(set_attr "type" "call")])
15019 (define_insn "*sibcall_1"
15020 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15021 (match_operand 1 "" ""))]
15022 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15024 if (constant_call_address_operand (operands[0], Pmode))
15028 [(set_attr "type" "call")])
15030 (define_insn "*call_1_rex64"
15031 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15032 (match_operand 1 "" ""))]
15033 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15034 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15036 if (constant_call_address_operand (operands[0], Pmode))
15037 return "call\t%P0";
15038 return "call\t%A0";
15040 [(set_attr "type" "call")])
15042 (define_insn "*call_1_rex64_large"
15043 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15044 (match_operand 1 "" ""))]
15045 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15047 [(set_attr "type" "call")])
15049 (define_insn "*sibcall_1_rex64"
15050 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15051 (match_operand 1 "" ""))]
15052 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15054 [(set_attr "type" "call")])
15056 (define_insn "*sibcall_1_rex64_v"
15057 [(call (mem:QI (reg:DI R11_REG))
15058 (match_operand 0 "" ""))]
15059 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15061 [(set_attr "type" "call")])
15064 ;; Call subroutine, returning value in operand 0
15066 (define_expand "call_value_pop"
15067 [(parallel [(set (match_operand 0 "" "")
15068 (call (match_operand:QI 1 "" "")
15069 (match_operand:SI 2 "" "")))
15070 (set (reg:SI SP_REG)
15071 (plus:SI (reg:SI SP_REG)
15072 (match_operand:SI 4 "" "")))])]
15075 ix86_expand_call (operands[0], operands[1], operands[2],
15076 operands[3], operands[4], 0);
15080 (define_expand "call_value"
15081 [(set (match_operand 0 "" "")
15082 (call (match_operand:QI 1 "" "")
15083 (match_operand:SI 2 "" "")))
15084 (use (match_operand:SI 3 "" ""))]
15085 ;; Operand 2 not used on the i386.
15088 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15092 (define_expand "sibcall_value"
15093 [(set (match_operand 0 "" "")
15094 (call (match_operand:QI 1 "" "")
15095 (match_operand:SI 2 "" "")))
15096 (use (match_operand:SI 3 "" ""))]
15097 ;; Operand 2 not used on the i386.
15100 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15104 ;; Call subroutine returning any type.
15106 (define_expand "untyped_call"
15107 [(parallel [(call (match_operand 0 "" "")
15109 (match_operand 1 "" "")
15110 (match_operand 2 "" "")])]
15115 /* In order to give reg-stack an easier job in validating two
15116 coprocessor registers as containing a possible return value,
15117 simply pretend the untyped call returns a complex long double
15120 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15121 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15122 operands[0], const0_rtx,
15123 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15124 : X64_SSE_REGPARM_MAX)
15128 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15130 rtx set = XVECEXP (operands[2], 0, i);
15131 emit_move_insn (SET_DEST (set), SET_SRC (set));
15134 /* The optimizer does not know that the call sets the function value
15135 registers we stored in the result block. We avoid problems by
15136 claiming that all hard registers are used and clobbered at this
15138 emit_insn (gen_blockage ());
15143 ;; Prologue and epilogue instructions
15145 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15146 ;; all of memory. This blocks insns from being moved across this point.
15148 (define_insn "blockage"
15149 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15152 [(set_attr "length" "0")])
15154 ;; As USE insns aren't meaningful after reload, this is used instead
15155 ;; to prevent deleting instructions setting registers for PIC code
15156 (define_insn "prologue_use"
15157 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15160 [(set_attr "length" "0")])
15162 ;; Insn emitted into the body of a function to return from a function.
15163 ;; This is only done if the function's epilogue is known to be simple.
15164 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15166 (define_expand "return"
15168 "ix86_can_use_return_insn_p ()"
15170 if (crtl->args.pops_args)
15172 rtx popc = GEN_INT (crtl->args.pops_args);
15173 emit_jump_insn (gen_return_pop_internal (popc));
15178 (define_insn "return_internal"
15182 [(set_attr "length" "1")
15183 (set_attr "length_immediate" "0")
15184 (set_attr "modrm" "0")])
15186 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15187 ;; instruction Athlon and K8 have.
15189 (define_insn "return_internal_long"
15191 (unspec [(const_int 0)] UNSPEC_REP)]
15194 [(set_attr "length" "1")
15195 (set_attr "length_immediate" "0")
15196 (set_attr "prefix_rep" "1")
15197 (set_attr "modrm" "0")])
15199 (define_insn "return_pop_internal"
15201 (use (match_operand:SI 0 "const_int_operand" ""))]
15204 [(set_attr "length" "3")
15205 (set_attr "length_immediate" "2")
15206 (set_attr "modrm" "0")])
15208 (define_insn "return_indirect_internal"
15210 (use (match_operand:SI 0 "register_operand" "r"))]
15213 [(set_attr "type" "ibr")
15214 (set_attr "length_immediate" "0")])
15220 [(set_attr "length" "1")
15221 (set_attr "length_immediate" "0")
15222 (set_attr "modrm" "0")])
15224 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15225 ;; branch prediction penalty for the third jump in a 16-byte
15228 (define_insn "align"
15229 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15232 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15233 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15235 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15236 The align insn is used to avoid 3 jump instructions in the row to improve
15237 branch prediction and the benefits hardly outweigh the cost of extra 8
15238 nops on the average inserted by full alignment pseudo operation. */
15242 [(set_attr "length" "16")])
15244 (define_expand "prologue"
15247 "ix86_expand_prologue (); DONE;")
15249 (define_insn "set_got"
15250 [(set (match_operand:SI 0 "register_operand" "=r")
15251 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15252 (clobber (reg:CC FLAGS_REG))]
15254 { return output_set_got (operands[0], NULL_RTX); }
15255 [(set_attr "type" "multi")
15256 (set_attr "length" "12")])
15258 (define_insn "set_got_labelled"
15259 [(set (match_operand:SI 0 "register_operand" "=r")
15260 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15262 (clobber (reg:CC FLAGS_REG))]
15264 { return output_set_got (operands[0], operands[1]); }
15265 [(set_attr "type" "multi")
15266 (set_attr "length" "12")])
15268 (define_insn "set_got_rex64"
15269 [(set (match_operand:DI 0 "register_operand" "=r")
15270 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15272 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15273 [(set_attr "type" "lea")
15274 (set_attr "length" "6")])
15276 (define_insn "set_rip_rex64"
15277 [(set (match_operand:DI 0 "register_operand" "=r")
15278 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15280 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15281 [(set_attr "type" "lea")
15282 (set_attr "length" "6")])
15284 (define_insn "set_got_offset_rex64"
15285 [(set (match_operand:DI 0 "register_operand" "=r")
15286 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15288 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15289 [(set_attr "type" "imov")
15290 (set_attr "length" "11")])
15292 (define_expand "epilogue"
15295 "ix86_expand_epilogue (1); DONE;")
15297 (define_expand "sibcall_epilogue"
15300 "ix86_expand_epilogue (0); DONE;")
15302 (define_expand "eh_return"
15303 [(use (match_operand 0 "register_operand" ""))]
15306 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15308 /* Tricky bit: we write the address of the handler to which we will
15309 be returning into someone else's stack frame, one word below the
15310 stack address we wish to restore. */
15311 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15312 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15313 tmp = gen_rtx_MEM (Pmode, tmp);
15314 emit_move_insn (tmp, ra);
15316 if (Pmode == SImode)
15317 emit_jump_insn (gen_eh_return_si (sa));
15319 emit_jump_insn (gen_eh_return_di (sa));
15324 (define_insn_and_split "eh_return_<mode>"
15326 (unspec [(match_operand:P 0 "register_operand" "c")]
15327 UNSPEC_EH_RETURN))]
15332 "ix86_expand_epilogue (2); DONE;")
15334 (define_insn "leave"
15335 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15336 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15337 (clobber (mem:BLK (scratch)))]
15340 [(set_attr "type" "leave")])
15342 (define_insn "leave_rex64"
15343 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15344 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15345 (clobber (mem:BLK (scratch)))]
15348 [(set_attr "type" "leave")])
15350 (define_expand "ffssi2"
15352 [(set (match_operand:SI 0 "register_operand" "")
15353 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15354 (clobber (match_scratch:SI 2 ""))
15355 (clobber (reg:CC FLAGS_REG))])]
15360 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15365 (define_expand "ffs_cmove"
15366 [(set (match_dup 2) (const_int -1))
15367 (parallel [(set (reg:CCZ FLAGS_REG)
15368 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15370 (set (match_operand:SI 0 "register_operand" "")
15371 (ctz:SI (match_dup 1)))])
15372 (set (match_dup 0) (if_then_else:SI
15373 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15376 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15377 (clobber (reg:CC FLAGS_REG))])]
15379 "operands[2] = gen_reg_rtx (SImode);")
15381 (define_insn_and_split "*ffs_no_cmove"
15382 [(set (match_operand:SI 0 "register_operand" "=r")
15383 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15384 (clobber (match_scratch:SI 2 "=&q"))
15385 (clobber (reg:CC FLAGS_REG))]
15388 "&& reload_completed"
15389 [(parallel [(set (reg:CCZ FLAGS_REG)
15390 (compare:CCZ (match_dup 1) (const_int 0)))
15391 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15392 (set (strict_low_part (match_dup 3))
15393 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15394 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15395 (clobber (reg:CC FLAGS_REG))])
15396 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15397 (clobber (reg:CC FLAGS_REG))])
15398 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15399 (clobber (reg:CC FLAGS_REG))])]
15401 operands[3] = gen_lowpart (QImode, operands[2]);
15402 ix86_expand_clear (operands[2]);
15405 (define_insn "*ffssi_1"
15406 [(set (reg:CCZ FLAGS_REG)
15407 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15409 (set (match_operand:SI 0 "register_operand" "=r")
15410 (ctz:SI (match_dup 1)))]
15412 "bsf{l}\t{%1, %0|%0, %1}"
15413 [(set_attr "prefix_0f" "1")])
15415 (define_expand "ffsdi2"
15416 [(set (match_dup 2) (const_int -1))
15417 (parallel [(set (reg:CCZ FLAGS_REG)
15418 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15420 (set (match_operand:DI 0 "register_operand" "")
15421 (ctz:DI (match_dup 1)))])
15422 (set (match_dup 0) (if_then_else:DI
15423 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15426 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15427 (clobber (reg:CC FLAGS_REG))])]
15429 "operands[2] = gen_reg_rtx (DImode);")
15431 (define_insn "*ffsdi_1"
15432 [(set (reg:CCZ FLAGS_REG)
15433 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15435 (set (match_operand:DI 0 "register_operand" "=r")
15436 (ctz:DI (match_dup 1)))]
15438 "bsf{q}\t{%1, %0|%0, %1}"
15439 [(set_attr "prefix_0f" "1")])
15441 (define_insn "ctzsi2"
15442 [(set (match_operand:SI 0 "register_operand" "=r")
15443 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15444 (clobber (reg:CC FLAGS_REG))]
15446 "bsf{l}\t{%1, %0|%0, %1}"
15447 [(set_attr "prefix_0f" "1")])
15449 (define_insn "ctzdi2"
15450 [(set (match_operand:DI 0 "register_operand" "=r")
15451 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15452 (clobber (reg:CC FLAGS_REG))]
15454 "bsf{q}\t{%1, %0|%0, %1}"
15455 [(set_attr "prefix_0f" "1")])
15457 (define_expand "clzsi2"
15459 [(set (match_operand:SI 0 "register_operand" "")
15460 (minus:SI (const_int 31)
15461 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15462 (clobber (reg:CC FLAGS_REG))])
15464 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15465 (clobber (reg:CC FLAGS_REG))])]
15470 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15475 (define_insn "clzsi2_abm"
15476 [(set (match_operand:SI 0 "register_operand" "=r")
15477 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15478 (clobber (reg:CC FLAGS_REG))]
15480 "lzcnt{l}\t{%1, %0|%0, %1}"
15481 [(set_attr "prefix_rep" "1")
15482 (set_attr "type" "bitmanip")
15483 (set_attr "mode" "SI")])
15485 (define_insn "*bsr"
15486 [(set (match_operand:SI 0 "register_operand" "=r")
15487 (minus:SI (const_int 31)
15488 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15489 (clobber (reg:CC FLAGS_REG))]
15491 "bsr{l}\t{%1, %0|%0, %1}"
15492 [(set_attr "prefix_0f" "1")
15493 (set_attr "mode" "SI")])
15495 (define_insn "popcount<mode>2"
15496 [(set (match_operand:SWI248 0 "register_operand" "=r")
15498 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15499 (clobber (reg:CC FLAGS_REG))]
15503 return "popcnt\t{%1, %0|%0, %1}";
15505 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15508 [(set_attr "prefix_rep" "1")
15509 (set_attr "type" "bitmanip")
15510 (set_attr "mode" "<MODE>")])
15512 (define_insn "*popcount<mode>2_cmp"
15513 [(set (reg FLAGS_REG)
15516 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15518 (set (match_operand:SWI248 0 "register_operand" "=r")
15519 (popcount:SWI248 (match_dup 1)))]
15520 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15523 return "popcnt\t{%1, %0|%0, %1}";
15525 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15528 [(set_attr "prefix_rep" "1")
15529 (set_attr "type" "bitmanip")
15530 (set_attr "mode" "<MODE>")])
15532 (define_insn "*popcountsi2_cmp_zext"
15533 [(set (reg FLAGS_REG)
15535 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15537 (set (match_operand:DI 0 "register_operand" "=r")
15538 (zero_extend:DI(popcount:SI (match_dup 1))))]
15539 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15542 return "popcnt\t{%1, %0|%0, %1}";
15544 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15547 [(set_attr "prefix_rep" "1")
15548 (set_attr "type" "bitmanip")
15549 (set_attr "mode" "SI")])
15551 (define_expand "bswapsi2"
15552 [(set (match_operand:SI 0 "register_operand" "")
15553 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15558 rtx x = operands[0];
15560 emit_move_insn (x, operands[1]);
15561 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15562 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15563 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15568 (define_insn "*bswapsi_1"
15569 [(set (match_operand:SI 0 "register_operand" "=r")
15570 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15573 [(set_attr "prefix_0f" "1")
15574 (set_attr "length" "2")])
15576 (define_insn "*bswaphi_lowpart_1"
15577 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15578 (bswap:HI (match_dup 0)))
15579 (clobber (reg:CC FLAGS_REG))]
15580 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15582 xchg{b}\t{%h0, %b0|%b0, %h0}
15583 rol{w}\t{$8, %0|%0, 8}"
15584 [(set_attr "length" "2,4")
15585 (set_attr "mode" "QI,HI")])
15587 (define_insn "bswaphi_lowpart"
15588 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15589 (bswap:HI (match_dup 0)))
15590 (clobber (reg:CC FLAGS_REG))]
15592 "rol{w}\t{$8, %0|%0, 8}"
15593 [(set_attr "length" "4")
15594 (set_attr "mode" "HI")])
15596 (define_insn "bswapdi2"
15597 [(set (match_operand:DI 0 "register_operand" "=r")
15598 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15601 [(set_attr "prefix_0f" "1")
15602 (set_attr "length" "3")])
15604 (define_expand "clzdi2"
15606 [(set (match_operand:DI 0 "register_operand" "")
15607 (minus:DI (const_int 63)
15608 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15609 (clobber (reg:CC FLAGS_REG))])
15611 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15612 (clobber (reg:CC FLAGS_REG))])]
15617 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15622 (define_insn "clzdi2_abm"
15623 [(set (match_operand:DI 0 "register_operand" "=r")
15624 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15625 (clobber (reg:CC FLAGS_REG))]
15626 "TARGET_64BIT && TARGET_ABM"
15627 "lzcnt{q}\t{%1, %0|%0, %1}"
15628 [(set_attr "prefix_rep" "1")
15629 (set_attr "type" "bitmanip")
15630 (set_attr "mode" "DI")])
15632 (define_insn "*bsr_rex64"
15633 [(set (match_operand:DI 0 "register_operand" "=r")
15634 (minus:DI (const_int 63)
15635 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15636 (clobber (reg:CC FLAGS_REG))]
15638 "bsr{q}\t{%1, %0|%0, %1}"
15639 [(set_attr "prefix_0f" "1")
15640 (set_attr "mode" "DI")])
15642 (define_expand "clzhi2"
15644 [(set (match_operand:HI 0 "register_operand" "")
15645 (minus:HI (const_int 15)
15646 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15647 (clobber (reg:CC FLAGS_REG))])
15649 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15650 (clobber (reg:CC FLAGS_REG))])]
15655 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15660 (define_insn "clzhi2_abm"
15661 [(set (match_operand:HI 0 "register_operand" "=r")
15662 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15663 (clobber (reg:CC FLAGS_REG))]
15665 "lzcnt{w}\t{%1, %0|%0, %1}"
15666 [(set_attr "prefix_rep" "1")
15667 (set_attr "type" "bitmanip")
15668 (set_attr "mode" "HI")])
15670 (define_insn "*bsrhi"
15671 [(set (match_operand:HI 0 "register_operand" "=r")
15672 (minus:HI (const_int 15)
15673 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15674 (clobber (reg:CC FLAGS_REG))]
15676 "bsr{w}\t{%1, %0|%0, %1}"
15677 [(set_attr "prefix_0f" "1")
15678 (set_attr "mode" "HI")])
15680 (define_expand "paritydi2"
15681 [(set (match_operand:DI 0 "register_operand" "")
15682 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15685 rtx scratch = gen_reg_rtx (QImode);
15688 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15689 NULL_RTX, operands[1]));
15691 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15692 gen_rtx_REG (CCmode, FLAGS_REG),
15694 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15697 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15700 rtx tmp = gen_reg_rtx (SImode);
15702 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15703 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15708 (define_insn_and_split "paritydi2_cmp"
15709 [(set (reg:CC FLAGS_REG)
15710 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15711 (clobber (match_scratch:DI 0 "=r"))
15712 (clobber (match_scratch:SI 1 "=&r"))
15713 (clobber (match_scratch:HI 2 "=Q"))]
15716 "&& reload_completed"
15718 [(set (match_dup 1)
15719 (xor:SI (match_dup 1) (match_dup 4)))
15720 (clobber (reg:CC FLAGS_REG))])
15722 [(set (reg:CC FLAGS_REG)
15723 (parity:CC (match_dup 1)))
15724 (clobber (match_dup 1))
15725 (clobber (match_dup 2))])]
15727 operands[4] = gen_lowpart (SImode, operands[3]);
15731 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15732 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15735 operands[1] = gen_highpart (SImode, operands[3]);
15738 (define_expand "paritysi2"
15739 [(set (match_operand:SI 0 "register_operand" "")
15740 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15743 rtx scratch = gen_reg_rtx (QImode);
15746 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15748 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15749 gen_rtx_REG (CCmode, FLAGS_REG),
15751 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15753 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15757 (define_insn_and_split "paritysi2_cmp"
15758 [(set (reg:CC FLAGS_REG)
15759 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15760 (clobber (match_scratch:SI 0 "=r"))
15761 (clobber (match_scratch:HI 1 "=&Q"))]
15764 "&& reload_completed"
15766 [(set (match_dup 1)
15767 (xor:HI (match_dup 1) (match_dup 3)))
15768 (clobber (reg:CC FLAGS_REG))])
15770 [(set (reg:CC FLAGS_REG)
15771 (parity:CC (match_dup 1)))
15772 (clobber (match_dup 1))])]
15774 operands[3] = gen_lowpart (HImode, operands[2]);
15776 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15777 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15780 (define_insn "*parityhi2_cmp"
15781 [(set (reg:CC FLAGS_REG)
15782 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15783 (clobber (match_scratch:HI 0 "=Q"))]
15785 "xor{b}\t{%h0, %b0|%b0, %h0}"
15786 [(set_attr "length" "2")
15787 (set_attr "mode" "HI")])
15789 (define_insn "*parityqi2_cmp"
15790 [(set (reg:CC FLAGS_REG)
15791 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15794 [(set_attr "length" "2")
15795 (set_attr "mode" "QI")])
15797 ;; Thread-local storage patterns for ELF.
15799 ;; Note that these code sequences must appear exactly as shown
15800 ;; in order to allow linker relaxation.
15802 (define_insn "*tls_global_dynamic_32_gnu"
15803 [(set (match_operand:SI 0 "register_operand" "=a")
15804 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15805 (match_operand:SI 2 "tls_symbolic_operand" "")
15806 (match_operand:SI 3 "call_insn_operand" "")]
15808 (clobber (match_scratch:SI 4 "=d"))
15809 (clobber (match_scratch:SI 5 "=c"))
15810 (clobber (reg:CC FLAGS_REG))]
15811 "!TARGET_64BIT && TARGET_GNU_TLS"
15812 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15813 [(set_attr "type" "multi")
15814 (set_attr "length" "12")])
15816 (define_insn "*tls_global_dynamic_32_sun"
15817 [(set (match_operand:SI 0 "register_operand" "=a")
15818 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15819 (match_operand:SI 2 "tls_symbolic_operand" "")
15820 (match_operand:SI 3 "call_insn_operand" "")]
15822 (clobber (match_scratch:SI 4 "=d"))
15823 (clobber (match_scratch:SI 5 "=c"))
15824 (clobber (reg:CC FLAGS_REG))]
15825 "!TARGET_64BIT && TARGET_SUN_TLS"
15826 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15827 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15828 [(set_attr "type" "multi")
15829 (set_attr "length" "14")])
15831 (define_expand "tls_global_dynamic_32"
15832 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15835 (match_operand:SI 1 "tls_symbolic_operand" "")
15838 (clobber (match_scratch:SI 4 ""))
15839 (clobber (match_scratch:SI 5 ""))
15840 (clobber (reg:CC FLAGS_REG))])]
15844 operands[2] = pic_offset_table_rtx;
15847 operands[2] = gen_reg_rtx (Pmode);
15848 emit_insn (gen_set_got (operands[2]));
15850 if (TARGET_GNU2_TLS)
15852 emit_insn (gen_tls_dynamic_gnu2_32
15853 (operands[0], operands[1], operands[2]));
15856 operands[3] = ix86_tls_get_addr ();
15859 (define_insn "*tls_global_dynamic_64"
15860 [(set (match_operand:DI 0 "register_operand" "=a")
15861 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15862 (match_operand:DI 3 "" "")))
15863 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15866 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15867 [(set_attr "type" "multi")
15868 (set_attr "length" "16")])
15870 (define_expand "tls_global_dynamic_64"
15871 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15872 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15873 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15877 if (TARGET_GNU2_TLS)
15879 emit_insn (gen_tls_dynamic_gnu2_64
15880 (operands[0], operands[1]));
15883 operands[2] = ix86_tls_get_addr ();
15886 (define_insn "*tls_local_dynamic_base_32_gnu"
15887 [(set (match_operand:SI 0 "register_operand" "=a")
15888 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15889 (match_operand:SI 2 "call_insn_operand" "")]
15890 UNSPEC_TLS_LD_BASE))
15891 (clobber (match_scratch:SI 3 "=d"))
15892 (clobber (match_scratch:SI 4 "=c"))
15893 (clobber (reg:CC FLAGS_REG))]
15894 "!TARGET_64BIT && TARGET_GNU_TLS"
15895 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15896 [(set_attr "type" "multi")
15897 (set_attr "length" "11")])
15899 (define_insn "*tls_local_dynamic_base_32_sun"
15900 [(set (match_operand:SI 0 "register_operand" "=a")
15901 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15902 (match_operand:SI 2 "call_insn_operand" "")]
15903 UNSPEC_TLS_LD_BASE))
15904 (clobber (match_scratch:SI 3 "=d"))
15905 (clobber (match_scratch:SI 4 "=c"))
15906 (clobber (reg:CC FLAGS_REG))]
15907 "!TARGET_64BIT && TARGET_SUN_TLS"
15908 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15909 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15910 [(set_attr "type" "multi")
15911 (set_attr "length" "13")])
15913 (define_expand "tls_local_dynamic_base_32"
15914 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15915 (unspec:SI [(match_dup 1) (match_dup 2)]
15916 UNSPEC_TLS_LD_BASE))
15917 (clobber (match_scratch:SI 3 ""))
15918 (clobber (match_scratch:SI 4 ""))
15919 (clobber (reg:CC FLAGS_REG))])]
15923 operands[1] = pic_offset_table_rtx;
15926 operands[1] = gen_reg_rtx (Pmode);
15927 emit_insn (gen_set_got (operands[1]));
15929 if (TARGET_GNU2_TLS)
15931 emit_insn (gen_tls_dynamic_gnu2_32
15932 (operands[0], ix86_tls_module_base (), operands[1]));
15935 operands[2] = ix86_tls_get_addr ();
15938 (define_insn "*tls_local_dynamic_base_64"
15939 [(set (match_operand:DI 0 "register_operand" "=a")
15940 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15941 (match_operand:DI 2 "" "")))
15942 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15944 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15945 [(set_attr "type" "multi")
15946 (set_attr "length" "12")])
15948 (define_expand "tls_local_dynamic_base_64"
15949 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15950 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15951 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15954 if (TARGET_GNU2_TLS)
15956 emit_insn (gen_tls_dynamic_gnu2_64
15957 (operands[0], ix86_tls_module_base ()));
15960 operands[1] = ix86_tls_get_addr ();
15963 ;; Local dynamic of a single variable is a lose. Show combine how
15964 ;; to convert that back to global dynamic.
15966 (define_insn_and_split "*tls_local_dynamic_32_once"
15967 [(set (match_operand:SI 0 "register_operand" "=a")
15968 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15969 (match_operand:SI 2 "call_insn_operand" "")]
15970 UNSPEC_TLS_LD_BASE)
15971 (const:SI (unspec:SI
15972 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15974 (clobber (match_scratch:SI 4 "=d"))
15975 (clobber (match_scratch:SI 5 "=c"))
15976 (clobber (reg:CC FLAGS_REG))]
15980 [(parallel [(set (match_dup 0)
15981 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15983 (clobber (match_dup 4))
15984 (clobber (match_dup 5))
15985 (clobber (reg:CC FLAGS_REG))])]
15988 ;; Load and add the thread base pointer from %gs:0.
15990 (define_insn "*load_tp_si"
15991 [(set (match_operand:SI 0 "register_operand" "=r")
15992 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15994 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15995 [(set_attr "type" "imov")
15996 (set_attr "modrm" "0")
15997 (set_attr "length" "7")
15998 (set_attr "memory" "load")
15999 (set_attr "imm_disp" "false")])
16001 (define_insn "*add_tp_si"
16002 [(set (match_operand:SI 0 "register_operand" "=r")
16003 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16004 (match_operand:SI 1 "register_operand" "0")))
16005 (clobber (reg:CC FLAGS_REG))]
16007 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16008 [(set_attr "type" "alu")
16009 (set_attr "modrm" "0")
16010 (set_attr "length" "7")
16011 (set_attr "memory" "load")
16012 (set_attr "imm_disp" "false")])
16014 (define_insn "*load_tp_di"
16015 [(set (match_operand:DI 0 "register_operand" "=r")
16016 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16018 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16019 [(set_attr "type" "imov")
16020 (set_attr "modrm" "0")
16021 (set_attr "length" "7")
16022 (set_attr "memory" "load")
16023 (set_attr "imm_disp" "false")])
16025 (define_insn "*add_tp_di"
16026 [(set (match_operand:DI 0 "register_operand" "=r")
16027 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16028 (match_operand:DI 1 "register_operand" "0")))
16029 (clobber (reg:CC FLAGS_REG))]
16031 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16032 [(set_attr "type" "alu")
16033 (set_attr "modrm" "0")
16034 (set_attr "length" "7")
16035 (set_attr "memory" "load")
16036 (set_attr "imm_disp" "false")])
16038 ;; GNU2 TLS patterns can be split.
16040 (define_expand "tls_dynamic_gnu2_32"
16041 [(set (match_dup 3)
16042 (plus:SI (match_operand:SI 2 "register_operand" "")
16044 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16047 [(set (match_operand:SI 0 "register_operand" "")
16048 (unspec:SI [(match_dup 1) (match_dup 3)
16049 (match_dup 2) (reg:SI SP_REG)]
16051 (clobber (reg:CC FLAGS_REG))])]
16052 "!TARGET_64BIT && TARGET_GNU2_TLS"
16054 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16055 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16058 (define_insn "*tls_dynamic_lea_32"
16059 [(set (match_operand:SI 0 "register_operand" "=r")
16060 (plus:SI (match_operand:SI 1 "register_operand" "b")
16062 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16063 UNSPEC_TLSDESC))))]
16064 "!TARGET_64BIT && TARGET_GNU2_TLS"
16065 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16066 [(set_attr "type" "lea")
16067 (set_attr "mode" "SI")
16068 (set_attr "length" "6")
16069 (set_attr "length_address" "4")])
16071 (define_insn "*tls_dynamic_call_32"
16072 [(set (match_operand:SI 0 "register_operand" "=a")
16073 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16074 (match_operand:SI 2 "register_operand" "0")
16075 ;; we have to make sure %ebx still points to the GOT
16076 (match_operand:SI 3 "register_operand" "b")
16079 (clobber (reg:CC FLAGS_REG))]
16080 "!TARGET_64BIT && TARGET_GNU2_TLS"
16081 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16082 [(set_attr "type" "call")
16083 (set_attr "length" "2")
16084 (set_attr "length_address" "0")])
16086 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16087 [(set (match_operand:SI 0 "register_operand" "=&a")
16089 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16090 (match_operand:SI 4 "" "")
16091 (match_operand:SI 2 "register_operand" "b")
16094 (const:SI (unspec:SI
16095 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16097 (clobber (reg:CC FLAGS_REG))]
16098 "!TARGET_64BIT && TARGET_GNU2_TLS"
16101 [(set (match_dup 0) (match_dup 5))]
16103 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16104 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16107 (define_expand "tls_dynamic_gnu2_64"
16108 [(set (match_dup 2)
16109 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16112 [(set (match_operand:DI 0 "register_operand" "")
16113 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16115 (clobber (reg:CC FLAGS_REG))])]
16116 "TARGET_64BIT && TARGET_GNU2_TLS"
16118 operands[2] = !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_64"
16123 [(set (match_operand:DI 0 "register_operand" "=r")
16124 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16126 "TARGET_64BIT && TARGET_GNU2_TLS"
16127 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16128 [(set_attr "type" "lea")
16129 (set_attr "mode" "DI")
16130 (set_attr "length" "7")
16131 (set_attr "length_address" "4")])
16133 (define_insn "*tls_dynamic_call_64"
16134 [(set (match_operand:DI 0 "register_operand" "=a")
16135 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16136 (match_operand:DI 2 "register_operand" "0")
16139 (clobber (reg:CC FLAGS_REG))]
16140 "TARGET_64BIT && TARGET_GNU2_TLS"
16141 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16142 [(set_attr "type" "call")
16143 (set_attr "length" "2")
16144 (set_attr "length_address" "0")])
16146 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16147 [(set (match_operand:DI 0 "register_operand" "=&a")
16149 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16150 (match_operand:DI 3 "" "")
16153 (const:DI (unspec:DI
16154 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16156 (clobber (reg:CC FLAGS_REG))]
16157 "TARGET_64BIT && TARGET_GNU2_TLS"
16160 [(set (match_dup 0) (match_dup 4))]
16162 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16163 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16168 ;; These patterns match the binary 387 instructions for addM3, subM3,
16169 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16170 ;; SFmode. The first is the normal insn, the second the same insn but
16171 ;; with one operand a conversion, and the third the same insn but with
16172 ;; the other operand a conversion. The conversion may be SFmode or
16173 ;; SImode if the target mode DFmode, but only SImode if the target mode
16176 ;; Gcc is slightly more smart about handling normal two address instructions
16177 ;; so use special patterns for add and mull.
16179 (define_insn "*fop_<mode>_comm_mixed_avx"
16180 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16181 (match_operator:MODEF 3 "binary_fp_operator"
16182 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16183 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16184 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16185 && COMMUTATIVE_ARITH_P (operands[3])
16186 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16187 "* return output_387_binary_op (insn, operands);"
16188 [(set (attr "type")
16189 (if_then_else (eq_attr "alternative" "1")
16190 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16191 (const_string "ssemul")
16192 (const_string "sseadd"))
16193 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16194 (const_string "fmul")
16195 (const_string "fop"))))
16196 (set_attr "prefix" "orig,maybe_vex")
16197 (set_attr "mode" "<MODE>")])
16199 (define_insn "*fop_<mode>_comm_mixed"
16200 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16201 (match_operator:MODEF 3 "binary_fp_operator"
16202 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16203 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16204 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16205 && COMMUTATIVE_ARITH_P (operands[3])
16206 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16207 "* return output_387_binary_op (insn, operands);"
16208 [(set (attr "type")
16209 (if_then_else (eq_attr "alternative" "1")
16210 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16211 (const_string "ssemul")
16212 (const_string "sseadd"))
16213 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16214 (const_string "fmul")
16215 (const_string "fop"))))
16216 (set_attr "mode" "<MODE>")])
16218 (define_insn "*fop_<mode>_comm_avx"
16219 [(set (match_operand:MODEF 0 "register_operand" "=x")
16220 (match_operator:MODEF 3 "binary_fp_operator"
16221 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16222 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16223 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16224 && COMMUTATIVE_ARITH_P (operands[3])
16225 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16226 "* return output_387_binary_op (insn, operands);"
16227 [(set (attr "type")
16228 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16229 (const_string "ssemul")
16230 (const_string "sseadd")))
16231 (set_attr "prefix" "vex")
16232 (set_attr "mode" "<MODE>")])
16234 (define_insn "*fop_<mode>_comm_sse"
16235 [(set (match_operand:MODEF 0 "register_operand" "=x")
16236 (match_operator:MODEF 3 "binary_fp_operator"
16237 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16238 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16239 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16240 && COMMUTATIVE_ARITH_P (operands[3])
16241 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16242 "* return output_387_binary_op (insn, operands);"
16243 [(set (attr "type")
16244 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16245 (const_string "ssemul")
16246 (const_string "sseadd")))
16247 (set_attr "mode" "<MODE>")])
16249 (define_insn "*fop_<mode>_comm_i387"
16250 [(set (match_operand:MODEF 0 "register_operand" "=f")
16251 (match_operator:MODEF 3 "binary_fp_operator"
16252 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16253 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16255 && COMMUTATIVE_ARITH_P (operands[3])
16256 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16257 "* return output_387_binary_op (insn, operands);"
16258 [(set (attr "type")
16259 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16260 (const_string "fmul")
16261 (const_string "fop")))
16262 (set_attr "mode" "<MODE>")])
16264 (define_insn "*fop_<mode>_1_mixed_avx"
16265 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16266 (match_operator:MODEF 3 "binary_fp_operator"
16267 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16268 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16269 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16270 && !COMMUTATIVE_ARITH_P (operands[3])
16271 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16272 "* return output_387_binary_op (insn, operands);"
16273 [(set (attr "type")
16274 (cond [(and (eq_attr "alternative" "2")
16275 (match_operand:MODEF 3 "mult_operator" ""))
16276 (const_string "ssemul")
16277 (and (eq_attr "alternative" "2")
16278 (match_operand:MODEF 3 "div_operator" ""))
16279 (const_string "ssediv")
16280 (eq_attr "alternative" "2")
16281 (const_string "sseadd")
16282 (match_operand:MODEF 3 "mult_operator" "")
16283 (const_string "fmul")
16284 (match_operand:MODEF 3 "div_operator" "")
16285 (const_string "fdiv")
16287 (const_string "fop")))
16288 (set_attr "prefix" "orig,orig,maybe_vex")
16289 (set_attr "mode" "<MODE>")])
16291 (define_insn "*fop_<mode>_1_mixed"
16292 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16293 (match_operator:MODEF 3 "binary_fp_operator"
16294 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16295 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16296 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16297 && !COMMUTATIVE_ARITH_P (operands[3])
16298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16299 "* return output_387_binary_op (insn, operands);"
16300 [(set (attr "type")
16301 (cond [(and (eq_attr "alternative" "2")
16302 (match_operand:MODEF 3 "mult_operator" ""))
16303 (const_string "ssemul")
16304 (and (eq_attr "alternative" "2")
16305 (match_operand:MODEF 3 "div_operator" ""))
16306 (const_string "ssediv")
16307 (eq_attr "alternative" "2")
16308 (const_string "sseadd")
16309 (match_operand:MODEF 3 "mult_operator" "")
16310 (const_string "fmul")
16311 (match_operand:MODEF 3 "div_operator" "")
16312 (const_string "fdiv")
16314 (const_string "fop")))
16315 (set_attr "mode" "<MODE>")])
16317 (define_insn "*rcpsf2_sse"
16318 [(set (match_operand:SF 0 "register_operand" "=x")
16319 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16322 "%vrcpss\t{%1, %d0|%d0, %1}"
16323 [(set_attr "type" "sse")
16324 (set_attr "prefix" "maybe_vex")
16325 (set_attr "mode" "SF")])
16327 (define_insn "*fop_<mode>_1_avx"
16328 [(set (match_operand:MODEF 0 "register_operand" "=x")
16329 (match_operator:MODEF 3 "binary_fp_operator"
16330 [(match_operand:MODEF 1 "register_operand" "x")
16331 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16332 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16333 && !COMMUTATIVE_ARITH_P (operands[3])"
16334 "* return output_387_binary_op (insn, operands);"
16335 [(set (attr "type")
16336 (cond [(match_operand:MODEF 3 "mult_operator" "")
16337 (const_string "ssemul")
16338 (match_operand:MODEF 3 "div_operator" "")
16339 (const_string "ssediv")
16341 (const_string "sseadd")))
16342 (set_attr "prefix" "vex")
16343 (set_attr "mode" "<MODE>")])
16345 (define_insn "*fop_<mode>_1_sse"
16346 [(set (match_operand:MODEF 0 "register_operand" "=x")
16347 (match_operator:MODEF 3 "binary_fp_operator"
16348 [(match_operand:MODEF 1 "register_operand" "0")
16349 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16350 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16351 && !COMMUTATIVE_ARITH_P (operands[3])"
16352 "* return output_387_binary_op (insn, operands);"
16353 [(set (attr "type")
16354 (cond [(match_operand:MODEF 3 "mult_operator" "")
16355 (const_string "ssemul")
16356 (match_operand:MODEF 3 "div_operator" "")
16357 (const_string "ssediv")
16359 (const_string "sseadd")))
16360 (set_attr "mode" "<MODE>")])
16362 ;; This pattern is not fully shadowed by the pattern above.
16363 (define_insn "*fop_<mode>_1_i387"
16364 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16365 (match_operator:MODEF 3 "binary_fp_operator"
16366 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16367 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16368 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16369 && !COMMUTATIVE_ARITH_P (operands[3])
16370 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16371 "* return output_387_binary_op (insn, operands);"
16372 [(set (attr "type")
16373 (cond [(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 ;; ??? Add SSE splitters for these!
16382 (define_insn "*fop_<MODEF:mode>_2_i387"
16383 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16384 (match_operator:MODEF 3 "binary_fp_operator"
16386 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16387 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16388 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16389 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16390 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16391 [(set (attr "type")
16392 (cond [(match_operand:MODEF 3 "mult_operator" "")
16393 (const_string "fmul")
16394 (match_operand:MODEF 3 "div_operator" "")
16395 (const_string "fdiv")
16397 (const_string "fop")))
16398 (set_attr "fp_int_src" "true")
16399 (set_attr "mode" "<X87MODEI12:MODE>")])
16401 (define_insn "*fop_<MODEF:mode>_3_i387"
16402 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16403 (match_operator:MODEF 3 "binary_fp_operator"
16404 [(match_operand:MODEF 1 "register_operand" "0,0")
16406 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16407 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16408 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16409 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16410 [(set (attr "type")
16411 (cond [(match_operand:MODEF 3 "mult_operator" "")
16412 (const_string "fmul")
16413 (match_operand:MODEF 3 "div_operator" "")
16414 (const_string "fdiv")
16416 (const_string "fop")))
16417 (set_attr "fp_int_src" "true")
16418 (set_attr "mode" "<MODE>")])
16420 (define_insn "*fop_df_4_i387"
16421 [(set (match_operand:DF 0 "register_operand" "=f,f")
16422 (match_operator:DF 3 "binary_fp_operator"
16424 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16425 (match_operand:DF 2 "register_operand" "0,f")]))]
16426 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16427 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16428 "* return output_387_binary_op (insn, operands);"
16429 [(set (attr "type")
16430 (cond [(match_operand:DF 3 "mult_operator" "")
16431 (const_string "fmul")
16432 (match_operand:DF 3 "div_operator" "")
16433 (const_string "fdiv")
16435 (const_string "fop")))
16436 (set_attr "mode" "SF")])
16438 (define_insn "*fop_df_5_i387"
16439 [(set (match_operand:DF 0 "register_operand" "=f,f")
16440 (match_operator:DF 3 "binary_fp_operator"
16441 [(match_operand:DF 1 "register_operand" "0,f")
16443 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16444 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16445 "* return output_387_binary_op (insn, operands);"
16446 [(set (attr "type")
16447 (cond [(match_operand:DF 3 "mult_operator" "")
16448 (const_string "fmul")
16449 (match_operand:DF 3 "div_operator" "")
16450 (const_string "fdiv")
16452 (const_string "fop")))
16453 (set_attr "mode" "SF")])
16455 (define_insn "*fop_df_6_i387"
16456 [(set (match_operand:DF 0 "register_operand" "=f,f")
16457 (match_operator:DF 3 "binary_fp_operator"
16459 (match_operand:SF 1 "register_operand" "0,f"))
16461 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16462 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16463 "* return output_387_binary_op (insn, operands);"
16464 [(set (attr "type")
16465 (cond [(match_operand:DF 3 "mult_operator" "")
16466 (const_string "fmul")
16467 (match_operand:DF 3 "div_operator" "")
16468 (const_string "fdiv")
16470 (const_string "fop")))
16471 (set_attr "mode" "SF")])
16473 (define_insn "*fop_xf_comm_i387"
16474 [(set (match_operand:XF 0 "register_operand" "=f")
16475 (match_operator:XF 3 "binary_fp_operator"
16476 [(match_operand:XF 1 "register_operand" "%0")
16477 (match_operand:XF 2 "register_operand" "f")]))]
16479 && COMMUTATIVE_ARITH_P (operands[3])"
16480 "* return output_387_binary_op (insn, operands);"
16481 [(set (attr "type")
16482 (if_then_else (match_operand:XF 3 "mult_operator" "")
16483 (const_string "fmul")
16484 (const_string "fop")))
16485 (set_attr "mode" "XF")])
16487 (define_insn "*fop_xf_1_i387"
16488 [(set (match_operand:XF 0 "register_operand" "=f,f")
16489 (match_operator:XF 3 "binary_fp_operator"
16490 [(match_operand:XF 1 "register_operand" "0,f")
16491 (match_operand:XF 2 "register_operand" "f,0")]))]
16493 && !COMMUTATIVE_ARITH_P (operands[3])"
16494 "* return output_387_binary_op (insn, operands);"
16495 [(set (attr "type")
16496 (cond [(match_operand:XF 3 "mult_operator" "")
16497 (const_string "fmul")
16498 (match_operand:XF 3 "div_operator" "")
16499 (const_string "fdiv")
16501 (const_string "fop")))
16502 (set_attr "mode" "XF")])
16504 (define_insn "*fop_xf_2_i387"
16505 [(set (match_operand:XF 0 "register_operand" "=f,f")
16506 (match_operator:XF 3 "binary_fp_operator"
16508 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16509 (match_operand:XF 2 "register_operand" "0,0")]))]
16510 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16511 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16512 [(set (attr "type")
16513 (cond [(match_operand:XF 3 "mult_operator" "")
16514 (const_string "fmul")
16515 (match_operand:XF 3 "div_operator" "")
16516 (const_string "fdiv")
16518 (const_string "fop")))
16519 (set_attr "fp_int_src" "true")
16520 (set_attr "mode" "<MODE>")])
16522 (define_insn "*fop_xf_3_i387"
16523 [(set (match_operand:XF 0 "register_operand" "=f,f")
16524 (match_operator:XF 3 "binary_fp_operator"
16525 [(match_operand:XF 1 "register_operand" "0,0")
16527 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16528 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16529 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16530 [(set (attr "type")
16531 (cond [(match_operand:XF 3 "mult_operator" "")
16532 (const_string "fmul")
16533 (match_operand:XF 3 "div_operator" "")
16534 (const_string "fdiv")
16536 (const_string "fop")))
16537 (set_attr "fp_int_src" "true")
16538 (set_attr "mode" "<MODE>")])
16540 (define_insn "*fop_xf_4_i387"
16541 [(set (match_operand:XF 0 "register_operand" "=f,f")
16542 (match_operator:XF 3 "binary_fp_operator"
16544 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16545 (match_operand:XF 2 "register_operand" "0,f")]))]
16547 "* return output_387_binary_op (insn, operands);"
16548 [(set (attr "type")
16549 (cond [(match_operand:XF 3 "mult_operator" "")
16550 (const_string "fmul")
16551 (match_operand:XF 3 "div_operator" "")
16552 (const_string "fdiv")
16554 (const_string "fop")))
16555 (set_attr "mode" "<MODE>")])
16557 (define_insn "*fop_xf_5_i387"
16558 [(set (match_operand:XF 0 "register_operand" "=f,f")
16559 (match_operator:XF 3 "binary_fp_operator"
16560 [(match_operand:XF 1 "register_operand" "0,f")
16562 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16564 "* return output_387_binary_op (insn, operands);"
16565 [(set (attr "type")
16566 (cond [(match_operand:XF 3 "mult_operator" "")
16567 (const_string "fmul")
16568 (match_operand:XF 3 "div_operator" "")
16569 (const_string "fdiv")
16571 (const_string "fop")))
16572 (set_attr "mode" "<MODE>")])
16574 (define_insn "*fop_xf_6_i387"
16575 [(set (match_operand:XF 0 "register_operand" "=f,f")
16576 (match_operator:XF 3 "binary_fp_operator"
16578 (match_operand:MODEF 1 "register_operand" "0,f"))
16580 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16582 "* return output_387_binary_op (insn, operands);"
16583 [(set (attr "type")
16584 (cond [(match_operand:XF 3 "mult_operator" "")
16585 (const_string "fmul")
16586 (match_operand:XF 3 "div_operator" "")
16587 (const_string "fdiv")
16589 (const_string "fop")))
16590 (set_attr "mode" "<MODE>")])
16593 [(set (match_operand 0 "register_operand" "")
16594 (match_operator 3 "binary_fp_operator"
16595 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16596 (match_operand 2 "register_operand" "")]))]
16598 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16601 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16602 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16603 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16604 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16605 GET_MODE (operands[3]),
16608 ix86_free_from_memory (GET_MODE (operands[1]));
16613 [(set (match_operand 0 "register_operand" "")
16614 (match_operator 3 "binary_fp_operator"
16615 [(match_operand 1 "register_operand" "")
16616 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16618 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16621 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16622 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16623 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16624 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16625 GET_MODE (operands[3]),
16628 ix86_free_from_memory (GET_MODE (operands[2]));
16632 ;; FPU special functions.
16634 ;; This pattern implements a no-op XFmode truncation for
16635 ;; all fancy i386 XFmode math functions.
16637 (define_insn "truncxf<mode>2_i387_noop_unspec"
16638 [(set (match_operand:MODEF 0 "register_operand" "=f")
16639 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16640 UNSPEC_TRUNC_NOOP))]
16641 "TARGET_USE_FANCY_MATH_387"
16642 "* return output_387_reg_move (insn, operands);"
16643 [(set_attr "type" "fmov")
16644 (set_attr "mode" "<MODE>")])
16646 (define_insn "sqrtxf2"
16647 [(set (match_operand:XF 0 "register_operand" "=f")
16648 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16649 "TARGET_USE_FANCY_MATH_387"
16651 [(set_attr "type" "fpspc")
16652 (set_attr "mode" "XF")
16653 (set_attr "athlon_decode" "direct")
16654 (set_attr "amdfam10_decode" "direct")])
16656 (define_insn "sqrt_extend<mode>xf2_i387"
16657 [(set (match_operand:XF 0 "register_operand" "=f")
16660 (match_operand:MODEF 1 "register_operand" "0"))))]
16661 "TARGET_USE_FANCY_MATH_387"
16663 [(set_attr "type" "fpspc")
16664 (set_attr "mode" "XF")
16665 (set_attr "athlon_decode" "direct")
16666 (set_attr "amdfam10_decode" "direct")])
16668 (define_insn "*rsqrtsf2_sse"
16669 [(set (match_operand:SF 0 "register_operand" "=x")
16670 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16673 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16674 [(set_attr "type" "sse")
16675 (set_attr "prefix" "maybe_vex")
16676 (set_attr "mode" "SF")])
16678 (define_expand "rsqrtsf2"
16679 [(set (match_operand:SF 0 "register_operand" "")
16680 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16684 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16688 (define_insn "*sqrt<mode>2_sse"
16689 [(set (match_operand:MODEF 0 "register_operand" "=x")
16691 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16692 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16693 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16694 [(set_attr "type" "sse")
16695 (set_attr "prefix" "maybe_vex")
16696 (set_attr "mode" "<MODE>")
16697 (set_attr "athlon_decode" "*")
16698 (set_attr "amdfam10_decode" "*")])
16700 (define_expand "sqrt<mode>2"
16701 [(set (match_operand:MODEF 0 "register_operand" "")
16703 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16704 "TARGET_USE_FANCY_MATH_387
16705 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16707 if (<MODE>mode == SFmode
16708 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16709 && flag_finite_math_only && !flag_trapping_math
16710 && flag_unsafe_math_optimizations)
16712 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16716 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16718 rtx op0 = gen_reg_rtx (XFmode);
16719 rtx op1 = force_reg (<MODE>mode, operands[1]);
16721 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16722 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16727 (define_insn "fpremxf4_i387"
16728 [(set (match_operand:XF 0 "register_operand" "=f")
16729 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16730 (match_operand:XF 3 "register_operand" "1")]
16732 (set (match_operand:XF 1 "register_operand" "=u")
16733 (unspec:XF [(match_dup 2) (match_dup 3)]
16735 (set (reg:CCFP FPSR_REG)
16736 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16738 "TARGET_USE_FANCY_MATH_387"
16740 [(set_attr "type" "fpspc")
16741 (set_attr "mode" "XF")])
16743 (define_expand "fmodxf3"
16744 [(use (match_operand:XF 0 "register_operand" ""))
16745 (use (match_operand:XF 1 "general_operand" ""))
16746 (use (match_operand:XF 2 "general_operand" ""))]
16747 "TARGET_USE_FANCY_MATH_387"
16749 rtx label = gen_label_rtx ();
16751 rtx op1 = gen_reg_rtx (XFmode);
16752 rtx op2 = gen_reg_rtx (XFmode);
16754 emit_move_insn (op2, operands[2]);
16755 emit_move_insn (op1, operands[1]);
16757 emit_label (label);
16758 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16759 ix86_emit_fp_unordered_jump (label);
16760 LABEL_NUSES (label) = 1;
16762 emit_move_insn (operands[0], op1);
16766 (define_expand "fmod<mode>3"
16767 [(use (match_operand:MODEF 0 "register_operand" ""))
16768 (use (match_operand:MODEF 1 "general_operand" ""))
16769 (use (match_operand:MODEF 2 "general_operand" ""))]
16770 "TARGET_USE_FANCY_MATH_387"
16772 rtx label = gen_label_rtx ();
16774 rtx op1 = gen_reg_rtx (XFmode);
16775 rtx op2 = gen_reg_rtx (XFmode);
16777 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16778 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16780 emit_label (label);
16781 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16782 ix86_emit_fp_unordered_jump (label);
16783 LABEL_NUSES (label) = 1;
16785 /* Truncate the result properly for strict SSE math. */
16786 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16787 && !TARGET_MIX_SSE_I387)
16788 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16790 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16795 (define_insn "fprem1xf4_i387"
16796 [(set (match_operand:XF 0 "register_operand" "=f")
16797 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16798 (match_operand:XF 3 "register_operand" "1")]
16800 (set (match_operand:XF 1 "register_operand" "=u")
16801 (unspec:XF [(match_dup 2) (match_dup 3)]
16803 (set (reg:CCFP FPSR_REG)
16804 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16806 "TARGET_USE_FANCY_MATH_387"
16808 [(set_attr "type" "fpspc")
16809 (set_attr "mode" "XF")])
16811 (define_expand "remainderxf3"
16812 [(use (match_operand:XF 0 "register_operand" ""))
16813 (use (match_operand:XF 1 "general_operand" ""))
16814 (use (match_operand:XF 2 "general_operand" ""))]
16815 "TARGET_USE_FANCY_MATH_387"
16817 rtx label = gen_label_rtx ();
16819 rtx op1 = gen_reg_rtx (XFmode);
16820 rtx op2 = gen_reg_rtx (XFmode);
16822 emit_move_insn (op2, operands[2]);
16823 emit_move_insn (op1, operands[1]);
16825 emit_label (label);
16826 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16827 ix86_emit_fp_unordered_jump (label);
16828 LABEL_NUSES (label) = 1;
16830 emit_move_insn (operands[0], op1);
16834 (define_expand "remainder<mode>3"
16835 [(use (match_operand:MODEF 0 "register_operand" ""))
16836 (use (match_operand:MODEF 1 "general_operand" ""))
16837 (use (match_operand:MODEF 2 "general_operand" ""))]
16838 "TARGET_USE_FANCY_MATH_387"
16840 rtx label = gen_label_rtx ();
16842 rtx op1 = gen_reg_rtx (XFmode);
16843 rtx op2 = gen_reg_rtx (XFmode);
16845 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16846 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16848 emit_label (label);
16850 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16851 ix86_emit_fp_unordered_jump (label);
16852 LABEL_NUSES (label) = 1;
16854 /* Truncate the result properly for strict SSE math. */
16855 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16856 && !TARGET_MIX_SSE_I387)
16857 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16859 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16864 (define_insn "*sinxf2_i387"
16865 [(set (match_operand:XF 0 "register_operand" "=f")
16866 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16867 "TARGET_USE_FANCY_MATH_387
16868 && flag_unsafe_math_optimizations"
16870 [(set_attr "type" "fpspc")
16871 (set_attr "mode" "XF")])
16873 (define_insn "*sin_extend<mode>xf2_i387"
16874 [(set (match_operand:XF 0 "register_operand" "=f")
16875 (unspec:XF [(float_extend:XF
16876 (match_operand:MODEF 1 "register_operand" "0"))]
16878 "TARGET_USE_FANCY_MATH_387
16879 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16880 || TARGET_MIX_SSE_I387)
16881 && flag_unsafe_math_optimizations"
16883 [(set_attr "type" "fpspc")
16884 (set_attr "mode" "XF")])
16886 (define_insn "*cosxf2_i387"
16887 [(set (match_operand:XF 0 "register_operand" "=f")
16888 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16889 "TARGET_USE_FANCY_MATH_387
16890 && flag_unsafe_math_optimizations"
16892 [(set_attr "type" "fpspc")
16893 (set_attr "mode" "XF")])
16895 (define_insn "*cos_extend<mode>xf2_i387"
16896 [(set (match_operand:XF 0 "register_operand" "=f")
16897 (unspec:XF [(float_extend:XF
16898 (match_operand:MODEF 1 "register_operand" "0"))]
16900 "TARGET_USE_FANCY_MATH_387
16901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16902 || TARGET_MIX_SSE_I387)
16903 && flag_unsafe_math_optimizations"
16905 [(set_attr "type" "fpspc")
16906 (set_attr "mode" "XF")])
16908 ;; When sincos pattern is defined, sin and cos builtin functions will be
16909 ;; expanded to sincos pattern with one of its outputs left unused.
16910 ;; CSE pass will figure out if two sincos patterns can be combined,
16911 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16912 ;; depending on the unused output.
16914 (define_insn "sincosxf3"
16915 [(set (match_operand:XF 0 "register_operand" "=f")
16916 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16917 UNSPEC_SINCOS_COS))
16918 (set (match_operand:XF 1 "register_operand" "=u")
16919 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16920 "TARGET_USE_FANCY_MATH_387
16921 && flag_unsafe_math_optimizations"
16923 [(set_attr "type" "fpspc")
16924 (set_attr "mode" "XF")])
16927 [(set (match_operand:XF 0 "register_operand" "")
16928 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16929 UNSPEC_SINCOS_COS))
16930 (set (match_operand:XF 1 "register_operand" "")
16931 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16932 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16933 && !(reload_completed || reload_in_progress)"
16934 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16938 [(set (match_operand:XF 0 "register_operand" "")
16939 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16940 UNSPEC_SINCOS_COS))
16941 (set (match_operand:XF 1 "register_operand" "")
16942 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16943 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16944 && !(reload_completed || reload_in_progress)"
16945 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16948 (define_insn "sincos_extend<mode>xf3_i387"
16949 [(set (match_operand:XF 0 "register_operand" "=f")
16950 (unspec:XF [(float_extend:XF
16951 (match_operand:MODEF 2 "register_operand" "0"))]
16952 UNSPEC_SINCOS_COS))
16953 (set (match_operand:XF 1 "register_operand" "=u")
16954 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16955 "TARGET_USE_FANCY_MATH_387
16956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16957 || TARGET_MIX_SSE_I387)
16958 && flag_unsafe_math_optimizations"
16960 [(set_attr "type" "fpspc")
16961 (set_attr "mode" "XF")])
16964 [(set (match_operand:XF 0 "register_operand" "")
16965 (unspec:XF [(float_extend:XF
16966 (match_operand:MODEF 2 "register_operand" ""))]
16967 UNSPEC_SINCOS_COS))
16968 (set (match_operand:XF 1 "register_operand" "")
16969 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16970 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16971 && !(reload_completed || reload_in_progress)"
16972 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16976 [(set (match_operand:XF 0 "register_operand" "")
16977 (unspec:XF [(float_extend:XF
16978 (match_operand:MODEF 2 "register_operand" ""))]
16979 UNSPEC_SINCOS_COS))
16980 (set (match_operand:XF 1 "register_operand" "")
16981 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16982 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16983 && !(reload_completed || reload_in_progress)"
16984 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16987 (define_expand "sincos<mode>3"
16988 [(use (match_operand:MODEF 0 "register_operand" ""))
16989 (use (match_operand:MODEF 1 "register_operand" ""))
16990 (use (match_operand:MODEF 2 "register_operand" ""))]
16991 "TARGET_USE_FANCY_MATH_387
16992 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16993 || TARGET_MIX_SSE_I387)
16994 && flag_unsafe_math_optimizations"
16996 rtx op0 = gen_reg_rtx (XFmode);
16997 rtx op1 = gen_reg_rtx (XFmode);
16999 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17000 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17001 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17005 (define_insn "fptanxf4_i387"
17006 [(set (match_operand:XF 0 "register_operand" "=f")
17007 (match_operand:XF 3 "const_double_operand" "F"))
17008 (set (match_operand:XF 1 "register_operand" "=u")
17009 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17011 "TARGET_USE_FANCY_MATH_387
17012 && flag_unsafe_math_optimizations
17013 && standard_80387_constant_p (operands[3]) == 2"
17015 [(set_attr "type" "fpspc")
17016 (set_attr "mode" "XF")])
17018 (define_insn "fptan_extend<mode>xf4_i387"
17019 [(set (match_operand:MODEF 0 "register_operand" "=f")
17020 (match_operand:MODEF 3 "const_double_operand" "F"))
17021 (set (match_operand:XF 1 "register_operand" "=u")
17022 (unspec:XF [(float_extend:XF
17023 (match_operand:MODEF 2 "register_operand" "0"))]
17025 "TARGET_USE_FANCY_MATH_387
17026 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17027 || TARGET_MIX_SSE_I387)
17028 && flag_unsafe_math_optimizations
17029 && standard_80387_constant_p (operands[3]) == 2"
17031 [(set_attr "type" "fpspc")
17032 (set_attr "mode" "XF")])
17034 (define_expand "tanxf2"
17035 [(use (match_operand:XF 0 "register_operand" ""))
17036 (use (match_operand:XF 1 "register_operand" ""))]
17037 "TARGET_USE_FANCY_MATH_387
17038 && flag_unsafe_math_optimizations"
17040 rtx one = gen_reg_rtx (XFmode);
17041 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17043 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17047 (define_expand "tan<mode>2"
17048 [(use (match_operand:MODEF 0 "register_operand" ""))
17049 (use (match_operand:MODEF 1 "register_operand" ""))]
17050 "TARGET_USE_FANCY_MATH_387
17051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17052 || TARGET_MIX_SSE_I387)
17053 && flag_unsafe_math_optimizations"
17055 rtx op0 = gen_reg_rtx (XFmode);
17057 rtx one = gen_reg_rtx (<MODE>mode);
17058 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17060 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17061 operands[1], op2));
17062 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17066 (define_insn "*fpatanxf3_i387"
17067 [(set (match_operand:XF 0 "register_operand" "=f")
17068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17069 (match_operand:XF 2 "register_operand" "u")]
17071 (clobber (match_scratch:XF 3 "=2"))]
17072 "TARGET_USE_FANCY_MATH_387
17073 && flag_unsafe_math_optimizations"
17075 [(set_attr "type" "fpspc")
17076 (set_attr "mode" "XF")])
17078 (define_insn "fpatan_extend<mode>xf3_i387"
17079 [(set (match_operand:XF 0 "register_operand" "=f")
17080 (unspec:XF [(float_extend:XF
17081 (match_operand:MODEF 1 "register_operand" "0"))
17083 (match_operand:MODEF 2 "register_operand" "u"))]
17085 (clobber (match_scratch:XF 3 "=2"))]
17086 "TARGET_USE_FANCY_MATH_387
17087 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17088 || TARGET_MIX_SSE_I387)
17089 && flag_unsafe_math_optimizations"
17091 [(set_attr "type" "fpspc")
17092 (set_attr "mode" "XF")])
17094 (define_expand "atan2xf3"
17095 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17096 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17097 (match_operand:XF 1 "register_operand" "")]
17099 (clobber (match_scratch:XF 3 ""))])]
17100 "TARGET_USE_FANCY_MATH_387
17101 && flag_unsafe_math_optimizations"
17104 (define_expand "atan2<mode>3"
17105 [(use (match_operand:MODEF 0 "register_operand" ""))
17106 (use (match_operand:MODEF 1 "register_operand" ""))
17107 (use (match_operand:MODEF 2 "register_operand" ""))]
17108 "TARGET_USE_FANCY_MATH_387
17109 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17110 || TARGET_MIX_SSE_I387)
17111 && flag_unsafe_math_optimizations"
17113 rtx op0 = gen_reg_rtx (XFmode);
17115 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17116 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17120 (define_expand "atanxf2"
17121 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17122 (unspec:XF [(match_dup 2)
17123 (match_operand:XF 1 "register_operand" "")]
17125 (clobber (match_scratch:XF 3 ""))])]
17126 "TARGET_USE_FANCY_MATH_387
17127 && flag_unsafe_math_optimizations"
17129 operands[2] = gen_reg_rtx (XFmode);
17130 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17133 (define_expand "atan<mode>2"
17134 [(use (match_operand:MODEF 0 "register_operand" ""))
17135 (use (match_operand:MODEF 1 "register_operand" ""))]
17136 "TARGET_USE_FANCY_MATH_387
17137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17138 || TARGET_MIX_SSE_I387)
17139 && flag_unsafe_math_optimizations"
17141 rtx op0 = gen_reg_rtx (XFmode);
17143 rtx op2 = gen_reg_rtx (<MODE>mode);
17144 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17146 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17147 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17151 (define_expand "asinxf2"
17152 [(set (match_dup 2)
17153 (mult:XF (match_operand:XF 1 "register_operand" "")
17155 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17156 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17157 (parallel [(set (match_operand:XF 0 "register_operand" "")
17158 (unspec:XF [(match_dup 5) (match_dup 1)]
17160 (clobber (match_scratch:XF 6 ""))])]
17161 "TARGET_USE_FANCY_MATH_387
17162 && flag_unsafe_math_optimizations"
17166 if (optimize_insn_for_size_p ())
17169 for (i = 2; i < 6; i++)
17170 operands[i] = gen_reg_rtx (XFmode);
17172 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17175 (define_expand "asin<mode>2"
17176 [(use (match_operand:MODEF 0 "register_operand" ""))
17177 (use (match_operand:MODEF 1 "general_operand" ""))]
17178 "TARGET_USE_FANCY_MATH_387
17179 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17180 || TARGET_MIX_SSE_I387)
17181 && flag_unsafe_math_optimizations"
17183 rtx op0 = gen_reg_rtx (XFmode);
17184 rtx op1 = gen_reg_rtx (XFmode);
17186 if (optimize_insn_for_size_p ())
17189 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17190 emit_insn (gen_asinxf2 (op0, op1));
17191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17195 (define_expand "acosxf2"
17196 [(set (match_dup 2)
17197 (mult:XF (match_operand:XF 1 "register_operand" "")
17199 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17200 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17201 (parallel [(set (match_operand:XF 0 "register_operand" "")
17202 (unspec:XF [(match_dup 1) (match_dup 5)]
17204 (clobber (match_scratch:XF 6 ""))])]
17205 "TARGET_USE_FANCY_MATH_387
17206 && flag_unsafe_math_optimizations"
17210 if (optimize_insn_for_size_p ())
17213 for (i = 2; i < 6; i++)
17214 operands[i] = gen_reg_rtx (XFmode);
17216 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17219 (define_expand "acos<mode>2"
17220 [(use (match_operand:MODEF 0 "register_operand" ""))
17221 (use (match_operand:MODEF 1 "general_operand" ""))]
17222 "TARGET_USE_FANCY_MATH_387
17223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224 || TARGET_MIX_SSE_I387)
17225 && flag_unsafe_math_optimizations"
17227 rtx op0 = gen_reg_rtx (XFmode);
17228 rtx op1 = gen_reg_rtx (XFmode);
17230 if (optimize_insn_for_size_p ())
17233 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17234 emit_insn (gen_acosxf2 (op0, op1));
17235 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17239 (define_insn "fyl2xxf3_i387"
17240 [(set (match_operand:XF 0 "register_operand" "=f")
17241 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17242 (match_operand:XF 2 "register_operand" "u")]
17244 (clobber (match_scratch:XF 3 "=2"))]
17245 "TARGET_USE_FANCY_MATH_387
17246 && flag_unsafe_math_optimizations"
17248 [(set_attr "type" "fpspc")
17249 (set_attr "mode" "XF")])
17251 (define_insn "fyl2x_extend<mode>xf3_i387"
17252 [(set (match_operand:XF 0 "register_operand" "=f")
17253 (unspec:XF [(float_extend:XF
17254 (match_operand:MODEF 1 "register_operand" "0"))
17255 (match_operand:XF 2 "register_operand" "u")]
17257 (clobber (match_scratch:XF 3 "=2"))]
17258 "TARGET_USE_FANCY_MATH_387
17259 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17260 || TARGET_MIX_SSE_I387)
17261 && flag_unsafe_math_optimizations"
17263 [(set_attr "type" "fpspc")
17264 (set_attr "mode" "XF")])
17266 (define_expand "logxf2"
17267 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17268 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17269 (match_dup 2)] UNSPEC_FYL2X))
17270 (clobber (match_scratch:XF 3 ""))])]
17271 "TARGET_USE_FANCY_MATH_387
17272 && flag_unsafe_math_optimizations"
17274 operands[2] = gen_reg_rtx (XFmode);
17275 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17278 (define_expand "log<mode>2"
17279 [(use (match_operand:MODEF 0 "register_operand" ""))
17280 (use (match_operand:MODEF 1 "register_operand" ""))]
17281 "TARGET_USE_FANCY_MATH_387
17282 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17283 || TARGET_MIX_SSE_I387)
17284 && flag_unsafe_math_optimizations"
17286 rtx op0 = gen_reg_rtx (XFmode);
17288 rtx op2 = gen_reg_rtx (XFmode);
17289 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17291 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17296 (define_expand "log10xf2"
17297 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17298 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17299 (match_dup 2)] UNSPEC_FYL2X))
17300 (clobber (match_scratch:XF 3 ""))])]
17301 "TARGET_USE_FANCY_MATH_387
17302 && flag_unsafe_math_optimizations"
17304 operands[2] = gen_reg_rtx (XFmode);
17305 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17308 (define_expand "log10<mode>2"
17309 [(use (match_operand:MODEF 0 "register_operand" ""))
17310 (use (match_operand:MODEF 1 "register_operand" ""))]
17311 "TARGET_USE_FANCY_MATH_387
17312 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17313 || TARGET_MIX_SSE_I387)
17314 && flag_unsafe_math_optimizations"
17316 rtx op0 = gen_reg_rtx (XFmode);
17318 rtx op2 = gen_reg_rtx (XFmode);
17319 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17321 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17326 (define_expand "log2xf2"
17327 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17328 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17329 (match_dup 2)] UNSPEC_FYL2X))
17330 (clobber (match_scratch:XF 3 ""))])]
17331 "TARGET_USE_FANCY_MATH_387
17332 && flag_unsafe_math_optimizations"
17334 operands[2] = gen_reg_rtx (XFmode);
17335 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17338 (define_expand "log2<mode>2"
17339 [(use (match_operand:MODEF 0 "register_operand" ""))
17340 (use (match_operand:MODEF 1 "register_operand" ""))]
17341 "TARGET_USE_FANCY_MATH_387
17342 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17343 || TARGET_MIX_SSE_I387)
17344 && flag_unsafe_math_optimizations"
17346 rtx op0 = gen_reg_rtx (XFmode);
17348 rtx op2 = gen_reg_rtx (XFmode);
17349 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17351 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17352 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17356 (define_insn "fyl2xp1xf3_i387"
17357 [(set (match_operand:XF 0 "register_operand" "=f")
17358 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17359 (match_operand:XF 2 "register_operand" "u")]
17361 (clobber (match_scratch:XF 3 "=2"))]
17362 "TARGET_USE_FANCY_MATH_387
17363 && flag_unsafe_math_optimizations"
17365 [(set_attr "type" "fpspc")
17366 (set_attr "mode" "XF")])
17368 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17369 [(set (match_operand:XF 0 "register_operand" "=f")
17370 (unspec:XF [(float_extend:XF
17371 (match_operand:MODEF 1 "register_operand" "0"))
17372 (match_operand:XF 2 "register_operand" "u")]
17374 (clobber (match_scratch:XF 3 "=2"))]
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 [(set_attr "type" "fpspc")
17381 (set_attr "mode" "XF")])
17383 (define_expand "log1pxf2"
17384 [(use (match_operand:XF 0 "register_operand" ""))
17385 (use (match_operand:XF 1 "register_operand" ""))]
17386 "TARGET_USE_FANCY_MATH_387
17387 && flag_unsafe_math_optimizations"
17389 if (optimize_insn_for_size_p ())
17392 ix86_emit_i387_log1p (operands[0], operands[1]);
17396 (define_expand "log1p<mode>2"
17397 [(use (match_operand:MODEF 0 "register_operand" ""))
17398 (use (match_operand:MODEF 1 "register_operand" ""))]
17399 "TARGET_USE_FANCY_MATH_387
17400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17401 || TARGET_MIX_SSE_I387)
17402 && flag_unsafe_math_optimizations"
17406 if (optimize_insn_for_size_p ())
17409 op0 = gen_reg_rtx (XFmode);
17411 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17413 ix86_emit_i387_log1p (op0, operands[1]);
17414 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17418 (define_insn "fxtractxf3_i387"
17419 [(set (match_operand:XF 0 "register_operand" "=f")
17420 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17421 UNSPEC_XTRACT_FRACT))
17422 (set (match_operand:XF 1 "register_operand" "=u")
17423 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17424 "TARGET_USE_FANCY_MATH_387
17425 && flag_unsafe_math_optimizations"
17427 [(set_attr "type" "fpspc")
17428 (set_attr "mode" "XF")])
17430 (define_insn "fxtract_extend<mode>xf3_i387"
17431 [(set (match_operand:XF 0 "register_operand" "=f")
17432 (unspec:XF [(float_extend:XF
17433 (match_operand:MODEF 2 "register_operand" "0"))]
17434 UNSPEC_XTRACT_FRACT))
17435 (set (match_operand:XF 1 "register_operand" "=u")
17436 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17437 "TARGET_USE_FANCY_MATH_387
17438 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17439 || TARGET_MIX_SSE_I387)
17440 && flag_unsafe_math_optimizations"
17442 [(set_attr "type" "fpspc")
17443 (set_attr "mode" "XF")])
17445 (define_expand "logbxf2"
17446 [(parallel [(set (match_dup 2)
17447 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17448 UNSPEC_XTRACT_FRACT))
17449 (set (match_operand:XF 0 "register_operand" "")
17450 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17451 "TARGET_USE_FANCY_MATH_387
17452 && flag_unsafe_math_optimizations"
17454 operands[2] = gen_reg_rtx (XFmode);
17457 (define_expand "logb<mode>2"
17458 [(use (match_operand:MODEF 0 "register_operand" ""))
17459 (use (match_operand:MODEF 1 "register_operand" ""))]
17460 "TARGET_USE_FANCY_MATH_387
17461 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17462 || TARGET_MIX_SSE_I387)
17463 && flag_unsafe_math_optimizations"
17465 rtx op0 = gen_reg_rtx (XFmode);
17466 rtx op1 = gen_reg_rtx (XFmode);
17468 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17469 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17473 (define_expand "ilogbxf2"
17474 [(use (match_operand:SI 0 "register_operand" ""))
17475 (use (match_operand:XF 1 "register_operand" ""))]
17476 "TARGET_USE_FANCY_MATH_387
17477 && flag_unsafe_math_optimizations"
17481 if (optimize_insn_for_size_p ())
17484 op0 = gen_reg_rtx (XFmode);
17485 op1 = gen_reg_rtx (XFmode);
17487 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17488 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17492 (define_expand "ilogb<mode>2"
17493 [(use (match_operand:SI 0 "register_operand" ""))
17494 (use (match_operand:MODEF 1 "register_operand" ""))]
17495 "TARGET_USE_FANCY_MATH_387
17496 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17497 || TARGET_MIX_SSE_I387)
17498 && flag_unsafe_math_optimizations"
17502 if (optimize_insn_for_size_p ())
17505 op0 = gen_reg_rtx (XFmode);
17506 op1 = gen_reg_rtx (XFmode);
17508 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17509 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17513 (define_insn "*f2xm1xf2_i387"
17514 [(set (match_operand:XF 0 "register_operand" "=f")
17515 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17517 "TARGET_USE_FANCY_MATH_387
17518 && flag_unsafe_math_optimizations"
17520 [(set_attr "type" "fpspc")
17521 (set_attr "mode" "XF")])
17523 (define_insn "*fscalexf4_i387"
17524 [(set (match_operand:XF 0 "register_operand" "=f")
17525 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17526 (match_operand:XF 3 "register_operand" "1")]
17527 UNSPEC_FSCALE_FRACT))
17528 (set (match_operand:XF 1 "register_operand" "=u")
17529 (unspec:XF [(match_dup 2) (match_dup 3)]
17530 UNSPEC_FSCALE_EXP))]
17531 "TARGET_USE_FANCY_MATH_387
17532 && flag_unsafe_math_optimizations"
17534 [(set_attr "type" "fpspc")
17535 (set_attr "mode" "XF")])
17537 (define_expand "expNcorexf3"
17538 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17539 (match_operand:XF 2 "register_operand" "")))
17540 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17541 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17542 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17543 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17544 (parallel [(set (match_operand:XF 0 "register_operand" "")
17545 (unspec:XF [(match_dup 8) (match_dup 4)]
17546 UNSPEC_FSCALE_FRACT))
17548 (unspec:XF [(match_dup 8) (match_dup 4)]
17549 UNSPEC_FSCALE_EXP))])]
17550 "TARGET_USE_FANCY_MATH_387
17551 && flag_unsafe_math_optimizations"
17555 if (optimize_insn_for_size_p ())
17558 for (i = 3; i < 10; i++)
17559 operands[i] = gen_reg_rtx (XFmode);
17561 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17564 (define_expand "expxf2"
17565 [(use (match_operand:XF 0 "register_operand" ""))
17566 (use (match_operand:XF 1 "register_operand" ""))]
17567 "TARGET_USE_FANCY_MATH_387
17568 && flag_unsafe_math_optimizations"
17572 if (optimize_insn_for_size_p ())
17575 op2 = gen_reg_rtx (XFmode);
17576 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17578 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17582 (define_expand "exp<mode>2"
17583 [(use (match_operand:MODEF 0 "register_operand" ""))
17584 (use (match_operand:MODEF 1 "general_operand" ""))]
17585 "TARGET_USE_FANCY_MATH_387
17586 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17587 || TARGET_MIX_SSE_I387)
17588 && flag_unsafe_math_optimizations"
17592 if (optimize_insn_for_size_p ())
17595 op0 = gen_reg_rtx (XFmode);
17596 op1 = gen_reg_rtx (XFmode);
17598 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17599 emit_insn (gen_expxf2 (op0, op1));
17600 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17604 (define_expand "exp10xf2"
17605 [(use (match_operand:XF 0 "register_operand" ""))
17606 (use (match_operand:XF 1 "register_operand" ""))]
17607 "TARGET_USE_FANCY_MATH_387
17608 && flag_unsafe_math_optimizations"
17612 if (optimize_insn_for_size_p ())
17615 op2 = gen_reg_rtx (XFmode);
17616 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17618 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17622 (define_expand "exp10<mode>2"
17623 [(use (match_operand:MODEF 0 "register_operand" ""))
17624 (use (match_operand:MODEF 1 "general_operand" ""))]
17625 "TARGET_USE_FANCY_MATH_387
17626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17627 || TARGET_MIX_SSE_I387)
17628 && flag_unsafe_math_optimizations"
17632 if (optimize_insn_for_size_p ())
17635 op0 = gen_reg_rtx (XFmode);
17636 op1 = gen_reg_rtx (XFmode);
17638 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17639 emit_insn (gen_exp10xf2 (op0, op1));
17640 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17644 (define_expand "exp2xf2"
17645 [(use (match_operand:XF 0 "register_operand" ""))
17646 (use (match_operand:XF 1 "register_operand" ""))]
17647 "TARGET_USE_FANCY_MATH_387
17648 && flag_unsafe_math_optimizations"
17652 if (optimize_insn_for_size_p ())
17655 op2 = gen_reg_rtx (XFmode);
17656 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17658 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17662 (define_expand "exp2<mode>2"
17663 [(use (match_operand:MODEF 0 "register_operand" ""))
17664 (use (match_operand:MODEF 1 "general_operand" ""))]
17665 "TARGET_USE_FANCY_MATH_387
17666 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17667 || TARGET_MIX_SSE_I387)
17668 && flag_unsafe_math_optimizations"
17672 if (optimize_insn_for_size_p ())
17675 op0 = gen_reg_rtx (XFmode);
17676 op1 = gen_reg_rtx (XFmode);
17678 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17679 emit_insn (gen_exp2xf2 (op0, op1));
17680 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17684 (define_expand "expm1xf2"
17685 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17687 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17688 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17689 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17690 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17691 (parallel [(set (match_dup 7)
17692 (unspec:XF [(match_dup 6) (match_dup 4)]
17693 UNSPEC_FSCALE_FRACT))
17695 (unspec:XF [(match_dup 6) (match_dup 4)]
17696 UNSPEC_FSCALE_EXP))])
17697 (parallel [(set (match_dup 10)
17698 (unspec:XF [(match_dup 9) (match_dup 8)]
17699 UNSPEC_FSCALE_FRACT))
17700 (set (match_dup 11)
17701 (unspec:XF [(match_dup 9) (match_dup 8)]
17702 UNSPEC_FSCALE_EXP))])
17703 (set (match_dup 12) (minus:XF (match_dup 10)
17704 (float_extend:XF (match_dup 13))))
17705 (set (match_operand:XF 0 "register_operand" "")
17706 (plus:XF (match_dup 12) (match_dup 7)))]
17707 "TARGET_USE_FANCY_MATH_387
17708 && flag_unsafe_math_optimizations"
17712 if (optimize_insn_for_size_p ())
17715 for (i = 2; i < 13; i++)
17716 operands[i] = gen_reg_rtx (XFmode);
17719 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17721 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17724 (define_expand "expm1<mode>2"
17725 [(use (match_operand:MODEF 0 "register_operand" ""))
17726 (use (match_operand:MODEF 1 "general_operand" ""))]
17727 "TARGET_USE_FANCY_MATH_387
17728 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17729 || TARGET_MIX_SSE_I387)
17730 && flag_unsafe_math_optimizations"
17734 if (optimize_insn_for_size_p ())
17737 op0 = gen_reg_rtx (XFmode);
17738 op1 = gen_reg_rtx (XFmode);
17740 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17741 emit_insn (gen_expm1xf2 (op0, op1));
17742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17746 (define_expand "ldexpxf3"
17747 [(set (match_dup 3)
17748 (float:XF (match_operand:SI 2 "register_operand" "")))
17749 (parallel [(set (match_operand:XF 0 " register_operand" "")
17750 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17752 UNSPEC_FSCALE_FRACT))
17754 (unspec:XF [(match_dup 1) (match_dup 3)]
17755 UNSPEC_FSCALE_EXP))])]
17756 "TARGET_USE_FANCY_MATH_387
17757 && flag_unsafe_math_optimizations"
17759 if (optimize_insn_for_size_p ())
17762 operands[3] = gen_reg_rtx (XFmode);
17763 operands[4] = gen_reg_rtx (XFmode);
17766 (define_expand "ldexp<mode>3"
17767 [(use (match_operand:MODEF 0 "register_operand" ""))
17768 (use (match_operand:MODEF 1 "general_operand" ""))
17769 (use (match_operand:SI 2 "register_operand" ""))]
17770 "TARGET_USE_FANCY_MATH_387
17771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17772 || TARGET_MIX_SSE_I387)
17773 && flag_unsafe_math_optimizations"
17777 if (optimize_insn_for_size_p ())
17780 op0 = gen_reg_rtx (XFmode);
17781 op1 = gen_reg_rtx (XFmode);
17783 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17784 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17785 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17789 (define_expand "scalbxf3"
17790 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17791 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17792 (match_operand:XF 2 "register_operand" "")]
17793 UNSPEC_FSCALE_FRACT))
17795 (unspec:XF [(match_dup 1) (match_dup 2)]
17796 UNSPEC_FSCALE_EXP))])]
17797 "TARGET_USE_FANCY_MATH_387
17798 && flag_unsafe_math_optimizations"
17800 if (optimize_insn_for_size_p ())
17803 operands[3] = gen_reg_rtx (XFmode);
17806 (define_expand "scalb<mode>3"
17807 [(use (match_operand:MODEF 0 "register_operand" ""))
17808 (use (match_operand:MODEF 1 "general_operand" ""))
17809 (use (match_operand:MODEF 2 "register_operand" ""))]
17810 "TARGET_USE_FANCY_MATH_387
17811 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17812 || TARGET_MIX_SSE_I387)
17813 && flag_unsafe_math_optimizations"
17817 if (optimize_insn_for_size_p ())
17820 op0 = gen_reg_rtx (XFmode);
17821 op1 = gen_reg_rtx (XFmode);
17822 op2 = gen_reg_rtx (XFmode);
17824 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17825 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17826 emit_insn (gen_scalbxf3 (op0, op1, op2));
17827 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17832 (define_insn "sse4_1_round<mode>2"
17833 [(set (match_operand:MODEF 0 "register_operand" "=x")
17834 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17835 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17838 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17839 [(set_attr "type" "ssecvt")
17840 (set_attr "prefix_extra" "1")
17841 (set_attr "prefix" "maybe_vex")
17842 (set_attr "mode" "<MODE>")])
17844 (define_insn "rintxf2"
17845 [(set (match_operand:XF 0 "register_operand" "=f")
17846 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17848 "TARGET_USE_FANCY_MATH_387
17849 && flag_unsafe_math_optimizations"
17851 [(set_attr "type" "fpspc")
17852 (set_attr "mode" "XF")])
17854 (define_expand "rint<mode>2"
17855 [(use (match_operand:MODEF 0 "register_operand" ""))
17856 (use (match_operand:MODEF 1 "register_operand" ""))]
17857 "(TARGET_USE_FANCY_MATH_387
17858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17859 || TARGET_MIX_SSE_I387)
17860 && flag_unsafe_math_optimizations)
17861 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17862 && !flag_trapping_math)"
17864 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17865 && !flag_trapping_math)
17867 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17870 emit_insn (gen_sse4_1_round<mode>2
17871 (operands[0], operands[1], GEN_INT (0x04)));
17873 ix86_expand_rint (operand0, operand1);
17877 rtx op0 = gen_reg_rtx (XFmode);
17878 rtx op1 = gen_reg_rtx (XFmode);
17880 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17881 emit_insn (gen_rintxf2 (op0, op1));
17883 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17888 (define_expand "round<mode>2"
17889 [(match_operand:MODEF 0 "register_operand" "")
17890 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17891 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17892 && !flag_trapping_math && !flag_rounding_math"
17894 if (optimize_insn_for_size_p ())
17896 if (TARGET_64BIT || (<MODE>mode != DFmode))
17897 ix86_expand_round (operand0, operand1);
17899 ix86_expand_rounddf_32 (operand0, operand1);
17903 (define_insn_and_split "*fistdi2_1"
17904 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17905 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17907 "TARGET_USE_FANCY_MATH_387
17908 && !(reload_completed || reload_in_progress)"
17913 if (memory_operand (operands[0], VOIDmode))
17914 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17917 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17918 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17923 [(set_attr "type" "fpspc")
17924 (set_attr "mode" "DI")])
17926 (define_insn "fistdi2"
17927 [(set (match_operand:DI 0 "memory_operand" "=m")
17928 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17930 (clobber (match_scratch:XF 2 "=&1f"))]
17931 "TARGET_USE_FANCY_MATH_387"
17932 "* return output_fix_trunc (insn, operands, 0);"
17933 [(set_attr "type" "fpspc")
17934 (set_attr "mode" "DI")])
17936 (define_insn "fistdi2_with_temp"
17937 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17938 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17940 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17941 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17942 "TARGET_USE_FANCY_MATH_387"
17944 [(set_attr "type" "fpspc")
17945 (set_attr "mode" "DI")])
17948 [(set (match_operand:DI 0 "register_operand" "")
17949 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17951 (clobber (match_operand:DI 2 "memory_operand" ""))
17952 (clobber (match_scratch 3 ""))]
17954 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17955 (clobber (match_dup 3))])
17956 (set (match_dup 0) (match_dup 2))]
17960 [(set (match_operand:DI 0 "memory_operand" "")
17961 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17963 (clobber (match_operand:DI 2 "memory_operand" ""))
17964 (clobber (match_scratch 3 ""))]
17966 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17967 (clobber (match_dup 3))])]
17970 (define_insn_and_split "*fist<mode>2_1"
17971 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17972 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17974 "TARGET_USE_FANCY_MATH_387
17975 && !(reload_completed || reload_in_progress)"
17980 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17981 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17985 [(set_attr "type" "fpspc")
17986 (set_attr "mode" "<MODE>")])
17988 (define_insn "fist<mode>2"
17989 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17990 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17992 "TARGET_USE_FANCY_MATH_387"
17993 "* return output_fix_trunc (insn, operands, 0);"
17994 [(set_attr "type" "fpspc")
17995 (set_attr "mode" "<MODE>")])
17997 (define_insn "fist<mode>2_with_temp"
17998 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17999 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18001 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18002 "TARGET_USE_FANCY_MATH_387"
18004 [(set_attr "type" "fpspc")
18005 (set_attr "mode" "<MODE>")])
18008 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18009 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18011 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18013 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18014 (set (match_dup 0) (match_dup 2))]
18018 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18019 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18021 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18023 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18026 (define_expand "lrintxf<mode>2"
18027 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18028 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18030 "TARGET_USE_FANCY_MATH_387"
18033 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18034 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18035 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18036 UNSPEC_FIX_NOTRUNC))]
18037 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18038 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18041 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18042 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18043 (match_operand:MODEF 1 "register_operand" "")]
18044 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18045 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18046 && !flag_trapping_math && !flag_rounding_math"
18048 if (optimize_insn_for_size_p ())
18050 ix86_expand_lround (operand0, operand1);
18054 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18055 (define_insn_and_split "frndintxf2_floor"
18056 [(set (match_operand:XF 0 "register_operand" "")
18057 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18058 UNSPEC_FRNDINT_FLOOR))
18059 (clobber (reg:CC FLAGS_REG))]
18060 "TARGET_USE_FANCY_MATH_387
18061 && flag_unsafe_math_optimizations
18062 && !(reload_completed || reload_in_progress)"
18067 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18069 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18070 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18072 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18073 operands[2], operands[3]));
18076 [(set_attr "type" "frndint")
18077 (set_attr "i387_cw" "floor")
18078 (set_attr "mode" "XF")])
18080 (define_insn "frndintxf2_floor_i387"
18081 [(set (match_operand:XF 0 "register_operand" "=f")
18082 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18083 UNSPEC_FRNDINT_FLOOR))
18084 (use (match_operand:HI 2 "memory_operand" "m"))
18085 (use (match_operand:HI 3 "memory_operand" "m"))]
18086 "TARGET_USE_FANCY_MATH_387
18087 && flag_unsafe_math_optimizations"
18088 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18089 [(set_attr "type" "frndint")
18090 (set_attr "i387_cw" "floor")
18091 (set_attr "mode" "XF")])
18093 (define_expand "floorxf2"
18094 [(use (match_operand:XF 0 "register_operand" ""))
18095 (use (match_operand:XF 1 "register_operand" ""))]
18096 "TARGET_USE_FANCY_MATH_387
18097 && flag_unsafe_math_optimizations"
18099 if (optimize_insn_for_size_p ())
18101 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18105 (define_expand "floor<mode>2"
18106 [(use (match_operand:MODEF 0 "register_operand" ""))
18107 (use (match_operand:MODEF 1 "register_operand" ""))]
18108 "(TARGET_USE_FANCY_MATH_387
18109 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18110 || TARGET_MIX_SSE_I387)
18111 && flag_unsafe_math_optimizations)
18112 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18113 && !flag_trapping_math)"
18115 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18116 && !flag_trapping_math
18117 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18119 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18122 emit_insn (gen_sse4_1_round<mode>2
18123 (operands[0], operands[1], GEN_INT (0x01)));
18124 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18125 ix86_expand_floorceil (operand0, operand1, true);
18127 ix86_expand_floorceildf_32 (operand0, operand1, true);
18133 if (optimize_insn_for_size_p ())
18136 op0 = gen_reg_rtx (XFmode);
18137 op1 = gen_reg_rtx (XFmode);
18138 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18139 emit_insn (gen_frndintxf2_floor (op0, op1));
18141 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18146 (define_insn_and_split "*fist<mode>2_floor_1"
18147 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18148 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18149 UNSPEC_FIST_FLOOR))
18150 (clobber (reg:CC FLAGS_REG))]
18151 "TARGET_USE_FANCY_MATH_387
18152 && flag_unsafe_math_optimizations
18153 && !(reload_completed || reload_in_progress)"
18158 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18160 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18161 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18162 if (memory_operand (operands[0], VOIDmode))
18163 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18164 operands[2], operands[3]));
18167 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18168 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18169 operands[2], operands[3],
18174 [(set_attr "type" "fistp")
18175 (set_attr "i387_cw" "floor")
18176 (set_attr "mode" "<MODE>")])
18178 (define_insn "fistdi2_floor"
18179 [(set (match_operand:DI 0 "memory_operand" "=m")
18180 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18181 UNSPEC_FIST_FLOOR))
18182 (use (match_operand:HI 2 "memory_operand" "m"))
18183 (use (match_operand:HI 3 "memory_operand" "m"))
18184 (clobber (match_scratch:XF 4 "=&1f"))]
18185 "TARGET_USE_FANCY_MATH_387
18186 && flag_unsafe_math_optimizations"
18187 "* return output_fix_trunc (insn, operands, 0);"
18188 [(set_attr "type" "fistp")
18189 (set_attr "i387_cw" "floor")
18190 (set_attr "mode" "DI")])
18192 (define_insn "fistdi2_floor_with_temp"
18193 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18194 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18195 UNSPEC_FIST_FLOOR))
18196 (use (match_operand:HI 2 "memory_operand" "m,m"))
18197 (use (match_operand:HI 3 "memory_operand" "m,m"))
18198 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18199 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18200 "TARGET_USE_FANCY_MATH_387
18201 && flag_unsafe_math_optimizations"
18203 [(set_attr "type" "fistp")
18204 (set_attr "i387_cw" "floor")
18205 (set_attr "mode" "DI")])
18208 [(set (match_operand:DI 0 "register_operand" "")
18209 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18210 UNSPEC_FIST_FLOOR))
18211 (use (match_operand:HI 2 "memory_operand" ""))
18212 (use (match_operand:HI 3 "memory_operand" ""))
18213 (clobber (match_operand:DI 4 "memory_operand" ""))
18214 (clobber (match_scratch 5 ""))]
18216 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18217 (use (match_dup 2))
18218 (use (match_dup 3))
18219 (clobber (match_dup 5))])
18220 (set (match_dup 0) (match_dup 4))]
18224 [(set (match_operand:DI 0 "memory_operand" "")
18225 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18226 UNSPEC_FIST_FLOOR))
18227 (use (match_operand:HI 2 "memory_operand" ""))
18228 (use (match_operand:HI 3 "memory_operand" ""))
18229 (clobber (match_operand:DI 4 "memory_operand" ""))
18230 (clobber (match_scratch 5 ""))]
18232 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18233 (use (match_dup 2))
18234 (use (match_dup 3))
18235 (clobber (match_dup 5))])]
18238 (define_insn "fist<mode>2_floor"
18239 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18240 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18241 UNSPEC_FIST_FLOOR))
18242 (use (match_operand:HI 2 "memory_operand" "m"))
18243 (use (match_operand:HI 3 "memory_operand" "m"))]
18244 "TARGET_USE_FANCY_MATH_387
18245 && flag_unsafe_math_optimizations"
18246 "* return output_fix_trunc (insn, operands, 0);"
18247 [(set_attr "type" "fistp")
18248 (set_attr "i387_cw" "floor")
18249 (set_attr "mode" "<MODE>")])
18251 (define_insn "fist<mode>2_floor_with_temp"
18252 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18253 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18254 UNSPEC_FIST_FLOOR))
18255 (use (match_operand:HI 2 "memory_operand" "m,m"))
18256 (use (match_operand:HI 3 "memory_operand" "m,m"))
18257 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18258 "TARGET_USE_FANCY_MATH_387
18259 && flag_unsafe_math_optimizations"
18261 [(set_attr "type" "fistp")
18262 (set_attr "i387_cw" "floor")
18263 (set_attr "mode" "<MODE>")])
18266 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18267 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18268 UNSPEC_FIST_FLOOR))
18269 (use (match_operand:HI 2 "memory_operand" ""))
18270 (use (match_operand:HI 3 "memory_operand" ""))
18271 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18273 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18274 UNSPEC_FIST_FLOOR))
18275 (use (match_dup 2))
18276 (use (match_dup 3))])
18277 (set (match_dup 0) (match_dup 4))]
18281 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18282 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18283 UNSPEC_FIST_FLOOR))
18284 (use (match_operand:HI 2 "memory_operand" ""))
18285 (use (match_operand:HI 3 "memory_operand" ""))
18286 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18288 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18289 UNSPEC_FIST_FLOOR))
18290 (use (match_dup 2))
18291 (use (match_dup 3))])]
18294 (define_expand "lfloorxf<mode>2"
18295 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18296 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18297 UNSPEC_FIST_FLOOR))
18298 (clobber (reg:CC FLAGS_REG))])]
18299 "TARGET_USE_FANCY_MATH_387
18300 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18301 && flag_unsafe_math_optimizations"
18304 (define_expand "lfloor<mode>di2"
18305 [(match_operand:DI 0 "nonimmediate_operand" "")
18306 (match_operand:MODEF 1 "register_operand" "")]
18307 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18308 && !flag_trapping_math"
18310 if (optimize_insn_for_size_p ())
18312 ix86_expand_lfloorceil (operand0, operand1, true);
18316 (define_expand "lfloor<mode>si2"
18317 [(match_operand:SI 0 "nonimmediate_operand" "")
18318 (match_operand:MODEF 1 "register_operand" "")]
18319 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18320 && !flag_trapping_math"
18322 if (optimize_insn_for_size_p () && TARGET_64BIT)
18324 ix86_expand_lfloorceil (operand0, operand1, true);
18328 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18329 (define_insn_and_split "frndintxf2_ceil"
18330 [(set (match_operand:XF 0 "register_operand" "")
18331 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18332 UNSPEC_FRNDINT_CEIL))
18333 (clobber (reg:CC FLAGS_REG))]
18334 "TARGET_USE_FANCY_MATH_387
18335 && flag_unsafe_math_optimizations
18336 && !(reload_completed || reload_in_progress)"
18341 ix86_optimize_mode_switching[I387_CEIL] = 1;
18343 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18344 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18346 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18347 operands[2], operands[3]));
18350 [(set_attr "type" "frndint")
18351 (set_attr "i387_cw" "ceil")
18352 (set_attr "mode" "XF")])
18354 (define_insn "frndintxf2_ceil_i387"
18355 [(set (match_operand:XF 0 "register_operand" "=f")
18356 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18357 UNSPEC_FRNDINT_CEIL))
18358 (use (match_operand:HI 2 "memory_operand" "m"))
18359 (use (match_operand:HI 3 "memory_operand" "m"))]
18360 "TARGET_USE_FANCY_MATH_387
18361 && flag_unsafe_math_optimizations"
18362 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18363 [(set_attr "type" "frndint")
18364 (set_attr "i387_cw" "ceil")
18365 (set_attr "mode" "XF")])
18367 (define_expand "ceilxf2"
18368 [(use (match_operand:XF 0 "register_operand" ""))
18369 (use (match_operand:XF 1 "register_operand" ""))]
18370 "TARGET_USE_FANCY_MATH_387
18371 && flag_unsafe_math_optimizations"
18373 if (optimize_insn_for_size_p ())
18375 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18379 (define_expand "ceil<mode>2"
18380 [(use (match_operand:MODEF 0 "register_operand" ""))
18381 (use (match_operand:MODEF 1 "register_operand" ""))]
18382 "(TARGET_USE_FANCY_MATH_387
18383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18384 || TARGET_MIX_SSE_I387)
18385 && flag_unsafe_math_optimizations)
18386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18387 && !flag_trapping_math)"
18389 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18390 && !flag_trapping_math
18391 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18394 emit_insn (gen_sse4_1_round<mode>2
18395 (operands[0], operands[1], GEN_INT (0x02)));
18396 else if (optimize_insn_for_size_p ())
18398 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18399 ix86_expand_floorceil (operand0, operand1, false);
18401 ix86_expand_floorceildf_32 (operand0, operand1, false);
18407 if (optimize_insn_for_size_p ())
18410 op0 = gen_reg_rtx (XFmode);
18411 op1 = gen_reg_rtx (XFmode);
18412 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18413 emit_insn (gen_frndintxf2_ceil (op0, op1));
18415 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18420 (define_insn_and_split "*fist<mode>2_ceil_1"
18421 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18422 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18424 (clobber (reg:CC FLAGS_REG))]
18425 "TARGET_USE_FANCY_MATH_387
18426 && flag_unsafe_math_optimizations
18427 && !(reload_completed || reload_in_progress)"
18432 ix86_optimize_mode_switching[I387_CEIL] = 1;
18434 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18435 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18436 if (memory_operand (operands[0], VOIDmode))
18437 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18438 operands[2], operands[3]));
18441 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18442 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18443 operands[2], operands[3],
18448 [(set_attr "type" "fistp")
18449 (set_attr "i387_cw" "ceil")
18450 (set_attr "mode" "<MODE>")])
18452 (define_insn "fistdi2_ceil"
18453 [(set (match_operand:DI 0 "memory_operand" "=m")
18454 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18456 (use (match_operand:HI 2 "memory_operand" "m"))
18457 (use (match_operand:HI 3 "memory_operand" "m"))
18458 (clobber (match_scratch:XF 4 "=&1f"))]
18459 "TARGET_USE_FANCY_MATH_387
18460 && flag_unsafe_math_optimizations"
18461 "* return output_fix_trunc (insn, operands, 0);"
18462 [(set_attr "type" "fistp")
18463 (set_attr "i387_cw" "ceil")
18464 (set_attr "mode" "DI")])
18466 (define_insn "fistdi2_ceil_with_temp"
18467 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18468 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18470 (use (match_operand:HI 2 "memory_operand" "m,m"))
18471 (use (match_operand:HI 3 "memory_operand" "m,m"))
18472 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18473 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18474 "TARGET_USE_FANCY_MATH_387
18475 && flag_unsafe_math_optimizations"
18477 [(set_attr "type" "fistp")
18478 (set_attr "i387_cw" "ceil")
18479 (set_attr "mode" "DI")])
18482 [(set (match_operand:DI 0 "register_operand" "")
18483 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18485 (use (match_operand:HI 2 "memory_operand" ""))
18486 (use (match_operand:HI 3 "memory_operand" ""))
18487 (clobber (match_operand:DI 4 "memory_operand" ""))
18488 (clobber (match_scratch 5 ""))]
18490 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18491 (use (match_dup 2))
18492 (use (match_dup 3))
18493 (clobber (match_dup 5))])
18494 (set (match_dup 0) (match_dup 4))]
18498 [(set (match_operand:DI 0 "memory_operand" "")
18499 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18501 (use (match_operand:HI 2 "memory_operand" ""))
18502 (use (match_operand:HI 3 "memory_operand" ""))
18503 (clobber (match_operand:DI 4 "memory_operand" ""))
18504 (clobber (match_scratch 5 ""))]
18506 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18507 (use (match_dup 2))
18508 (use (match_dup 3))
18509 (clobber (match_dup 5))])]
18512 (define_insn "fist<mode>2_ceil"
18513 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18514 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18516 (use (match_operand:HI 2 "memory_operand" "m"))
18517 (use (match_operand:HI 3 "memory_operand" "m"))]
18518 "TARGET_USE_FANCY_MATH_387
18519 && flag_unsafe_math_optimizations"
18520 "* return output_fix_trunc (insn, operands, 0);"
18521 [(set_attr "type" "fistp")
18522 (set_attr "i387_cw" "ceil")
18523 (set_attr "mode" "<MODE>")])
18525 (define_insn "fist<mode>2_ceil_with_temp"
18526 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18527 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18529 (use (match_operand:HI 2 "memory_operand" "m,m"))
18530 (use (match_operand:HI 3 "memory_operand" "m,m"))
18531 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18532 "TARGET_USE_FANCY_MATH_387
18533 && flag_unsafe_math_optimizations"
18535 [(set_attr "type" "fistp")
18536 (set_attr "i387_cw" "ceil")
18537 (set_attr "mode" "<MODE>")])
18540 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18541 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18543 (use (match_operand:HI 2 "memory_operand" ""))
18544 (use (match_operand:HI 3 "memory_operand" ""))
18545 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18547 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18549 (use (match_dup 2))
18550 (use (match_dup 3))])
18551 (set (match_dup 0) (match_dup 4))]
18555 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18556 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18558 (use (match_operand:HI 2 "memory_operand" ""))
18559 (use (match_operand:HI 3 "memory_operand" ""))
18560 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18562 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18564 (use (match_dup 2))
18565 (use (match_dup 3))])]
18568 (define_expand "lceilxf<mode>2"
18569 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18570 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18572 (clobber (reg:CC FLAGS_REG))])]
18573 "TARGET_USE_FANCY_MATH_387
18574 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18575 && flag_unsafe_math_optimizations"
18578 (define_expand "lceil<mode>di2"
18579 [(match_operand:DI 0 "nonimmediate_operand" "")
18580 (match_operand:MODEF 1 "register_operand" "")]
18581 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18582 && !flag_trapping_math"
18584 ix86_expand_lfloorceil (operand0, operand1, false);
18588 (define_expand "lceil<mode>si2"
18589 [(match_operand:SI 0 "nonimmediate_operand" "")
18590 (match_operand:MODEF 1 "register_operand" "")]
18591 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18592 && !flag_trapping_math"
18594 ix86_expand_lfloorceil (operand0, operand1, false);
18598 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18599 (define_insn_and_split "frndintxf2_trunc"
18600 [(set (match_operand:XF 0 "register_operand" "")
18601 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18602 UNSPEC_FRNDINT_TRUNC))
18603 (clobber (reg:CC FLAGS_REG))]
18604 "TARGET_USE_FANCY_MATH_387
18605 && flag_unsafe_math_optimizations
18606 && !(reload_completed || reload_in_progress)"
18611 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18613 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18614 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18616 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18617 operands[2], operands[3]));
18620 [(set_attr "type" "frndint")
18621 (set_attr "i387_cw" "trunc")
18622 (set_attr "mode" "XF")])
18624 (define_insn "frndintxf2_trunc_i387"
18625 [(set (match_operand:XF 0 "register_operand" "=f")
18626 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18627 UNSPEC_FRNDINT_TRUNC))
18628 (use (match_operand:HI 2 "memory_operand" "m"))
18629 (use (match_operand:HI 3 "memory_operand" "m"))]
18630 "TARGET_USE_FANCY_MATH_387
18631 && flag_unsafe_math_optimizations"
18632 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18633 [(set_attr "type" "frndint")
18634 (set_attr "i387_cw" "trunc")
18635 (set_attr "mode" "XF")])
18637 (define_expand "btruncxf2"
18638 [(use (match_operand:XF 0 "register_operand" ""))
18639 (use (match_operand:XF 1 "register_operand" ""))]
18640 "TARGET_USE_FANCY_MATH_387
18641 && flag_unsafe_math_optimizations"
18643 if (optimize_insn_for_size_p ())
18645 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18649 (define_expand "btrunc<mode>2"
18650 [(use (match_operand:MODEF 0 "register_operand" ""))
18651 (use (match_operand:MODEF 1 "register_operand" ""))]
18652 "(TARGET_USE_FANCY_MATH_387
18653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18654 || TARGET_MIX_SSE_I387)
18655 && flag_unsafe_math_optimizations)
18656 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18657 && !flag_trapping_math)"
18659 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18660 && !flag_trapping_math
18661 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18664 emit_insn (gen_sse4_1_round<mode>2
18665 (operands[0], operands[1], GEN_INT (0x03)));
18666 else if (optimize_insn_for_size_p ())
18668 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18669 ix86_expand_trunc (operand0, operand1);
18671 ix86_expand_truncdf_32 (operand0, operand1);
18677 if (optimize_insn_for_size_p ())
18680 op0 = gen_reg_rtx (XFmode);
18681 op1 = gen_reg_rtx (XFmode);
18682 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18683 emit_insn (gen_frndintxf2_trunc (op0, op1));
18685 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18690 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18691 (define_insn_and_split "frndintxf2_mask_pm"
18692 [(set (match_operand:XF 0 "register_operand" "")
18693 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18694 UNSPEC_FRNDINT_MASK_PM))
18695 (clobber (reg:CC FLAGS_REG))]
18696 "TARGET_USE_FANCY_MATH_387
18697 && flag_unsafe_math_optimizations
18698 && !(reload_completed || reload_in_progress)"
18703 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18705 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18706 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18708 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18709 operands[2], operands[3]));
18712 [(set_attr "type" "frndint")
18713 (set_attr "i387_cw" "mask_pm")
18714 (set_attr "mode" "XF")])
18716 (define_insn "frndintxf2_mask_pm_i387"
18717 [(set (match_operand:XF 0 "register_operand" "=f")
18718 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18719 UNSPEC_FRNDINT_MASK_PM))
18720 (use (match_operand:HI 2 "memory_operand" "m"))
18721 (use (match_operand:HI 3 "memory_operand" "m"))]
18722 "TARGET_USE_FANCY_MATH_387
18723 && flag_unsafe_math_optimizations"
18724 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18725 [(set_attr "type" "frndint")
18726 (set_attr "i387_cw" "mask_pm")
18727 (set_attr "mode" "XF")])
18729 (define_expand "nearbyintxf2"
18730 [(use (match_operand:XF 0 "register_operand" ""))
18731 (use (match_operand:XF 1 "register_operand" ""))]
18732 "TARGET_USE_FANCY_MATH_387
18733 && flag_unsafe_math_optimizations"
18735 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18740 (define_expand "nearbyint<mode>2"
18741 [(use (match_operand:MODEF 0 "register_operand" ""))
18742 (use (match_operand:MODEF 1 "register_operand" ""))]
18743 "TARGET_USE_FANCY_MATH_387
18744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18745 || TARGET_MIX_SSE_I387)
18746 && flag_unsafe_math_optimizations"
18748 rtx op0 = gen_reg_rtx (XFmode);
18749 rtx op1 = gen_reg_rtx (XFmode);
18751 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18752 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18758 (define_insn "fxam<mode>2_i387"
18759 [(set (match_operand:HI 0 "register_operand" "=a")
18761 [(match_operand:X87MODEF 1 "register_operand" "f")]
18763 "TARGET_USE_FANCY_MATH_387"
18764 "fxam\n\tfnstsw\t%0"
18765 [(set_attr "type" "multi")
18766 (set_attr "unit" "i387")
18767 (set_attr "mode" "<MODE>")])
18769 (define_expand "isinf<mode>2"
18770 [(use (match_operand:SI 0 "register_operand" ""))
18771 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18772 "TARGET_USE_FANCY_MATH_387
18773 && TARGET_C99_FUNCTIONS
18774 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18776 rtx mask = GEN_INT (0x45);
18777 rtx val = GEN_INT (0x05);
18781 rtx scratch = gen_reg_rtx (HImode);
18782 rtx res = gen_reg_rtx (QImode);
18784 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18785 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18786 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18787 cond = gen_rtx_fmt_ee (EQ, QImode,
18788 gen_rtx_REG (CCmode, FLAGS_REG),
18790 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18791 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18795 (define_expand "signbit<mode>2"
18796 [(use (match_operand:SI 0 "register_operand" ""))
18797 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18798 "TARGET_USE_FANCY_MATH_387
18799 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18801 rtx mask = GEN_INT (0x0200);
18803 rtx scratch = gen_reg_rtx (HImode);
18805 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18806 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18810 ;; Block operation instructions
18813 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18816 [(set_attr "length" "1")
18817 (set_attr "length_immediate" "0")
18818 (set_attr "modrm" "0")])
18820 (define_expand "movmemsi"
18821 [(use (match_operand:BLK 0 "memory_operand" ""))
18822 (use (match_operand:BLK 1 "memory_operand" ""))
18823 (use (match_operand:SI 2 "nonmemory_operand" ""))
18824 (use (match_operand:SI 3 "const_int_operand" ""))
18825 (use (match_operand:SI 4 "const_int_operand" ""))
18826 (use (match_operand:SI 5 "const_int_operand" ""))]
18829 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18830 operands[4], operands[5]))
18836 (define_expand "movmemdi"
18837 [(use (match_operand:BLK 0 "memory_operand" ""))
18838 (use (match_operand:BLK 1 "memory_operand" ""))
18839 (use (match_operand:DI 2 "nonmemory_operand" ""))
18840 (use (match_operand:DI 3 "const_int_operand" ""))
18841 (use (match_operand:SI 4 "const_int_operand" ""))
18842 (use (match_operand:SI 5 "const_int_operand" ""))]
18845 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18846 operands[4], operands[5]))
18852 ;; Most CPUs don't like single string operations
18853 ;; Handle this case here to simplify previous expander.
18855 (define_expand "strmov"
18856 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18857 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18858 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18859 (clobber (reg:CC FLAGS_REG))])
18860 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18861 (clobber (reg:CC FLAGS_REG))])]
18864 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18866 /* If .md ever supports :P for Pmode, these can be directly
18867 in the pattern above. */
18868 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18869 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18871 /* Can't use this if the user has appropriated esi or edi. */
18872 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18873 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18875 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18876 operands[2], operands[3],
18877 operands[5], operands[6]));
18881 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18884 (define_expand "strmov_singleop"
18885 [(parallel [(set (match_operand 1 "memory_operand" "")
18886 (match_operand 3 "memory_operand" ""))
18887 (set (match_operand 0 "register_operand" "")
18888 (match_operand 4 "" ""))
18889 (set (match_operand 2 "register_operand" "")
18890 (match_operand 5 "" ""))])]
18892 "ix86_current_function_needs_cld = 1;")
18894 (define_insn "*strmovdi_rex_1"
18895 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18896 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18897 (set (match_operand:DI 0 "register_operand" "=D")
18898 (plus:DI (match_dup 2)
18900 (set (match_operand:DI 1 "register_operand" "=S")
18901 (plus:DI (match_dup 3)
18905 [(set_attr "type" "str")
18906 (set_attr "mode" "DI")
18907 (set_attr "memory" "both")])
18909 (define_insn "*strmovsi_1"
18910 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18911 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18912 (set (match_operand:SI 0 "register_operand" "=D")
18913 (plus:SI (match_dup 2)
18915 (set (match_operand:SI 1 "register_operand" "=S")
18916 (plus:SI (match_dup 3)
18920 [(set_attr "type" "str")
18921 (set_attr "mode" "SI")
18922 (set_attr "memory" "both")])
18924 (define_insn "*strmovsi_rex_1"
18925 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18926 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18927 (set (match_operand:DI 0 "register_operand" "=D")
18928 (plus:DI (match_dup 2)
18930 (set (match_operand:DI 1 "register_operand" "=S")
18931 (plus:DI (match_dup 3)
18935 [(set_attr "type" "str")
18936 (set_attr "mode" "SI")
18937 (set_attr "memory" "both")])
18939 (define_insn "*strmovhi_1"
18940 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18941 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18942 (set (match_operand:SI 0 "register_operand" "=D")
18943 (plus:SI (match_dup 2)
18945 (set (match_operand:SI 1 "register_operand" "=S")
18946 (plus:SI (match_dup 3)
18950 [(set_attr "type" "str")
18951 (set_attr "memory" "both")
18952 (set_attr "mode" "HI")])
18954 (define_insn "*strmovhi_rex_1"
18955 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18956 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18957 (set (match_operand:DI 0 "register_operand" "=D")
18958 (plus:DI (match_dup 2)
18960 (set (match_operand:DI 1 "register_operand" "=S")
18961 (plus:DI (match_dup 3)
18965 [(set_attr "type" "str")
18966 (set_attr "memory" "both")
18967 (set_attr "mode" "HI")])
18969 (define_insn "*strmovqi_1"
18970 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18971 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18972 (set (match_operand:SI 0 "register_operand" "=D")
18973 (plus:SI (match_dup 2)
18975 (set (match_operand:SI 1 "register_operand" "=S")
18976 (plus:SI (match_dup 3)
18980 [(set_attr "type" "str")
18981 (set_attr "memory" "both")
18982 (set_attr "mode" "QI")])
18984 (define_insn "*strmovqi_rex_1"
18985 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18986 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18987 (set (match_operand:DI 0 "register_operand" "=D")
18988 (plus:DI (match_dup 2)
18990 (set (match_operand:DI 1 "register_operand" "=S")
18991 (plus:DI (match_dup 3)
18995 [(set_attr "type" "str")
18996 (set_attr "memory" "both")
18997 (set_attr "mode" "QI")])
18999 (define_expand "rep_mov"
19000 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19001 (set (match_operand 0 "register_operand" "")
19002 (match_operand 5 "" ""))
19003 (set (match_operand 2 "register_operand" "")
19004 (match_operand 6 "" ""))
19005 (set (match_operand 1 "memory_operand" "")
19006 (match_operand 3 "memory_operand" ""))
19007 (use (match_dup 4))])]
19009 "ix86_current_function_needs_cld = 1;")
19011 (define_insn "*rep_movdi_rex64"
19012 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19013 (set (match_operand:DI 0 "register_operand" "=D")
19014 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19016 (match_operand:DI 3 "register_operand" "0")))
19017 (set (match_operand:DI 1 "register_operand" "=S")
19018 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19019 (match_operand:DI 4 "register_operand" "1")))
19020 (set (mem:BLK (match_dup 3))
19021 (mem:BLK (match_dup 4)))
19022 (use (match_dup 5))]
19025 [(set_attr "type" "str")
19026 (set_attr "prefix_rep" "1")
19027 (set_attr "memory" "both")
19028 (set_attr "mode" "DI")])
19030 (define_insn "*rep_movsi"
19031 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19032 (set (match_operand:SI 0 "register_operand" "=D")
19033 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19035 (match_operand:SI 3 "register_operand" "0")))
19036 (set (match_operand:SI 1 "register_operand" "=S")
19037 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19038 (match_operand:SI 4 "register_operand" "1")))
19039 (set (mem:BLK (match_dup 3))
19040 (mem:BLK (match_dup 4)))
19041 (use (match_dup 5))]
19044 [(set_attr "type" "str")
19045 (set_attr "prefix_rep" "1")
19046 (set_attr "memory" "both")
19047 (set_attr "mode" "SI")])
19049 (define_insn "*rep_movsi_rex64"
19050 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19051 (set (match_operand:DI 0 "register_operand" "=D")
19052 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19054 (match_operand:DI 3 "register_operand" "0")))
19055 (set (match_operand:DI 1 "register_operand" "=S")
19056 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19057 (match_operand:DI 4 "register_operand" "1")))
19058 (set (mem:BLK (match_dup 3))
19059 (mem:BLK (match_dup 4)))
19060 (use (match_dup 5))]
19063 [(set_attr "type" "str")
19064 (set_attr "prefix_rep" "1")
19065 (set_attr "memory" "both")
19066 (set_attr "mode" "SI")])
19068 (define_insn "*rep_movqi"
19069 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19070 (set (match_operand:SI 0 "register_operand" "=D")
19071 (plus:SI (match_operand:SI 3 "register_operand" "0")
19072 (match_operand:SI 5 "register_operand" "2")))
19073 (set (match_operand:SI 1 "register_operand" "=S")
19074 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19075 (set (mem:BLK (match_dup 3))
19076 (mem:BLK (match_dup 4)))
19077 (use (match_dup 5))]
19080 [(set_attr "type" "str")
19081 (set_attr "prefix_rep" "1")
19082 (set_attr "memory" "both")
19083 (set_attr "mode" "SI")])
19085 (define_insn "*rep_movqi_rex64"
19086 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19087 (set (match_operand:DI 0 "register_operand" "=D")
19088 (plus:DI (match_operand:DI 3 "register_operand" "0")
19089 (match_operand:DI 5 "register_operand" "2")))
19090 (set (match_operand:DI 1 "register_operand" "=S")
19091 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19092 (set (mem:BLK (match_dup 3))
19093 (mem:BLK (match_dup 4)))
19094 (use (match_dup 5))]
19097 [(set_attr "type" "str")
19098 (set_attr "prefix_rep" "1")
19099 (set_attr "memory" "both")
19100 (set_attr "mode" "SI")])
19102 (define_expand "setmemsi"
19103 [(use (match_operand:BLK 0 "memory_operand" ""))
19104 (use (match_operand:SI 1 "nonmemory_operand" ""))
19105 (use (match_operand 2 "const_int_operand" ""))
19106 (use (match_operand 3 "const_int_operand" ""))
19107 (use (match_operand:SI 4 "const_int_operand" ""))
19108 (use (match_operand:SI 5 "const_int_operand" ""))]
19111 if (ix86_expand_setmem (operands[0], operands[1],
19112 operands[2], operands[3],
19113 operands[4], operands[5]))
19119 (define_expand "setmemdi"
19120 [(use (match_operand:BLK 0 "memory_operand" ""))
19121 (use (match_operand:DI 1 "nonmemory_operand" ""))
19122 (use (match_operand 2 "const_int_operand" ""))
19123 (use (match_operand 3 "const_int_operand" ""))
19124 (use (match_operand 4 "const_int_operand" ""))
19125 (use (match_operand 5 "const_int_operand" ""))]
19128 if (ix86_expand_setmem (operands[0], operands[1],
19129 operands[2], operands[3],
19130 operands[4], operands[5]))
19136 ;; Most CPUs don't like single string operations
19137 ;; Handle this case here to simplify previous expander.
19139 (define_expand "strset"
19140 [(set (match_operand 1 "memory_operand" "")
19141 (match_operand 2 "register_operand" ""))
19142 (parallel [(set (match_operand 0 "register_operand" "")
19144 (clobber (reg:CC FLAGS_REG))])]
19147 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19148 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19150 /* If .md ever supports :P for Pmode, this can be directly
19151 in the pattern above. */
19152 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19153 GEN_INT (GET_MODE_SIZE (GET_MODE
19155 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19157 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19163 (define_expand "strset_singleop"
19164 [(parallel [(set (match_operand 1 "memory_operand" "")
19165 (match_operand 2 "register_operand" ""))
19166 (set (match_operand 0 "register_operand" "")
19167 (match_operand 3 "" ""))])]
19169 "ix86_current_function_needs_cld = 1;")
19171 (define_insn "*strsetdi_rex_1"
19172 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19173 (match_operand:DI 2 "register_operand" "a"))
19174 (set (match_operand:DI 0 "register_operand" "=D")
19175 (plus:DI (match_dup 1)
19179 [(set_attr "type" "str")
19180 (set_attr "memory" "store")
19181 (set_attr "mode" "DI")])
19183 (define_insn "*strsetsi_1"
19184 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19185 (match_operand:SI 2 "register_operand" "a"))
19186 (set (match_operand:SI 0 "register_operand" "=D")
19187 (plus:SI (match_dup 1)
19191 [(set_attr "type" "str")
19192 (set_attr "memory" "store")
19193 (set_attr "mode" "SI")])
19195 (define_insn "*strsetsi_rex_1"
19196 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19197 (match_operand:SI 2 "register_operand" "a"))
19198 (set (match_operand:DI 0 "register_operand" "=D")
19199 (plus:DI (match_dup 1)
19203 [(set_attr "type" "str")
19204 (set_attr "memory" "store")
19205 (set_attr "mode" "SI")])
19207 (define_insn "*strsethi_1"
19208 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19209 (match_operand:HI 2 "register_operand" "a"))
19210 (set (match_operand:SI 0 "register_operand" "=D")
19211 (plus:SI (match_dup 1)
19215 [(set_attr "type" "str")
19216 (set_attr "memory" "store")
19217 (set_attr "mode" "HI")])
19219 (define_insn "*strsethi_rex_1"
19220 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19221 (match_operand:HI 2 "register_operand" "a"))
19222 (set (match_operand:DI 0 "register_operand" "=D")
19223 (plus:DI (match_dup 1)
19227 [(set_attr "type" "str")
19228 (set_attr "memory" "store")
19229 (set_attr "mode" "HI")])
19231 (define_insn "*strsetqi_1"
19232 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19233 (match_operand:QI 2 "register_operand" "a"))
19234 (set (match_operand:SI 0 "register_operand" "=D")
19235 (plus:SI (match_dup 1)
19239 [(set_attr "type" "str")
19240 (set_attr "memory" "store")
19241 (set_attr "mode" "QI")])
19243 (define_insn "*strsetqi_rex_1"
19244 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19245 (match_operand:QI 2 "register_operand" "a"))
19246 (set (match_operand:DI 0 "register_operand" "=D")
19247 (plus:DI (match_dup 1)
19251 [(set_attr "type" "str")
19252 (set_attr "memory" "store")
19253 (set_attr "mode" "QI")])
19255 (define_expand "rep_stos"
19256 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19257 (set (match_operand 0 "register_operand" "")
19258 (match_operand 4 "" ""))
19259 (set (match_operand 2 "memory_operand" "") (const_int 0))
19260 (use (match_operand 3 "register_operand" ""))
19261 (use (match_dup 1))])]
19263 "ix86_current_function_needs_cld = 1;")
19265 (define_insn "*rep_stosdi_rex64"
19266 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19267 (set (match_operand:DI 0 "register_operand" "=D")
19268 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19270 (match_operand:DI 3 "register_operand" "0")))
19271 (set (mem:BLK (match_dup 3))
19273 (use (match_operand:DI 2 "register_operand" "a"))
19274 (use (match_dup 4))]
19277 [(set_attr "type" "str")
19278 (set_attr "prefix_rep" "1")
19279 (set_attr "memory" "store")
19280 (set_attr "mode" "DI")])
19282 (define_insn "*rep_stossi"
19283 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19284 (set (match_operand:SI 0 "register_operand" "=D")
19285 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19287 (match_operand:SI 3 "register_operand" "0")))
19288 (set (mem:BLK (match_dup 3))
19290 (use (match_operand:SI 2 "register_operand" "a"))
19291 (use (match_dup 4))]
19294 [(set_attr "type" "str")
19295 (set_attr "prefix_rep" "1")
19296 (set_attr "memory" "store")
19297 (set_attr "mode" "SI")])
19299 (define_insn "*rep_stossi_rex64"
19300 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19301 (set (match_operand:DI 0 "register_operand" "=D")
19302 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19304 (match_operand:DI 3 "register_operand" "0")))
19305 (set (mem:BLK (match_dup 3))
19307 (use (match_operand:SI 2 "register_operand" "a"))
19308 (use (match_dup 4))]
19311 [(set_attr "type" "str")
19312 (set_attr "prefix_rep" "1")
19313 (set_attr "memory" "store")
19314 (set_attr "mode" "SI")])
19316 (define_insn "*rep_stosqi"
19317 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19318 (set (match_operand:SI 0 "register_operand" "=D")
19319 (plus:SI (match_operand:SI 3 "register_operand" "0")
19320 (match_operand:SI 4 "register_operand" "1")))
19321 (set (mem:BLK (match_dup 3))
19323 (use (match_operand:QI 2 "register_operand" "a"))
19324 (use (match_dup 4))]
19327 [(set_attr "type" "str")
19328 (set_attr "prefix_rep" "1")
19329 (set_attr "memory" "store")
19330 (set_attr "mode" "QI")])
19332 (define_insn "*rep_stosqi_rex64"
19333 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19334 (set (match_operand:DI 0 "register_operand" "=D")
19335 (plus:DI (match_operand:DI 3 "register_operand" "0")
19336 (match_operand:DI 4 "register_operand" "1")))
19337 (set (mem:BLK (match_dup 3))
19339 (use (match_operand:QI 2 "register_operand" "a"))
19340 (use (match_dup 4))]
19343 [(set_attr "type" "str")
19344 (set_attr "prefix_rep" "1")
19345 (set_attr "memory" "store")
19346 (set_attr "mode" "QI")])
19348 (define_expand "cmpstrnsi"
19349 [(set (match_operand:SI 0 "register_operand" "")
19350 (compare:SI (match_operand:BLK 1 "general_operand" "")
19351 (match_operand:BLK 2 "general_operand" "")))
19352 (use (match_operand 3 "general_operand" ""))
19353 (use (match_operand 4 "immediate_operand" ""))]
19356 rtx addr1, addr2, out, outlow, count, countreg, align;
19358 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19361 /* Can't use this if the user has appropriated esi or edi. */
19362 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19367 out = gen_reg_rtx (SImode);
19369 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19370 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19371 if (addr1 != XEXP (operands[1], 0))
19372 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19373 if (addr2 != XEXP (operands[2], 0))
19374 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19376 count = operands[3];
19377 countreg = ix86_zero_extend_to_Pmode (count);
19379 /* %%% Iff we are testing strict equality, we can use known alignment
19380 to good advantage. This may be possible with combine, particularly
19381 once cc0 is dead. */
19382 align = operands[4];
19384 if (CONST_INT_P (count))
19386 if (INTVAL (count) == 0)
19388 emit_move_insn (operands[0], const0_rtx);
19391 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19392 operands[1], operands[2]));
19397 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19399 emit_insn (gen_cmpsi_1 (countreg, countreg));
19400 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19401 operands[1], operands[2]));
19404 outlow = gen_lowpart (QImode, out);
19405 emit_insn (gen_cmpintqi (outlow));
19406 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19408 if (operands[0] != out)
19409 emit_move_insn (operands[0], out);
19414 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19416 (define_expand "cmpintqi"
19417 [(set (match_dup 1)
19418 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19420 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19421 (parallel [(set (match_operand:QI 0 "register_operand" "")
19422 (minus:QI (match_dup 1)
19424 (clobber (reg:CC FLAGS_REG))])]
19426 "operands[1] = gen_reg_rtx (QImode);
19427 operands[2] = gen_reg_rtx (QImode);")
19429 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19430 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19432 (define_expand "cmpstrnqi_nz_1"
19433 [(parallel [(set (reg:CC FLAGS_REG)
19434 (compare:CC (match_operand 4 "memory_operand" "")
19435 (match_operand 5 "memory_operand" "")))
19436 (use (match_operand 2 "register_operand" ""))
19437 (use (match_operand:SI 3 "immediate_operand" ""))
19438 (clobber (match_operand 0 "register_operand" ""))
19439 (clobber (match_operand 1 "register_operand" ""))
19440 (clobber (match_dup 2))])]
19442 "ix86_current_function_needs_cld = 1;")
19444 (define_insn "*cmpstrnqi_nz_1"
19445 [(set (reg:CC FLAGS_REG)
19446 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19447 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19448 (use (match_operand:SI 6 "register_operand" "2"))
19449 (use (match_operand:SI 3 "immediate_operand" "i"))
19450 (clobber (match_operand:SI 0 "register_operand" "=S"))
19451 (clobber (match_operand:SI 1 "register_operand" "=D"))
19452 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19455 [(set_attr "type" "str")
19456 (set_attr "mode" "QI")
19457 (set_attr "prefix_rep" "1")])
19459 (define_insn "*cmpstrnqi_nz_rex_1"
19460 [(set (reg:CC FLAGS_REG)
19461 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19462 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19463 (use (match_operand:DI 6 "register_operand" "2"))
19464 (use (match_operand:SI 3 "immediate_operand" "i"))
19465 (clobber (match_operand:DI 0 "register_operand" "=S"))
19466 (clobber (match_operand:DI 1 "register_operand" "=D"))
19467 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19470 [(set_attr "type" "str")
19471 (set_attr "mode" "QI")
19472 (set_attr "prefix_rep" "1")])
19474 ;; The same, but the count is not known to not be zero.
19476 (define_expand "cmpstrnqi_1"
19477 [(parallel [(set (reg:CC FLAGS_REG)
19478 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19480 (compare:CC (match_operand 4 "memory_operand" "")
19481 (match_operand 5 "memory_operand" ""))
19483 (use (match_operand:SI 3 "immediate_operand" ""))
19484 (use (reg:CC FLAGS_REG))
19485 (clobber (match_operand 0 "register_operand" ""))
19486 (clobber (match_operand 1 "register_operand" ""))
19487 (clobber (match_dup 2))])]
19489 "ix86_current_function_needs_cld = 1;")
19491 (define_insn "*cmpstrnqi_1"
19492 [(set (reg:CC FLAGS_REG)
19493 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19495 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19496 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19498 (use (match_operand:SI 3 "immediate_operand" "i"))
19499 (use (reg:CC FLAGS_REG))
19500 (clobber (match_operand:SI 0 "register_operand" "=S"))
19501 (clobber (match_operand:SI 1 "register_operand" "=D"))
19502 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19505 [(set_attr "type" "str")
19506 (set_attr "mode" "QI")
19507 (set_attr "prefix_rep" "1")])
19509 (define_insn "*cmpstrnqi_rex_1"
19510 [(set (reg:CC FLAGS_REG)
19511 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19513 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19514 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19516 (use (match_operand:SI 3 "immediate_operand" "i"))
19517 (use (reg:CC FLAGS_REG))
19518 (clobber (match_operand:DI 0 "register_operand" "=S"))
19519 (clobber (match_operand:DI 1 "register_operand" "=D"))
19520 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19523 [(set_attr "type" "str")
19524 (set_attr "mode" "QI")
19525 (set_attr "prefix_rep" "1")])
19527 (define_expand "strlensi"
19528 [(set (match_operand:SI 0 "register_operand" "")
19529 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19530 (match_operand:QI 2 "immediate_operand" "")
19531 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19534 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19540 (define_expand "strlendi"
19541 [(set (match_operand:DI 0 "register_operand" "")
19542 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19543 (match_operand:QI 2 "immediate_operand" "")
19544 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19547 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19553 (define_expand "strlenqi_1"
19554 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19555 (clobber (match_operand 1 "register_operand" ""))
19556 (clobber (reg:CC FLAGS_REG))])]
19558 "ix86_current_function_needs_cld = 1;")
19560 (define_insn "*strlenqi_1"
19561 [(set (match_operand:SI 0 "register_operand" "=&c")
19562 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19563 (match_operand:QI 2 "register_operand" "a")
19564 (match_operand:SI 3 "immediate_operand" "i")
19565 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19566 (clobber (match_operand:SI 1 "register_operand" "=D"))
19567 (clobber (reg:CC FLAGS_REG))]
19570 [(set_attr "type" "str")
19571 (set_attr "mode" "QI")
19572 (set_attr "prefix_rep" "1")])
19574 (define_insn "*strlenqi_rex_1"
19575 [(set (match_operand:DI 0 "register_operand" "=&c")
19576 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19577 (match_operand:QI 2 "register_operand" "a")
19578 (match_operand:DI 3 "immediate_operand" "i")
19579 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19580 (clobber (match_operand:DI 1 "register_operand" "=D"))
19581 (clobber (reg:CC FLAGS_REG))]
19584 [(set_attr "type" "str")
19585 (set_attr "mode" "QI")
19586 (set_attr "prefix_rep" "1")])
19588 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19589 ;; handled in combine, but it is not currently up to the task.
19590 ;; When used for their truth value, the cmpstrn* expanders generate
19599 ;; The intermediate three instructions are unnecessary.
19601 ;; This one handles cmpstrn*_nz_1...
19604 (set (reg:CC FLAGS_REG)
19605 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19606 (mem:BLK (match_operand 5 "register_operand" ""))))
19607 (use (match_operand 6 "register_operand" ""))
19608 (use (match_operand:SI 3 "immediate_operand" ""))
19609 (clobber (match_operand 0 "register_operand" ""))
19610 (clobber (match_operand 1 "register_operand" ""))
19611 (clobber (match_operand 2 "register_operand" ""))])
19612 (set (match_operand:QI 7 "register_operand" "")
19613 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19614 (set (match_operand:QI 8 "register_operand" "")
19615 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19616 (set (reg FLAGS_REG)
19617 (compare (match_dup 7) (match_dup 8)))
19619 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19621 (set (reg:CC FLAGS_REG)
19622 (compare:CC (mem:BLK (match_dup 4))
19623 (mem:BLK (match_dup 5))))
19624 (use (match_dup 6))
19625 (use (match_dup 3))
19626 (clobber (match_dup 0))
19627 (clobber (match_dup 1))
19628 (clobber (match_dup 2))])]
19631 ;; ...and this one handles cmpstrn*_1.
19634 (set (reg:CC FLAGS_REG)
19635 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19637 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19638 (mem:BLK (match_operand 5 "register_operand" "")))
19640 (use (match_operand:SI 3 "immediate_operand" ""))
19641 (use (reg:CC FLAGS_REG))
19642 (clobber (match_operand 0 "register_operand" ""))
19643 (clobber (match_operand 1 "register_operand" ""))
19644 (clobber (match_operand 2 "register_operand" ""))])
19645 (set (match_operand:QI 7 "register_operand" "")
19646 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19647 (set (match_operand:QI 8 "register_operand" "")
19648 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19649 (set (reg FLAGS_REG)
19650 (compare (match_dup 7) (match_dup 8)))
19652 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19654 (set (reg:CC FLAGS_REG)
19655 (if_then_else:CC (ne (match_dup 6)
19657 (compare:CC (mem:BLK (match_dup 4))
19658 (mem:BLK (match_dup 5)))
19660 (use (match_dup 3))
19661 (use (reg:CC FLAGS_REG))
19662 (clobber (match_dup 0))
19663 (clobber (match_dup 1))
19664 (clobber (match_dup 2))])]
19669 ;; Conditional move instructions.
19671 (define_expand "movdicc"
19672 [(set (match_operand:DI 0 "register_operand" "")
19673 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19674 (match_operand:DI 2 "general_operand" "")
19675 (match_operand:DI 3 "general_operand" "")))]
19677 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19679 (define_insn "x86_movdicc_0_m1_rex64"
19680 [(set (match_operand:DI 0 "register_operand" "=r")
19681 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19684 (clobber (reg:CC FLAGS_REG))]
19687 ; Since we don't have the proper number of operands for an alu insn,
19688 ; fill in all the blanks.
19689 [(set_attr "type" "alu")
19690 (set_attr "pent_pair" "pu")
19691 (set_attr "memory" "none")
19692 (set_attr "imm_disp" "false")
19693 (set_attr "mode" "DI")
19694 (set_attr "length_immediate" "0")])
19696 (define_insn "*x86_movdicc_0_m1_se"
19697 [(set (match_operand:DI 0 "register_operand" "=r")
19698 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19701 (clobber (reg:CC FLAGS_REG))]
19704 [(set_attr "type" "alu")
19705 (set_attr "pent_pair" "pu")
19706 (set_attr "memory" "none")
19707 (set_attr "imm_disp" "false")
19708 (set_attr "mode" "DI")
19709 (set_attr "length_immediate" "0")])
19711 (define_insn "*movdicc_c_rex64"
19712 [(set (match_operand:DI 0 "register_operand" "=r,r")
19713 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19714 [(reg FLAGS_REG) (const_int 0)])
19715 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19716 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19717 "TARGET_64BIT && TARGET_CMOVE
19718 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19720 cmov%O2%C1\t{%2, %0|%0, %2}
19721 cmov%O2%c1\t{%3, %0|%0, %3}"
19722 [(set_attr "type" "icmov")
19723 (set_attr "mode" "DI")])
19725 (define_expand "movsicc"
19726 [(set (match_operand:SI 0 "register_operand" "")
19727 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19728 (match_operand:SI 2 "general_operand" "")
19729 (match_operand:SI 3 "general_operand" "")))]
19731 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19733 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19734 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19735 ;; So just document what we're doing explicitly.
19737 (define_insn "x86_movsicc_0_m1"
19738 [(set (match_operand:SI 0 "register_operand" "=r")
19739 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19742 (clobber (reg:CC FLAGS_REG))]
19745 ; Since we don't have the proper number of operands for an alu insn,
19746 ; fill in all the blanks.
19747 [(set_attr "type" "alu")
19748 (set_attr "pent_pair" "pu")
19749 (set_attr "memory" "none")
19750 (set_attr "imm_disp" "false")
19751 (set_attr "mode" "SI")
19752 (set_attr "length_immediate" "0")])
19754 (define_insn "*x86_movsicc_0_m1_se"
19755 [(set (match_operand:SI 0 "register_operand" "=r")
19756 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19759 (clobber (reg:CC FLAGS_REG))]
19762 [(set_attr "type" "alu")
19763 (set_attr "pent_pair" "pu")
19764 (set_attr "memory" "none")
19765 (set_attr "imm_disp" "false")
19766 (set_attr "mode" "SI")
19767 (set_attr "length_immediate" "0")])
19769 (define_insn "*movsicc_noc"
19770 [(set (match_operand:SI 0 "register_operand" "=r,r")
19771 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19772 [(reg FLAGS_REG) (const_int 0)])
19773 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19774 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19776 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19778 cmov%O2%C1\t{%2, %0|%0, %2}
19779 cmov%O2%c1\t{%3, %0|%0, %3}"
19780 [(set_attr "type" "icmov")
19781 (set_attr "mode" "SI")])
19783 (define_expand "movhicc"
19784 [(set (match_operand:HI 0 "register_operand" "")
19785 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19786 (match_operand:HI 2 "general_operand" "")
19787 (match_operand:HI 3 "general_operand" "")))]
19788 "TARGET_HIMODE_MATH"
19789 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19791 (define_insn "*movhicc_noc"
19792 [(set (match_operand:HI 0 "register_operand" "=r,r")
19793 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19794 [(reg FLAGS_REG) (const_int 0)])
19795 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19796 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19798 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19800 cmov%O2%C1\t{%2, %0|%0, %2}
19801 cmov%O2%c1\t{%3, %0|%0, %3}"
19802 [(set_attr "type" "icmov")
19803 (set_attr "mode" "HI")])
19805 (define_expand "movqicc"
19806 [(set (match_operand:QI 0 "register_operand" "")
19807 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19808 (match_operand:QI 2 "general_operand" "")
19809 (match_operand:QI 3 "general_operand" "")))]
19810 "TARGET_QIMODE_MATH"
19811 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19813 (define_insn_and_split "*movqicc_noc"
19814 [(set (match_operand:QI 0 "register_operand" "=r,r")
19815 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19816 [(match_operand 4 "flags_reg_operand" "")
19818 (match_operand:QI 2 "register_operand" "r,0")
19819 (match_operand:QI 3 "register_operand" "0,r")))]
19820 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19822 "&& reload_completed"
19823 [(set (match_dup 0)
19824 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19827 "operands[0] = gen_lowpart (SImode, operands[0]);
19828 operands[2] = gen_lowpart (SImode, operands[2]);
19829 operands[3] = gen_lowpart (SImode, operands[3]);"
19830 [(set_attr "type" "icmov")
19831 (set_attr "mode" "SI")])
19833 (define_expand "mov<mode>cc"
19834 [(set (match_operand:X87MODEF 0 "register_operand" "")
19835 (if_then_else:X87MODEF
19836 (match_operand 1 "comparison_operator" "")
19837 (match_operand:X87MODEF 2 "register_operand" "")
19838 (match_operand:X87MODEF 3 "register_operand" "")))]
19839 "(TARGET_80387 && TARGET_CMOVE)
19840 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19841 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19843 (define_insn "*movsfcc_1_387"
19844 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19845 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19846 [(reg FLAGS_REG) (const_int 0)])
19847 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19848 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19849 "TARGET_80387 && TARGET_CMOVE
19850 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19852 fcmov%F1\t{%2, %0|%0, %2}
19853 fcmov%f1\t{%3, %0|%0, %3}
19854 cmov%O2%C1\t{%2, %0|%0, %2}
19855 cmov%O2%c1\t{%3, %0|%0, %3}"
19856 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19857 (set_attr "mode" "SF,SF,SI,SI")])
19859 (define_insn "*movdfcc_1"
19860 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19861 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19862 [(reg FLAGS_REG) (const_int 0)])
19863 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19864 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19865 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19866 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19868 fcmov%F1\t{%2, %0|%0, %2}
19869 fcmov%f1\t{%3, %0|%0, %3}
19872 [(set_attr "type" "fcmov,fcmov,multi,multi")
19873 (set_attr "mode" "DF")])
19875 (define_insn "*movdfcc_1_rex64"
19876 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19877 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19878 [(reg FLAGS_REG) (const_int 0)])
19879 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19880 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19881 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19882 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19884 fcmov%F1\t{%2, %0|%0, %2}
19885 fcmov%f1\t{%3, %0|%0, %3}
19886 cmov%O2%C1\t{%2, %0|%0, %2}
19887 cmov%O2%c1\t{%3, %0|%0, %3}"
19888 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19889 (set_attr "mode" "DF")])
19892 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19893 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19894 [(match_operand 4 "flags_reg_operand" "")
19896 (match_operand:DF 2 "nonimmediate_operand" "")
19897 (match_operand:DF 3 "nonimmediate_operand" "")))]
19898 "!TARGET_64BIT && reload_completed"
19899 [(set (match_dup 2)
19900 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19904 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19907 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19908 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19910 (define_insn "*movxfcc_1"
19911 [(set (match_operand:XF 0 "register_operand" "=f,f")
19912 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19913 [(reg FLAGS_REG) (const_int 0)])
19914 (match_operand:XF 2 "register_operand" "f,0")
19915 (match_operand:XF 3 "register_operand" "0,f")))]
19916 "TARGET_80387 && TARGET_CMOVE"
19918 fcmov%F1\t{%2, %0|%0, %2}
19919 fcmov%f1\t{%3, %0|%0, %3}"
19920 [(set_attr "type" "fcmov")
19921 (set_attr "mode" "XF")])
19923 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19924 ;; the scalar versions to have only XMM registers as operands.
19926 ;; SSE5 conditional move
19927 (define_insn "*sse5_pcmov_<mode>"
19928 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19929 (if_then_else:MODEF
19930 (match_operand:MODEF 1 "register_operand" "x,0")
19931 (match_operand:MODEF 2 "register_operand" "0,x")
19932 (match_operand:MODEF 3 "register_operand" "x,x")))]
19933 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19934 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19935 [(set_attr "type" "sse4arg")])
19937 ;; These versions of the min/max patterns are intentionally ignorant of
19938 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19939 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19940 ;; are undefined in this condition, we're certain this is correct.
19942 (define_insn "*avx_<code><mode>3"
19943 [(set (match_operand:MODEF 0 "register_operand" "=x")
19945 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19946 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19947 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19948 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19949 [(set_attr "type" "sseadd")
19950 (set_attr "prefix" "vex")
19951 (set_attr "mode" "<MODE>")])
19953 (define_insn "<code><mode>3"
19954 [(set (match_operand:MODEF 0 "register_operand" "=x")
19956 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19957 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19958 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19959 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19960 [(set_attr "type" "sseadd")
19961 (set_attr "mode" "<MODE>")])
19963 ;; These versions of the min/max patterns implement exactly the operations
19964 ;; min = (op1 < op2 ? op1 : op2)
19965 ;; max = (!(op1 < op2) ? op1 : op2)
19966 ;; Their operands are not commutative, and thus they may be used in the
19967 ;; presence of -0.0 and NaN.
19969 (define_insn "*avx_ieee_smin<mode>3"
19970 [(set (match_operand:MODEF 0 "register_operand" "=x")
19972 [(match_operand:MODEF 1 "register_operand" "x")
19973 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19975 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19976 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19977 [(set_attr "type" "sseadd")
19978 (set_attr "prefix" "vex")
19979 (set_attr "mode" "<MODE>")])
19981 (define_insn "*ieee_smin<mode>3"
19982 [(set (match_operand:MODEF 0 "register_operand" "=x")
19984 [(match_operand:MODEF 1 "register_operand" "0")
19985 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19987 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19988 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19989 [(set_attr "type" "sseadd")
19990 (set_attr "mode" "<MODE>")])
19992 (define_insn "*avx_ieee_smax<mode>3"
19993 [(set (match_operand:MODEF 0 "register_operand" "=x")
19995 [(match_operand:MODEF 1 "register_operand" "0")
19996 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19998 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19999 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20000 [(set_attr "type" "sseadd")
20001 (set_attr "prefix" "vex")
20002 (set_attr "mode" "<MODE>")])
20004 (define_insn "*ieee_smax<mode>3"
20005 [(set (match_operand:MODEF 0 "register_operand" "=x")
20007 [(match_operand:MODEF 1 "register_operand" "0")
20008 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20010 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20011 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20012 [(set_attr "type" "sseadd")
20013 (set_attr "mode" "<MODE>")])
20015 ;; Make two stack loads independent:
20017 ;; fld %st(0) -> fld bb
20018 ;; fmul bb fmul %st(1), %st
20020 ;; Actually we only match the last two instructions for simplicity.
20022 [(set (match_operand 0 "fp_register_operand" "")
20023 (match_operand 1 "fp_register_operand" ""))
20025 (match_operator 2 "binary_fp_operator"
20027 (match_operand 3 "memory_operand" "")]))]
20028 "REGNO (operands[0]) != REGNO (operands[1])"
20029 [(set (match_dup 0) (match_dup 3))
20030 (set (match_dup 0) (match_dup 4))]
20032 ;; The % modifier is not operational anymore in peephole2's, so we have to
20033 ;; swap the operands manually in the case of addition and multiplication.
20034 "if (COMMUTATIVE_ARITH_P (operands[2]))
20035 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20036 operands[0], operands[1]);
20038 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20039 operands[1], operands[0]);")
20041 ;; Conditional addition patterns
20042 (define_expand "add<mode>cc"
20043 [(match_operand:SWI 0 "register_operand" "")
20044 (match_operand 1 "comparison_operator" "")
20045 (match_operand:SWI 2 "register_operand" "")
20046 (match_operand:SWI 3 "const_int_operand" "")]
20048 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20051 ;; Misc patterns (?)
20053 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20054 ;; Otherwise there will be nothing to keep
20056 ;; [(set (reg ebp) (reg esp))]
20057 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20058 ;; (clobber (eflags)]
20059 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20061 ;; in proper program order.
20062 (define_insn "pro_epilogue_adjust_stack_1"
20063 [(set (match_operand:SI 0 "register_operand" "=r,r")
20064 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20065 (match_operand:SI 2 "immediate_operand" "i,i")))
20066 (clobber (reg:CC FLAGS_REG))
20067 (clobber (mem:BLK (scratch)))]
20070 switch (get_attr_type (insn))
20073 return "mov{l}\t{%1, %0|%0, %1}";
20076 if (CONST_INT_P (operands[2])
20077 && (INTVAL (operands[2]) == 128
20078 || (INTVAL (operands[2]) < 0
20079 && INTVAL (operands[2]) != -128)))
20081 operands[2] = GEN_INT (-INTVAL (operands[2]));
20082 return "sub{l}\t{%2, %0|%0, %2}";
20084 return "add{l}\t{%2, %0|%0, %2}";
20087 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20088 return "lea{l}\t{%a2, %0|%0, %a2}";
20091 gcc_unreachable ();
20094 [(set (attr "type")
20095 (cond [(eq_attr "alternative" "0")
20096 (const_string "alu")
20097 (match_operand:SI 2 "const0_operand" "")
20098 (const_string "imov")
20100 (const_string "lea")))
20101 (set_attr "mode" "SI")])
20103 (define_insn "pro_epilogue_adjust_stack_rex64"
20104 [(set (match_operand:DI 0 "register_operand" "=r,r")
20105 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20106 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20107 (clobber (reg:CC FLAGS_REG))
20108 (clobber (mem:BLK (scratch)))]
20111 switch (get_attr_type (insn))
20114 return "mov{q}\t{%1, %0|%0, %1}";
20117 if (CONST_INT_P (operands[2])
20118 /* Avoid overflows. */
20119 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20120 && (INTVAL (operands[2]) == 128
20121 || (INTVAL (operands[2]) < 0
20122 && INTVAL (operands[2]) != -128)))
20124 operands[2] = GEN_INT (-INTVAL (operands[2]));
20125 return "sub{q}\t{%2, %0|%0, %2}";
20127 return "add{q}\t{%2, %0|%0, %2}";
20130 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20131 return "lea{q}\t{%a2, %0|%0, %a2}";
20134 gcc_unreachable ();
20137 [(set (attr "type")
20138 (cond [(eq_attr "alternative" "0")
20139 (const_string "alu")
20140 (match_operand:DI 2 "const0_operand" "")
20141 (const_string "imov")
20143 (const_string "lea")))
20144 (set_attr "mode" "DI")])
20146 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20147 [(set (match_operand:DI 0 "register_operand" "=r,r")
20148 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20149 (match_operand:DI 3 "immediate_operand" "i,i")))
20150 (use (match_operand:DI 2 "register_operand" "r,r"))
20151 (clobber (reg:CC FLAGS_REG))
20152 (clobber (mem:BLK (scratch)))]
20155 switch (get_attr_type (insn))
20158 return "add{q}\t{%2, %0|%0, %2}";
20161 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20162 return "lea{q}\t{%a2, %0|%0, %a2}";
20165 gcc_unreachable ();
20168 [(set_attr "type" "alu,lea")
20169 (set_attr "mode" "DI")])
20171 (define_insn "allocate_stack_worker_32"
20172 [(set (match_operand:SI 0 "register_operand" "=a")
20173 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20174 UNSPECV_STACK_PROBE))
20175 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20176 (clobber (reg:CC FLAGS_REG))]
20177 "!TARGET_64BIT && TARGET_STACK_PROBE"
20179 [(set_attr "type" "multi")
20180 (set_attr "length" "5")])
20182 (define_insn "allocate_stack_worker_64"
20183 [(set (match_operand:DI 0 "register_operand" "=a")
20184 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20185 UNSPECV_STACK_PROBE))
20186 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20187 (clobber (reg:DI R10_REG))
20188 (clobber (reg:DI R11_REG))
20189 (clobber (reg:CC FLAGS_REG))]
20190 "TARGET_64BIT && TARGET_STACK_PROBE"
20192 [(set_attr "type" "multi")
20193 (set_attr "length" "5")])
20195 (define_expand "allocate_stack"
20196 [(match_operand 0 "register_operand" "")
20197 (match_operand 1 "general_operand" "")]
20198 "TARGET_STACK_PROBE"
20202 #ifndef CHECK_STACK_LIMIT
20203 #define CHECK_STACK_LIMIT 0
20206 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20207 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20209 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20210 stack_pointer_rtx, 0, OPTAB_DIRECT);
20211 if (x != stack_pointer_rtx)
20212 emit_move_insn (stack_pointer_rtx, x);
20216 x = copy_to_mode_reg (Pmode, operands[1]);
20218 x = gen_allocate_stack_worker_64 (x, x);
20220 x = gen_allocate_stack_worker_32 (x, x);
20224 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20228 (define_expand "builtin_setjmp_receiver"
20229 [(label_ref (match_operand 0 "" ""))]
20230 "!TARGET_64BIT && flag_pic"
20236 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20237 rtx label_rtx = gen_label_rtx ();
20238 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20239 xops[0] = xops[1] = picreg;
20240 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20241 ix86_expand_binary_operator (MINUS, SImode, xops);
20245 emit_insn (gen_set_got (pic_offset_table_rtx));
20249 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20252 [(set (match_operand 0 "register_operand" "")
20253 (match_operator 3 "promotable_binary_operator"
20254 [(match_operand 1 "register_operand" "")
20255 (match_operand 2 "aligned_operand" "")]))
20256 (clobber (reg:CC FLAGS_REG))]
20257 "! TARGET_PARTIAL_REG_STALL && reload_completed
20258 && ((GET_MODE (operands[0]) == HImode
20259 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20260 /* ??? next two lines just !satisfies_constraint_K (...) */
20261 || !CONST_INT_P (operands[2])
20262 || satisfies_constraint_K (operands[2])))
20263 || (GET_MODE (operands[0]) == QImode
20264 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20265 [(parallel [(set (match_dup 0)
20266 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20267 (clobber (reg:CC FLAGS_REG))])]
20268 "operands[0] = gen_lowpart (SImode, operands[0]);
20269 operands[1] = gen_lowpart (SImode, operands[1]);
20270 if (GET_CODE (operands[3]) != ASHIFT)
20271 operands[2] = gen_lowpart (SImode, operands[2]);
20272 PUT_MODE (operands[3], SImode);")
20274 ; Promote the QImode tests, as i386 has encoding of the AND
20275 ; instruction with 32-bit sign-extended immediate and thus the
20276 ; instruction size is unchanged, except in the %eax case for
20277 ; which it is increased by one byte, hence the ! optimize_size.
20279 [(set (match_operand 0 "flags_reg_operand" "")
20280 (match_operator 2 "compare_operator"
20281 [(and (match_operand 3 "aligned_operand" "")
20282 (match_operand 4 "const_int_operand" ""))
20284 (set (match_operand 1 "register_operand" "")
20285 (and (match_dup 3) (match_dup 4)))]
20286 "! TARGET_PARTIAL_REG_STALL && reload_completed
20287 && optimize_insn_for_speed_p ()
20288 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20289 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20290 /* Ensure that the operand will remain sign-extended immediate. */
20291 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20292 [(parallel [(set (match_dup 0)
20293 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20296 (and:SI (match_dup 3) (match_dup 4)))])]
20299 = gen_int_mode (INTVAL (operands[4])
20300 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20301 operands[1] = gen_lowpart (SImode, operands[1]);
20302 operands[3] = gen_lowpart (SImode, operands[3]);
20305 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20306 ; the TEST instruction with 32-bit sign-extended immediate and thus
20307 ; the instruction size would at least double, which is not what we
20308 ; want even with ! optimize_size.
20310 [(set (match_operand 0 "flags_reg_operand" "")
20311 (match_operator 1 "compare_operator"
20312 [(and (match_operand:HI 2 "aligned_operand" "")
20313 (match_operand:HI 3 "const_int_operand" ""))
20315 "! TARGET_PARTIAL_REG_STALL && reload_completed
20316 && ! TARGET_FAST_PREFIX
20317 && optimize_insn_for_speed_p ()
20318 /* Ensure that the operand will remain sign-extended immediate. */
20319 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20320 [(set (match_dup 0)
20321 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20325 = gen_int_mode (INTVAL (operands[3])
20326 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20327 operands[2] = gen_lowpart (SImode, operands[2]);
20331 [(set (match_operand 0 "register_operand" "")
20332 (neg (match_operand 1 "register_operand" "")))
20333 (clobber (reg:CC FLAGS_REG))]
20334 "! TARGET_PARTIAL_REG_STALL && reload_completed
20335 && (GET_MODE (operands[0]) == HImode
20336 || (GET_MODE (operands[0]) == QImode
20337 && (TARGET_PROMOTE_QImode
20338 || optimize_insn_for_size_p ())))"
20339 [(parallel [(set (match_dup 0)
20340 (neg:SI (match_dup 1)))
20341 (clobber (reg:CC FLAGS_REG))])]
20342 "operands[0] = gen_lowpart (SImode, operands[0]);
20343 operands[1] = gen_lowpart (SImode, operands[1]);")
20346 [(set (match_operand 0 "register_operand" "")
20347 (not (match_operand 1 "register_operand" "")))]
20348 "! TARGET_PARTIAL_REG_STALL && reload_completed
20349 && (GET_MODE (operands[0]) == HImode
20350 || (GET_MODE (operands[0]) == QImode
20351 && (TARGET_PROMOTE_QImode
20352 || optimize_insn_for_size_p ())))"
20353 [(set (match_dup 0)
20354 (not:SI (match_dup 1)))]
20355 "operands[0] = gen_lowpart (SImode, operands[0]);
20356 operands[1] = gen_lowpart (SImode, operands[1]);")
20359 [(set (match_operand 0 "register_operand" "")
20360 (if_then_else (match_operator 1 "comparison_operator"
20361 [(reg FLAGS_REG) (const_int 0)])
20362 (match_operand 2 "register_operand" "")
20363 (match_operand 3 "register_operand" "")))]
20364 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20365 && (GET_MODE (operands[0]) == HImode
20366 || (GET_MODE (operands[0]) == QImode
20367 && (TARGET_PROMOTE_QImode
20368 || optimize_insn_for_size_p ())))"
20369 [(set (match_dup 0)
20370 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20371 "operands[0] = gen_lowpart (SImode, operands[0]);
20372 operands[2] = gen_lowpart (SImode, operands[2]);
20373 operands[3] = gen_lowpart (SImode, operands[3]);")
20376 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20377 ;; transform a complex memory operation into two memory to register operations.
20379 ;; Don't push memory operands
20381 [(set (match_operand:SI 0 "push_operand" "")
20382 (match_operand:SI 1 "memory_operand" ""))
20383 (match_scratch:SI 2 "r")]
20384 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20385 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20386 [(set (match_dup 2) (match_dup 1))
20387 (set (match_dup 0) (match_dup 2))]
20391 [(set (match_operand:DI 0 "push_operand" "")
20392 (match_operand:DI 1 "memory_operand" ""))
20393 (match_scratch:DI 2 "r")]
20394 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20395 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20396 [(set (match_dup 2) (match_dup 1))
20397 (set (match_dup 0) (match_dup 2))]
20400 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20403 [(set (match_operand:SF 0 "push_operand" "")
20404 (match_operand:SF 1 "memory_operand" ""))
20405 (match_scratch:SF 2 "r")]
20406 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20407 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20408 [(set (match_dup 2) (match_dup 1))
20409 (set (match_dup 0) (match_dup 2))]
20413 [(set (match_operand:HI 0 "push_operand" "")
20414 (match_operand:HI 1 "memory_operand" ""))
20415 (match_scratch:HI 2 "r")]
20416 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20417 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20418 [(set (match_dup 2) (match_dup 1))
20419 (set (match_dup 0) (match_dup 2))]
20423 [(set (match_operand:QI 0 "push_operand" "")
20424 (match_operand:QI 1 "memory_operand" ""))
20425 (match_scratch:QI 2 "q")]
20426 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20427 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20428 [(set (match_dup 2) (match_dup 1))
20429 (set (match_dup 0) (match_dup 2))]
20432 ;; Don't move an immediate directly to memory when the instruction
20435 [(match_scratch:SI 1 "r")
20436 (set (match_operand:SI 0 "memory_operand" "")
20438 "optimize_insn_for_speed_p ()
20439 && ! TARGET_USE_MOV0
20440 && TARGET_SPLIT_LONG_MOVES
20441 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20442 && peep2_regno_dead_p (0, FLAGS_REG)"
20443 [(parallel [(set (match_dup 1) (const_int 0))
20444 (clobber (reg:CC FLAGS_REG))])
20445 (set (match_dup 0) (match_dup 1))]
20449 [(match_scratch:HI 1 "r")
20450 (set (match_operand:HI 0 "memory_operand" "")
20452 "optimize_insn_for_speed_p ()
20453 && ! TARGET_USE_MOV0
20454 && TARGET_SPLIT_LONG_MOVES
20455 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20456 && peep2_regno_dead_p (0, FLAGS_REG)"
20457 [(parallel [(set (match_dup 2) (const_int 0))
20458 (clobber (reg:CC FLAGS_REG))])
20459 (set (match_dup 0) (match_dup 1))]
20460 "operands[2] = gen_lowpart (SImode, operands[1]);")
20463 [(match_scratch:QI 1 "q")
20464 (set (match_operand:QI 0 "memory_operand" "")
20466 "optimize_insn_for_speed_p ()
20467 && ! TARGET_USE_MOV0
20468 && TARGET_SPLIT_LONG_MOVES
20469 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20470 && peep2_regno_dead_p (0, FLAGS_REG)"
20471 [(parallel [(set (match_dup 2) (const_int 0))
20472 (clobber (reg:CC FLAGS_REG))])
20473 (set (match_dup 0) (match_dup 1))]
20474 "operands[2] = gen_lowpart (SImode, operands[1]);")
20477 [(match_scratch:SI 2 "r")
20478 (set (match_operand:SI 0 "memory_operand" "")
20479 (match_operand:SI 1 "immediate_operand" ""))]
20480 "optimize_insn_for_speed_p ()
20481 && TARGET_SPLIT_LONG_MOVES
20482 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20483 [(set (match_dup 2) (match_dup 1))
20484 (set (match_dup 0) (match_dup 2))]
20488 [(match_scratch:HI 2 "r")
20489 (set (match_operand:HI 0 "memory_operand" "")
20490 (match_operand:HI 1 "immediate_operand" ""))]
20491 "optimize_insn_for_speed_p ()
20492 && TARGET_SPLIT_LONG_MOVES
20493 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20494 [(set (match_dup 2) (match_dup 1))
20495 (set (match_dup 0) (match_dup 2))]
20499 [(match_scratch:QI 2 "q")
20500 (set (match_operand:QI 0 "memory_operand" "")
20501 (match_operand:QI 1 "immediate_operand" ""))]
20502 "optimize_insn_for_speed_p ()
20503 && TARGET_SPLIT_LONG_MOVES
20504 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20505 [(set (match_dup 2) (match_dup 1))
20506 (set (match_dup 0) (match_dup 2))]
20509 ;; Don't compare memory with zero, load and use a test instead.
20511 [(set (match_operand 0 "flags_reg_operand" "")
20512 (match_operator 1 "compare_operator"
20513 [(match_operand:SI 2 "memory_operand" "")
20515 (match_scratch:SI 3 "r")]
20516 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20517 [(set (match_dup 3) (match_dup 2))
20518 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20521 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20522 ;; Don't split NOTs with a displacement operand, because resulting XOR
20523 ;; will not be pairable anyway.
20525 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20526 ;; represented using a modRM byte. The XOR replacement is long decoded,
20527 ;; so this split helps here as well.
20529 ;; Note: Can't do this as a regular split because we can't get proper
20530 ;; lifetime information then.
20533 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20534 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20535 "optimize_insn_for_speed_p ()
20536 && ((TARGET_NOT_UNPAIRABLE
20537 && (!MEM_P (operands[0])
20538 || !memory_displacement_operand (operands[0], SImode)))
20539 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20540 && peep2_regno_dead_p (0, FLAGS_REG)"
20541 [(parallel [(set (match_dup 0)
20542 (xor:SI (match_dup 1) (const_int -1)))
20543 (clobber (reg:CC FLAGS_REG))])]
20547 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20548 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20549 "optimize_insn_for_speed_p ()
20550 && ((TARGET_NOT_UNPAIRABLE
20551 && (!MEM_P (operands[0])
20552 || !memory_displacement_operand (operands[0], HImode)))
20553 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20554 && peep2_regno_dead_p (0, FLAGS_REG)"
20555 [(parallel [(set (match_dup 0)
20556 (xor:HI (match_dup 1) (const_int -1)))
20557 (clobber (reg:CC FLAGS_REG))])]
20561 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20562 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20563 "optimize_insn_for_speed_p ()
20564 && ((TARGET_NOT_UNPAIRABLE
20565 && (!MEM_P (operands[0])
20566 || !memory_displacement_operand (operands[0], QImode)))
20567 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20568 && peep2_regno_dead_p (0, FLAGS_REG)"
20569 [(parallel [(set (match_dup 0)
20570 (xor:QI (match_dup 1) (const_int -1)))
20571 (clobber (reg:CC FLAGS_REG))])]
20574 ;; Non pairable "test imm, reg" instructions can be translated to
20575 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20576 ;; byte opcode instead of two, have a short form for byte operands),
20577 ;; so do it for other CPUs as well. Given that the value was dead,
20578 ;; this should not create any new dependencies. Pass on the sub-word
20579 ;; versions if we're concerned about partial register stalls.
20582 [(set (match_operand 0 "flags_reg_operand" "")
20583 (match_operator 1 "compare_operator"
20584 [(and:SI (match_operand:SI 2 "register_operand" "")
20585 (match_operand:SI 3 "immediate_operand" ""))
20587 "ix86_match_ccmode (insn, CCNOmode)
20588 && (true_regnum (operands[2]) != AX_REG
20589 || satisfies_constraint_K (operands[3]))
20590 && peep2_reg_dead_p (1, operands[2])"
20592 [(set (match_dup 0)
20593 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20596 (and:SI (match_dup 2) (match_dup 3)))])]
20599 ;; We don't need to handle HImode case, because it will be promoted to SImode
20600 ;; on ! TARGET_PARTIAL_REG_STALL
20603 [(set (match_operand 0 "flags_reg_operand" "")
20604 (match_operator 1 "compare_operator"
20605 [(and:QI (match_operand:QI 2 "register_operand" "")
20606 (match_operand:QI 3 "immediate_operand" ""))
20608 "! TARGET_PARTIAL_REG_STALL
20609 && ix86_match_ccmode (insn, CCNOmode)
20610 && true_regnum (operands[2]) != AX_REG
20611 && peep2_reg_dead_p (1, operands[2])"
20613 [(set (match_dup 0)
20614 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20617 (and:QI (match_dup 2) (match_dup 3)))])]
20621 [(set (match_operand 0 "flags_reg_operand" "")
20622 (match_operator 1 "compare_operator"
20625 (match_operand 2 "ext_register_operand" "")
20628 (match_operand 3 "const_int_operand" ""))
20630 "! TARGET_PARTIAL_REG_STALL
20631 && ix86_match_ccmode (insn, CCNOmode)
20632 && true_regnum (operands[2]) != AX_REG
20633 && peep2_reg_dead_p (1, operands[2])"
20634 [(parallel [(set (match_dup 0)
20643 (set (zero_extract:SI (match_dup 2)
20654 ;; Don't do logical operations with memory inputs.
20656 [(match_scratch:SI 2 "r")
20657 (parallel [(set (match_operand:SI 0 "register_operand" "")
20658 (match_operator:SI 3 "arith_or_logical_operator"
20660 (match_operand:SI 1 "memory_operand" "")]))
20661 (clobber (reg:CC FLAGS_REG))])]
20662 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20663 [(set (match_dup 2) (match_dup 1))
20664 (parallel [(set (match_dup 0)
20665 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20666 (clobber (reg:CC FLAGS_REG))])]
20670 [(match_scratch:SI 2 "r")
20671 (parallel [(set (match_operand:SI 0 "register_operand" "")
20672 (match_operator:SI 3 "arith_or_logical_operator"
20673 [(match_operand:SI 1 "memory_operand" "")
20675 (clobber (reg:CC FLAGS_REG))])]
20676 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20677 [(set (match_dup 2) (match_dup 1))
20678 (parallel [(set (match_dup 0)
20679 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20680 (clobber (reg:CC FLAGS_REG))])]
20683 ; Don't do logical operations with memory outputs
20685 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20686 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20687 ; the same decoder scheduling characteristics as the original.
20690 [(match_scratch:SI 2 "r")
20691 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20692 (match_operator:SI 3 "arith_or_logical_operator"
20694 (match_operand:SI 1 "nonmemory_operand" "")]))
20695 (clobber (reg:CC FLAGS_REG))])]
20696 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20697 [(set (match_dup 2) (match_dup 0))
20698 (parallel [(set (match_dup 2)
20699 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20700 (clobber (reg:CC FLAGS_REG))])
20701 (set (match_dup 0) (match_dup 2))]
20705 [(match_scratch:SI 2 "r")
20706 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20707 (match_operator:SI 3 "arith_or_logical_operator"
20708 [(match_operand:SI 1 "nonmemory_operand" "")
20710 (clobber (reg:CC FLAGS_REG))])]
20711 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20712 [(set (match_dup 2) (match_dup 0))
20713 (parallel [(set (match_dup 2)
20714 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20715 (clobber (reg:CC FLAGS_REG))])
20716 (set (match_dup 0) (match_dup 2))]
20719 ;; Attempt to always use XOR for zeroing registers.
20721 [(set (match_operand 0 "register_operand" "")
20722 (match_operand 1 "const0_operand" ""))]
20723 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20724 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20725 && GENERAL_REG_P (operands[0])
20726 && peep2_regno_dead_p (0, FLAGS_REG)"
20727 [(parallel [(set (match_dup 0) (const_int 0))
20728 (clobber (reg:CC FLAGS_REG))])]
20730 operands[0] = gen_lowpart (word_mode, operands[0]);
20734 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20736 "(GET_MODE (operands[0]) == QImode
20737 || GET_MODE (operands[0]) == HImode)
20738 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20739 && peep2_regno_dead_p (0, FLAGS_REG)"
20740 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20741 (clobber (reg:CC FLAGS_REG))])])
20743 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20745 [(set (match_operand 0 "register_operand" "")
20747 "(GET_MODE (operands[0]) == HImode
20748 || GET_MODE (operands[0]) == SImode
20749 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20750 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20751 && peep2_regno_dead_p (0, FLAGS_REG)"
20752 [(parallel [(set (match_dup 0) (const_int -1))
20753 (clobber (reg:CC FLAGS_REG))])]
20754 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20757 ;; Attempt to convert simple leas to adds. These can be created by
20760 [(set (match_operand:SI 0 "register_operand" "")
20761 (plus:SI (match_dup 0)
20762 (match_operand:SI 1 "nonmemory_operand" "")))]
20763 "peep2_regno_dead_p (0, FLAGS_REG)"
20764 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20765 (clobber (reg:CC FLAGS_REG))])]
20769 [(set (match_operand:SI 0 "register_operand" "")
20770 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20771 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20772 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20773 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20774 (clobber (reg:CC FLAGS_REG))])]
20775 "operands[2] = gen_lowpart (SImode, operands[2]);")
20778 [(set (match_operand:DI 0 "register_operand" "")
20779 (plus:DI (match_dup 0)
20780 (match_operand:DI 1 "x86_64_general_operand" "")))]
20781 "peep2_regno_dead_p (0, FLAGS_REG)"
20782 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20783 (clobber (reg:CC FLAGS_REG))])]
20787 [(set (match_operand:SI 0 "register_operand" "")
20788 (mult:SI (match_dup 0)
20789 (match_operand:SI 1 "const_int_operand" "")))]
20790 "exact_log2 (INTVAL (operands[1])) >= 0
20791 && peep2_regno_dead_p (0, FLAGS_REG)"
20792 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20793 (clobber (reg:CC FLAGS_REG))])]
20794 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20797 [(set (match_operand:DI 0 "register_operand" "")
20798 (mult:DI (match_dup 0)
20799 (match_operand:DI 1 "const_int_operand" "")))]
20800 "exact_log2 (INTVAL (operands[1])) >= 0
20801 && peep2_regno_dead_p (0, FLAGS_REG)"
20802 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20803 (clobber (reg:CC FLAGS_REG))])]
20804 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20807 [(set (match_operand:SI 0 "register_operand" "")
20808 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20809 (match_operand:DI 2 "const_int_operand" "")) 0))]
20810 "exact_log2 (INTVAL (operands[2])) >= 0
20811 && REGNO (operands[0]) == REGNO (operands[1])
20812 && peep2_regno_dead_p (0, FLAGS_REG)"
20813 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20814 (clobber (reg:CC FLAGS_REG))])]
20815 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20817 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20818 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20819 ;; many CPUs it is also faster, since special hardware to avoid esp
20820 ;; dependencies is present.
20822 ;; While some of these conversions may be done using splitters, we use peepholes
20823 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20825 ;; Convert prologue esp subtractions to push.
20826 ;; We need register to push. In order to keep verify_flow_info happy we have
20828 ;; - use scratch and clobber it in order to avoid dependencies
20829 ;; - use already live register
20830 ;; We can't use the second way right now, since there is no reliable way how to
20831 ;; verify that given register is live. First choice will also most likely in
20832 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20833 ;; call clobbered registers are dead. We may want to use base pointer as an
20834 ;; alternative when no register is available later.
20837 [(match_scratch:SI 0 "r")
20838 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20839 (clobber (reg:CC FLAGS_REG))
20840 (clobber (mem:BLK (scratch)))])]
20841 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20842 [(clobber (match_dup 0))
20843 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20844 (clobber (mem:BLK (scratch)))])])
20847 [(match_scratch:SI 0 "r")
20848 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20849 (clobber (reg:CC FLAGS_REG))
20850 (clobber (mem:BLK (scratch)))])]
20851 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20852 [(clobber (match_dup 0))
20853 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20854 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20855 (clobber (mem:BLK (scratch)))])])
20857 ;; Convert esp subtractions to push.
20859 [(match_scratch:SI 0 "r")
20860 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20861 (clobber (reg:CC FLAGS_REG))])]
20862 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20863 [(clobber (match_dup 0))
20864 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20867 [(match_scratch:SI 0 "r")
20868 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20869 (clobber (reg:CC FLAGS_REG))])]
20870 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20871 [(clobber (match_dup 0))
20872 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20873 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20875 ;; Convert epilogue deallocator to pop.
20877 [(match_scratch:SI 0 "r")
20878 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20879 (clobber (reg:CC FLAGS_REG))
20880 (clobber (mem:BLK (scratch)))])]
20881 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20882 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20883 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20884 (clobber (mem:BLK (scratch)))])]
20887 ;; Two pops case is tricky, since pop causes dependency on destination register.
20888 ;; We use two registers if available.
20890 [(match_scratch:SI 0 "r")
20891 (match_scratch:SI 1 "r")
20892 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20893 (clobber (reg:CC FLAGS_REG))
20894 (clobber (mem:BLK (scratch)))])]
20895 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20896 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20897 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20898 (clobber (mem:BLK (scratch)))])
20899 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20900 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20904 [(match_scratch:SI 0 "r")
20905 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20906 (clobber (reg:CC FLAGS_REG))
20907 (clobber (mem:BLK (scratch)))])]
20908 "optimize_insn_for_size_p ()"
20909 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20910 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20911 (clobber (mem:BLK (scratch)))])
20912 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20913 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20916 ;; Convert esp additions to pop.
20918 [(match_scratch:SI 0 "r")
20919 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20920 (clobber (reg:CC FLAGS_REG))])]
20922 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20923 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20926 ;; Two pops case is tricky, since pop causes dependency on destination register.
20927 ;; We use two registers if available.
20929 [(match_scratch:SI 0 "r")
20930 (match_scratch:SI 1 "r")
20931 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20932 (clobber (reg:CC FLAGS_REG))])]
20934 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20935 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20936 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20937 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20941 [(match_scratch:SI 0 "r")
20942 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20943 (clobber (reg:CC FLAGS_REG))])]
20944 "optimize_insn_for_size_p ()"
20945 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20946 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20947 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20948 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20951 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20952 ;; required and register dies. Similarly for 128 to -128.
20954 [(set (match_operand 0 "flags_reg_operand" "")
20955 (match_operator 1 "compare_operator"
20956 [(match_operand 2 "register_operand" "")
20957 (match_operand 3 "const_int_operand" "")]))]
20958 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20959 && incdec_operand (operands[3], GET_MODE (operands[3])))
20960 || (!TARGET_FUSE_CMP_AND_BRANCH
20961 && INTVAL (operands[3]) == 128))
20962 && ix86_match_ccmode (insn, CCGCmode)
20963 && peep2_reg_dead_p (1, operands[2])"
20964 [(parallel [(set (match_dup 0)
20965 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20966 (clobber (match_dup 2))])]
20970 [(match_scratch:DI 0 "r")
20971 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20972 (clobber (reg:CC FLAGS_REG))
20973 (clobber (mem:BLK (scratch)))])]
20974 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20975 [(clobber (match_dup 0))
20976 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20977 (clobber (mem:BLK (scratch)))])])
20980 [(match_scratch:DI 0 "r")
20981 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20982 (clobber (reg:CC FLAGS_REG))
20983 (clobber (mem:BLK (scratch)))])]
20984 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20985 [(clobber (match_dup 0))
20986 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20987 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20988 (clobber (mem:BLK (scratch)))])])
20990 ;; Convert esp subtractions to push.
20992 [(match_scratch:DI 0 "r")
20993 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20994 (clobber (reg:CC FLAGS_REG))])]
20995 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20996 [(clobber (match_dup 0))
20997 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21000 [(match_scratch:DI 0 "r")
21001 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21002 (clobber (reg:CC FLAGS_REG))])]
21003 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21004 [(clobber (match_dup 0))
21005 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21006 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21008 ;; Convert epilogue deallocator to pop.
21010 [(match_scratch:DI 0 "r")
21011 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21012 (clobber (reg:CC FLAGS_REG))
21013 (clobber (mem:BLK (scratch)))])]
21014 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21015 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21016 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21017 (clobber (mem:BLK (scratch)))])]
21020 ;; Two pops case is tricky, since pop causes dependency on destination register.
21021 ;; We use two registers if available.
21023 [(match_scratch:DI 0 "r")
21024 (match_scratch:DI 1 "r")
21025 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21026 (clobber (reg:CC FLAGS_REG))
21027 (clobber (mem:BLK (scratch)))])]
21028 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21029 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21030 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21031 (clobber (mem:BLK (scratch)))])
21032 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21033 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21037 [(match_scratch:DI 0 "r")
21038 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21039 (clobber (reg:CC FLAGS_REG))
21040 (clobber (mem:BLK (scratch)))])]
21041 "optimize_insn_for_size_p ()"
21042 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21043 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21044 (clobber (mem:BLK (scratch)))])
21045 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21046 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21049 ;; Convert esp additions to pop.
21051 [(match_scratch:DI 0 "r")
21052 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21053 (clobber (reg:CC FLAGS_REG))])]
21055 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21056 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21059 ;; Two pops case is tricky, since pop causes dependency on destination register.
21060 ;; We use two registers if available.
21062 [(match_scratch:DI 0 "r")
21063 (match_scratch:DI 1 "r")
21064 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21065 (clobber (reg:CC FLAGS_REG))])]
21067 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21068 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21069 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21070 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21074 [(match_scratch:DI 0 "r")
21075 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21076 (clobber (reg:CC FLAGS_REG))])]
21077 "optimize_insn_for_size_p ()"
21078 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21079 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21080 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21081 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21084 ;; Convert imul by three, five and nine into lea
21087 [(set (match_operand:SI 0 "register_operand" "")
21088 (mult:SI (match_operand:SI 1 "register_operand" "")
21089 (match_operand:SI 2 "const_int_operand" "")))
21090 (clobber (reg:CC FLAGS_REG))])]
21091 "INTVAL (operands[2]) == 3
21092 || INTVAL (operands[2]) == 5
21093 || INTVAL (operands[2]) == 9"
21094 [(set (match_dup 0)
21095 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21097 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21101 [(set (match_operand:SI 0 "register_operand" "")
21102 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21103 (match_operand:SI 2 "const_int_operand" "")))
21104 (clobber (reg:CC FLAGS_REG))])]
21105 "optimize_insn_for_speed_p ()
21106 && (INTVAL (operands[2]) == 3
21107 || INTVAL (operands[2]) == 5
21108 || INTVAL (operands[2]) == 9)"
21109 [(set (match_dup 0) (match_dup 1))
21111 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21113 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21117 [(set (match_operand:DI 0 "register_operand" "")
21118 (mult:DI (match_operand:DI 1 "register_operand" "")
21119 (match_operand:DI 2 "const_int_operand" "")))
21120 (clobber (reg:CC FLAGS_REG))])]
21122 && (INTVAL (operands[2]) == 3
21123 || INTVAL (operands[2]) == 5
21124 || INTVAL (operands[2]) == 9)"
21125 [(set (match_dup 0)
21126 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21128 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21132 [(set (match_operand:DI 0 "register_operand" "")
21133 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21134 (match_operand:DI 2 "const_int_operand" "")))
21135 (clobber (reg:CC FLAGS_REG))])]
21137 && optimize_insn_for_speed_p ()
21138 && (INTVAL (operands[2]) == 3
21139 || INTVAL (operands[2]) == 5
21140 || INTVAL (operands[2]) == 9)"
21141 [(set (match_dup 0) (match_dup 1))
21143 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21145 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21147 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21148 ;; imul $32bit_imm, reg, reg is direct decoded.
21150 [(match_scratch:DI 3 "r")
21151 (parallel [(set (match_operand:DI 0 "register_operand" "")
21152 (mult:DI (match_operand:DI 1 "memory_operand" "")
21153 (match_operand:DI 2 "immediate_operand" "")))
21154 (clobber (reg:CC FLAGS_REG))])]
21155 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21156 && !satisfies_constraint_K (operands[2])"
21157 [(set (match_dup 3) (match_dup 1))
21158 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21159 (clobber (reg:CC FLAGS_REG))])]
21163 [(match_scratch:SI 3 "r")
21164 (parallel [(set (match_operand:SI 0 "register_operand" "")
21165 (mult:SI (match_operand:SI 1 "memory_operand" "")
21166 (match_operand:SI 2 "immediate_operand" "")))
21167 (clobber (reg:CC FLAGS_REG))])]
21168 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21169 && !satisfies_constraint_K (operands[2])"
21170 [(set (match_dup 3) (match_dup 1))
21171 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21172 (clobber (reg:CC FLAGS_REG))])]
21176 [(match_scratch:SI 3 "r")
21177 (parallel [(set (match_operand:DI 0 "register_operand" "")
21179 (mult:SI (match_operand:SI 1 "memory_operand" "")
21180 (match_operand:SI 2 "immediate_operand" ""))))
21181 (clobber (reg:CC FLAGS_REG))])]
21182 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21183 && !satisfies_constraint_K (operands[2])"
21184 [(set (match_dup 3) (match_dup 1))
21185 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21186 (clobber (reg:CC FLAGS_REG))])]
21189 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21190 ;; Convert it into imul reg, reg
21191 ;; It would be better to force assembler to encode instruction using long
21192 ;; immediate, but there is apparently no way to do so.
21194 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21195 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21196 (match_operand:DI 2 "const_int_operand" "")))
21197 (clobber (reg:CC FLAGS_REG))])
21198 (match_scratch:DI 3 "r")]
21199 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21200 && satisfies_constraint_K (operands[2])"
21201 [(set (match_dup 3) (match_dup 2))
21202 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21203 (clobber (reg:CC FLAGS_REG))])]
21205 if (!rtx_equal_p (operands[0], operands[1]))
21206 emit_move_insn (operands[0], operands[1]);
21210 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21211 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21212 (match_operand:SI 2 "const_int_operand" "")))
21213 (clobber (reg:CC FLAGS_REG))])
21214 (match_scratch:SI 3 "r")]
21215 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21216 && satisfies_constraint_K (operands[2])"
21217 [(set (match_dup 3) (match_dup 2))
21218 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21219 (clobber (reg:CC FLAGS_REG))])]
21221 if (!rtx_equal_p (operands[0], operands[1]))
21222 emit_move_insn (operands[0], operands[1]);
21226 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21227 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21228 (match_operand:HI 2 "immediate_operand" "")))
21229 (clobber (reg:CC FLAGS_REG))])
21230 (match_scratch:HI 3 "r")]
21231 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21232 [(set (match_dup 3) (match_dup 2))
21233 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21234 (clobber (reg:CC FLAGS_REG))])]
21236 if (!rtx_equal_p (operands[0], operands[1]))
21237 emit_move_insn (operands[0], operands[1]);
21240 ;; After splitting up read-modify operations, array accesses with memory
21241 ;; operands might end up in form:
21243 ;; movl 4(%esp), %edx
21245 ;; instead of pre-splitting:
21247 ;; addl 4(%esp), %eax
21249 ;; movl 4(%esp), %edx
21250 ;; leal (%edx,%eax,4), %eax
21253 [(parallel [(set (match_operand 0 "register_operand" "")
21254 (ashift (match_operand 1 "register_operand" "")
21255 (match_operand 2 "const_int_operand" "")))
21256 (clobber (reg:CC FLAGS_REG))])
21257 (set (match_operand 3 "register_operand")
21258 (match_operand 4 "x86_64_general_operand" ""))
21259 (parallel [(set (match_operand 5 "register_operand" "")
21260 (plus (match_operand 6 "register_operand" "")
21261 (match_operand 7 "register_operand" "")))
21262 (clobber (reg:CC FLAGS_REG))])]
21263 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21264 /* Validate MODE for lea. */
21265 && ((!TARGET_PARTIAL_REG_STALL
21266 && (GET_MODE (operands[0]) == QImode
21267 || GET_MODE (operands[0]) == HImode))
21268 || GET_MODE (operands[0]) == SImode
21269 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21270 /* We reorder load and the shift. */
21271 && !rtx_equal_p (operands[1], operands[3])
21272 && !reg_overlap_mentioned_p (operands[0], operands[4])
21273 /* Last PLUS must consist of operand 0 and 3. */
21274 && !rtx_equal_p (operands[0], operands[3])
21275 && (rtx_equal_p (operands[3], operands[6])
21276 || rtx_equal_p (operands[3], operands[7]))
21277 && (rtx_equal_p (operands[0], operands[6])
21278 || rtx_equal_p (operands[0], operands[7]))
21279 /* The intermediate operand 0 must die or be same as output. */
21280 && (rtx_equal_p (operands[0], operands[5])
21281 || peep2_reg_dead_p (3, operands[0]))"
21282 [(set (match_dup 3) (match_dup 4))
21283 (set (match_dup 0) (match_dup 1))]
21285 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21286 int scale = 1 << INTVAL (operands[2]);
21287 rtx index = gen_lowpart (Pmode, operands[1]);
21288 rtx base = gen_lowpart (Pmode, operands[3]);
21289 rtx dest = gen_lowpart (mode, operands[5]);
21291 operands[1] = gen_rtx_PLUS (Pmode, base,
21292 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21294 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21295 operands[0] = dest;
21298 ;; Call-value patterns last so that the wildcard operand does not
21299 ;; disrupt insn-recog's switch tables.
21301 (define_insn "*call_value_pop_0"
21302 [(set (match_operand 0 "" "")
21303 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21304 (match_operand:SI 2 "" "")))
21305 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21306 (match_operand:SI 3 "immediate_operand" "")))]
21309 if (SIBLING_CALL_P (insn))
21312 return "call\t%P1";
21314 [(set_attr "type" "callv")])
21316 (define_insn "*call_value_pop_1"
21317 [(set (match_operand 0 "" "")
21318 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21319 (match_operand:SI 2 "" "")))
21320 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21321 (match_operand:SI 3 "immediate_operand" "i")))]
21324 if (constant_call_address_operand (operands[1], Pmode))
21326 if (SIBLING_CALL_P (insn))
21329 return "call\t%P1";
21331 if (SIBLING_CALL_P (insn))
21334 return "call\t%A1";
21336 [(set_attr "type" "callv")])
21338 (define_insn "*call_value_0"
21339 [(set (match_operand 0 "" "")
21340 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21341 (match_operand:SI 2 "" "")))]
21344 if (SIBLING_CALL_P (insn))
21347 return "call\t%P1";
21349 [(set_attr "type" "callv")])
21351 (define_insn "*call_value_0_rex64"
21352 [(set (match_operand 0 "" "")
21353 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21354 (match_operand:DI 2 "const_int_operand" "")))]
21357 if (SIBLING_CALL_P (insn))
21360 return "call\t%P1";
21362 [(set_attr "type" "callv")])
21364 (define_insn "*call_value_1"
21365 [(set (match_operand 0 "" "")
21366 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21367 (match_operand:SI 2 "" "")))]
21368 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21370 if (constant_call_address_operand (operands[1], Pmode))
21371 return "call\t%P1";
21372 return "call\t%A1";
21374 [(set_attr "type" "callv")])
21376 (define_insn "*sibcall_value_1"
21377 [(set (match_operand 0 "" "")
21378 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21379 (match_operand:SI 2 "" "")))]
21380 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21382 if (constant_call_address_operand (operands[1], Pmode))
21386 [(set_attr "type" "callv")])
21388 (define_insn "*call_value_1_rex64"
21389 [(set (match_operand 0 "" "")
21390 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21391 (match_operand:DI 2 "" "")))]
21392 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21393 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21395 if (constant_call_address_operand (operands[1], Pmode))
21396 return "call\t%P1";
21397 return "call\t%A1";
21399 [(set_attr "type" "callv")])
21401 (define_insn "*call_value_1_rex64_large"
21402 [(set (match_operand 0 "" "")
21403 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21404 (match_operand:DI 2 "" "")))]
21405 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21407 [(set_attr "type" "callv")])
21409 (define_insn "*sibcall_value_1_rex64"
21410 [(set (match_operand 0 "" "")
21411 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21412 (match_operand:DI 2 "" "")))]
21413 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21415 [(set_attr "type" "callv")])
21417 (define_insn "*sibcall_value_1_rex64_v"
21418 [(set (match_operand 0 "" "")
21419 (call (mem:QI (reg:DI R11_REG))
21420 (match_operand:DI 1 "" "")))]
21421 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21423 [(set_attr "type" "callv")])
21425 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21426 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21427 ;; caught for use by garbage collectors and the like. Using an insn that
21428 ;; maps to SIGILL makes it more likely the program will rightfully die.
21429 ;; Keeping with tradition, "6" is in honor of #UD.
21430 (define_insn "trap"
21431 [(trap_if (const_int 1) (const_int 6))]
21433 { return ASM_SHORT "0x0b0f"; }
21434 [(set_attr "length" "2")])
21436 (define_expand "sse_prologue_save"
21437 [(parallel [(set (match_operand:BLK 0 "" "")
21438 (unspec:BLK [(reg:DI 21)
21445 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21446 (use (match_operand:DI 1 "register_operand" ""))
21447 (use (match_operand:DI 2 "immediate_operand" ""))
21448 (use (label_ref:DI (match_operand 3 "" "")))])]
21452 (define_insn "*sse_prologue_save_insn"
21453 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21454 (match_operand:DI 4 "const_int_operand" "n")))
21455 (unspec:BLK [(reg:DI 21)
21462 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21463 (use (match_operand:DI 1 "register_operand" "r"))
21464 (use (match_operand:DI 2 "const_int_operand" "i"))
21465 (use (label_ref:DI (match_operand 3 "" "X")))]
21467 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21468 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21471 operands[0] = gen_rtx_MEM (Pmode,
21472 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21473 /* VEX instruction with a REX prefix will #UD. */
21474 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21475 gcc_unreachable ();
21477 output_asm_insn ("jmp\t%A1", operands);
21478 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21480 operands[4] = adjust_address (operands[0], DImode, i*16);
21481 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21482 PUT_MODE (operands[4], TImode);
21483 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21484 output_asm_insn ("rex", operands);
21485 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21487 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21488 CODE_LABEL_NUMBER (operands[3]));
21491 [(set_attr "type" "other")
21492 (set_attr "length_immediate" "0")
21493 (set_attr "length_address" "0")
21494 (set (attr "length")
21496 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21497 (const_string "34")
21498 (const_string "42")))
21499 (set_attr "memory" "store")
21500 (set_attr "modrm" "0")
21501 (set_attr "prefix" "maybe_vex")
21502 (set_attr "mode" "DI")])
21504 (define_expand "prefetch"
21505 [(prefetch (match_operand 0 "address_operand" "")
21506 (match_operand:SI 1 "const_int_operand" "")
21507 (match_operand:SI 2 "const_int_operand" ""))]
21508 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21510 int rw = INTVAL (operands[1]);
21511 int locality = INTVAL (operands[2]);
21513 gcc_assert (rw == 0 || rw == 1);
21514 gcc_assert (locality >= 0 && locality <= 3);
21515 gcc_assert (GET_MODE (operands[0]) == Pmode
21516 || GET_MODE (operands[0]) == VOIDmode);
21518 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21519 supported by SSE counterpart or the SSE prefetch is not available
21520 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21522 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21523 operands[2] = GEN_INT (3);
21525 operands[1] = const0_rtx;
21528 (define_insn "*prefetch_sse"
21529 [(prefetch (match_operand:SI 0 "address_operand" "p")
21531 (match_operand:SI 1 "const_int_operand" ""))]
21532 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21534 static const char * const patterns[4] = {
21535 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21538 int locality = INTVAL (operands[1]);
21539 gcc_assert (locality >= 0 && locality <= 3);
21541 return patterns[locality];
21543 [(set_attr "type" "sse")
21544 (set_attr "memory" "none")])
21546 (define_insn "*prefetch_sse_rex"
21547 [(prefetch (match_operand:DI 0 "address_operand" "p")
21549 (match_operand:SI 1 "const_int_operand" ""))]
21550 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21552 static const char * const patterns[4] = {
21553 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21556 int locality = INTVAL (operands[1]);
21557 gcc_assert (locality >= 0 && locality <= 3);
21559 return patterns[locality];
21561 [(set_attr "type" "sse")
21562 (set_attr "memory" "none")])
21564 (define_insn "*prefetch_3dnow"
21565 [(prefetch (match_operand:SI 0 "address_operand" "p")
21566 (match_operand:SI 1 "const_int_operand" "n")
21568 "TARGET_3DNOW && !TARGET_64BIT"
21570 if (INTVAL (operands[1]) == 0)
21571 return "prefetch\t%a0";
21573 return "prefetchw\t%a0";
21575 [(set_attr "type" "mmx")
21576 (set_attr "memory" "none")])
21578 (define_insn "*prefetch_3dnow_rex"
21579 [(prefetch (match_operand:DI 0 "address_operand" "p")
21580 (match_operand:SI 1 "const_int_operand" "n")
21582 "TARGET_3DNOW && TARGET_64BIT"
21584 if (INTVAL (operands[1]) == 0)
21585 return "prefetch\t%a0";
21587 return "prefetchw\t%a0";
21589 [(set_attr "type" "mmx")
21590 (set_attr "memory" "none")])
21592 (define_expand "stack_protect_set"
21593 [(match_operand 0 "memory_operand" "")
21594 (match_operand 1 "memory_operand" "")]
21597 #ifdef TARGET_THREAD_SSP_OFFSET
21599 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21600 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21602 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21603 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21606 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21608 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21613 (define_insn "stack_protect_set_si"
21614 [(set (match_operand:SI 0 "memory_operand" "=m")
21615 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21616 (set (match_scratch:SI 2 "=&r") (const_int 0))
21617 (clobber (reg:CC FLAGS_REG))]
21619 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21620 [(set_attr "type" "multi")])
21622 (define_insn "stack_protect_set_di"
21623 [(set (match_operand:DI 0 "memory_operand" "=m")
21624 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21625 (set (match_scratch:DI 2 "=&r") (const_int 0))
21626 (clobber (reg:CC FLAGS_REG))]
21628 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21629 [(set_attr "type" "multi")])
21631 (define_insn "stack_tls_protect_set_si"
21632 [(set (match_operand:SI 0 "memory_operand" "=m")
21633 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21634 (set (match_scratch:SI 2 "=&r") (const_int 0))
21635 (clobber (reg:CC FLAGS_REG))]
21637 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21638 [(set_attr "type" "multi")])
21640 (define_insn "stack_tls_protect_set_di"
21641 [(set (match_operand:DI 0 "memory_operand" "=m")
21642 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21643 (set (match_scratch:DI 2 "=&r") (const_int 0))
21644 (clobber (reg:CC FLAGS_REG))]
21647 /* The kernel uses a different segment register for performance reasons; a
21648 system call would not have to trash the userspace segment register,
21649 which would be expensive */
21650 if (ix86_cmodel != CM_KERNEL)
21651 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21653 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21655 [(set_attr "type" "multi")])
21657 (define_expand "stack_protect_test"
21658 [(match_operand 0 "memory_operand" "")
21659 (match_operand 1 "memory_operand" "")
21660 (match_operand 2 "" "")]
21663 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21664 ix86_compare_op0 = operands[0];
21665 ix86_compare_op1 = operands[1];
21666 ix86_compare_emitted = flags;
21668 #ifdef TARGET_THREAD_SSP_OFFSET
21670 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21671 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21673 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21674 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21677 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21679 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21681 emit_jump_insn (gen_beq (operands[2]));
21685 (define_insn "stack_protect_test_si"
21686 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21687 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21688 (match_operand:SI 2 "memory_operand" "m")]
21690 (clobber (match_scratch:SI 3 "=&r"))]
21692 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21693 [(set_attr "type" "multi")])
21695 (define_insn "stack_protect_test_di"
21696 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21697 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21698 (match_operand:DI 2 "memory_operand" "m")]
21700 (clobber (match_scratch:DI 3 "=&r"))]
21702 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21703 [(set_attr "type" "multi")])
21705 (define_insn "stack_tls_protect_test_si"
21706 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21707 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21708 (match_operand:SI 2 "const_int_operand" "i")]
21709 UNSPEC_SP_TLS_TEST))
21710 (clobber (match_scratch:SI 3 "=r"))]
21712 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21713 [(set_attr "type" "multi")])
21715 (define_insn "stack_tls_protect_test_di"
21716 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21717 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21718 (match_operand:DI 2 "const_int_operand" "i")]
21719 UNSPEC_SP_TLS_TEST))
21720 (clobber (match_scratch:DI 3 "=r"))]
21723 /* The kernel uses a different segment register for performance reasons; a
21724 system call would not have to trash the userspace segment register,
21725 which would be expensive */
21726 if (ix86_cmodel != CM_KERNEL)
21727 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21729 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21731 [(set_attr "type" "multi")])
21733 (define_mode_iterator CRC32MODE [QI HI SI])
21734 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21735 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21737 (define_insn "sse4_2_crc32<mode>"
21738 [(set (match_operand:SI 0 "register_operand" "=r")
21740 [(match_operand:SI 1 "register_operand" "0")
21741 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21744 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21745 [(set_attr "type" "sselog1")
21746 (set_attr "prefix_rep" "1")
21747 (set_attr "prefix_extra" "1")
21748 (set_attr "mode" "SI")])
21750 (define_insn "sse4_2_crc32di"
21751 [(set (match_operand:DI 0 "register_operand" "=r")
21753 [(match_operand:DI 1 "register_operand" "0")
21754 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21756 "TARGET_SSE4_2 && TARGET_64BIT"
21757 "crc32q\t{%2, %0|%0, %2}"
21758 [(set_attr "type" "sselog1")
21759 (set_attr "prefix_rep" "1")
21760 (set_attr "prefix_extra" "1")
21761 (set_attr "mode" "DI")])
21765 (include "sync.md")