1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
61 (UNSPEC_MACHOPIC_OFFSET 10)
64 (UNSPEC_STACK_ALLOC 11)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70 (UNSPEC_SET_GOT_OFFSET 17)
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)
108 (UNSPEC_MS_TO_SYSV_CALL 48)
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
152 (UNSPEC_SP_TLS_SET 102)
153 (UNSPEC_SP_TLS_TEST 103)
163 (UNSPEC_INSERTQI 132)
168 (UNSPEC_INSERTPS 135)
170 (UNSPEC_MOVNTDQA 137)
172 (UNSPEC_PHMINPOSUW 139)
178 (UNSPEC_PCMPESTR 144)
179 (UNSPEC_PCMPISTR 145)
182 (UNSPEC_SSE5_INTRINSIC 150)
183 (UNSPEC_SSE5_UNSIGNED_CMP 151)
184 (UNSPEC_SSE5_TRUEFALSE 152)
185 (UNSPEC_SSE5_PERMUTE 153)
187 (UNSPEC_CVTPH2PS 155)
188 (UNSPEC_CVTPS2PH 156)
192 (UNSPEC_AESENCLAST 160)
194 (UNSPEC_AESDECLAST 162)
196 (UNSPEC_AESKEYGENASSIST 164)
204 (UNSPEC_VPERMIL2F128 168)
205 (UNSPEC_MASKLOAD 169)
206 (UNSPEC_MASKSTORE 170)
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_ms_sysv"
15043 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15044 (match_operand 1 "" ""))
15045 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15046 (clobber (reg:DI SI_REG))
15047 (clobber (reg:DI DI_REG))]
15048 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15050 if (constant_call_address_operand (operands[0], Pmode))
15051 return "call\t%P0";
15052 return "call\t%A0";
15054 [(set_attr "type" "call")])
15056 (define_insn "*call_1_rex64_large"
15057 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15058 (match_operand 1 "" ""))]
15059 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15061 [(set_attr "type" "call")])
15063 (define_insn "*sibcall_1_rex64"
15064 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15065 (match_operand 1 "" ""))]
15066 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15068 [(set_attr "type" "call")])
15070 (define_insn "*sibcall_1_rex64_v"
15071 [(call (mem:QI (reg:DI R11_REG))
15072 (match_operand 0 "" ""))]
15073 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15075 [(set_attr "type" "call")])
15078 ;; Call subroutine, returning value in operand 0
15080 (define_expand "call_value_pop"
15081 [(parallel [(set (match_operand 0 "" "")
15082 (call (match_operand:QI 1 "" "")
15083 (match_operand:SI 2 "" "")))
15084 (set (reg:SI SP_REG)
15085 (plus:SI (reg:SI SP_REG)
15086 (match_operand:SI 4 "" "")))])]
15089 ix86_expand_call (operands[0], operands[1], operands[2],
15090 operands[3], operands[4], 0);
15094 (define_expand "call_value"
15095 [(set (match_operand 0 "" "")
15096 (call (match_operand:QI 1 "" "")
15097 (match_operand:SI 2 "" "")))
15098 (use (match_operand:SI 3 "" ""))]
15099 ;; Operand 2 not used on the i386.
15102 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15106 (define_expand "sibcall_value"
15107 [(set (match_operand 0 "" "")
15108 (call (match_operand:QI 1 "" "")
15109 (match_operand:SI 2 "" "")))
15110 (use (match_operand:SI 3 "" ""))]
15111 ;; Operand 2 not used on the i386.
15114 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15118 ;; Call subroutine returning any type.
15120 (define_expand "untyped_call"
15121 [(parallel [(call (match_operand 0 "" "")
15123 (match_operand 1 "" "")
15124 (match_operand 2 "" "")])]
15129 /* In order to give reg-stack an easier job in validating two
15130 coprocessor registers as containing a possible return value,
15131 simply pretend the untyped call returns a complex long double
15134 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15135 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15136 operands[0], const0_rtx,
15137 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15138 : X64_SSE_REGPARM_MAX)
15142 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15144 rtx set = XVECEXP (operands[2], 0, i);
15145 emit_move_insn (SET_DEST (set), SET_SRC (set));
15148 /* The optimizer does not know that the call sets the function value
15149 registers we stored in the result block. We avoid problems by
15150 claiming that all hard registers are used and clobbered at this
15152 emit_insn (gen_blockage ());
15157 ;; Prologue and epilogue instructions
15159 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15160 ;; all of memory. This blocks insns from being moved across this point.
15162 (define_insn "blockage"
15163 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15166 [(set_attr "length" "0")])
15168 ;; As USE insns aren't meaningful after reload, this is used instead
15169 ;; to prevent deleting instructions setting registers for PIC code
15170 (define_insn "prologue_use"
15171 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15174 [(set_attr "length" "0")])
15176 ;; Insn emitted into the body of a function to return from a function.
15177 ;; This is only done if the function's epilogue is known to be simple.
15178 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15180 (define_expand "return"
15182 "ix86_can_use_return_insn_p ()"
15184 if (crtl->args.pops_args)
15186 rtx popc = GEN_INT (crtl->args.pops_args);
15187 emit_jump_insn (gen_return_pop_internal (popc));
15192 (define_insn "return_internal"
15196 [(set_attr "length" "1")
15197 (set_attr "length_immediate" "0")
15198 (set_attr "modrm" "0")])
15200 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15201 ;; instruction Athlon and K8 have.
15203 (define_insn "return_internal_long"
15205 (unspec [(const_int 0)] UNSPEC_REP)]
15208 [(set_attr "length" "1")
15209 (set_attr "length_immediate" "0")
15210 (set_attr "prefix_rep" "1")
15211 (set_attr "modrm" "0")])
15213 (define_insn "return_pop_internal"
15215 (use (match_operand:SI 0 "const_int_operand" ""))]
15218 [(set_attr "length" "3")
15219 (set_attr "length_immediate" "2")
15220 (set_attr "modrm" "0")])
15222 (define_insn "return_indirect_internal"
15224 (use (match_operand:SI 0 "register_operand" "r"))]
15227 [(set_attr "type" "ibr")
15228 (set_attr "length_immediate" "0")])
15234 [(set_attr "length" "1")
15235 (set_attr "length_immediate" "0")
15236 (set_attr "modrm" "0")])
15238 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15239 ;; branch prediction penalty for the third jump in a 16-byte
15242 (define_insn "align"
15243 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15246 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15247 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15249 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15250 The align insn is used to avoid 3 jump instructions in the row to improve
15251 branch prediction and the benefits hardly outweigh the cost of extra 8
15252 nops on the average inserted by full alignment pseudo operation. */
15256 [(set_attr "length" "16")])
15258 (define_expand "prologue"
15261 "ix86_expand_prologue (); DONE;")
15263 (define_insn "set_got"
15264 [(set (match_operand:SI 0 "register_operand" "=r")
15265 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15266 (clobber (reg:CC FLAGS_REG))]
15268 { return output_set_got (operands[0], NULL_RTX); }
15269 [(set_attr "type" "multi")
15270 (set_attr "length" "12")])
15272 (define_insn "set_got_labelled"
15273 [(set (match_operand:SI 0 "register_operand" "=r")
15274 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15276 (clobber (reg:CC FLAGS_REG))]
15278 { return output_set_got (operands[0], operands[1]); }
15279 [(set_attr "type" "multi")
15280 (set_attr "length" "12")])
15282 (define_insn "set_got_rex64"
15283 [(set (match_operand:DI 0 "register_operand" "=r")
15284 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15286 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15287 [(set_attr "type" "lea")
15288 (set_attr "length" "6")])
15290 (define_insn "set_rip_rex64"
15291 [(set (match_operand:DI 0 "register_operand" "=r")
15292 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15294 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15295 [(set_attr "type" "lea")
15296 (set_attr "length" "6")])
15298 (define_insn "set_got_offset_rex64"
15299 [(set (match_operand:DI 0 "register_operand" "=r")
15300 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15302 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15303 [(set_attr "type" "imov")
15304 (set_attr "length" "11")])
15306 (define_expand "epilogue"
15309 "ix86_expand_epilogue (1); DONE;")
15311 (define_expand "sibcall_epilogue"
15314 "ix86_expand_epilogue (0); DONE;")
15316 (define_expand "eh_return"
15317 [(use (match_operand 0 "register_operand" ""))]
15320 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15322 /* Tricky bit: we write the address of the handler to which we will
15323 be returning into someone else's stack frame, one word below the
15324 stack address we wish to restore. */
15325 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15326 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15327 tmp = gen_rtx_MEM (Pmode, tmp);
15328 emit_move_insn (tmp, ra);
15330 if (Pmode == SImode)
15331 emit_jump_insn (gen_eh_return_si (sa));
15333 emit_jump_insn (gen_eh_return_di (sa));
15338 (define_insn_and_split "eh_return_<mode>"
15340 (unspec [(match_operand:P 0 "register_operand" "c")]
15341 UNSPEC_EH_RETURN))]
15346 "ix86_expand_epilogue (2); DONE;")
15348 (define_insn "leave"
15349 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15350 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15351 (clobber (mem:BLK (scratch)))]
15354 [(set_attr "type" "leave")])
15356 (define_insn "leave_rex64"
15357 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15358 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15359 (clobber (mem:BLK (scratch)))]
15362 [(set_attr "type" "leave")])
15364 (define_expand "ffssi2"
15366 [(set (match_operand:SI 0 "register_operand" "")
15367 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15368 (clobber (match_scratch:SI 2 ""))
15369 (clobber (reg:CC FLAGS_REG))])]
15374 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15379 (define_expand "ffs_cmove"
15380 [(set (match_dup 2) (const_int -1))
15381 (parallel [(set (reg:CCZ FLAGS_REG)
15382 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15384 (set (match_operand:SI 0 "register_operand" "")
15385 (ctz:SI (match_dup 1)))])
15386 (set (match_dup 0) (if_then_else:SI
15387 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15390 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15391 (clobber (reg:CC FLAGS_REG))])]
15393 "operands[2] = gen_reg_rtx (SImode);")
15395 (define_insn_and_split "*ffs_no_cmove"
15396 [(set (match_operand:SI 0 "register_operand" "=r")
15397 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15398 (clobber (match_scratch:SI 2 "=&q"))
15399 (clobber (reg:CC FLAGS_REG))]
15402 "&& reload_completed"
15403 [(parallel [(set (reg:CCZ FLAGS_REG)
15404 (compare:CCZ (match_dup 1) (const_int 0)))
15405 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15406 (set (strict_low_part (match_dup 3))
15407 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15408 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15409 (clobber (reg:CC FLAGS_REG))])
15410 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15411 (clobber (reg:CC FLAGS_REG))])
15412 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15413 (clobber (reg:CC FLAGS_REG))])]
15415 operands[3] = gen_lowpart (QImode, operands[2]);
15416 ix86_expand_clear (operands[2]);
15419 (define_insn "*ffssi_1"
15420 [(set (reg:CCZ FLAGS_REG)
15421 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15423 (set (match_operand:SI 0 "register_operand" "=r")
15424 (ctz:SI (match_dup 1)))]
15426 "bsf{l}\t{%1, %0|%0, %1}"
15427 [(set_attr "prefix_0f" "1")])
15429 (define_expand "ffsdi2"
15430 [(set (match_dup 2) (const_int -1))
15431 (parallel [(set (reg:CCZ FLAGS_REG)
15432 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15434 (set (match_operand:DI 0 "register_operand" "")
15435 (ctz:DI (match_dup 1)))])
15436 (set (match_dup 0) (if_then_else:DI
15437 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15440 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15441 (clobber (reg:CC FLAGS_REG))])]
15443 "operands[2] = gen_reg_rtx (DImode);")
15445 (define_insn "*ffsdi_1"
15446 [(set (reg:CCZ FLAGS_REG)
15447 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15449 (set (match_operand:DI 0 "register_operand" "=r")
15450 (ctz:DI (match_dup 1)))]
15452 "bsf{q}\t{%1, %0|%0, %1}"
15453 [(set_attr "prefix_0f" "1")])
15455 (define_insn "ctzsi2"
15456 [(set (match_operand:SI 0 "register_operand" "=r")
15457 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15458 (clobber (reg:CC FLAGS_REG))]
15460 "bsf{l}\t{%1, %0|%0, %1}"
15461 [(set_attr "prefix_0f" "1")])
15463 (define_insn "ctzdi2"
15464 [(set (match_operand:DI 0 "register_operand" "=r")
15465 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15466 (clobber (reg:CC FLAGS_REG))]
15468 "bsf{q}\t{%1, %0|%0, %1}"
15469 [(set_attr "prefix_0f" "1")])
15471 (define_expand "clzsi2"
15473 [(set (match_operand:SI 0 "register_operand" "")
15474 (minus:SI (const_int 31)
15475 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15476 (clobber (reg:CC FLAGS_REG))])
15478 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15479 (clobber (reg:CC FLAGS_REG))])]
15484 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15489 (define_insn "clzsi2_abm"
15490 [(set (match_operand:SI 0 "register_operand" "=r")
15491 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15492 (clobber (reg:CC FLAGS_REG))]
15494 "lzcnt{l}\t{%1, %0|%0, %1}"
15495 [(set_attr "prefix_rep" "1")
15496 (set_attr "type" "bitmanip")
15497 (set_attr "mode" "SI")])
15499 (define_insn "*bsr"
15500 [(set (match_operand:SI 0 "register_operand" "=r")
15501 (minus:SI (const_int 31)
15502 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15503 (clobber (reg:CC FLAGS_REG))]
15505 "bsr{l}\t{%1, %0|%0, %1}"
15506 [(set_attr "prefix_0f" "1")
15507 (set_attr "mode" "SI")])
15509 (define_insn "popcount<mode>2"
15510 [(set (match_operand:SWI248 0 "register_operand" "=r")
15512 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15513 (clobber (reg:CC FLAGS_REG))]
15517 return "popcnt\t{%1, %0|%0, %1}";
15519 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15522 [(set_attr "prefix_rep" "1")
15523 (set_attr "type" "bitmanip")
15524 (set_attr "mode" "<MODE>")])
15526 (define_insn "*popcount<mode>2_cmp"
15527 [(set (reg FLAGS_REG)
15530 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15532 (set (match_operand:SWI248 0 "register_operand" "=r")
15533 (popcount:SWI248 (match_dup 1)))]
15534 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15537 return "popcnt\t{%1, %0|%0, %1}";
15539 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15542 [(set_attr "prefix_rep" "1")
15543 (set_attr "type" "bitmanip")
15544 (set_attr "mode" "<MODE>")])
15546 (define_insn "*popcountsi2_cmp_zext"
15547 [(set (reg FLAGS_REG)
15549 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15551 (set (match_operand:DI 0 "register_operand" "=r")
15552 (zero_extend:DI(popcount:SI (match_dup 1))))]
15553 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15556 return "popcnt\t{%1, %0|%0, %1}";
15558 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15561 [(set_attr "prefix_rep" "1")
15562 (set_attr "type" "bitmanip")
15563 (set_attr "mode" "SI")])
15565 (define_expand "bswapsi2"
15566 [(set (match_operand:SI 0 "register_operand" "")
15567 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15572 rtx x = operands[0];
15574 emit_move_insn (x, operands[1]);
15575 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15576 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15577 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15582 (define_insn "*bswapsi_1"
15583 [(set (match_operand:SI 0 "register_operand" "=r")
15584 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15587 [(set_attr "prefix_0f" "1")
15588 (set_attr "length" "2")])
15590 (define_insn "*bswaphi_lowpart_1"
15591 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15592 (bswap:HI (match_dup 0)))
15593 (clobber (reg:CC FLAGS_REG))]
15594 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15596 xchg{b}\t{%h0, %b0|%b0, %h0}
15597 rol{w}\t{$8, %0|%0, 8}"
15598 [(set_attr "length" "2,4")
15599 (set_attr "mode" "QI,HI")])
15601 (define_insn "bswaphi_lowpart"
15602 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15603 (bswap:HI (match_dup 0)))
15604 (clobber (reg:CC FLAGS_REG))]
15606 "rol{w}\t{$8, %0|%0, 8}"
15607 [(set_attr "length" "4")
15608 (set_attr "mode" "HI")])
15610 (define_insn "bswapdi2"
15611 [(set (match_operand:DI 0 "register_operand" "=r")
15612 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15615 [(set_attr "prefix_0f" "1")
15616 (set_attr "length" "3")])
15618 (define_expand "clzdi2"
15620 [(set (match_operand:DI 0 "register_operand" "")
15621 (minus:DI (const_int 63)
15622 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15623 (clobber (reg:CC FLAGS_REG))])
15625 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15626 (clobber (reg:CC FLAGS_REG))])]
15631 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15636 (define_insn "clzdi2_abm"
15637 [(set (match_operand:DI 0 "register_operand" "=r")
15638 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15639 (clobber (reg:CC FLAGS_REG))]
15640 "TARGET_64BIT && TARGET_ABM"
15641 "lzcnt{q}\t{%1, %0|%0, %1}"
15642 [(set_attr "prefix_rep" "1")
15643 (set_attr "type" "bitmanip")
15644 (set_attr "mode" "DI")])
15646 (define_insn "*bsr_rex64"
15647 [(set (match_operand:DI 0 "register_operand" "=r")
15648 (minus:DI (const_int 63)
15649 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15650 (clobber (reg:CC FLAGS_REG))]
15652 "bsr{q}\t{%1, %0|%0, %1}"
15653 [(set_attr "prefix_0f" "1")
15654 (set_attr "mode" "DI")])
15656 (define_expand "clzhi2"
15658 [(set (match_operand:HI 0 "register_operand" "")
15659 (minus:HI (const_int 15)
15660 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15661 (clobber (reg:CC FLAGS_REG))])
15663 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15664 (clobber (reg:CC FLAGS_REG))])]
15669 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15674 (define_insn "clzhi2_abm"
15675 [(set (match_operand:HI 0 "register_operand" "=r")
15676 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15677 (clobber (reg:CC FLAGS_REG))]
15679 "lzcnt{w}\t{%1, %0|%0, %1}"
15680 [(set_attr "prefix_rep" "1")
15681 (set_attr "type" "bitmanip")
15682 (set_attr "mode" "HI")])
15684 (define_insn "*bsrhi"
15685 [(set (match_operand:HI 0 "register_operand" "=r")
15686 (minus:HI (const_int 15)
15687 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15688 (clobber (reg:CC FLAGS_REG))]
15690 "bsr{w}\t{%1, %0|%0, %1}"
15691 [(set_attr "prefix_0f" "1")
15692 (set_attr "mode" "HI")])
15694 (define_expand "paritydi2"
15695 [(set (match_operand:DI 0 "register_operand" "")
15696 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15699 rtx scratch = gen_reg_rtx (QImode);
15702 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15703 NULL_RTX, operands[1]));
15705 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15706 gen_rtx_REG (CCmode, FLAGS_REG),
15708 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15711 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15714 rtx tmp = gen_reg_rtx (SImode);
15716 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15717 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15722 (define_insn_and_split "paritydi2_cmp"
15723 [(set (reg:CC FLAGS_REG)
15724 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15725 (clobber (match_scratch:DI 0 "=r"))
15726 (clobber (match_scratch:SI 1 "=&r"))
15727 (clobber (match_scratch:HI 2 "=Q"))]
15730 "&& reload_completed"
15732 [(set (match_dup 1)
15733 (xor:SI (match_dup 1) (match_dup 4)))
15734 (clobber (reg:CC FLAGS_REG))])
15736 [(set (reg:CC FLAGS_REG)
15737 (parity:CC (match_dup 1)))
15738 (clobber (match_dup 1))
15739 (clobber (match_dup 2))])]
15741 operands[4] = gen_lowpart (SImode, operands[3]);
15745 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15746 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15749 operands[1] = gen_highpart (SImode, operands[3]);
15752 (define_expand "paritysi2"
15753 [(set (match_operand:SI 0 "register_operand" "")
15754 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15757 rtx scratch = gen_reg_rtx (QImode);
15760 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15762 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15763 gen_rtx_REG (CCmode, FLAGS_REG),
15765 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15767 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15771 (define_insn_and_split "paritysi2_cmp"
15772 [(set (reg:CC FLAGS_REG)
15773 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15774 (clobber (match_scratch:SI 0 "=r"))
15775 (clobber (match_scratch:HI 1 "=&Q"))]
15778 "&& reload_completed"
15780 [(set (match_dup 1)
15781 (xor:HI (match_dup 1) (match_dup 3)))
15782 (clobber (reg:CC FLAGS_REG))])
15784 [(set (reg:CC FLAGS_REG)
15785 (parity:CC (match_dup 1)))
15786 (clobber (match_dup 1))])]
15788 operands[3] = gen_lowpart (HImode, operands[2]);
15790 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15791 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15794 (define_insn "*parityhi2_cmp"
15795 [(set (reg:CC FLAGS_REG)
15796 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15797 (clobber (match_scratch:HI 0 "=Q"))]
15799 "xor{b}\t{%h0, %b0|%b0, %h0}"
15800 [(set_attr "length" "2")
15801 (set_attr "mode" "HI")])
15803 (define_insn "*parityqi2_cmp"
15804 [(set (reg:CC FLAGS_REG)
15805 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15808 [(set_attr "length" "2")
15809 (set_attr "mode" "QI")])
15811 ;; Thread-local storage patterns for ELF.
15813 ;; Note that these code sequences must appear exactly as shown
15814 ;; in order to allow linker relaxation.
15816 (define_insn "*tls_global_dynamic_32_gnu"
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_GNU_TLS"
15826 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15827 [(set_attr "type" "multi")
15828 (set_attr "length" "12")])
15830 (define_insn "*tls_global_dynamic_32_sun"
15831 [(set (match_operand:SI 0 "register_operand" "=a")
15832 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15833 (match_operand:SI 2 "tls_symbolic_operand" "")
15834 (match_operand:SI 3 "call_insn_operand" "")]
15836 (clobber (match_scratch:SI 4 "=d"))
15837 (clobber (match_scratch:SI 5 "=c"))
15838 (clobber (reg:CC FLAGS_REG))]
15839 "!TARGET_64BIT && TARGET_SUN_TLS"
15840 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15841 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15842 [(set_attr "type" "multi")
15843 (set_attr "length" "14")])
15845 (define_expand "tls_global_dynamic_32"
15846 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15849 (match_operand:SI 1 "tls_symbolic_operand" "")
15852 (clobber (match_scratch:SI 4 ""))
15853 (clobber (match_scratch:SI 5 ""))
15854 (clobber (reg:CC FLAGS_REG))])]
15858 operands[2] = pic_offset_table_rtx;
15861 operands[2] = gen_reg_rtx (Pmode);
15862 emit_insn (gen_set_got (operands[2]));
15864 if (TARGET_GNU2_TLS)
15866 emit_insn (gen_tls_dynamic_gnu2_32
15867 (operands[0], operands[1], operands[2]));
15870 operands[3] = ix86_tls_get_addr ();
15873 (define_insn "*tls_global_dynamic_64"
15874 [(set (match_operand:DI 0 "register_operand" "=a")
15875 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15876 (match_operand:DI 3 "" "")))
15877 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15880 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15881 [(set_attr "type" "multi")
15882 (set_attr "length" "16")])
15884 (define_expand "tls_global_dynamic_64"
15885 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15886 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15887 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15891 if (TARGET_GNU2_TLS)
15893 emit_insn (gen_tls_dynamic_gnu2_64
15894 (operands[0], operands[1]));
15897 operands[2] = ix86_tls_get_addr ();
15900 (define_insn "*tls_local_dynamic_base_32_gnu"
15901 [(set (match_operand:SI 0 "register_operand" "=a")
15902 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15903 (match_operand:SI 2 "call_insn_operand" "")]
15904 UNSPEC_TLS_LD_BASE))
15905 (clobber (match_scratch:SI 3 "=d"))
15906 (clobber (match_scratch:SI 4 "=c"))
15907 (clobber (reg:CC FLAGS_REG))]
15908 "!TARGET_64BIT && TARGET_GNU_TLS"
15909 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15910 [(set_attr "type" "multi")
15911 (set_attr "length" "11")])
15913 (define_insn "*tls_local_dynamic_base_32_sun"
15914 [(set (match_operand:SI 0 "register_operand" "=a")
15915 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15916 (match_operand:SI 2 "call_insn_operand" "")]
15917 UNSPEC_TLS_LD_BASE))
15918 (clobber (match_scratch:SI 3 "=d"))
15919 (clobber (match_scratch:SI 4 "=c"))
15920 (clobber (reg:CC FLAGS_REG))]
15921 "!TARGET_64BIT && TARGET_SUN_TLS"
15922 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15923 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15924 [(set_attr "type" "multi")
15925 (set_attr "length" "13")])
15927 (define_expand "tls_local_dynamic_base_32"
15928 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15929 (unspec:SI [(match_dup 1) (match_dup 2)]
15930 UNSPEC_TLS_LD_BASE))
15931 (clobber (match_scratch:SI 3 ""))
15932 (clobber (match_scratch:SI 4 ""))
15933 (clobber (reg:CC FLAGS_REG))])]
15937 operands[1] = pic_offset_table_rtx;
15940 operands[1] = gen_reg_rtx (Pmode);
15941 emit_insn (gen_set_got (operands[1]));
15943 if (TARGET_GNU2_TLS)
15945 emit_insn (gen_tls_dynamic_gnu2_32
15946 (operands[0], ix86_tls_module_base (), operands[1]));
15949 operands[2] = ix86_tls_get_addr ();
15952 (define_insn "*tls_local_dynamic_base_64"
15953 [(set (match_operand:DI 0 "register_operand" "=a")
15954 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15955 (match_operand:DI 2 "" "")))
15956 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15958 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15959 [(set_attr "type" "multi")
15960 (set_attr "length" "12")])
15962 (define_expand "tls_local_dynamic_base_64"
15963 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15964 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15965 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15968 if (TARGET_GNU2_TLS)
15970 emit_insn (gen_tls_dynamic_gnu2_64
15971 (operands[0], ix86_tls_module_base ()));
15974 operands[1] = ix86_tls_get_addr ();
15977 ;; Local dynamic of a single variable is a lose. Show combine how
15978 ;; to convert that back to global dynamic.
15980 (define_insn_and_split "*tls_local_dynamic_32_once"
15981 [(set (match_operand:SI 0 "register_operand" "=a")
15982 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15983 (match_operand:SI 2 "call_insn_operand" "")]
15984 UNSPEC_TLS_LD_BASE)
15985 (const:SI (unspec:SI
15986 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15988 (clobber (match_scratch:SI 4 "=d"))
15989 (clobber (match_scratch:SI 5 "=c"))
15990 (clobber (reg:CC FLAGS_REG))]
15994 [(parallel [(set (match_dup 0)
15995 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15997 (clobber (match_dup 4))
15998 (clobber (match_dup 5))
15999 (clobber (reg:CC FLAGS_REG))])]
16002 ;; Load and add the thread base pointer from %gs:0.
16004 (define_insn "*load_tp_si"
16005 [(set (match_operand:SI 0 "register_operand" "=r")
16006 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16008 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16009 [(set_attr "type" "imov")
16010 (set_attr "modrm" "0")
16011 (set_attr "length" "7")
16012 (set_attr "memory" "load")
16013 (set_attr "imm_disp" "false")])
16015 (define_insn "*add_tp_si"
16016 [(set (match_operand:SI 0 "register_operand" "=r")
16017 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16018 (match_operand:SI 1 "register_operand" "0")))
16019 (clobber (reg:CC FLAGS_REG))]
16021 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16022 [(set_attr "type" "alu")
16023 (set_attr "modrm" "0")
16024 (set_attr "length" "7")
16025 (set_attr "memory" "load")
16026 (set_attr "imm_disp" "false")])
16028 (define_insn "*load_tp_di"
16029 [(set (match_operand:DI 0 "register_operand" "=r")
16030 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16032 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16033 [(set_attr "type" "imov")
16034 (set_attr "modrm" "0")
16035 (set_attr "length" "7")
16036 (set_attr "memory" "load")
16037 (set_attr "imm_disp" "false")])
16039 (define_insn "*add_tp_di"
16040 [(set (match_operand:DI 0 "register_operand" "=r")
16041 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16042 (match_operand:DI 1 "register_operand" "0")))
16043 (clobber (reg:CC FLAGS_REG))]
16045 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16046 [(set_attr "type" "alu")
16047 (set_attr "modrm" "0")
16048 (set_attr "length" "7")
16049 (set_attr "memory" "load")
16050 (set_attr "imm_disp" "false")])
16052 ;; GNU2 TLS patterns can be split.
16054 (define_expand "tls_dynamic_gnu2_32"
16055 [(set (match_dup 3)
16056 (plus:SI (match_operand:SI 2 "register_operand" "")
16058 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16061 [(set (match_operand:SI 0 "register_operand" "")
16062 (unspec:SI [(match_dup 1) (match_dup 3)
16063 (match_dup 2) (reg:SI SP_REG)]
16065 (clobber (reg:CC FLAGS_REG))])]
16066 "!TARGET_64BIT && TARGET_GNU2_TLS"
16068 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16069 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16072 (define_insn "*tls_dynamic_lea_32"
16073 [(set (match_operand:SI 0 "register_operand" "=r")
16074 (plus:SI (match_operand:SI 1 "register_operand" "b")
16076 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16077 UNSPEC_TLSDESC))))]
16078 "!TARGET_64BIT && TARGET_GNU2_TLS"
16079 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16080 [(set_attr "type" "lea")
16081 (set_attr "mode" "SI")
16082 (set_attr "length" "6")
16083 (set_attr "length_address" "4")])
16085 (define_insn "*tls_dynamic_call_32"
16086 [(set (match_operand:SI 0 "register_operand" "=a")
16087 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16088 (match_operand:SI 2 "register_operand" "0")
16089 ;; we have to make sure %ebx still points to the GOT
16090 (match_operand:SI 3 "register_operand" "b")
16093 (clobber (reg:CC FLAGS_REG))]
16094 "!TARGET_64BIT && TARGET_GNU2_TLS"
16095 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16096 [(set_attr "type" "call")
16097 (set_attr "length" "2")
16098 (set_attr "length_address" "0")])
16100 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16101 [(set (match_operand:SI 0 "register_operand" "=&a")
16103 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16104 (match_operand:SI 4 "" "")
16105 (match_operand:SI 2 "register_operand" "b")
16108 (const:SI (unspec:SI
16109 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16111 (clobber (reg:CC FLAGS_REG))]
16112 "!TARGET_64BIT && TARGET_GNU2_TLS"
16115 [(set (match_dup 0) (match_dup 5))]
16117 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16118 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16121 (define_expand "tls_dynamic_gnu2_64"
16122 [(set (match_dup 2)
16123 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16126 [(set (match_operand:DI 0 "register_operand" "")
16127 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16129 (clobber (reg:CC FLAGS_REG))])]
16130 "TARGET_64BIT && TARGET_GNU2_TLS"
16132 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16133 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16136 (define_insn "*tls_dynamic_lea_64"
16137 [(set (match_operand:DI 0 "register_operand" "=r")
16138 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16140 "TARGET_64BIT && TARGET_GNU2_TLS"
16141 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16142 [(set_attr "type" "lea")
16143 (set_attr "mode" "DI")
16144 (set_attr "length" "7")
16145 (set_attr "length_address" "4")])
16147 (define_insn "*tls_dynamic_call_64"
16148 [(set (match_operand:DI 0 "register_operand" "=a")
16149 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16150 (match_operand:DI 2 "register_operand" "0")
16153 (clobber (reg:CC FLAGS_REG))]
16154 "TARGET_64BIT && TARGET_GNU2_TLS"
16155 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16156 [(set_attr "type" "call")
16157 (set_attr "length" "2")
16158 (set_attr "length_address" "0")])
16160 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16161 [(set (match_operand:DI 0 "register_operand" "=&a")
16163 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16164 (match_operand:DI 3 "" "")
16167 (const:DI (unspec:DI
16168 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16170 (clobber (reg:CC FLAGS_REG))]
16171 "TARGET_64BIT && TARGET_GNU2_TLS"
16174 [(set (match_dup 0) (match_dup 4))]
16176 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16177 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16182 ;; These patterns match the binary 387 instructions for addM3, subM3,
16183 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16184 ;; SFmode. The first is the normal insn, the second the same insn but
16185 ;; with one operand a conversion, and the third the same insn but with
16186 ;; the other operand a conversion. The conversion may be SFmode or
16187 ;; SImode if the target mode DFmode, but only SImode if the target mode
16190 ;; Gcc is slightly more smart about handling normal two address instructions
16191 ;; so use special patterns for add and mull.
16193 (define_insn "*fop_<mode>_comm_mixed_avx"
16194 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16195 (match_operator:MODEF 3 "binary_fp_operator"
16196 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16197 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16198 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16199 && COMMUTATIVE_ARITH_P (operands[3])
16200 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16201 "* return output_387_binary_op (insn, operands);"
16202 [(set (attr "type")
16203 (if_then_else (eq_attr "alternative" "1")
16204 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16205 (const_string "ssemul")
16206 (const_string "sseadd"))
16207 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16208 (const_string "fmul")
16209 (const_string "fop"))))
16210 (set_attr "prefix" "orig,maybe_vex")
16211 (set_attr "mode" "<MODE>")])
16213 (define_insn "*fop_<mode>_comm_mixed"
16214 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16215 (match_operator:MODEF 3 "binary_fp_operator"
16216 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16217 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16218 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16219 && COMMUTATIVE_ARITH_P (operands[3])
16220 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16221 "* return output_387_binary_op (insn, operands);"
16222 [(set (attr "type")
16223 (if_then_else (eq_attr "alternative" "1")
16224 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16225 (const_string "ssemul")
16226 (const_string "sseadd"))
16227 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16228 (const_string "fmul")
16229 (const_string "fop"))))
16230 (set_attr "mode" "<MODE>")])
16232 (define_insn "*fop_<mode>_comm_avx"
16233 [(set (match_operand:MODEF 0 "register_operand" "=x")
16234 (match_operator:MODEF 3 "binary_fp_operator"
16235 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16236 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16237 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16238 && COMMUTATIVE_ARITH_P (operands[3])
16239 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16240 "* return output_387_binary_op (insn, operands);"
16241 [(set (attr "type")
16242 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16243 (const_string "ssemul")
16244 (const_string "sseadd")))
16245 (set_attr "prefix" "vex")
16246 (set_attr "mode" "<MODE>")])
16248 (define_insn "*fop_<mode>_comm_sse"
16249 [(set (match_operand:MODEF 0 "register_operand" "=x")
16250 (match_operator:MODEF 3 "binary_fp_operator"
16251 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16252 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16253 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16254 && COMMUTATIVE_ARITH_P (operands[3])
16255 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16256 "* return output_387_binary_op (insn, operands);"
16257 [(set (attr "type")
16258 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16259 (const_string "ssemul")
16260 (const_string "sseadd")))
16261 (set_attr "mode" "<MODE>")])
16263 (define_insn "*fop_<mode>_comm_i387"
16264 [(set (match_operand:MODEF 0 "register_operand" "=f")
16265 (match_operator:MODEF 3 "binary_fp_operator"
16266 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16267 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16269 && COMMUTATIVE_ARITH_P (operands[3])
16270 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16271 "* return output_387_binary_op (insn, operands);"
16272 [(set (attr "type")
16273 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16274 (const_string "fmul")
16275 (const_string "fop")))
16276 (set_attr "mode" "<MODE>")])
16278 (define_insn "*fop_<mode>_1_mixed_avx"
16279 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16280 (match_operator:MODEF 3 "binary_fp_operator"
16281 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16282 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16283 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16284 && !COMMUTATIVE_ARITH_P (operands[3])
16285 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16286 "* return output_387_binary_op (insn, operands);"
16287 [(set (attr "type")
16288 (cond [(and (eq_attr "alternative" "2")
16289 (match_operand:MODEF 3 "mult_operator" ""))
16290 (const_string "ssemul")
16291 (and (eq_attr "alternative" "2")
16292 (match_operand:MODEF 3 "div_operator" ""))
16293 (const_string "ssediv")
16294 (eq_attr "alternative" "2")
16295 (const_string "sseadd")
16296 (match_operand:MODEF 3 "mult_operator" "")
16297 (const_string "fmul")
16298 (match_operand:MODEF 3 "div_operator" "")
16299 (const_string "fdiv")
16301 (const_string "fop")))
16302 (set_attr "prefix" "orig,orig,maybe_vex")
16303 (set_attr "mode" "<MODE>")])
16305 (define_insn "*fop_<mode>_1_mixed"
16306 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16307 (match_operator:MODEF 3 "binary_fp_operator"
16308 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16309 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16310 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16311 && !COMMUTATIVE_ARITH_P (operands[3])
16312 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16313 "* return output_387_binary_op (insn, operands);"
16314 [(set (attr "type")
16315 (cond [(and (eq_attr "alternative" "2")
16316 (match_operand:MODEF 3 "mult_operator" ""))
16317 (const_string "ssemul")
16318 (and (eq_attr "alternative" "2")
16319 (match_operand:MODEF 3 "div_operator" ""))
16320 (const_string "ssediv")
16321 (eq_attr "alternative" "2")
16322 (const_string "sseadd")
16323 (match_operand:MODEF 3 "mult_operator" "")
16324 (const_string "fmul")
16325 (match_operand:MODEF 3 "div_operator" "")
16326 (const_string "fdiv")
16328 (const_string "fop")))
16329 (set_attr "mode" "<MODE>")])
16331 (define_insn "*rcpsf2_sse"
16332 [(set (match_operand:SF 0 "register_operand" "=x")
16333 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16336 "%vrcpss\t{%1, %d0|%d0, %1}"
16337 [(set_attr "type" "sse")
16338 (set_attr "prefix" "maybe_vex")
16339 (set_attr "mode" "SF")])
16341 (define_insn "*fop_<mode>_1_avx"
16342 [(set (match_operand:MODEF 0 "register_operand" "=x")
16343 (match_operator:MODEF 3 "binary_fp_operator"
16344 [(match_operand:MODEF 1 "register_operand" "x")
16345 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16346 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16347 && !COMMUTATIVE_ARITH_P (operands[3])"
16348 "* return output_387_binary_op (insn, operands);"
16349 [(set (attr "type")
16350 (cond [(match_operand:MODEF 3 "mult_operator" "")
16351 (const_string "ssemul")
16352 (match_operand:MODEF 3 "div_operator" "")
16353 (const_string "ssediv")
16355 (const_string "sseadd")))
16356 (set_attr "prefix" "vex")
16357 (set_attr "mode" "<MODE>")])
16359 (define_insn "*fop_<mode>_1_sse"
16360 [(set (match_operand:MODEF 0 "register_operand" "=x")
16361 (match_operator:MODEF 3 "binary_fp_operator"
16362 [(match_operand:MODEF 1 "register_operand" "0")
16363 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16364 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16365 && !COMMUTATIVE_ARITH_P (operands[3])"
16366 "* return output_387_binary_op (insn, operands);"
16367 [(set (attr "type")
16368 (cond [(match_operand:MODEF 3 "mult_operator" "")
16369 (const_string "ssemul")
16370 (match_operand:MODEF 3 "div_operator" "")
16371 (const_string "ssediv")
16373 (const_string "sseadd")))
16374 (set_attr "mode" "<MODE>")])
16376 ;; This pattern is not fully shadowed by the pattern above.
16377 (define_insn "*fop_<mode>_1_i387"
16378 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16379 (match_operator:MODEF 3 "binary_fp_operator"
16380 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16381 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16382 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16383 && !COMMUTATIVE_ARITH_P (operands[3])
16384 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16385 "* return output_387_binary_op (insn, operands);"
16386 [(set (attr "type")
16387 (cond [(match_operand:MODEF 3 "mult_operator" "")
16388 (const_string "fmul")
16389 (match_operand:MODEF 3 "div_operator" "")
16390 (const_string "fdiv")
16392 (const_string "fop")))
16393 (set_attr "mode" "<MODE>")])
16395 ;; ??? Add SSE splitters for these!
16396 (define_insn "*fop_<MODEF:mode>_2_i387"
16397 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16398 (match_operator:MODEF 3 "binary_fp_operator"
16400 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16401 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16402 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16403 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16404 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16405 [(set (attr "type")
16406 (cond [(match_operand:MODEF 3 "mult_operator" "")
16407 (const_string "fmul")
16408 (match_operand:MODEF 3 "div_operator" "")
16409 (const_string "fdiv")
16411 (const_string "fop")))
16412 (set_attr "fp_int_src" "true")
16413 (set_attr "mode" "<X87MODEI12:MODE>")])
16415 (define_insn "*fop_<MODEF:mode>_3_i387"
16416 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16417 (match_operator:MODEF 3 "binary_fp_operator"
16418 [(match_operand:MODEF 1 "register_operand" "0,0")
16420 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16421 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16422 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16423 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16424 [(set (attr "type")
16425 (cond [(match_operand:MODEF 3 "mult_operator" "")
16426 (const_string "fmul")
16427 (match_operand:MODEF 3 "div_operator" "")
16428 (const_string "fdiv")
16430 (const_string "fop")))
16431 (set_attr "fp_int_src" "true")
16432 (set_attr "mode" "<MODE>")])
16434 (define_insn "*fop_df_4_i387"
16435 [(set (match_operand:DF 0 "register_operand" "=f,f")
16436 (match_operator:DF 3 "binary_fp_operator"
16438 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16439 (match_operand:DF 2 "register_operand" "0,f")]))]
16440 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16441 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16442 "* return output_387_binary_op (insn, operands);"
16443 [(set (attr "type")
16444 (cond [(match_operand:DF 3 "mult_operator" "")
16445 (const_string "fmul")
16446 (match_operand:DF 3 "div_operator" "")
16447 (const_string "fdiv")
16449 (const_string "fop")))
16450 (set_attr "mode" "SF")])
16452 (define_insn "*fop_df_5_i387"
16453 [(set (match_operand:DF 0 "register_operand" "=f,f")
16454 (match_operator:DF 3 "binary_fp_operator"
16455 [(match_operand:DF 1 "register_operand" "0,f")
16457 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16458 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16459 "* return output_387_binary_op (insn, operands);"
16460 [(set (attr "type")
16461 (cond [(match_operand:DF 3 "mult_operator" "")
16462 (const_string "fmul")
16463 (match_operand:DF 3 "div_operator" "")
16464 (const_string "fdiv")
16466 (const_string "fop")))
16467 (set_attr "mode" "SF")])
16469 (define_insn "*fop_df_6_i387"
16470 [(set (match_operand:DF 0 "register_operand" "=f,f")
16471 (match_operator:DF 3 "binary_fp_operator"
16473 (match_operand:SF 1 "register_operand" "0,f"))
16475 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16476 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16477 "* return output_387_binary_op (insn, operands);"
16478 [(set (attr "type")
16479 (cond [(match_operand:DF 3 "mult_operator" "")
16480 (const_string "fmul")
16481 (match_operand:DF 3 "div_operator" "")
16482 (const_string "fdiv")
16484 (const_string "fop")))
16485 (set_attr "mode" "SF")])
16487 (define_insn "*fop_xf_comm_i387"
16488 [(set (match_operand:XF 0 "register_operand" "=f")
16489 (match_operator:XF 3 "binary_fp_operator"
16490 [(match_operand:XF 1 "register_operand" "%0")
16491 (match_operand:XF 2 "register_operand" "f")]))]
16493 && COMMUTATIVE_ARITH_P (operands[3])"
16494 "* return output_387_binary_op (insn, operands);"
16495 [(set (attr "type")
16496 (if_then_else (match_operand:XF 3 "mult_operator" "")
16497 (const_string "fmul")
16498 (const_string "fop")))
16499 (set_attr "mode" "XF")])
16501 (define_insn "*fop_xf_1_i387"
16502 [(set (match_operand:XF 0 "register_operand" "=f,f")
16503 (match_operator:XF 3 "binary_fp_operator"
16504 [(match_operand:XF 1 "register_operand" "0,f")
16505 (match_operand:XF 2 "register_operand" "f,0")]))]
16507 && !COMMUTATIVE_ARITH_P (operands[3])"
16508 "* return output_387_binary_op (insn, operands);"
16509 [(set (attr "type")
16510 (cond [(match_operand:XF 3 "mult_operator" "")
16511 (const_string "fmul")
16512 (match_operand:XF 3 "div_operator" "")
16513 (const_string "fdiv")
16515 (const_string "fop")))
16516 (set_attr "mode" "XF")])
16518 (define_insn "*fop_xf_2_i387"
16519 [(set (match_operand:XF 0 "register_operand" "=f,f")
16520 (match_operator:XF 3 "binary_fp_operator"
16522 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16523 (match_operand:XF 2 "register_operand" "0,0")]))]
16524 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16525 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16526 [(set (attr "type")
16527 (cond [(match_operand:XF 3 "mult_operator" "")
16528 (const_string "fmul")
16529 (match_operand:XF 3 "div_operator" "")
16530 (const_string "fdiv")
16532 (const_string "fop")))
16533 (set_attr "fp_int_src" "true")
16534 (set_attr "mode" "<MODE>")])
16536 (define_insn "*fop_xf_3_i387"
16537 [(set (match_operand:XF 0 "register_operand" "=f,f")
16538 (match_operator:XF 3 "binary_fp_operator"
16539 [(match_operand:XF 1 "register_operand" "0,0")
16541 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16542 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16543 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16544 [(set (attr "type")
16545 (cond [(match_operand:XF 3 "mult_operator" "")
16546 (const_string "fmul")
16547 (match_operand:XF 3 "div_operator" "")
16548 (const_string "fdiv")
16550 (const_string "fop")))
16551 (set_attr "fp_int_src" "true")
16552 (set_attr "mode" "<MODE>")])
16554 (define_insn "*fop_xf_4_i387"
16555 [(set (match_operand:XF 0 "register_operand" "=f,f")
16556 (match_operator:XF 3 "binary_fp_operator"
16558 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16559 (match_operand:XF 2 "register_operand" "0,f")]))]
16561 "* return output_387_binary_op (insn, operands);"
16562 [(set (attr "type")
16563 (cond [(match_operand:XF 3 "mult_operator" "")
16564 (const_string "fmul")
16565 (match_operand:XF 3 "div_operator" "")
16566 (const_string "fdiv")
16568 (const_string "fop")))
16569 (set_attr "mode" "<MODE>")])
16571 (define_insn "*fop_xf_5_i387"
16572 [(set (match_operand:XF 0 "register_operand" "=f,f")
16573 (match_operator:XF 3 "binary_fp_operator"
16574 [(match_operand:XF 1 "register_operand" "0,f")
16576 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16578 "* return output_387_binary_op (insn, operands);"
16579 [(set (attr "type")
16580 (cond [(match_operand:XF 3 "mult_operator" "")
16581 (const_string "fmul")
16582 (match_operand:XF 3 "div_operator" "")
16583 (const_string "fdiv")
16585 (const_string "fop")))
16586 (set_attr "mode" "<MODE>")])
16588 (define_insn "*fop_xf_6_i387"
16589 [(set (match_operand:XF 0 "register_operand" "=f,f")
16590 (match_operator:XF 3 "binary_fp_operator"
16592 (match_operand:MODEF 1 "register_operand" "0,f"))
16594 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16596 "* return output_387_binary_op (insn, operands);"
16597 [(set (attr "type")
16598 (cond [(match_operand:XF 3 "mult_operator" "")
16599 (const_string "fmul")
16600 (match_operand:XF 3 "div_operator" "")
16601 (const_string "fdiv")
16603 (const_string "fop")))
16604 (set_attr "mode" "<MODE>")])
16607 [(set (match_operand 0 "register_operand" "")
16608 (match_operator 3 "binary_fp_operator"
16609 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16610 (match_operand 2 "register_operand" "")]))]
16612 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16615 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16616 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16617 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16618 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16619 GET_MODE (operands[3]),
16622 ix86_free_from_memory (GET_MODE (operands[1]));
16627 [(set (match_operand 0 "register_operand" "")
16628 (match_operator 3 "binary_fp_operator"
16629 [(match_operand 1 "register_operand" "")
16630 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16632 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16635 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16636 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16637 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16638 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16639 GET_MODE (operands[3]),
16642 ix86_free_from_memory (GET_MODE (operands[2]));
16646 ;; FPU special functions.
16648 ;; This pattern implements a no-op XFmode truncation for
16649 ;; all fancy i386 XFmode math functions.
16651 (define_insn "truncxf<mode>2_i387_noop_unspec"
16652 [(set (match_operand:MODEF 0 "register_operand" "=f")
16653 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16654 UNSPEC_TRUNC_NOOP))]
16655 "TARGET_USE_FANCY_MATH_387"
16656 "* return output_387_reg_move (insn, operands);"
16657 [(set_attr "type" "fmov")
16658 (set_attr "mode" "<MODE>")])
16660 (define_insn "sqrtxf2"
16661 [(set (match_operand:XF 0 "register_operand" "=f")
16662 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16663 "TARGET_USE_FANCY_MATH_387"
16665 [(set_attr "type" "fpspc")
16666 (set_attr "mode" "XF")
16667 (set_attr "athlon_decode" "direct")
16668 (set_attr "amdfam10_decode" "direct")])
16670 (define_insn "sqrt_extend<mode>xf2_i387"
16671 [(set (match_operand:XF 0 "register_operand" "=f")
16674 (match_operand:MODEF 1 "register_operand" "0"))))]
16675 "TARGET_USE_FANCY_MATH_387"
16677 [(set_attr "type" "fpspc")
16678 (set_attr "mode" "XF")
16679 (set_attr "athlon_decode" "direct")
16680 (set_attr "amdfam10_decode" "direct")])
16682 (define_insn "*rsqrtsf2_sse"
16683 [(set (match_operand:SF 0 "register_operand" "=x")
16684 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16687 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16688 [(set_attr "type" "sse")
16689 (set_attr "prefix" "maybe_vex")
16690 (set_attr "mode" "SF")])
16692 (define_expand "rsqrtsf2"
16693 [(set (match_operand:SF 0 "register_operand" "")
16694 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16698 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16702 (define_insn "*sqrt<mode>2_sse"
16703 [(set (match_operand:MODEF 0 "register_operand" "=x")
16705 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16706 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16707 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16708 [(set_attr "type" "sse")
16709 (set_attr "prefix" "maybe_vex")
16710 (set_attr "mode" "<MODE>")
16711 (set_attr "athlon_decode" "*")
16712 (set_attr "amdfam10_decode" "*")])
16714 (define_expand "sqrt<mode>2"
16715 [(set (match_operand:MODEF 0 "register_operand" "")
16717 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16718 "TARGET_USE_FANCY_MATH_387
16719 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16721 if (<MODE>mode == SFmode
16722 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16723 && flag_finite_math_only && !flag_trapping_math
16724 && flag_unsafe_math_optimizations)
16726 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16730 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16732 rtx op0 = gen_reg_rtx (XFmode);
16733 rtx op1 = force_reg (<MODE>mode, operands[1]);
16735 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16736 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16741 (define_insn "fpremxf4_i387"
16742 [(set (match_operand:XF 0 "register_operand" "=f")
16743 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16744 (match_operand:XF 3 "register_operand" "1")]
16746 (set (match_operand:XF 1 "register_operand" "=u")
16747 (unspec:XF [(match_dup 2) (match_dup 3)]
16749 (set (reg:CCFP FPSR_REG)
16750 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16752 "TARGET_USE_FANCY_MATH_387"
16754 [(set_attr "type" "fpspc")
16755 (set_attr "mode" "XF")])
16757 (define_expand "fmodxf3"
16758 [(use (match_operand:XF 0 "register_operand" ""))
16759 (use (match_operand:XF 1 "general_operand" ""))
16760 (use (match_operand:XF 2 "general_operand" ""))]
16761 "TARGET_USE_FANCY_MATH_387"
16763 rtx label = gen_label_rtx ();
16765 rtx op1 = gen_reg_rtx (XFmode);
16766 rtx op2 = gen_reg_rtx (XFmode);
16768 emit_move_insn (op2, operands[2]);
16769 emit_move_insn (op1, operands[1]);
16771 emit_label (label);
16772 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16773 ix86_emit_fp_unordered_jump (label);
16774 LABEL_NUSES (label) = 1;
16776 emit_move_insn (operands[0], op1);
16780 (define_expand "fmod<mode>3"
16781 [(use (match_operand:MODEF 0 "register_operand" ""))
16782 (use (match_operand:MODEF 1 "general_operand" ""))
16783 (use (match_operand:MODEF 2 "general_operand" ""))]
16784 "TARGET_USE_FANCY_MATH_387"
16786 rtx label = gen_label_rtx ();
16788 rtx op1 = gen_reg_rtx (XFmode);
16789 rtx op2 = gen_reg_rtx (XFmode);
16791 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16792 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16794 emit_label (label);
16795 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16796 ix86_emit_fp_unordered_jump (label);
16797 LABEL_NUSES (label) = 1;
16799 /* Truncate the result properly for strict SSE math. */
16800 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16801 && !TARGET_MIX_SSE_I387)
16802 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16804 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16809 (define_insn "fprem1xf4_i387"
16810 [(set (match_operand:XF 0 "register_operand" "=f")
16811 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16812 (match_operand:XF 3 "register_operand" "1")]
16814 (set (match_operand:XF 1 "register_operand" "=u")
16815 (unspec:XF [(match_dup 2) (match_dup 3)]
16817 (set (reg:CCFP FPSR_REG)
16818 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16820 "TARGET_USE_FANCY_MATH_387"
16822 [(set_attr "type" "fpspc")
16823 (set_attr "mode" "XF")])
16825 (define_expand "remainderxf3"
16826 [(use (match_operand:XF 0 "register_operand" ""))
16827 (use (match_operand:XF 1 "general_operand" ""))
16828 (use (match_operand:XF 2 "general_operand" ""))]
16829 "TARGET_USE_FANCY_MATH_387"
16831 rtx label = gen_label_rtx ();
16833 rtx op1 = gen_reg_rtx (XFmode);
16834 rtx op2 = gen_reg_rtx (XFmode);
16836 emit_move_insn (op2, operands[2]);
16837 emit_move_insn (op1, operands[1]);
16839 emit_label (label);
16840 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16841 ix86_emit_fp_unordered_jump (label);
16842 LABEL_NUSES (label) = 1;
16844 emit_move_insn (operands[0], op1);
16848 (define_expand "remainder<mode>3"
16849 [(use (match_operand:MODEF 0 "register_operand" ""))
16850 (use (match_operand:MODEF 1 "general_operand" ""))
16851 (use (match_operand:MODEF 2 "general_operand" ""))]
16852 "TARGET_USE_FANCY_MATH_387"
16854 rtx label = gen_label_rtx ();
16856 rtx op1 = gen_reg_rtx (XFmode);
16857 rtx op2 = gen_reg_rtx (XFmode);
16859 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16860 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16862 emit_label (label);
16864 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16865 ix86_emit_fp_unordered_jump (label);
16866 LABEL_NUSES (label) = 1;
16868 /* Truncate the result properly for strict SSE math. */
16869 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16870 && !TARGET_MIX_SSE_I387)
16871 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16873 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16878 (define_insn "*sinxf2_i387"
16879 [(set (match_operand:XF 0 "register_operand" "=f")
16880 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16881 "TARGET_USE_FANCY_MATH_387
16882 && flag_unsafe_math_optimizations"
16884 [(set_attr "type" "fpspc")
16885 (set_attr "mode" "XF")])
16887 (define_insn "*sin_extend<mode>xf2_i387"
16888 [(set (match_operand:XF 0 "register_operand" "=f")
16889 (unspec:XF [(float_extend:XF
16890 (match_operand:MODEF 1 "register_operand" "0"))]
16892 "TARGET_USE_FANCY_MATH_387
16893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16894 || TARGET_MIX_SSE_I387)
16895 && flag_unsafe_math_optimizations"
16897 [(set_attr "type" "fpspc")
16898 (set_attr "mode" "XF")])
16900 (define_insn "*cosxf2_i387"
16901 [(set (match_operand:XF 0 "register_operand" "=f")
16902 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16903 "TARGET_USE_FANCY_MATH_387
16904 && flag_unsafe_math_optimizations"
16906 [(set_attr "type" "fpspc")
16907 (set_attr "mode" "XF")])
16909 (define_insn "*cos_extend<mode>xf2_i387"
16910 [(set (match_operand:XF 0 "register_operand" "=f")
16911 (unspec:XF [(float_extend:XF
16912 (match_operand:MODEF 1 "register_operand" "0"))]
16914 "TARGET_USE_FANCY_MATH_387
16915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16916 || TARGET_MIX_SSE_I387)
16917 && flag_unsafe_math_optimizations"
16919 [(set_attr "type" "fpspc")
16920 (set_attr "mode" "XF")])
16922 ;; When sincos pattern is defined, sin and cos builtin functions will be
16923 ;; expanded to sincos pattern with one of its outputs left unused.
16924 ;; CSE pass will figure out if two sincos patterns can be combined,
16925 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16926 ;; depending on the unused output.
16928 (define_insn "sincosxf3"
16929 [(set (match_operand:XF 0 "register_operand" "=f")
16930 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16931 UNSPEC_SINCOS_COS))
16932 (set (match_operand:XF 1 "register_operand" "=u")
16933 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16934 "TARGET_USE_FANCY_MATH_387
16935 && flag_unsafe_math_optimizations"
16937 [(set_attr "type" "fpspc")
16938 (set_attr "mode" "XF")])
16941 [(set (match_operand:XF 0 "register_operand" "")
16942 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16943 UNSPEC_SINCOS_COS))
16944 (set (match_operand:XF 1 "register_operand" "")
16945 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16946 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16947 && !(reload_completed || reload_in_progress)"
16948 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16952 [(set (match_operand:XF 0 "register_operand" "")
16953 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16954 UNSPEC_SINCOS_COS))
16955 (set (match_operand:XF 1 "register_operand" "")
16956 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16957 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16958 && !(reload_completed || reload_in_progress)"
16959 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16962 (define_insn "sincos_extend<mode>xf3_i387"
16963 [(set (match_operand:XF 0 "register_operand" "=f")
16964 (unspec:XF [(float_extend:XF
16965 (match_operand:MODEF 2 "register_operand" "0"))]
16966 UNSPEC_SINCOS_COS))
16967 (set (match_operand:XF 1 "register_operand" "=u")
16968 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16969 "TARGET_USE_FANCY_MATH_387
16970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16971 || TARGET_MIX_SSE_I387)
16972 && flag_unsafe_math_optimizations"
16974 [(set_attr "type" "fpspc")
16975 (set_attr "mode" "XF")])
16978 [(set (match_operand:XF 0 "register_operand" "")
16979 (unspec:XF [(float_extend:XF
16980 (match_operand:MODEF 2 "register_operand" ""))]
16981 UNSPEC_SINCOS_COS))
16982 (set (match_operand:XF 1 "register_operand" "")
16983 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16984 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16985 && !(reload_completed || reload_in_progress)"
16986 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16990 [(set (match_operand:XF 0 "register_operand" "")
16991 (unspec:XF [(float_extend:XF
16992 (match_operand:MODEF 2 "register_operand" ""))]
16993 UNSPEC_SINCOS_COS))
16994 (set (match_operand:XF 1 "register_operand" "")
16995 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16996 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16997 && !(reload_completed || reload_in_progress)"
16998 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17001 (define_expand "sincos<mode>3"
17002 [(use (match_operand:MODEF 0 "register_operand" ""))
17003 (use (match_operand:MODEF 1 "register_operand" ""))
17004 (use (match_operand:MODEF 2 "register_operand" ""))]
17005 "TARGET_USE_FANCY_MATH_387
17006 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17007 || TARGET_MIX_SSE_I387)
17008 && flag_unsafe_math_optimizations"
17010 rtx op0 = gen_reg_rtx (XFmode);
17011 rtx op1 = gen_reg_rtx (XFmode);
17013 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17014 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17015 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17019 (define_insn "fptanxf4_i387"
17020 [(set (match_operand:XF 0 "register_operand" "=f")
17021 (match_operand:XF 3 "const_double_operand" "F"))
17022 (set (match_operand:XF 1 "register_operand" "=u")
17023 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17025 "TARGET_USE_FANCY_MATH_387
17026 && flag_unsafe_math_optimizations
17027 && standard_80387_constant_p (operands[3]) == 2"
17029 [(set_attr "type" "fpspc")
17030 (set_attr "mode" "XF")])
17032 (define_insn "fptan_extend<mode>xf4_i387"
17033 [(set (match_operand:MODEF 0 "register_operand" "=f")
17034 (match_operand:MODEF 3 "const_double_operand" "F"))
17035 (set (match_operand:XF 1 "register_operand" "=u")
17036 (unspec:XF [(float_extend:XF
17037 (match_operand:MODEF 2 "register_operand" "0"))]
17039 "TARGET_USE_FANCY_MATH_387
17040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17041 || TARGET_MIX_SSE_I387)
17042 && flag_unsafe_math_optimizations
17043 && standard_80387_constant_p (operands[3]) == 2"
17045 [(set_attr "type" "fpspc")
17046 (set_attr "mode" "XF")])
17048 (define_expand "tanxf2"
17049 [(use (match_operand:XF 0 "register_operand" ""))
17050 (use (match_operand:XF 1 "register_operand" ""))]
17051 "TARGET_USE_FANCY_MATH_387
17052 && flag_unsafe_math_optimizations"
17054 rtx one = gen_reg_rtx (XFmode);
17055 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17057 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17061 (define_expand "tan<mode>2"
17062 [(use (match_operand:MODEF 0 "register_operand" ""))
17063 (use (match_operand:MODEF 1 "register_operand" ""))]
17064 "TARGET_USE_FANCY_MATH_387
17065 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17066 || TARGET_MIX_SSE_I387)
17067 && flag_unsafe_math_optimizations"
17069 rtx op0 = gen_reg_rtx (XFmode);
17071 rtx one = gen_reg_rtx (<MODE>mode);
17072 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17074 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17075 operands[1], op2));
17076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17080 (define_insn "*fpatanxf3_i387"
17081 [(set (match_operand:XF 0 "register_operand" "=f")
17082 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17083 (match_operand:XF 2 "register_operand" "u")]
17085 (clobber (match_scratch:XF 3 "=2"))]
17086 "TARGET_USE_FANCY_MATH_387
17087 && flag_unsafe_math_optimizations"
17089 [(set_attr "type" "fpspc")
17090 (set_attr "mode" "XF")])
17092 (define_insn "fpatan_extend<mode>xf3_i387"
17093 [(set (match_operand:XF 0 "register_operand" "=f")
17094 (unspec:XF [(float_extend:XF
17095 (match_operand:MODEF 1 "register_operand" "0"))
17097 (match_operand:MODEF 2 "register_operand" "u"))]
17099 (clobber (match_scratch:XF 3 "=2"))]
17100 "TARGET_USE_FANCY_MATH_387
17101 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17102 || TARGET_MIX_SSE_I387)
17103 && flag_unsafe_math_optimizations"
17105 [(set_attr "type" "fpspc")
17106 (set_attr "mode" "XF")])
17108 (define_expand "atan2xf3"
17109 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17110 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17111 (match_operand:XF 1 "register_operand" "")]
17113 (clobber (match_scratch:XF 3 ""))])]
17114 "TARGET_USE_FANCY_MATH_387
17115 && flag_unsafe_math_optimizations"
17118 (define_expand "atan2<mode>3"
17119 [(use (match_operand:MODEF 0 "register_operand" ""))
17120 (use (match_operand:MODEF 1 "register_operand" ""))
17121 (use (match_operand:MODEF 2 "register_operand" ""))]
17122 "TARGET_USE_FANCY_MATH_387
17123 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17124 || TARGET_MIX_SSE_I387)
17125 && flag_unsafe_math_optimizations"
17127 rtx op0 = gen_reg_rtx (XFmode);
17129 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17130 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17134 (define_expand "atanxf2"
17135 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17136 (unspec:XF [(match_dup 2)
17137 (match_operand:XF 1 "register_operand" "")]
17139 (clobber (match_scratch:XF 3 ""))])]
17140 "TARGET_USE_FANCY_MATH_387
17141 && flag_unsafe_math_optimizations"
17143 operands[2] = gen_reg_rtx (XFmode);
17144 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17147 (define_expand "atan<mode>2"
17148 [(use (match_operand:MODEF 0 "register_operand" ""))
17149 (use (match_operand:MODEF 1 "register_operand" ""))]
17150 "TARGET_USE_FANCY_MATH_387
17151 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17152 || TARGET_MIX_SSE_I387)
17153 && flag_unsafe_math_optimizations"
17155 rtx op0 = gen_reg_rtx (XFmode);
17157 rtx op2 = gen_reg_rtx (<MODE>mode);
17158 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17160 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17165 (define_expand "asinxf2"
17166 [(set (match_dup 2)
17167 (mult:XF (match_operand:XF 1 "register_operand" "")
17169 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17170 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17171 (parallel [(set (match_operand:XF 0 "register_operand" "")
17172 (unspec:XF [(match_dup 5) (match_dup 1)]
17174 (clobber (match_scratch:XF 6 ""))])]
17175 "TARGET_USE_FANCY_MATH_387
17176 && flag_unsafe_math_optimizations"
17180 if (optimize_insn_for_size_p ())
17183 for (i = 2; i < 6; i++)
17184 operands[i] = gen_reg_rtx (XFmode);
17186 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17189 (define_expand "asin<mode>2"
17190 [(use (match_operand:MODEF 0 "register_operand" ""))
17191 (use (match_operand:MODEF 1 "general_operand" ""))]
17192 "TARGET_USE_FANCY_MATH_387
17193 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17194 || TARGET_MIX_SSE_I387)
17195 && flag_unsafe_math_optimizations"
17197 rtx op0 = gen_reg_rtx (XFmode);
17198 rtx op1 = gen_reg_rtx (XFmode);
17200 if (optimize_insn_for_size_p ())
17203 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17204 emit_insn (gen_asinxf2 (op0, op1));
17205 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17209 (define_expand "acosxf2"
17210 [(set (match_dup 2)
17211 (mult:XF (match_operand:XF 1 "register_operand" "")
17213 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17214 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17215 (parallel [(set (match_operand:XF 0 "register_operand" "")
17216 (unspec:XF [(match_dup 1) (match_dup 5)]
17218 (clobber (match_scratch:XF 6 ""))])]
17219 "TARGET_USE_FANCY_MATH_387
17220 && flag_unsafe_math_optimizations"
17224 if (optimize_insn_for_size_p ())
17227 for (i = 2; i < 6; i++)
17228 operands[i] = gen_reg_rtx (XFmode);
17230 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17233 (define_expand "acos<mode>2"
17234 [(use (match_operand:MODEF 0 "register_operand" ""))
17235 (use (match_operand:MODEF 1 "general_operand" ""))]
17236 "TARGET_USE_FANCY_MATH_387
17237 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17238 || TARGET_MIX_SSE_I387)
17239 && flag_unsafe_math_optimizations"
17241 rtx op0 = gen_reg_rtx (XFmode);
17242 rtx op1 = gen_reg_rtx (XFmode);
17244 if (optimize_insn_for_size_p ())
17247 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17248 emit_insn (gen_acosxf2 (op0, op1));
17249 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17253 (define_insn "fyl2xxf3_i387"
17254 [(set (match_operand:XF 0 "register_operand" "=f")
17255 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17256 (match_operand:XF 2 "register_operand" "u")]
17258 (clobber (match_scratch:XF 3 "=2"))]
17259 "TARGET_USE_FANCY_MATH_387
17260 && flag_unsafe_math_optimizations"
17262 [(set_attr "type" "fpspc")
17263 (set_attr "mode" "XF")])
17265 (define_insn "fyl2x_extend<mode>xf3_i387"
17266 [(set (match_operand:XF 0 "register_operand" "=f")
17267 (unspec:XF [(float_extend:XF
17268 (match_operand:MODEF 1 "register_operand" "0"))
17269 (match_operand:XF 2 "register_operand" "u")]
17271 (clobber (match_scratch:XF 3 "=2"))]
17272 "TARGET_USE_FANCY_MATH_387
17273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17274 || TARGET_MIX_SSE_I387)
17275 && flag_unsafe_math_optimizations"
17277 [(set_attr "type" "fpspc")
17278 (set_attr "mode" "XF")])
17280 (define_expand "logxf2"
17281 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17282 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17283 (match_dup 2)] UNSPEC_FYL2X))
17284 (clobber (match_scratch:XF 3 ""))])]
17285 "TARGET_USE_FANCY_MATH_387
17286 && flag_unsafe_math_optimizations"
17288 operands[2] = gen_reg_rtx (XFmode);
17289 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17292 (define_expand "log<mode>2"
17293 [(use (match_operand:MODEF 0 "register_operand" ""))
17294 (use (match_operand:MODEF 1 "register_operand" ""))]
17295 "TARGET_USE_FANCY_MATH_387
17296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17297 || TARGET_MIX_SSE_I387)
17298 && flag_unsafe_math_optimizations"
17300 rtx op0 = gen_reg_rtx (XFmode);
17302 rtx op2 = gen_reg_rtx (XFmode);
17303 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17305 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17306 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17310 (define_expand "log10xf2"
17311 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17312 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17313 (match_dup 2)] UNSPEC_FYL2X))
17314 (clobber (match_scratch:XF 3 ""))])]
17315 "TARGET_USE_FANCY_MATH_387
17316 && flag_unsafe_math_optimizations"
17318 operands[2] = gen_reg_rtx (XFmode);
17319 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17322 (define_expand "log10<mode>2"
17323 [(use (match_operand:MODEF 0 "register_operand" ""))
17324 (use (match_operand:MODEF 1 "register_operand" ""))]
17325 "TARGET_USE_FANCY_MATH_387
17326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17327 || TARGET_MIX_SSE_I387)
17328 && flag_unsafe_math_optimizations"
17330 rtx op0 = gen_reg_rtx (XFmode);
17332 rtx op2 = gen_reg_rtx (XFmode);
17333 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17335 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17336 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17340 (define_expand "log2xf2"
17341 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17342 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17343 (match_dup 2)] UNSPEC_FYL2X))
17344 (clobber (match_scratch:XF 3 ""))])]
17345 "TARGET_USE_FANCY_MATH_387
17346 && flag_unsafe_math_optimizations"
17348 operands[2] = gen_reg_rtx (XFmode);
17349 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17352 (define_expand "log2<mode>2"
17353 [(use (match_operand:MODEF 0 "register_operand" ""))
17354 (use (match_operand:MODEF 1 "register_operand" ""))]
17355 "TARGET_USE_FANCY_MATH_387
17356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17357 || TARGET_MIX_SSE_I387)
17358 && flag_unsafe_math_optimizations"
17360 rtx op0 = gen_reg_rtx (XFmode);
17362 rtx op2 = gen_reg_rtx (XFmode);
17363 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17365 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17366 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17370 (define_insn "fyl2xp1xf3_i387"
17371 [(set (match_operand:XF 0 "register_operand" "=f")
17372 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17373 (match_operand:XF 2 "register_operand" "u")]
17375 (clobber (match_scratch:XF 3 "=2"))]
17376 "TARGET_USE_FANCY_MATH_387
17377 && flag_unsafe_math_optimizations"
17379 [(set_attr "type" "fpspc")
17380 (set_attr "mode" "XF")])
17382 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17383 [(set (match_operand:XF 0 "register_operand" "=f")
17384 (unspec:XF [(float_extend:XF
17385 (match_operand:MODEF 1 "register_operand" "0"))
17386 (match_operand:XF 2 "register_operand" "u")]
17388 (clobber (match_scratch:XF 3 "=2"))]
17389 "TARGET_USE_FANCY_MATH_387
17390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17391 || TARGET_MIX_SSE_I387)
17392 && flag_unsafe_math_optimizations"
17394 [(set_attr "type" "fpspc")
17395 (set_attr "mode" "XF")])
17397 (define_expand "log1pxf2"
17398 [(use (match_operand:XF 0 "register_operand" ""))
17399 (use (match_operand:XF 1 "register_operand" ""))]
17400 "TARGET_USE_FANCY_MATH_387
17401 && flag_unsafe_math_optimizations"
17403 if (optimize_insn_for_size_p ())
17406 ix86_emit_i387_log1p (operands[0], operands[1]);
17410 (define_expand "log1p<mode>2"
17411 [(use (match_operand:MODEF 0 "register_operand" ""))
17412 (use (match_operand:MODEF 1 "register_operand" ""))]
17413 "TARGET_USE_FANCY_MATH_387
17414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17415 || TARGET_MIX_SSE_I387)
17416 && flag_unsafe_math_optimizations"
17420 if (optimize_insn_for_size_p ())
17423 op0 = gen_reg_rtx (XFmode);
17425 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17427 ix86_emit_i387_log1p (op0, operands[1]);
17428 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17432 (define_insn "fxtractxf3_i387"
17433 [(set (match_operand:XF 0 "register_operand" "=f")
17434 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17435 UNSPEC_XTRACT_FRACT))
17436 (set (match_operand:XF 1 "register_operand" "=u")
17437 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17438 "TARGET_USE_FANCY_MATH_387
17439 && flag_unsafe_math_optimizations"
17441 [(set_attr "type" "fpspc")
17442 (set_attr "mode" "XF")])
17444 (define_insn "fxtract_extend<mode>xf3_i387"
17445 [(set (match_operand:XF 0 "register_operand" "=f")
17446 (unspec:XF [(float_extend:XF
17447 (match_operand:MODEF 2 "register_operand" "0"))]
17448 UNSPEC_XTRACT_FRACT))
17449 (set (match_operand:XF 1 "register_operand" "=u")
17450 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17451 "TARGET_USE_FANCY_MATH_387
17452 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17453 || TARGET_MIX_SSE_I387)
17454 && flag_unsafe_math_optimizations"
17456 [(set_attr "type" "fpspc")
17457 (set_attr "mode" "XF")])
17459 (define_expand "logbxf2"
17460 [(parallel [(set (match_dup 2)
17461 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17462 UNSPEC_XTRACT_FRACT))
17463 (set (match_operand:XF 0 "register_operand" "")
17464 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17465 "TARGET_USE_FANCY_MATH_387
17466 && flag_unsafe_math_optimizations"
17468 operands[2] = gen_reg_rtx (XFmode);
17471 (define_expand "logb<mode>2"
17472 [(use (match_operand:MODEF 0 "register_operand" ""))
17473 (use (match_operand:MODEF 1 "register_operand" ""))]
17474 "TARGET_USE_FANCY_MATH_387
17475 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17476 || TARGET_MIX_SSE_I387)
17477 && flag_unsafe_math_optimizations"
17479 rtx op0 = gen_reg_rtx (XFmode);
17480 rtx op1 = gen_reg_rtx (XFmode);
17482 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17483 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17487 (define_expand "ilogbxf2"
17488 [(use (match_operand:SI 0 "register_operand" ""))
17489 (use (match_operand:XF 1 "register_operand" ""))]
17490 "TARGET_USE_FANCY_MATH_387
17491 && flag_unsafe_math_optimizations"
17495 if (optimize_insn_for_size_p ())
17498 op0 = gen_reg_rtx (XFmode);
17499 op1 = gen_reg_rtx (XFmode);
17501 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17502 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17506 (define_expand "ilogb<mode>2"
17507 [(use (match_operand:SI 0 "register_operand" ""))
17508 (use (match_operand:MODEF 1 "register_operand" ""))]
17509 "TARGET_USE_FANCY_MATH_387
17510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17511 || TARGET_MIX_SSE_I387)
17512 && flag_unsafe_math_optimizations"
17516 if (optimize_insn_for_size_p ())
17519 op0 = gen_reg_rtx (XFmode);
17520 op1 = gen_reg_rtx (XFmode);
17522 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17523 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17527 (define_insn "*f2xm1xf2_i387"
17528 [(set (match_operand:XF 0 "register_operand" "=f")
17529 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17531 "TARGET_USE_FANCY_MATH_387
17532 && flag_unsafe_math_optimizations"
17534 [(set_attr "type" "fpspc")
17535 (set_attr "mode" "XF")])
17537 (define_insn "*fscalexf4_i387"
17538 [(set (match_operand:XF 0 "register_operand" "=f")
17539 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17540 (match_operand:XF 3 "register_operand" "1")]
17541 UNSPEC_FSCALE_FRACT))
17542 (set (match_operand:XF 1 "register_operand" "=u")
17543 (unspec:XF [(match_dup 2) (match_dup 3)]
17544 UNSPEC_FSCALE_EXP))]
17545 "TARGET_USE_FANCY_MATH_387
17546 && flag_unsafe_math_optimizations"
17548 [(set_attr "type" "fpspc")
17549 (set_attr "mode" "XF")])
17551 (define_expand "expNcorexf3"
17552 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17553 (match_operand:XF 2 "register_operand" "")))
17554 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17555 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17556 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17557 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17558 (parallel [(set (match_operand:XF 0 "register_operand" "")
17559 (unspec:XF [(match_dup 8) (match_dup 4)]
17560 UNSPEC_FSCALE_FRACT))
17562 (unspec:XF [(match_dup 8) (match_dup 4)]
17563 UNSPEC_FSCALE_EXP))])]
17564 "TARGET_USE_FANCY_MATH_387
17565 && flag_unsafe_math_optimizations"
17569 if (optimize_insn_for_size_p ())
17572 for (i = 3; i < 10; i++)
17573 operands[i] = gen_reg_rtx (XFmode);
17575 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17578 (define_expand "expxf2"
17579 [(use (match_operand:XF 0 "register_operand" ""))
17580 (use (match_operand:XF 1 "register_operand" ""))]
17581 "TARGET_USE_FANCY_MATH_387
17582 && flag_unsafe_math_optimizations"
17586 if (optimize_insn_for_size_p ())
17589 op2 = gen_reg_rtx (XFmode);
17590 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17592 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17596 (define_expand "exp<mode>2"
17597 [(use (match_operand:MODEF 0 "register_operand" ""))
17598 (use (match_operand:MODEF 1 "general_operand" ""))]
17599 "TARGET_USE_FANCY_MATH_387
17600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17601 || TARGET_MIX_SSE_I387)
17602 && flag_unsafe_math_optimizations"
17606 if (optimize_insn_for_size_p ())
17609 op0 = gen_reg_rtx (XFmode);
17610 op1 = gen_reg_rtx (XFmode);
17612 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17613 emit_insn (gen_expxf2 (op0, op1));
17614 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17618 (define_expand "exp10xf2"
17619 [(use (match_operand:XF 0 "register_operand" ""))
17620 (use (match_operand:XF 1 "register_operand" ""))]
17621 "TARGET_USE_FANCY_MATH_387
17622 && flag_unsafe_math_optimizations"
17626 if (optimize_insn_for_size_p ())
17629 op2 = gen_reg_rtx (XFmode);
17630 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17632 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17636 (define_expand "exp10<mode>2"
17637 [(use (match_operand:MODEF 0 "register_operand" ""))
17638 (use (match_operand:MODEF 1 "general_operand" ""))]
17639 "TARGET_USE_FANCY_MATH_387
17640 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17641 || TARGET_MIX_SSE_I387)
17642 && flag_unsafe_math_optimizations"
17646 if (optimize_insn_for_size_p ())
17649 op0 = gen_reg_rtx (XFmode);
17650 op1 = gen_reg_rtx (XFmode);
17652 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17653 emit_insn (gen_exp10xf2 (op0, op1));
17654 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17658 (define_expand "exp2xf2"
17659 [(use (match_operand:XF 0 "register_operand" ""))
17660 (use (match_operand:XF 1 "register_operand" ""))]
17661 "TARGET_USE_FANCY_MATH_387
17662 && flag_unsafe_math_optimizations"
17666 if (optimize_insn_for_size_p ())
17669 op2 = gen_reg_rtx (XFmode);
17670 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17672 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17676 (define_expand "exp2<mode>2"
17677 [(use (match_operand:MODEF 0 "register_operand" ""))
17678 (use (match_operand:MODEF 1 "general_operand" ""))]
17679 "TARGET_USE_FANCY_MATH_387
17680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17681 || TARGET_MIX_SSE_I387)
17682 && flag_unsafe_math_optimizations"
17686 if (optimize_insn_for_size_p ())
17689 op0 = gen_reg_rtx (XFmode);
17690 op1 = gen_reg_rtx (XFmode);
17692 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17693 emit_insn (gen_exp2xf2 (op0, op1));
17694 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17698 (define_expand "expm1xf2"
17699 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17701 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17702 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17703 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17704 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17705 (parallel [(set (match_dup 7)
17706 (unspec:XF [(match_dup 6) (match_dup 4)]
17707 UNSPEC_FSCALE_FRACT))
17709 (unspec:XF [(match_dup 6) (match_dup 4)]
17710 UNSPEC_FSCALE_EXP))])
17711 (parallel [(set (match_dup 10)
17712 (unspec:XF [(match_dup 9) (match_dup 8)]
17713 UNSPEC_FSCALE_FRACT))
17714 (set (match_dup 11)
17715 (unspec:XF [(match_dup 9) (match_dup 8)]
17716 UNSPEC_FSCALE_EXP))])
17717 (set (match_dup 12) (minus:XF (match_dup 10)
17718 (float_extend:XF (match_dup 13))))
17719 (set (match_operand:XF 0 "register_operand" "")
17720 (plus:XF (match_dup 12) (match_dup 7)))]
17721 "TARGET_USE_FANCY_MATH_387
17722 && flag_unsafe_math_optimizations"
17726 if (optimize_insn_for_size_p ())
17729 for (i = 2; i < 13; i++)
17730 operands[i] = gen_reg_rtx (XFmode);
17733 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17735 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17738 (define_expand "expm1<mode>2"
17739 [(use (match_operand:MODEF 0 "register_operand" ""))
17740 (use (match_operand:MODEF 1 "general_operand" ""))]
17741 "TARGET_USE_FANCY_MATH_387
17742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17743 || TARGET_MIX_SSE_I387)
17744 && flag_unsafe_math_optimizations"
17748 if (optimize_insn_for_size_p ())
17751 op0 = gen_reg_rtx (XFmode);
17752 op1 = gen_reg_rtx (XFmode);
17754 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17755 emit_insn (gen_expm1xf2 (op0, op1));
17756 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17760 (define_expand "ldexpxf3"
17761 [(set (match_dup 3)
17762 (float:XF (match_operand:SI 2 "register_operand" "")))
17763 (parallel [(set (match_operand:XF 0 " register_operand" "")
17764 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17766 UNSPEC_FSCALE_FRACT))
17768 (unspec:XF [(match_dup 1) (match_dup 3)]
17769 UNSPEC_FSCALE_EXP))])]
17770 "TARGET_USE_FANCY_MATH_387
17771 && flag_unsafe_math_optimizations"
17773 if (optimize_insn_for_size_p ())
17776 operands[3] = gen_reg_rtx (XFmode);
17777 operands[4] = gen_reg_rtx (XFmode);
17780 (define_expand "ldexp<mode>3"
17781 [(use (match_operand:MODEF 0 "register_operand" ""))
17782 (use (match_operand:MODEF 1 "general_operand" ""))
17783 (use (match_operand:SI 2 "register_operand" ""))]
17784 "TARGET_USE_FANCY_MATH_387
17785 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17786 || TARGET_MIX_SSE_I387)
17787 && flag_unsafe_math_optimizations"
17791 if (optimize_insn_for_size_p ())
17794 op0 = gen_reg_rtx (XFmode);
17795 op1 = gen_reg_rtx (XFmode);
17797 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17798 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17803 (define_expand "scalbxf3"
17804 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17805 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17806 (match_operand:XF 2 "register_operand" "")]
17807 UNSPEC_FSCALE_FRACT))
17809 (unspec:XF [(match_dup 1) (match_dup 2)]
17810 UNSPEC_FSCALE_EXP))])]
17811 "TARGET_USE_FANCY_MATH_387
17812 && flag_unsafe_math_optimizations"
17814 if (optimize_insn_for_size_p ())
17817 operands[3] = gen_reg_rtx (XFmode);
17820 (define_expand "scalb<mode>3"
17821 [(use (match_operand:MODEF 0 "register_operand" ""))
17822 (use (match_operand:MODEF 1 "general_operand" ""))
17823 (use (match_operand:MODEF 2 "register_operand" ""))]
17824 "TARGET_USE_FANCY_MATH_387
17825 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17826 || TARGET_MIX_SSE_I387)
17827 && flag_unsafe_math_optimizations"
17831 if (optimize_insn_for_size_p ())
17834 op0 = gen_reg_rtx (XFmode);
17835 op1 = gen_reg_rtx (XFmode);
17836 op2 = gen_reg_rtx (XFmode);
17838 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17839 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17840 emit_insn (gen_scalbxf3 (op0, op1, op2));
17841 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17846 (define_insn "sse4_1_round<mode>2"
17847 [(set (match_operand:MODEF 0 "register_operand" "=x")
17848 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17849 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17852 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17853 [(set_attr "type" "ssecvt")
17854 (set_attr "prefix_extra" "1")
17855 (set_attr "prefix" "maybe_vex")
17856 (set_attr "mode" "<MODE>")])
17858 (define_insn "rintxf2"
17859 [(set (match_operand:XF 0 "register_operand" "=f")
17860 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17862 "TARGET_USE_FANCY_MATH_387
17863 && flag_unsafe_math_optimizations"
17865 [(set_attr "type" "fpspc")
17866 (set_attr "mode" "XF")])
17868 (define_expand "rint<mode>2"
17869 [(use (match_operand:MODEF 0 "register_operand" ""))
17870 (use (match_operand:MODEF 1 "register_operand" ""))]
17871 "(TARGET_USE_FANCY_MATH_387
17872 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17873 || TARGET_MIX_SSE_I387)
17874 && flag_unsafe_math_optimizations)
17875 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17876 && !flag_trapping_math)"
17878 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17879 && !flag_trapping_math)
17881 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17884 emit_insn (gen_sse4_1_round<mode>2
17885 (operands[0], operands[1], GEN_INT (0x04)));
17887 ix86_expand_rint (operand0, operand1);
17891 rtx op0 = gen_reg_rtx (XFmode);
17892 rtx op1 = gen_reg_rtx (XFmode);
17894 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17895 emit_insn (gen_rintxf2 (op0, op1));
17897 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17902 (define_expand "round<mode>2"
17903 [(match_operand:MODEF 0 "register_operand" "")
17904 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17905 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17906 && !flag_trapping_math && !flag_rounding_math"
17908 if (optimize_insn_for_size_p ())
17910 if (TARGET_64BIT || (<MODE>mode != DFmode))
17911 ix86_expand_round (operand0, operand1);
17913 ix86_expand_rounddf_32 (operand0, operand1);
17917 (define_insn_and_split "*fistdi2_1"
17918 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17919 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17921 "TARGET_USE_FANCY_MATH_387
17922 && !(reload_completed || reload_in_progress)"
17927 if (memory_operand (operands[0], VOIDmode))
17928 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17931 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17932 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17937 [(set_attr "type" "fpspc")
17938 (set_attr "mode" "DI")])
17940 (define_insn "fistdi2"
17941 [(set (match_operand:DI 0 "memory_operand" "=m")
17942 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17944 (clobber (match_scratch:XF 2 "=&1f"))]
17945 "TARGET_USE_FANCY_MATH_387"
17946 "* return output_fix_trunc (insn, operands, 0);"
17947 [(set_attr "type" "fpspc")
17948 (set_attr "mode" "DI")])
17950 (define_insn "fistdi2_with_temp"
17951 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17952 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17954 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17955 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17956 "TARGET_USE_FANCY_MATH_387"
17958 [(set_attr "type" "fpspc")
17959 (set_attr "mode" "DI")])
17962 [(set (match_operand:DI 0 "register_operand" "")
17963 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17965 (clobber (match_operand:DI 2 "memory_operand" ""))
17966 (clobber (match_scratch 3 ""))]
17968 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17969 (clobber (match_dup 3))])
17970 (set (match_dup 0) (match_dup 2))]
17974 [(set (match_operand:DI 0 "memory_operand" "")
17975 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17977 (clobber (match_operand:DI 2 "memory_operand" ""))
17978 (clobber (match_scratch 3 ""))]
17980 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17981 (clobber (match_dup 3))])]
17984 (define_insn_and_split "*fist<mode>2_1"
17985 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17986 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17988 "TARGET_USE_FANCY_MATH_387
17989 && !(reload_completed || reload_in_progress)"
17994 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17995 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17999 [(set_attr "type" "fpspc")
18000 (set_attr "mode" "<MODE>")])
18002 (define_insn "fist<mode>2"
18003 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18004 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18006 "TARGET_USE_FANCY_MATH_387"
18007 "* return output_fix_trunc (insn, operands, 0);"
18008 [(set_attr "type" "fpspc")
18009 (set_attr "mode" "<MODE>")])
18011 (define_insn "fist<mode>2_with_temp"
18012 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18013 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18015 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18016 "TARGET_USE_FANCY_MATH_387"
18018 [(set_attr "type" "fpspc")
18019 (set_attr "mode" "<MODE>")])
18022 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18023 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18025 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18027 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18028 (set (match_dup 0) (match_dup 2))]
18032 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18033 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18035 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18037 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18040 (define_expand "lrintxf<mode>2"
18041 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18042 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18044 "TARGET_USE_FANCY_MATH_387"
18047 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18048 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18049 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18050 UNSPEC_FIX_NOTRUNC))]
18051 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18052 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18055 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18056 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18057 (match_operand:MODEF 1 "register_operand" "")]
18058 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18059 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18060 && !flag_trapping_math && !flag_rounding_math"
18062 if (optimize_insn_for_size_p ())
18064 ix86_expand_lround (operand0, operand1);
18068 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18069 (define_insn_and_split "frndintxf2_floor"
18070 [(set (match_operand:XF 0 "register_operand" "")
18071 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18072 UNSPEC_FRNDINT_FLOOR))
18073 (clobber (reg:CC FLAGS_REG))]
18074 "TARGET_USE_FANCY_MATH_387
18075 && flag_unsafe_math_optimizations
18076 && !(reload_completed || reload_in_progress)"
18081 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18083 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18084 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18086 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18087 operands[2], operands[3]));
18090 [(set_attr "type" "frndint")
18091 (set_attr "i387_cw" "floor")
18092 (set_attr "mode" "XF")])
18094 (define_insn "frndintxf2_floor_i387"
18095 [(set (match_operand:XF 0 "register_operand" "=f")
18096 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18097 UNSPEC_FRNDINT_FLOOR))
18098 (use (match_operand:HI 2 "memory_operand" "m"))
18099 (use (match_operand:HI 3 "memory_operand" "m"))]
18100 "TARGET_USE_FANCY_MATH_387
18101 && flag_unsafe_math_optimizations"
18102 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18103 [(set_attr "type" "frndint")
18104 (set_attr "i387_cw" "floor")
18105 (set_attr "mode" "XF")])
18107 (define_expand "floorxf2"
18108 [(use (match_operand:XF 0 "register_operand" ""))
18109 (use (match_operand:XF 1 "register_operand" ""))]
18110 "TARGET_USE_FANCY_MATH_387
18111 && flag_unsafe_math_optimizations"
18113 if (optimize_insn_for_size_p ())
18115 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18119 (define_expand "floor<mode>2"
18120 [(use (match_operand:MODEF 0 "register_operand" ""))
18121 (use (match_operand:MODEF 1 "register_operand" ""))]
18122 "(TARGET_USE_FANCY_MATH_387
18123 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18124 || TARGET_MIX_SSE_I387)
18125 && flag_unsafe_math_optimizations)
18126 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18127 && !flag_trapping_math)"
18129 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18130 && !flag_trapping_math
18131 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18133 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18136 emit_insn (gen_sse4_1_round<mode>2
18137 (operands[0], operands[1], GEN_INT (0x01)));
18138 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18139 ix86_expand_floorceil (operand0, operand1, true);
18141 ix86_expand_floorceildf_32 (operand0, operand1, true);
18147 if (optimize_insn_for_size_p ())
18150 op0 = gen_reg_rtx (XFmode);
18151 op1 = gen_reg_rtx (XFmode);
18152 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18153 emit_insn (gen_frndintxf2_floor (op0, op1));
18155 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18160 (define_insn_and_split "*fist<mode>2_floor_1"
18161 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18162 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18163 UNSPEC_FIST_FLOOR))
18164 (clobber (reg:CC FLAGS_REG))]
18165 "TARGET_USE_FANCY_MATH_387
18166 && flag_unsafe_math_optimizations
18167 && !(reload_completed || reload_in_progress)"
18172 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18174 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18175 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18176 if (memory_operand (operands[0], VOIDmode))
18177 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18178 operands[2], operands[3]));
18181 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18182 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18183 operands[2], operands[3],
18188 [(set_attr "type" "fistp")
18189 (set_attr "i387_cw" "floor")
18190 (set_attr "mode" "<MODE>")])
18192 (define_insn "fistdi2_floor"
18193 [(set (match_operand:DI 0 "memory_operand" "=m")
18194 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18195 UNSPEC_FIST_FLOOR))
18196 (use (match_operand:HI 2 "memory_operand" "m"))
18197 (use (match_operand:HI 3 "memory_operand" "m"))
18198 (clobber (match_scratch:XF 4 "=&1f"))]
18199 "TARGET_USE_FANCY_MATH_387
18200 && flag_unsafe_math_optimizations"
18201 "* return output_fix_trunc (insn, operands, 0);"
18202 [(set_attr "type" "fistp")
18203 (set_attr "i387_cw" "floor")
18204 (set_attr "mode" "DI")])
18206 (define_insn "fistdi2_floor_with_temp"
18207 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18208 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18209 UNSPEC_FIST_FLOOR))
18210 (use (match_operand:HI 2 "memory_operand" "m,m"))
18211 (use (match_operand:HI 3 "memory_operand" "m,m"))
18212 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18213 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18214 "TARGET_USE_FANCY_MATH_387
18215 && flag_unsafe_math_optimizations"
18217 [(set_attr "type" "fistp")
18218 (set_attr "i387_cw" "floor")
18219 (set_attr "mode" "DI")])
18222 [(set (match_operand:DI 0 "register_operand" "")
18223 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18224 UNSPEC_FIST_FLOOR))
18225 (use (match_operand:HI 2 "memory_operand" ""))
18226 (use (match_operand:HI 3 "memory_operand" ""))
18227 (clobber (match_operand:DI 4 "memory_operand" ""))
18228 (clobber (match_scratch 5 ""))]
18230 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18231 (use (match_dup 2))
18232 (use (match_dup 3))
18233 (clobber (match_dup 5))])
18234 (set (match_dup 0) (match_dup 4))]
18238 [(set (match_operand:DI 0 "memory_operand" "")
18239 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18240 UNSPEC_FIST_FLOOR))
18241 (use (match_operand:HI 2 "memory_operand" ""))
18242 (use (match_operand:HI 3 "memory_operand" ""))
18243 (clobber (match_operand:DI 4 "memory_operand" ""))
18244 (clobber (match_scratch 5 ""))]
18246 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18247 (use (match_dup 2))
18248 (use (match_dup 3))
18249 (clobber (match_dup 5))])]
18252 (define_insn "fist<mode>2_floor"
18253 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18254 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18255 UNSPEC_FIST_FLOOR))
18256 (use (match_operand:HI 2 "memory_operand" "m"))
18257 (use (match_operand:HI 3 "memory_operand" "m"))]
18258 "TARGET_USE_FANCY_MATH_387
18259 && flag_unsafe_math_optimizations"
18260 "* return output_fix_trunc (insn, operands, 0);"
18261 [(set_attr "type" "fistp")
18262 (set_attr "i387_cw" "floor")
18263 (set_attr "mode" "<MODE>")])
18265 (define_insn "fist<mode>2_floor_with_temp"
18266 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18267 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18268 UNSPEC_FIST_FLOOR))
18269 (use (match_operand:HI 2 "memory_operand" "m,m"))
18270 (use (match_operand:HI 3 "memory_operand" "m,m"))
18271 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18272 "TARGET_USE_FANCY_MATH_387
18273 && flag_unsafe_math_optimizations"
18275 [(set_attr "type" "fistp")
18276 (set_attr "i387_cw" "floor")
18277 (set_attr "mode" "<MODE>")])
18280 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18281 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18282 UNSPEC_FIST_FLOOR))
18283 (use (match_operand:HI 2 "memory_operand" ""))
18284 (use (match_operand:HI 3 "memory_operand" ""))
18285 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18287 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18288 UNSPEC_FIST_FLOOR))
18289 (use (match_dup 2))
18290 (use (match_dup 3))])
18291 (set (match_dup 0) (match_dup 4))]
18295 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18296 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18297 UNSPEC_FIST_FLOOR))
18298 (use (match_operand:HI 2 "memory_operand" ""))
18299 (use (match_operand:HI 3 "memory_operand" ""))
18300 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18302 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18303 UNSPEC_FIST_FLOOR))
18304 (use (match_dup 2))
18305 (use (match_dup 3))])]
18308 (define_expand "lfloorxf<mode>2"
18309 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18310 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18311 UNSPEC_FIST_FLOOR))
18312 (clobber (reg:CC FLAGS_REG))])]
18313 "TARGET_USE_FANCY_MATH_387
18314 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18315 && flag_unsafe_math_optimizations"
18318 (define_expand "lfloor<mode>di2"
18319 [(match_operand:DI 0 "nonimmediate_operand" "")
18320 (match_operand:MODEF 1 "register_operand" "")]
18321 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18322 && !flag_trapping_math"
18324 if (optimize_insn_for_size_p ())
18326 ix86_expand_lfloorceil (operand0, operand1, true);
18330 (define_expand "lfloor<mode>si2"
18331 [(match_operand:SI 0 "nonimmediate_operand" "")
18332 (match_operand:MODEF 1 "register_operand" "")]
18333 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18334 && !flag_trapping_math"
18336 if (optimize_insn_for_size_p () && TARGET_64BIT)
18338 ix86_expand_lfloorceil (operand0, operand1, true);
18342 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18343 (define_insn_and_split "frndintxf2_ceil"
18344 [(set (match_operand:XF 0 "register_operand" "")
18345 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18346 UNSPEC_FRNDINT_CEIL))
18347 (clobber (reg:CC FLAGS_REG))]
18348 "TARGET_USE_FANCY_MATH_387
18349 && flag_unsafe_math_optimizations
18350 && !(reload_completed || reload_in_progress)"
18355 ix86_optimize_mode_switching[I387_CEIL] = 1;
18357 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18358 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18360 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18361 operands[2], operands[3]));
18364 [(set_attr "type" "frndint")
18365 (set_attr "i387_cw" "ceil")
18366 (set_attr "mode" "XF")])
18368 (define_insn "frndintxf2_ceil_i387"
18369 [(set (match_operand:XF 0 "register_operand" "=f")
18370 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18371 UNSPEC_FRNDINT_CEIL))
18372 (use (match_operand:HI 2 "memory_operand" "m"))
18373 (use (match_operand:HI 3 "memory_operand" "m"))]
18374 "TARGET_USE_FANCY_MATH_387
18375 && flag_unsafe_math_optimizations"
18376 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18377 [(set_attr "type" "frndint")
18378 (set_attr "i387_cw" "ceil")
18379 (set_attr "mode" "XF")])
18381 (define_expand "ceilxf2"
18382 [(use (match_operand:XF 0 "register_operand" ""))
18383 (use (match_operand:XF 1 "register_operand" ""))]
18384 "TARGET_USE_FANCY_MATH_387
18385 && flag_unsafe_math_optimizations"
18387 if (optimize_insn_for_size_p ())
18389 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18393 (define_expand "ceil<mode>2"
18394 [(use (match_operand:MODEF 0 "register_operand" ""))
18395 (use (match_operand:MODEF 1 "register_operand" ""))]
18396 "(TARGET_USE_FANCY_MATH_387
18397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18398 || TARGET_MIX_SSE_I387)
18399 && flag_unsafe_math_optimizations)
18400 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18401 && !flag_trapping_math)"
18403 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18404 && !flag_trapping_math
18405 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18408 emit_insn (gen_sse4_1_round<mode>2
18409 (operands[0], operands[1], GEN_INT (0x02)));
18410 else if (optimize_insn_for_size_p ())
18412 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18413 ix86_expand_floorceil (operand0, operand1, false);
18415 ix86_expand_floorceildf_32 (operand0, operand1, false);
18421 if (optimize_insn_for_size_p ())
18424 op0 = gen_reg_rtx (XFmode);
18425 op1 = gen_reg_rtx (XFmode);
18426 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18427 emit_insn (gen_frndintxf2_ceil (op0, op1));
18429 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18434 (define_insn_and_split "*fist<mode>2_ceil_1"
18435 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18436 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18438 (clobber (reg:CC FLAGS_REG))]
18439 "TARGET_USE_FANCY_MATH_387
18440 && flag_unsafe_math_optimizations
18441 && !(reload_completed || reload_in_progress)"
18446 ix86_optimize_mode_switching[I387_CEIL] = 1;
18448 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18449 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18450 if (memory_operand (operands[0], VOIDmode))
18451 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18452 operands[2], operands[3]));
18455 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18456 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18457 operands[2], operands[3],
18462 [(set_attr "type" "fistp")
18463 (set_attr "i387_cw" "ceil")
18464 (set_attr "mode" "<MODE>")])
18466 (define_insn "fistdi2_ceil"
18467 [(set (match_operand:DI 0 "memory_operand" "=m")
18468 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18470 (use (match_operand:HI 2 "memory_operand" "m"))
18471 (use (match_operand:HI 3 "memory_operand" "m"))
18472 (clobber (match_scratch:XF 4 "=&1f"))]
18473 "TARGET_USE_FANCY_MATH_387
18474 && flag_unsafe_math_optimizations"
18475 "* return output_fix_trunc (insn, operands, 0);"
18476 [(set_attr "type" "fistp")
18477 (set_attr "i387_cw" "ceil")
18478 (set_attr "mode" "DI")])
18480 (define_insn "fistdi2_ceil_with_temp"
18481 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18482 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18484 (use (match_operand:HI 2 "memory_operand" "m,m"))
18485 (use (match_operand:HI 3 "memory_operand" "m,m"))
18486 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18487 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18488 "TARGET_USE_FANCY_MATH_387
18489 && flag_unsafe_math_optimizations"
18491 [(set_attr "type" "fistp")
18492 (set_attr "i387_cw" "ceil")
18493 (set_attr "mode" "DI")])
18496 [(set (match_operand:DI 0 "register_operand" "")
18497 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18499 (use (match_operand:HI 2 "memory_operand" ""))
18500 (use (match_operand:HI 3 "memory_operand" ""))
18501 (clobber (match_operand:DI 4 "memory_operand" ""))
18502 (clobber (match_scratch 5 ""))]
18504 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18505 (use (match_dup 2))
18506 (use (match_dup 3))
18507 (clobber (match_dup 5))])
18508 (set (match_dup 0) (match_dup 4))]
18512 [(set (match_operand:DI 0 "memory_operand" "")
18513 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18515 (use (match_operand:HI 2 "memory_operand" ""))
18516 (use (match_operand:HI 3 "memory_operand" ""))
18517 (clobber (match_operand:DI 4 "memory_operand" ""))
18518 (clobber (match_scratch 5 ""))]
18520 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18521 (use (match_dup 2))
18522 (use (match_dup 3))
18523 (clobber (match_dup 5))])]
18526 (define_insn "fist<mode>2_ceil"
18527 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18528 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18530 (use (match_operand:HI 2 "memory_operand" "m"))
18531 (use (match_operand:HI 3 "memory_operand" "m"))]
18532 "TARGET_USE_FANCY_MATH_387
18533 && flag_unsafe_math_optimizations"
18534 "* return output_fix_trunc (insn, operands, 0);"
18535 [(set_attr "type" "fistp")
18536 (set_attr "i387_cw" "ceil")
18537 (set_attr "mode" "<MODE>")])
18539 (define_insn "fist<mode>2_ceil_with_temp"
18540 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18541 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18543 (use (match_operand:HI 2 "memory_operand" "m,m"))
18544 (use (match_operand:HI 3 "memory_operand" "m,m"))
18545 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18546 "TARGET_USE_FANCY_MATH_387
18547 && flag_unsafe_math_optimizations"
18549 [(set_attr "type" "fistp")
18550 (set_attr "i387_cw" "ceil")
18551 (set_attr "mode" "<MODE>")])
18554 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18555 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18557 (use (match_operand:HI 2 "memory_operand" ""))
18558 (use (match_operand:HI 3 "memory_operand" ""))
18559 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18561 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18563 (use (match_dup 2))
18564 (use (match_dup 3))])
18565 (set (match_dup 0) (match_dup 4))]
18569 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18570 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18572 (use (match_operand:HI 2 "memory_operand" ""))
18573 (use (match_operand:HI 3 "memory_operand" ""))
18574 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18576 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18578 (use (match_dup 2))
18579 (use (match_dup 3))])]
18582 (define_expand "lceilxf<mode>2"
18583 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18584 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18586 (clobber (reg:CC FLAGS_REG))])]
18587 "TARGET_USE_FANCY_MATH_387
18588 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18589 && flag_unsafe_math_optimizations"
18592 (define_expand "lceil<mode>di2"
18593 [(match_operand:DI 0 "nonimmediate_operand" "")
18594 (match_operand:MODEF 1 "register_operand" "")]
18595 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18596 && !flag_trapping_math"
18598 ix86_expand_lfloorceil (operand0, operand1, false);
18602 (define_expand "lceil<mode>si2"
18603 [(match_operand:SI 0 "nonimmediate_operand" "")
18604 (match_operand:MODEF 1 "register_operand" "")]
18605 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18606 && !flag_trapping_math"
18608 ix86_expand_lfloorceil (operand0, operand1, false);
18612 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18613 (define_insn_and_split "frndintxf2_trunc"
18614 [(set (match_operand:XF 0 "register_operand" "")
18615 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18616 UNSPEC_FRNDINT_TRUNC))
18617 (clobber (reg:CC FLAGS_REG))]
18618 "TARGET_USE_FANCY_MATH_387
18619 && flag_unsafe_math_optimizations
18620 && !(reload_completed || reload_in_progress)"
18625 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18627 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18628 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18630 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18631 operands[2], operands[3]));
18634 [(set_attr "type" "frndint")
18635 (set_attr "i387_cw" "trunc")
18636 (set_attr "mode" "XF")])
18638 (define_insn "frndintxf2_trunc_i387"
18639 [(set (match_operand:XF 0 "register_operand" "=f")
18640 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18641 UNSPEC_FRNDINT_TRUNC))
18642 (use (match_operand:HI 2 "memory_operand" "m"))
18643 (use (match_operand:HI 3 "memory_operand" "m"))]
18644 "TARGET_USE_FANCY_MATH_387
18645 && flag_unsafe_math_optimizations"
18646 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18647 [(set_attr "type" "frndint")
18648 (set_attr "i387_cw" "trunc")
18649 (set_attr "mode" "XF")])
18651 (define_expand "btruncxf2"
18652 [(use (match_operand:XF 0 "register_operand" ""))
18653 (use (match_operand:XF 1 "register_operand" ""))]
18654 "TARGET_USE_FANCY_MATH_387
18655 && flag_unsafe_math_optimizations"
18657 if (optimize_insn_for_size_p ())
18659 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18663 (define_expand "btrunc<mode>2"
18664 [(use (match_operand:MODEF 0 "register_operand" ""))
18665 (use (match_operand:MODEF 1 "register_operand" ""))]
18666 "(TARGET_USE_FANCY_MATH_387
18667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18668 || TARGET_MIX_SSE_I387)
18669 && flag_unsafe_math_optimizations)
18670 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18671 && !flag_trapping_math)"
18673 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18674 && !flag_trapping_math
18675 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18678 emit_insn (gen_sse4_1_round<mode>2
18679 (operands[0], operands[1], GEN_INT (0x03)));
18680 else if (optimize_insn_for_size_p ())
18682 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18683 ix86_expand_trunc (operand0, operand1);
18685 ix86_expand_truncdf_32 (operand0, operand1);
18691 if (optimize_insn_for_size_p ())
18694 op0 = gen_reg_rtx (XFmode);
18695 op1 = gen_reg_rtx (XFmode);
18696 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18697 emit_insn (gen_frndintxf2_trunc (op0, op1));
18699 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18704 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18705 (define_insn_and_split "frndintxf2_mask_pm"
18706 [(set (match_operand:XF 0 "register_operand" "")
18707 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18708 UNSPEC_FRNDINT_MASK_PM))
18709 (clobber (reg:CC FLAGS_REG))]
18710 "TARGET_USE_FANCY_MATH_387
18711 && flag_unsafe_math_optimizations
18712 && !(reload_completed || reload_in_progress)"
18717 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18719 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18720 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18722 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18723 operands[2], operands[3]));
18726 [(set_attr "type" "frndint")
18727 (set_attr "i387_cw" "mask_pm")
18728 (set_attr "mode" "XF")])
18730 (define_insn "frndintxf2_mask_pm_i387"
18731 [(set (match_operand:XF 0 "register_operand" "=f")
18732 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18733 UNSPEC_FRNDINT_MASK_PM))
18734 (use (match_operand:HI 2 "memory_operand" "m"))
18735 (use (match_operand:HI 3 "memory_operand" "m"))]
18736 "TARGET_USE_FANCY_MATH_387
18737 && flag_unsafe_math_optimizations"
18738 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18739 [(set_attr "type" "frndint")
18740 (set_attr "i387_cw" "mask_pm")
18741 (set_attr "mode" "XF")])
18743 (define_expand "nearbyintxf2"
18744 [(use (match_operand:XF 0 "register_operand" ""))
18745 (use (match_operand:XF 1 "register_operand" ""))]
18746 "TARGET_USE_FANCY_MATH_387
18747 && flag_unsafe_math_optimizations"
18749 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18754 (define_expand "nearbyint<mode>2"
18755 [(use (match_operand:MODEF 0 "register_operand" ""))
18756 (use (match_operand:MODEF 1 "register_operand" ""))]
18757 "TARGET_USE_FANCY_MATH_387
18758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18759 || TARGET_MIX_SSE_I387)
18760 && flag_unsafe_math_optimizations"
18762 rtx op0 = gen_reg_rtx (XFmode);
18763 rtx op1 = gen_reg_rtx (XFmode);
18765 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18766 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18768 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18772 (define_insn "fxam<mode>2_i387"
18773 [(set (match_operand:HI 0 "register_operand" "=a")
18775 [(match_operand:X87MODEF 1 "register_operand" "f")]
18777 "TARGET_USE_FANCY_MATH_387"
18778 "fxam\n\tfnstsw\t%0"
18779 [(set_attr "type" "multi")
18780 (set_attr "unit" "i387")
18781 (set_attr "mode" "<MODE>")])
18783 (define_expand "isinf<mode>2"
18784 [(use (match_operand:SI 0 "register_operand" ""))
18785 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18786 "TARGET_USE_FANCY_MATH_387
18787 && TARGET_C99_FUNCTIONS
18788 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18790 rtx mask = GEN_INT (0x45);
18791 rtx val = GEN_INT (0x05);
18795 rtx scratch = gen_reg_rtx (HImode);
18796 rtx res = gen_reg_rtx (QImode);
18798 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18799 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18800 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18801 cond = gen_rtx_fmt_ee (EQ, QImode,
18802 gen_rtx_REG (CCmode, FLAGS_REG),
18804 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18805 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18809 (define_expand "signbit<mode>2"
18810 [(use (match_operand:SI 0 "register_operand" ""))
18811 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18812 "TARGET_USE_FANCY_MATH_387
18813 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18815 rtx mask = GEN_INT (0x0200);
18817 rtx scratch = gen_reg_rtx (HImode);
18819 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18820 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18824 ;; Block operation instructions
18827 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18830 [(set_attr "length" "1")
18831 (set_attr "length_immediate" "0")
18832 (set_attr "modrm" "0")])
18834 (define_expand "movmemsi"
18835 [(use (match_operand:BLK 0 "memory_operand" ""))
18836 (use (match_operand:BLK 1 "memory_operand" ""))
18837 (use (match_operand:SI 2 "nonmemory_operand" ""))
18838 (use (match_operand:SI 3 "const_int_operand" ""))
18839 (use (match_operand:SI 4 "const_int_operand" ""))
18840 (use (match_operand:SI 5 "const_int_operand" ""))]
18843 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18844 operands[4], operands[5]))
18850 (define_expand "movmemdi"
18851 [(use (match_operand:BLK 0 "memory_operand" ""))
18852 (use (match_operand:BLK 1 "memory_operand" ""))
18853 (use (match_operand:DI 2 "nonmemory_operand" ""))
18854 (use (match_operand:DI 3 "const_int_operand" ""))
18855 (use (match_operand:SI 4 "const_int_operand" ""))
18856 (use (match_operand:SI 5 "const_int_operand" ""))]
18859 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18860 operands[4], operands[5]))
18866 ;; Most CPUs don't like single string operations
18867 ;; Handle this case here to simplify previous expander.
18869 (define_expand "strmov"
18870 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18871 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18872 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18873 (clobber (reg:CC FLAGS_REG))])
18874 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18875 (clobber (reg:CC FLAGS_REG))])]
18878 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18880 /* If .md ever supports :P for Pmode, these can be directly
18881 in the pattern above. */
18882 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18883 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18885 /* Can't use this if the user has appropriated esi or edi. */
18886 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18887 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18889 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18890 operands[2], operands[3],
18891 operands[5], operands[6]));
18895 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18898 (define_expand "strmov_singleop"
18899 [(parallel [(set (match_operand 1 "memory_operand" "")
18900 (match_operand 3 "memory_operand" ""))
18901 (set (match_operand 0 "register_operand" "")
18902 (match_operand 4 "" ""))
18903 (set (match_operand 2 "register_operand" "")
18904 (match_operand 5 "" ""))])]
18906 "ix86_current_function_needs_cld = 1;")
18908 (define_insn "*strmovdi_rex_1"
18909 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18910 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18911 (set (match_operand:DI 0 "register_operand" "=D")
18912 (plus:DI (match_dup 2)
18914 (set (match_operand:DI 1 "register_operand" "=S")
18915 (plus:DI (match_dup 3)
18919 [(set_attr "type" "str")
18920 (set_attr "mode" "DI")
18921 (set_attr "memory" "both")])
18923 (define_insn "*strmovsi_1"
18924 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18925 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18926 (set (match_operand:SI 0 "register_operand" "=D")
18927 (plus:SI (match_dup 2)
18929 (set (match_operand:SI 1 "register_operand" "=S")
18930 (plus:SI (match_dup 3)
18934 [(set_attr "type" "str")
18935 (set_attr "mode" "SI")
18936 (set_attr "memory" "both")])
18938 (define_insn "*strmovsi_rex_1"
18939 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18940 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18941 (set (match_operand:DI 0 "register_operand" "=D")
18942 (plus:DI (match_dup 2)
18944 (set (match_operand:DI 1 "register_operand" "=S")
18945 (plus:DI (match_dup 3)
18949 [(set_attr "type" "str")
18950 (set_attr "mode" "SI")
18951 (set_attr "memory" "both")])
18953 (define_insn "*strmovhi_1"
18954 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18955 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18956 (set (match_operand:SI 0 "register_operand" "=D")
18957 (plus:SI (match_dup 2)
18959 (set (match_operand:SI 1 "register_operand" "=S")
18960 (plus:SI (match_dup 3)
18964 [(set_attr "type" "str")
18965 (set_attr "memory" "both")
18966 (set_attr "mode" "HI")])
18968 (define_insn "*strmovhi_rex_1"
18969 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18970 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18971 (set (match_operand:DI 0 "register_operand" "=D")
18972 (plus:DI (match_dup 2)
18974 (set (match_operand:DI 1 "register_operand" "=S")
18975 (plus:DI (match_dup 3)
18979 [(set_attr "type" "str")
18980 (set_attr "memory" "both")
18981 (set_attr "mode" "HI")])
18983 (define_insn "*strmovqi_1"
18984 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18985 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18986 (set (match_operand:SI 0 "register_operand" "=D")
18987 (plus:SI (match_dup 2)
18989 (set (match_operand:SI 1 "register_operand" "=S")
18990 (plus:SI (match_dup 3)
18994 [(set_attr "type" "str")
18995 (set_attr "memory" "both")
18996 (set_attr "mode" "QI")])
18998 (define_insn "*strmovqi_rex_1"
18999 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19000 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19001 (set (match_operand:DI 0 "register_operand" "=D")
19002 (plus:DI (match_dup 2)
19004 (set (match_operand:DI 1 "register_operand" "=S")
19005 (plus:DI (match_dup 3)
19009 [(set_attr "type" "str")
19010 (set_attr "memory" "both")
19011 (set_attr "mode" "QI")])
19013 (define_expand "rep_mov"
19014 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19015 (set (match_operand 0 "register_operand" "")
19016 (match_operand 5 "" ""))
19017 (set (match_operand 2 "register_operand" "")
19018 (match_operand 6 "" ""))
19019 (set (match_operand 1 "memory_operand" "")
19020 (match_operand 3 "memory_operand" ""))
19021 (use (match_dup 4))])]
19023 "ix86_current_function_needs_cld = 1;")
19025 (define_insn "*rep_movdi_rex64"
19026 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19027 (set (match_operand:DI 0 "register_operand" "=D")
19028 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19030 (match_operand:DI 3 "register_operand" "0")))
19031 (set (match_operand:DI 1 "register_operand" "=S")
19032 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19033 (match_operand:DI 4 "register_operand" "1")))
19034 (set (mem:BLK (match_dup 3))
19035 (mem:BLK (match_dup 4)))
19036 (use (match_dup 5))]
19039 [(set_attr "type" "str")
19040 (set_attr "prefix_rep" "1")
19041 (set_attr "memory" "both")
19042 (set_attr "mode" "DI")])
19044 (define_insn "*rep_movsi"
19045 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19046 (set (match_operand:SI 0 "register_operand" "=D")
19047 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19049 (match_operand:SI 3 "register_operand" "0")))
19050 (set (match_operand:SI 1 "register_operand" "=S")
19051 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19052 (match_operand:SI 4 "register_operand" "1")))
19053 (set (mem:BLK (match_dup 3))
19054 (mem:BLK (match_dup 4)))
19055 (use (match_dup 5))]
19058 [(set_attr "type" "str")
19059 (set_attr "prefix_rep" "1")
19060 (set_attr "memory" "both")
19061 (set_attr "mode" "SI")])
19063 (define_insn "*rep_movsi_rex64"
19064 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19065 (set (match_operand:DI 0 "register_operand" "=D")
19066 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19068 (match_operand:DI 3 "register_operand" "0")))
19069 (set (match_operand:DI 1 "register_operand" "=S")
19070 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19071 (match_operand:DI 4 "register_operand" "1")))
19072 (set (mem:BLK (match_dup 3))
19073 (mem:BLK (match_dup 4)))
19074 (use (match_dup 5))]
19077 [(set_attr "type" "str")
19078 (set_attr "prefix_rep" "1")
19079 (set_attr "memory" "both")
19080 (set_attr "mode" "SI")])
19082 (define_insn "*rep_movqi"
19083 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19084 (set (match_operand:SI 0 "register_operand" "=D")
19085 (plus:SI (match_operand:SI 3 "register_operand" "0")
19086 (match_operand:SI 5 "register_operand" "2")))
19087 (set (match_operand:SI 1 "register_operand" "=S")
19088 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19089 (set (mem:BLK (match_dup 3))
19090 (mem:BLK (match_dup 4)))
19091 (use (match_dup 5))]
19094 [(set_attr "type" "str")
19095 (set_attr "prefix_rep" "1")
19096 (set_attr "memory" "both")
19097 (set_attr "mode" "SI")])
19099 (define_insn "*rep_movqi_rex64"
19100 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19101 (set (match_operand:DI 0 "register_operand" "=D")
19102 (plus:DI (match_operand:DI 3 "register_operand" "0")
19103 (match_operand:DI 5 "register_operand" "2")))
19104 (set (match_operand:DI 1 "register_operand" "=S")
19105 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19106 (set (mem:BLK (match_dup 3))
19107 (mem:BLK (match_dup 4)))
19108 (use (match_dup 5))]
19111 [(set_attr "type" "str")
19112 (set_attr "prefix_rep" "1")
19113 (set_attr "memory" "both")
19114 (set_attr "mode" "SI")])
19116 (define_expand "setmemsi"
19117 [(use (match_operand:BLK 0 "memory_operand" ""))
19118 (use (match_operand:SI 1 "nonmemory_operand" ""))
19119 (use (match_operand 2 "const_int_operand" ""))
19120 (use (match_operand 3 "const_int_operand" ""))
19121 (use (match_operand:SI 4 "const_int_operand" ""))
19122 (use (match_operand:SI 5 "const_int_operand" ""))]
19125 if (ix86_expand_setmem (operands[0], operands[1],
19126 operands[2], operands[3],
19127 operands[4], operands[5]))
19133 (define_expand "setmemdi"
19134 [(use (match_operand:BLK 0 "memory_operand" ""))
19135 (use (match_operand:DI 1 "nonmemory_operand" ""))
19136 (use (match_operand 2 "const_int_operand" ""))
19137 (use (match_operand 3 "const_int_operand" ""))
19138 (use (match_operand 4 "const_int_operand" ""))
19139 (use (match_operand 5 "const_int_operand" ""))]
19142 if (ix86_expand_setmem (operands[0], operands[1],
19143 operands[2], operands[3],
19144 operands[4], operands[5]))
19150 ;; Most CPUs don't like single string operations
19151 ;; Handle this case here to simplify previous expander.
19153 (define_expand "strset"
19154 [(set (match_operand 1 "memory_operand" "")
19155 (match_operand 2 "register_operand" ""))
19156 (parallel [(set (match_operand 0 "register_operand" "")
19158 (clobber (reg:CC FLAGS_REG))])]
19161 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19162 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19164 /* If .md ever supports :P for Pmode, this can be directly
19165 in the pattern above. */
19166 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19167 GEN_INT (GET_MODE_SIZE (GET_MODE
19169 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19171 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19177 (define_expand "strset_singleop"
19178 [(parallel [(set (match_operand 1 "memory_operand" "")
19179 (match_operand 2 "register_operand" ""))
19180 (set (match_operand 0 "register_operand" "")
19181 (match_operand 3 "" ""))])]
19183 "ix86_current_function_needs_cld = 1;")
19185 (define_insn "*strsetdi_rex_1"
19186 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19187 (match_operand:DI 2 "register_operand" "a"))
19188 (set (match_operand:DI 0 "register_operand" "=D")
19189 (plus:DI (match_dup 1)
19193 [(set_attr "type" "str")
19194 (set_attr "memory" "store")
19195 (set_attr "mode" "DI")])
19197 (define_insn "*strsetsi_1"
19198 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19199 (match_operand:SI 2 "register_operand" "a"))
19200 (set (match_operand:SI 0 "register_operand" "=D")
19201 (plus:SI (match_dup 1)
19205 [(set_attr "type" "str")
19206 (set_attr "memory" "store")
19207 (set_attr "mode" "SI")])
19209 (define_insn "*strsetsi_rex_1"
19210 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19211 (match_operand:SI 2 "register_operand" "a"))
19212 (set (match_operand:DI 0 "register_operand" "=D")
19213 (plus:DI (match_dup 1)
19217 [(set_attr "type" "str")
19218 (set_attr "memory" "store")
19219 (set_attr "mode" "SI")])
19221 (define_insn "*strsethi_1"
19222 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19223 (match_operand:HI 2 "register_operand" "a"))
19224 (set (match_operand:SI 0 "register_operand" "=D")
19225 (plus:SI (match_dup 1)
19229 [(set_attr "type" "str")
19230 (set_attr "memory" "store")
19231 (set_attr "mode" "HI")])
19233 (define_insn "*strsethi_rex_1"
19234 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19235 (match_operand:HI 2 "register_operand" "a"))
19236 (set (match_operand:DI 0 "register_operand" "=D")
19237 (plus:DI (match_dup 1)
19241 [(set_attr "type" "str")
19242 (set_attr "memory" "store")
19243 (set_attr "mode" "HI")])
19245 (define_insn "*strsetqi_1"
19246 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19247 (match_operand:QI 2 "register_operand" "a"))
19248 (set (match_operand:SI 0 "register_operand" "=D")
19249 (plus:SI (match_dup 1)
19253 [(set_attr "type" "str")
19254 (set_attr "memory" "store")
19255 (set_attr "mode" "QI")])
19257 (define_insn "*strsetqi_rex_1"
19258 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19259 (match_operand:QI 2 "register_operand" "a"))
19260 (set (match_operand:DI 0 "register_operand" "=D")
19261 (plus:DI (match_dup 1)
19265 [(set_attr "type" "str")
19266 (set_attr "memory" "store")
19267 (set_attr "mode" "QI")])
19269 (define_expand "rep_stos"
19270 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19271 (set (match_operand 0 "register_operand" "")
19272 (match_operand 4 "" ""))
19273 (set (match_operand 2 "memory_operand" "") (const_int 0))
19274 (use (match_operand 3 "register_operand" ""))
19275 (use (match_dup 1))])]
19277 "ix86_current_function_needs_cld = 1;")
19279 (define_insn "*rep_stosdi_rex64"
19280 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19281 (set (match_operand:DI 0 "register_operand" "=D")
19282 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19284 (match_operand:DI 3 "register_operand" "0")))
19285 (set (mem:BLK (match_dup 3))
19287 (use (match_operand:DI 2 "register_operand" "a"))
19288 (use (match_dup 4))]
19291 [(set_attr "type" "str")
19292 (set_attr "prefix_rep" "1")
19293 (set_attr "memory" "store")
19294 (set_attr "mode" "DI")])
19296 (define_insn "*rep_stossi"
19297 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19298 (set (match_operand:SI 0 "register_operand" "=D")
19299 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19301 (match_operand:SI 3 "register_operand" "0")))
19302 (set (mem:BLK (match_dup 3))
19304 (use (match_operand:SI 2 "register_operand" "a"))
19305 (use (match_dup 4))]
19308 [(set_attr "type" "str")
19309 (set_attr "prefix_rep" "1")
19310 (set_attr "memory" "store")
19311 (set_attr "mode" "SI")])
19313 (define_insn "*rep_stossi_rex64"
19314 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19315 (set (match_operand:DI 0 "register_operand" "=D")
19316 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19318 (match_operand:DI 3 "register_operand" "0")))
19319 (set (mem:BLK (match_dup 3))
19321 (use (match_operand:SI 2 "register_operand" "a"))
19322 (use (match_dup 4))]
19325 [(set_attr "type" "str")
19326 (set_attr "prefix_rep" "1")
19327 (set_attr "memory" "store")
19328 (set_attr "mode" "SI")])
19330 (define_insn "*rep_stosqi"
19331 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19332 (set (match_operand:SI 0 "register_operand" "=D")
19333 (plus:SI (match_operand:SI 3 "register_operand" "0")
19334 (match_operand:SI 4 "register_operand" "1")))
19335 (set (mem:BLK (match_dup 3))
19337 (use (match_operand:QI 2 "register_operand" "a"))
19338 (use (match_dup 4))]
19341 [(set_attr "type" "str")
19342 (set_attr "prefix_rep" "1")
19343 (set_attr "memory" "store")
19344 (set_attr "mode" "QI")])
19346 (define_insn "*rep_stosqi_rex64"
19347 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19348 (set (match_operand:DI 0 "register_operand" "=D")
19349 (plus:DI (match_operand:DI 3 "register_operand" "0")
19350 (match_operand:DI 4 "register_operand" "1")))
19351 (set (mem:BLK (match_dup 3))
19353 (use (match_operand:QI 2 "register_operand" "a"))
19354 (use (match_dup 4))]
19357 [(set_attr "type" "str")
19358 (set_attr "prefix_rep" "1")
19359 (set_attr "memory" "store")
19360 (set_attr "mode" "QI")])
19362 (define_expand "cmpstrnsi"
19363 [(set (match_operand:SI 0 "register_operand" "")
19364 (compare:SI (match_operand:BLK 1 "general_operand" "")
19365 (match_operand:BLK 2 "general_operand" "")))
19366 (use (match_operand 3 "general_operand" ""))
19367 (use (match_operand 4 "immediate_operand" ""))]
19370 rtx addr1, addr2, out, outlow, count, countreg, align;
19372 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19375 /* Can't use this if the user has appropriated esi or edi. */
19376 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19381 out = gen_reg_rtx (SImode);
19383 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19384 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19385 if (addr1 != XEXP (operands[1], 0))
19386 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19387 if (addr2 != XEXP (operands[2], 0))
19388 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19390 count = operands[3];
19391 countreg = ix86_zero_extend_to_Pmode (count);
19393 /* %%% Iff we are testing strict equality, we can use known alignment
19394 to good advantage. This may be possible with combine, particularly
19395 once cc0 is dead. */
19396 align = operands[4];
19398 if (CONST_INT_P (count))
19400 if (INTVAL (count) == 0)
19402 emit_move_insn (operands[0], const0_rtx);
19405 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19406 operands[1], operands[2]));
19411 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19413 emit_insn (gen_cmpsi_1 (countreg, countreg));
19414 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19415 operands[1], operands[2]));
19418 outlow = gen_lowpart (QImode, out);
19419 emit_insn (gen_cmpintqi (outlow));
19420 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19422 if (operands[0] != out)
19423 emit_move_insn (operands[0], out);
19428 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19430 (define_expand "cmpintqi"
19431 [(set (match_dup 1)
19432 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19434 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19435 (parallel [(set (match_operand:QI 0 "register_operand" "")
19436 (minus:QI (match_dup 1)
19438 (clobber (reg:CC FLAGS_REG))])]
19440 "operands[1] = gen_reg_rtx (QImode);
19441 operands[2] = gen_reg_rtx (QImode);")
19443 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19444 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19446 (define_expand "cmpstrnqi_nz_1"
19447 [(parallel [(set (reg:CC FLAGS_REG)
19448 (compare:CC (match_operand 4 "memory_operand" "")
19449 (match_operand 5 "memory_operand" "")))
19450 (use (match_operand 2 "register_operand" ""))
19451 (use (match_operand:SI 3 "immediate_operand" ""))
19452 (clobber (match_operand 0 "register_operand" ""))
19453 (clobber (match_operand 1 "register_operand" ""))
19454 (clobber (match_dup 2))])]
19456 "ix86_current_function_needs_cld = 1;")
19458 (define_insn "*cmpstrnqi_nz_1"
19459 [(set (reg:CC FLAGS_REG)
19460 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19461 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19462 (use (match_operand:SI 6 "register_operand" "2"))
19463 (use (match_operand:SI 3 "immediate_operand" "i"))
19464 (clobber (match_operand:SI 0 "register_operand" "=S"))
19465 (clobber (match_operand:SI 1 "register_operand" "=D"))
19466 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19469 [(set_attr "type" "str")
19470 (set_attr "mode" "QI")
19471 (set_attr "prefix_rep" "1")])
19473 (define_insn "*cmpstrnqi_nz_rex_1"
19474 [(set (reg:CC FLAGS_REG)
19475 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19476 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19477 (use (match_operand:DI 6 "register_operand" "2"))
19478 (use (match_operand:SI 3 "immediate_operand" "i"))
19479 (clobber (match_operand:DI 0 "register_operand" "=S"))
19480 (clobber (match_operand:DI 1 "register_operand" "=D"))
19481 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19484 [(set_attr "type" "str")
19485 (set_attr "mode" "QI")
19486 (set_attr "prefix_rep" "1")])
19488 ;; The same, but the count is not known to not be zero.
19490 (define_expand "cmpstrnqi_1"
19491 [(parallel [(set (reg:CC FLAGS_REG)
19492 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19494 (compare:CC (match_operand 4 "memory_operand" "")
19495 (match_operand 5 "memory_operand" ""))
19497 (use (match_operand:SI 3 "immediate_operand" ""))
19498 (use (reg:CC FLAGS_REG))
19499 (clobber (match_operand 0 "register_operand" ""))
19500 (clobber (match_operand 1 "register_operand" ""))
19501 (clobber (match_dup 2))])]
19503 "ix86_current_function_needs_cld = 1;")
19505 (define_insn "*cmpstrnqi_1"
19506 [(set (reg:CC FLAGS_REG)
19507 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19509 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19510 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19512 (use (match_operand:SI 3 "immediate_operand" "i"))
19513 (use (reg:CC FLAGS_REG))
19514 (clobber (match_operand:SI 0 "register_operand" "=S"))
19515 (clobber (match_operand:SI 1 "register_operand" "=D"))
19516 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19519 [(set_attr "type" "str")
19520 (set_attr "mode" "QI")
19521 (set_attr "prefix_rep" "1")])
19523 (define_insn "*cmpstrnqi_rex_1"
19524 [(set (reg:CC FLAGS_REG)
19525 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19527 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19528 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19530 (use (match_operand:SI 3 "immediate_operand" "i"))
19531 (use (reg:CC FLAGS_REG))
19532 (clobber (match_operand:DI 0 "register_operand" "=S"))
19533 (clobber (match_operand:DI 1 "register_operand" "=D"))
19534 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19537 [(set_attr "type" "str")
19538 (set_attr "mode" "QI")
19539 (set_attr "prefix_rep" "1")])
19541 (define_expand "strlensi"
19542 [(set (match_operand:SI 0 "register_operand" "")
19543 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19544 (match_operand:QI 2 "immediate_operand" "")
19545 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19548 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19554 (define_expand "strlendi"
19555 [(set (match_operand:DI 0 "register_operand" "")
19556 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19557 (match_operand:QI 2 "immediate_operand" "")
19558 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19561 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19567 (define_expand "strlenqi_1"
19568 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19569 (clobber (match_operand 1 "register_operand" ""))
19570 (clobber (reg:CC FLAGS_REG))])]
19572 "ix86_current_function_needs_cld = 1;")
19574 (define_insn "*strlenqi_1"
19575 [(set (match_operand:SI 0 "register_operand" "=&c")
19576 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19577 (match_operand:QI 2 "register_operand" "a")
19578 (match_operand:SI 3 "immediate_operand" "i")
19579 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19580 (clobber (match_operand:SI 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 (define_insn "*strlenqi_rex_1"
19589 [(set (match_operand:DI 0 "register_operand" "=&c")
19590 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19591 (match_operand:QI 2 "register_operand" "a")
19592 (match_operand:DI 3 "immediate_operand" "i")
19593 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19594 (clobber (match_operand:DI 1 "register_operand" "=D"))
19595 (clobber (reg:CC FLAGS_REG))]
19598 [(set_attr "type" "str")
19599 (set_attr "mode" "QI")
19600 (set_attr "prefix_rep" "1")])
19602 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19603 ;; handled in combine, but it is not currently up to the task.
19604 ;; When used for their truth value, the cmpstrn* expanders generate
19613 ;; The intermediate three instructions are unnecessary.
19615 ;; This one handles cmpstrn*_nz_1...
19618 (set (reg:CC FLAGS_REG)
19619 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19620 (mem:BLK (match_operand 5 "register_operand" ""))))
19621 (use (match_operand 6 "register_operand" ""))
19622 (use (match_operand:SI 3 "immediate_operand" ""))
19623 (clobber (match_operand 0 "register_operand" ""))
19624 (clobber (match_operand 1 "register_operand" ""))
19625 (clobber (match_operand 2 "register_operand" ""))])
19626 (set (match_operand:QI 7 "register_operand" "")
19627 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19628 (set (match_operand:QI 8 "register_operand" "")
19629 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19630 (set (reg FLAGS_REG)
19631 (compare (match_dup 7) (match_dup 8)))
19633 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19635 (set (reg:CC FLAGS_REG)
19636 (compare:CC (mem:BLK (match_dup 4))
19637 (mem:BLK (match_dup 5))))
19638 (use (match_dup 6))
19639 (use (match_dup 3))
19640 (clobber (match_dup 0))
19641 (clobber (match_dup 1))
19642 (clobber (match_dup 2))])]
19645 ;; ...and this one handles cmpstrn*_1.
19648 (set (reg:CC FLAGS_REG)
19649 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19651 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19652 (mem:BLK (match_operand 5 "register_operand" "")))
19654 (use (match_operand:SI 3 "immediate_operand" ""))
19655 (use (reg:CC FLAGS_REG))
19656 (clobber (match_operand 0 "register_operand" ""))
19657 (clobber (match_operand 1 "register_operand" ""))
19658 (clobber (match_operand 2 "register_operand" ""))])
19659 (set (match_operand:QI 7 "register_operand" "")
19660 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19661 (set (match_operand:QI 8 "register_operand" "")
19662 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19663 (set (reg FLAGS_REG)
19664 (compare (match_dup 7) (match_dup 8)))
19666 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19668 (set (reg:CC FLAGS_REG)
19669 (if_then_else:CC (ne (match_dup 6)
19671 (compare:CC (mem:BLK (match_dup 4))
19672 (mem:BLK (match_dup 5)))
19674 (use (match_dup 3))
19675 (use (reg:CC FLAGS_REG))
19676 (clobber (match_dup 0))
19677 (clobber (match_dup 1))
19678 (clobber (match_dup 2))])]
19683 ;; Conditional move instructions.
19685 (define_expand "movdicc"
19686 [(set (match_operand:DI 0 "register_operand" "")
19687 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19688 (match_operand:DI 2 "general_operand" "")
19689 (match_operand:DI 3 "general_operand" "")))]
19691 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19693 (define_insn "x86_movdicc_0_m1_rex64"
19694 [(set (match_operand:DI 0 "register_operand" "=r")
19695 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19698 (clobber (reg:CC FLAGS_REG))]
19701 ; Since we don't have the proper number of operands for an alu insn,
19702 ; fill in all the blanks.
19703 [(set_attr "type" "alu")
19704 (set_attr "pent_pair" "pu")
19705 (set_attr "memory" "none")
19706 (set_attr "imm_disp" "false")
19707 (set_attr "mode" "DI")
19708 (set_attr "length_immediate" "0")])
19710 (define_insn "*x86_movdicc_0_m1_se"
19711 [(set (match_operand:DI 0 "register_operand" "=r")
19712 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19715 (clobber (reg:CC FLAGS_REG))]
19718 [(set_attr "type" "alu")
19719 (set_attr "pent_pair" "pu")
19720 (set_attr "memory" "none")
19721 (set_attr "imm_disp" "false")
19722 (set_attr "mode" "DI")
19723 (set_attr "length_immediate" "0")])
19725 (define_insn "*movdicc_c_rex64"
19726 [(set (match_operand:DI 0 "register_operand" "=r,r")
19727 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19728 [(reg FLAGS_REG) (const_int 0)])
19729 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19730 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19731 "TARGET_64BIT && TARGET_CMOVE
19732 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19734 cmov%O2%C1\t{%2, %0|%0, %2}
19735 cmov%O2%c1\t{%3, %0|%0, %3}"
19736 [(set_attr "type" "icmov")
19737 (set_attr "mode" "DI")])
19739 (define_expand "movsicc"
19740 [(set (match_operand:SI 0 "register_operand" "")
19741 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19742 (match_operand:SI 2 "general_operand" "")
19743 (match_operand:SI 3 "general_operand" "")))]
19745 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19747 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19748 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19749 ;; So just document what we're doing explicitly.
19751 (define_insn "x86_movsicc_0_m1"
19752 [(set (match_operand:SI 0 "register_operand" "=r")
19753 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19756 (clobber (reg:CC FLAGS_REG))]
19759 ; Since we don't have the proper number of operands for an alu insn,
19760 ; fill in all the blanks.
19761 [(set_attr "type" "alu")
19762 (set_attr "pent_pair" "pu")
19763 (set_attr "memory" "none")
19764 (set_attr "imm_disp" "false")
19765 (set_attr "mode" "SI")
19766 (set_attr "length_immediate" "0")])
19768 (define_insn "*x86_movsicc_0_m1_se"
19769 [(set (match_operand:SI 0 "register_operand" "=r")
19770 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19773 (clobber (reg:CC FLAGS_REG))]
19776 [(set_attr "type" "alu")
19777 (set_attr "pent_pair" "pu")
19778 (set_attr "memory" "none")
19779 (set_attr "imm_disp" "false")
19780 (set_attr "mode" "SI")
19781 (set_attr "length_immediate" "0")])
19783 (define_insn "*movsicc_noc"
19784 [(set (match_operand:SI 0 "register_operand" "=r,r")
19785 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19786 [(reg FLAGS_REG) (const_int 0)])
19787 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19788 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19790 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19792 cmov%O2%C1\t{%2, %0|%0, %2}
19793 cmov%O2%c1\t{%3, %0|%0, %3}"
19794 [(set_attr "type" "icmov")
19795 (set_attr "mode" "SI")])
19797 (define_expand "movhicc"
19798 [(set (match_operand:HI 0 "register_operand" "")
19799 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19800 (match_operand:HI 2 "general_operand" "")
19801 (match_operand:HI 3 "general_operand" "")))]
19802 "TARGET_HIMODE_MATH"
19803 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19805 (define_insn "*movhicc_noc"
19806 [(set (match_operand:HI 0 "register_operand" "=r,r")
19807 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19808 [(reg FLAGS_REG) (const_int 0)])
19809 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19810 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19812 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19814 cmov%O2%C1\t{%2, %0|%0, %2}
19815 cmov%O2%c1\t{%3, %0|%0, %3}"
19816 [(set_attr "type" "icmov")
19817 (set_attr "mode" "HI")])
19819 (define_expand "movqicc"
19820 [(set (match_operand:QI 0 "register_operand" "")
19821 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19822 (match_operand:QI 2 "general_operand" "")
19823 (match_operand:QI 3 "general_operand" "")))]
19824 "TARGET_QIMODE_MATH"
19825 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19827 (define_insn_and_split "*movqicc_noc"
19828 [(set (match_operand:QI 0 "register_operand" "=r,r")
19829 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19830 [(match_operand 4 "flags_reg_operand" "")
19832 (match_operand:QI 2 "register_operand" "r,0")
19833 (match_operand:QI 3 "register_operand" "0,r")))]
19834 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19836 "&& reload_completed"
19837 [(set (match_dup 0)
19838 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19841 "operands[0] = gen_lowpart (SImode, operands[0]);
19842 operands[2] = gen_lowpart (SImode, operands[2]);
19843 operands[3] = gen_lowpart (SImode, operands[3]);"
19844 [(set_attr "type" "icmov")
19845 (set_attr "mode" "SI")])
19847 (define_expand "mov<mode>cc"
19848 [(set (match_operand:X87MODEF 0 "register_operand" "")
19849 (if_then_else:X87MODEF
19850 (match_operand 1 "comparison_operator" "")
19851 (match_operand:X87MODEF 2 "register_operand" "")
19852 (match_operand:X87MODEF 3 "register_operand" "")))]
19853 "(TARGET_80387 && TARGET_CMOVE)
19854 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19855 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19857 (define_insn "*movsfcc_1_387"
19858 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19859 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19860 [(reg FLAGS_REG) (const_int 0)])
19861 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19862 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19863 "TARGET_80387 && TARGET_CMOVE
19864 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19866 fcmov%F1\t{%2, %0|%0, %2}
19867 fcmov%f1\t{%3, %0|%0, %3}
19868 cmov%O2%C1\t{%2, %0|%0, %2}
19869 cmov%O2%c1\t{%3, %0|%0, %3}"
19870 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19871 (set_attr "mode" "SF,SF,SI,SI")])
19873 (define_insn "*movdfcc_1"
19874 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19875 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19876 [(reg FLAGS_REG) (const_int 0)])
19877 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19878 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19879 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19880 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19882 fcmov%F1\t{%2, %0|%0, %2}
19883 fcmov%f1\t{%3, %0|%0, %3}
19886 [(set_attr "type" "fcmov,fcmov,multi,multi")
19887 (set_attr "mode" "DF")])
19889 (define_insn "*movdfcc_1_rex64"
19890 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19891 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19892 [(reg FLAGS_REG) (const_int 0)])
19893 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19894 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19895 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19896 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19898 fcmov%F1\t{%2, %0|%0, %2}
19899 fcmov%f1\t{%3, %0|%0, %3}
19900 cmov%O2%C1\t{%2, %0|%0, %2}
19901 cmov%O2%c1\t{%3, %0|%0, %3}"
19902 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19903 (set_attr "mode" "DF")])
19906 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19907 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19908 [(match_operand 4 "flags_reg_operand" "")
19910 (match_operand:DF 2 "nonimmediate_operand" "")
19911 (match_operand:DF 3 "nonimmediate_operand" "")))]
19912 "!TARGET_64BIT && reload_completed"
19913 [(set (match_dup 2)
19914 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19918 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19921 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19922 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19924 (define_insn "*movxfcc_1"
19925 [(set (match_operand:XF 0 "register_operand" "=f,f")
19926 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19927 [(reg FLAGS_REG) (const_int 0)])
19928 (match_operand:XF 2 "register_operand" "f,0")
19929 (match_operand:XF 3 "register_operand" "0,f")))]
19930 "TARGET_80387 && TARGET_CMOVE"
19932 fcmov%F1\t{%2, %0|%0, %2}
19933 fcmov%f1\t{%3, %0|%0, %3}"
19934 [(set_attr "type" "fcmov")
19935 (set_attr "mode" "XF")])
19937 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19938 ;; the scalar versions to have only XMM registers as operands.
19940 ;; SSE5 conditional move
19941 (define_insn "*sse5_pcmov_<mode>"
19942 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19943 (if_then_else:MODEF
19944 (match_operand:MODEF 1 "register_operand" "x,0")
19945 (match_operand:MODEF 2 "register_operand" "0,x")
19946 (match_operand:MODEF 3 "register_operand" "x,x")))]
19947 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19948 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19949 [(set_attr "type" "sse4arg")])
19951 ;; These versions of the min/max patterns are intentionally ignorant of
19952 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19953 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19954 ;; are undefined in this condition, we're certain this is correct.
19956 (define_insn "*avx_<code><mode>3"
19957 [(set (match_operand:MODEF 0 "register_operand" "=x")
19959 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19960 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19961 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19962 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19963 [(set_attr "type" "sseadd")
19964 (set_attr "prefix" "vex")
19965 (set_attr "mode" "<MODE>")])
19967 (define_insn "<code><mode>3"
19968 [(set (match_operand:MODEF 0 "register_operand" "=x")
19970 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19971 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19972 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19973 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19974 [(set_attr "type" "sseadd")
19975 (set_attr "mode" "<MODE>")])
19977 ;; These versions of the min/max patterns implement exactly the operations
19978 ;; min = (op1 < op2 ? op1 : op2)
19979 ;; max = (!(op1 < op2) ? op1 : op2)
19980 ;; Their operands are not commutative, and thus they may be used in the
19981 ;; presence of -0.0 and NaN.
19983 (define_insn "*avx_ieee_smin<mode>3"
19984 [(set (match_operand:MODEF 0 "register_operand" "=x")
19986 [(match_operand:MODEF 1 "register_operand" "x")
19987 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19989 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19990 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19991 [(set_attr "type" "sseadd")
19992 (set_attr "prefix" "vex")
19993 (set_attr "mode" "<MODE>")])
19995 (define_insn "*ieee_smin<mode>3"
19996 [(set (match_operand:MODEF 0 "register_operand" "=x")
19998 [(match_operand:MODEF 1 "register_operand" "0")
19999 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20001 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20002 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20003 [(set_attr "type" "sseadd")
20004 (set_attr "mode" "<MODE>")])
20006 (define_insn "*avx_ieee_smax<mode>3"
20007 [(set (match_operand:MODEF 0 "register_operand" "=x")
20009 [(match_operand:MODEF 1 "register_operand" "0")
20010 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20012 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20013 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20014 [(set_attr "type" "sseadd")
20015 (set_attr "prefix" "vex")
20016 (set_attr "mode" "<MODE>")])
20018 (define_insn "*ieee_smax<mode>3"
20019 [(set (match_operand:MODEF 0 "register_operand" "=x")
20021 [(match_operand:MODEF 1 "register_operand" "0")
20022 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20024 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20025 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20026 [(set_attr "type" "sseadd")
20027 (set_attr "mode" "<MODE>")])
20029 ;; Make two stack loads independent:
20031 ;; fld %st(0) -> fld bb
20032 ;; fmul bb fmul %st(1), %st
20034 ;; Actually we only match the last two instructions for simplicity.
20036 [(set (match_operand 0 "fp_register_operand" "")
20037 (match_operand 1 "fp_register_operand" ""))
20039 (match_operator 2 "binary_fp_operator"
20041 (match_operand 3 "memory_operand" "")]))]
20042 "REGNO (operands[0]) != REGNO (operands[1])"
20043 [(set (match_dup 0) (match_dup 3))
20044 (set (match_dup 0) (match_dup 4))]
20046 ;; The % modifier is not operational anymore in peephole2's, so we have to
20047 ;; swap the operands manually in the case of addition and multiplication.
20048 "if (COMMUTATIVE_ARITH_P (operands[2]))
20049 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20050 operands[0], operands[1]);
20052 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20053 operands[1], operands[0]);")
20055 ;; Conditional addition patterns
20056 (define_expand "add<mode>cc"
20057 [(match_operand:SWI 0 "register_operand" "")
20058 (match_operand 1 "comparison_operator" "")
20059 (match_operand:SWI 2 "register_operand" "")
20060 (match_operand:SWI 3 "const_int_operand" "")]
20062 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20065 ;; Misc patterns (?)
20067 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20068 ;; Otherwise there will be nothing to keep
20070 ;; [(set (reg ebp) (reg esp))]
20071 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20072 ;; (clobber (eflags)]
20073 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20075 ;; in proper program order.
20076 (define_insn "pro_epilogue_adjust_stack_1"
20077 [(set (match_operand:SI 0 "register_operand" "=r,r")
20078 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20079 (match_operand:SI 2 "immediate_operand" "i,i")))
20080 (clobber (reg:CC FLAGS_REG))
20081 (clobber (mem:BLK (scratch)))]
20084 switch (get_attr_type (insn))
20087 return "mov{l}\t{%1, %0|%0, %1}";
20090 if (CONST_INT_P (operands[2])
20091 && (INTVAL (operands[2]) == 128
20092 || (INTVAL (operands[2]) < 0
20093 && INTVAL (operands[2]) != -128)))
20095 operands[2] = GEN_INT (-INTVAL (operands[2]));
20096 return "sub{l}\t{%2, %0|%0, %2}";
20098 return "add{l}\t{%2, %0|%0, %2}";
20101 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20102 return "lea{l}\t{%a2, %0|%0, %a2}";
20105 gcc_unreachable ();
20108 [(set (attr "type")
20109 (cond [(eq_attr "alternative" "0")
20110 (const_string "alu")
20111 (match_operand:SI 2 "const0_operand" "")
20112 (const_string "imov")
20114 (const_string "lea")))
20115 (set_attr "mode" "SI")])
20117 (define_insn "pro_epilogue_adjust_stack_rex64"
20118 [(set (match_operand:DI 0 "register_operand" "=r,r")
20119 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20120 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20121 (clobber (reg:CC FLAGS_REG))
20122 (clobber (mem:BLK (scratch)))]
20125 switch (get_attr_type (insn))
20128 return "mov{q}\t{%1, %0|%0, %1}";
20131 if (CONST_INT_P (operands[2])
20132 /* Avoid overflows. */
20133 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20134 && (INTVAL (operands[2]) == 128
20135 || (INTVAL (operands[2]) < 0
20136 && INTVAL (operands[2]) != -128)))
20138 operands[2] = GEN_INT (-INTVAL (operands[2]));
20139 return "sub{q}\t{%2, %0|%0, %2}";
20141 return "add{q}\t{%2, %0|%0, %2}";
20144 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20145 return "lea{q}\t{%a2, %0|%0, %a2}";
20148 gcc_unreachable ();
20151 [(set (attr "type")
20152 (cond [(eq_attr "alternative" "0")
20153 (const_string "alu")
20154 (match_operand:DI 2 "const0_operand" "")
20155 (const_string "imov")
20157 (const_string "lea")))
20158 (set_attr "mode" "DI")])
20160 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20161 [(set (match_operand:DI 0 "register_operand" "=r,r")
20162 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20163 (match_operand:DI 3 "immediate_operand" "i,i")))
20164 (use (match_operand:DI 2 "register_operand" "r,r"))
20165 (clobber (reg:CC FLAGS_REG))
20166 (clobber (mem:BLK (scratch)))]
20169 switch (get_attr_type (insn))
20172 return "add{q}\t{%2, %0|%0, %2}";
20175 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20176 return "lea{q}\t{%a2, %0|%0, %a2}";
20179 gcc_unreachable ();
20182 [(set_attr "type" "alu,lea")
20183 (set_attr "mode" "DI")])
20185 (define_insn "allocate_stack_worker_32"
20186 [(set (match_operand:SI 0 "register_operand" "=a")
20187 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20188 UNSPECV_STACK_PROBE))
20189 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20190 (clobber (reg:CC FLAGS_REG))]
20191 "!TARGET_64BIT && TARGET_STACK_PROBE"
20193 [(set_attr "type" "multi")
20194 (set_attr "length" "5")])
20196 (define_insn "allocate_stack_worker_64"
20197 [(set (match_operand:DI 0 "register_operand" "=a")
20198 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20199 UNSPECV_STACK_PROBE))
20200 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20201 (clobber (reg:DI R10_REG))
20202 (clobber (reg:DI R11_REG))
20203 (clobber (reg:CC FLAGS_REG))]
20204 "TARGET_64BIT && TARGET_STACK_PROBE"
20206 [(set_attr "type" "multi")
20207 (set_attr "length" "5")])
20209 (define_expand "allocate_stack"
20210 [(match_operand 0 "register_operand" "")
20211 (match_operand 1 "general_operand" "")]
20212 "TARGET_STACK_PROBE"
20216 #ifndef CHECK_STACK_LIMIT
20217 #define CHECK_STACK_LIMIT 0
20220 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20221 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20223 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20224 stack_pointer_rtx, 0, OPTAB_DIRECT);
20225 if (x != stack_pointer_rtx)
20226 emit_move_insn (stack_pointer_rtx, x);
20230 x = copy_to_mode_reg (Pmode, operands[1]);
20232 x = gen_allocate_stack_worker_64 (x, x);
20234 x = gen_allocate_stack_worker_32 (x, x);
20238 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20242 (define_expand "builtin_setjmp_receiver"
20243 [(label_ref (match_operand 0 "" ""))]
20244 "!TARGET_64BIT && flag_pic"
20250 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20251 rtx label_rtx = gen_label_rtx ();
20252 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20253 xops[0] = xops[1] = picreg;
20254 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20255 ix86_expand_binary_operator (MINUS, SImode, xops);
20259 emit_insn (gen_set_got (pic_offset_table_rtx));
20263 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20266 [(set (match_operand 0 "register_operand" "")
20267 (match_operator 3 "promotable_binary_operator"
20268 [(match_operand 1 "register_operand" "")
20269 (match_operand 2 "aligned_operand" "")]))
20270 (clobber (reg:CC FLAGS_REG))]
20271 "! TARGET_PARTIAL_REG_STALL && reload_completed
20272 && ((GET_MODE (operands[0]) == HImode
20273 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20274 /* ??? next two lines just !satisfies_constraint_K (...) */
20275 || !CONST_INT_P (operands[2])
20276 || satisfies_constraint_K (operands[2])))
20277 || (GET_MODE (operands[0]) == QImode
20278 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20279 [(parallel [(set (match_dup 0)
20280 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20281 (clobber (reg:CC FLAGS_REG))])]
20282 "operands[0] = gen_lowpart (SImode, operands[0]);
20283 operands[1] = gen_lowpart (SImode, operands[1]);
20284 if (GET_CODE (operands[3]) != ASHIFT)
20285 operands[2] = gen_lowpart (SImode, operands[2]);
20286 PUT_MODE (operands[3], SImode);")
20288 ; Promote the QImode tests, as i386 has encoding of the AND
20289 ; instruction with 32-bit sign-extended immediate and thus the
20290 ; instruction size is unchanged, except in the %eax case for
20291 ; which it is increased by one byte, hence the ! optimize_size.
20293 [(set (match_operand 0 "flags_reg_operand" "")
20294 (match_operator 2 "compare_operator"
20295 [(and (match_operand 3 "aligned_operand" "")
20296 (match_operand 4 "const_int_operand" ""))
20298 (set (match_operand 1 "register_operand" "")
20299 (and (match_dup 3) (match_dup 4)))]
20300 "! TARGET_PARTIAL_REG_STALL && reload_completed
20301 && optimize_insn_for_speed_p ()
20302 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20303 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20304 /* Ensure that the operand will remain sign-extended immediate. */
20305 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20306 [(parallel [(set (match_dup 0)
20307 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20310 (and:SI (match_dup 3) (match_dup 4)))])]
20313 = gen_int_mode (INTVAL (operands[4])
20314 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20315 operands[1] = gen_lowpart (SImode, operands[1]);
20316 operands[3] = gen_lowpart (SImode, operands[3]);
20319 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20320 ; the TEST instruction with 32-bit sign-extended immediate and thus
20321 ; the instruction size would at least double, which is not what we
20322 ; want even with ! optimize_size.
20324 [(set (match_operand 0 "flags_reg_operand" "")
20325 (match_operator 1 "compare_operator"
20326 [(and (match_operand:HI 2 "aligned_operand" "")
20327 (match_operand:HI 3 "const_int_operand" ""))
20329 "! TARGET_PARTIAL_REG_STALL && reload_completed
20330 && ! TARGET_FAST_PREFIX
20331 && optimize_insn_for_speed_p ()
20332 /* Ensure that the operand will remain sign-extended immediate. */
20333 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20334 [(set (match_dup 0)
20335 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20339 = gen_int_mode (INTVAL (operands[3])
20340 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20341 operands[2] = gen_lowpart (SImode, operands[2]);
20345 [(set (match_operand 0 "register_operand" "")
20346 (neg (match_operand 1 "register_operand" "")))
20347 (clobber (reg:CC FLAGS_REG))]
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 [(parallel [(set (match_dup 0)
20354 (neg:SI (match_dup 1)))
20355 (clobber (reg:CC FLAGS_REG))])]
20356 "operands[0] = gen_lowpart (SImode, operands[0]);
20357 operands[1] = gen_lowpart (SImode, operands[1]);")
20360 [(set (match_operand 0 "register_operand" "")
20361 (not (match_operand 1 "register_operand" "")))]
20362 "! TARGET_PARTIAL_REG_STALL && reload_completed
20363 && (GET_MODE (operands[0]) == HImode
20364 || (GET_MODE (operands[0]) == QImode
20365 && (TARGET_PROMOTE_QImode
20366 || optimize_insn_for_size_p ())))"
20367 [(set (match_dup 0)
20368 (not:SI (match_dup 1)))]
20369 "operands[0] = gen_lowpart (SImode, operands[0]);
20370 operands[1] = gen_lowpart (SImode, operands[1]);")
20373 [(set (match_operand 0 "register_operand" "")
20374 (if_then_else (match_operator 1 "comparison_operator"
20375 [(reg FLAGS_REG) (const_int 0)])
20376 (match_operand 2 "register_operand" "")
20377 (match_operand 3 "register_operand" "")))]
20378 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20379 && (GET_MODE (operands[0]) == HImode
20380 || (GET_MODE (operands[0]) == QImode
20381 && (TARGET_PROMOTE_QImode
20382 || optimize_insn_for_size_p ())))"
20383 [(set (match_dup 0)
20384 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20385 "operands[0] = gen_lowpart (SImode, operands[0]);
20386 operands[2] = gen_lowpart (SImode, operands[2]);
20387 operands[3] = gen_lowpart (SImode, operands[3]);")
20390 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20391 ;; transform a complex memory operation into two memory to register operations.
20393 ;; Don't push memory operands
20395 [(set (match_operand:SI 0 "push_operand" "")
20396 (match_operand:SI 1 "memory_operand" ""))
20397 (match_scratch:SI 2 "r")]
20398 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20399 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20400 [(set (match_dup 2) (match_dup 1))
20401 (set (match_dup 0) (match_dup 2))]
20405 [(set (match_operand:DI 0 "push_operand" "")
20406 (match_operand:DI 1 "memory_operand" ""))
20407 (match_scratch:DI 2 "r")]
20408 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20409 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20410 [(set (match_dup 2) (match_dup 1))
20411 (set (match_dup 0) (match_dup 2))]
20414 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20417 [(set (match_operand:SF 0 "push_operand" "")
20418 (match_operand:SF 1 "memory_operand" ""))
20419 (match_scratch:SF 2 "r")]
20420 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20421 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20422 [(set (match_dup 2) (match_dup 1))
20423 (set (match_dup 0) (match_dup 2))]
20427 [(set (match_operand:HI 0 "push_operand" "")
20428 (match_operand:HI 1 "memory_operand" ""))
20429 (match_scratch:HI 2 "r")]
20430 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20431 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20432 [(set (match_dup 2) (match_dup 1))
20433 (set (match_dup 0) (match_dup 2))]
20437 [(set (match_operand:QI 0 "push_operand" "")
20438 (match_operand:QI 1 "memory_operand" ""))
20439 (match_scratch:QI 2 "q")]
20440 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20441 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20442 [(set (match_dup 2) (match_dup 1))
20443 (set (match_dup 0) (match_dup 2))]
20446 ;; Don't move an immediate directly to memory when the instruction
20449 [(match_scratch:SI 1 "r")
20450 (set (match_operand:SI 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 1) (const_int 0))
20458 (clobber (reg:CC FLAGS_REG))])
20459 (set (match_dup 0) (match_dup 1))]
20463 [(match_scratch:HI 1 "r")
20464 (set (match_operand:HI 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:QI 1 "q")
20478 (set (match_operand:QI 0 "memory_operand" "")
20480 "optimize_insn_for_speed_p ()
20481 && ! TARGET_USE_MOV0
20482 && TARGET_SPLIT_LONG_MOVES
20483 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20484 && peep2_regno_dead_p (0, FLAGS_REG)"
20485 [(parallel [(set (match_dup 2) (const_int 0))
20486 (clobber (reg:CC FLAGS_REG))])
20487 (set (match_dup 0) (match_dup 1))]
20488 "operands[2] = gen_lowpart (SImode, operands[1]);")
20491 [(match_scratch:SI 2 "r")
20492 (set (match_operand:SI 0 "memory_operand" "")
20493 (match_operand:SI 1 "immediate_operand" ""))]
20494 "optimize_insn_for_speed_p ()
20495 && TARGET_SPLIT_LONG_MOVES
20496 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20497 [(set (match_dup 2) (match_dup 1))
20498 (set (match_dup 0) (match_dup 2))]
20502 [(match_scratch:HI 2 "r")
20503 (set (match_operand:HI 0 "memory_operand" "")
20504 (match_operand:HI 1 "immediate_operand" ""))]
20505 "optimize_insn_for_speed_p ()
20506 && TARGET_SPLIT_LONG_MOVES
20507 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20508 [(set (match_dup 2) (match_dup 1))
20509 (set (match_dup 0) (match_dup 2))]
20513 [(match_scratch:QI 2 "q")
20514 (set (match_operand:QI 0 "memory_operand" "")
20515 (match_operand:QI 1 "immediate_operand" ""))]
20516 "optimize_insn_for_speed_p ()
20517 && TARGET_SPLIT_LONG_MOVES
20518 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20519 [(set (match_dup 2) (match_dup 1))
20520 (set (match_dup 0) (match_dup 2))]
20523 ;; Don't compare memory with zero, load and use a test instead.
20525 [(set (match_operand 0 "flags_reg_operand" "")
20526 (match_operator 1 "compare_operator"
20527 [(match_operand:SI 2 "memory_operand" "")
20529 (match_scratch:SI 3 "r")]
20530 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20531 [(set (match_dup 3) (match_dup 2))
20532 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20535 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20536 ;; Don't split NOTs with a displacement operand, because resulting XOR
20537 ;; will not be pairable anyway.
20539 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20540 ;; represented using a modRM byte. The XOR replacement is long decoded,
20541 ;; so this split helps here as well.
20543 ;; Note: Can't do this as a regular split because we can't get proper
20544 ;; lifetime information then.
20547 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20548 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20549 "optimize_insn_for_speed_p ()
20550 && ((TARGET_NOT_UNPAIRABLE
20551 && (!MEM_P (operands[0])
20552 || !memory_displacement_operand (operands[0], SImode)))
20553 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20554 && peep2_regno_dead_p (0, FLAGS_REG)"
20555 [(parallel [(set (match_dup 0)
20556 (xor:SI (match_dup 1) (const_int -1)))
20557 (clobber (reg:CC FLAGS_REG))])]
20561 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20562 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20563 "optimize_insn_for_speed_p ()
20564 && ((TARGET_NOT_UNPAIRABLE
20565 && (!MEM_P (operands[0])
20566 || !memory_displacement_operand (operands[0], HImode)))
20567 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20568 && peep2_regno_dead_p (0, FLAGS_REG)"
20569 [(parallel [(set (match_dup 0)
20570 (xor:HI (match_dup 1) (const_int -1)))
20571 (clobber (reg:CC FLAGS_REG))])]
20575 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20576 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20577 "optimize_insn_for_speed_p ()
20578 && ((TARGET_NOT_UNPAIRABLE
20579 && (!MEM_P (operands[0])
20580 || !memory_displacement_operand (operands[0], QImode)))
20581 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20582 && peep2_regno_dead_p (0, FLAGS_REG)"
20583 [(parallel [(set (match_dup 0)
20584 (xor:QI (match_dup 1) (const_int -1)))
20585 (clobber (reg:CC FLAGS_REG))])]
20588 ;; Non pairable "test imm, reg" instructions can be translated to
20589 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20590 ;; byte opcode instead of two, have a short form for byte operands),
20591 ;; so do it for other CPUs as well. Given that the value was dead,
20592 ;; this should not create any new dependencies. Pass on the sub-word
20593 ;; versions if we're concerned about partial register stalls.
20596 [(set (match_operand 0 "flags_reg_operand" "")
20597 (match_operator 1 "compare_operator"
20598 [(and:SI (match_operand:SI 2 "register_operand" "")
20599 (match_operand:SI 3 "immediate_operand" ""))
20601 "ix86_match_ccmode (insn, CCNOmode)
20602 && (true_regnum (operands[2]) != AX_REG
20603 || satisfies_constraint_K (operands[3]))
20604 && peep2_reg_dead_p (1, operands[2])"
20606 [(set (match_dup 0)
20607 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20610 (and:SI (match_dup 2) (match_dup 3)))])]
20613 ;; We don't need to handle HImode case, because it will be promoted to SImode
20614 ;; on ! TARGET_PARTIAL_REG_STALL
20617 [(set (match_operand 0 "flags_reg_operand" "")
20618 (match_operator 1 "compare_operator"
20619 [(and:QI (match_operand:QI 2 "register_operand" "")
20620 (match_operand:QI 3 "immediate_operand" ""))
20622 "! TARGET_PARTIAL_REG_STALL
20623 && ix86_match_ccmode (insn, CCNOmode)
20624 && true_regnum (operands[2]) != AX_REG
20625 && peep2_reg_dead_p (1, operands[2])"
20627 [(set (match_dup 0)
20628 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20631 (and:QI (match_dup 2) (match_dup 3)))])]
20635 [(set (match_operand 0 "flags_reg_operand" "")
20636 (match_operator 1 "compare_operator"
20639 (match_operand 2 "ext_register_operand" "")
20642 (match_operand 3 "const_int_operand" ""))
20644 "! TARGET_PARTIAL_REG_STALL
20645 && ix86_match_ccmode (insn, CCNOmode)
20646 && true_regnum (operands[2]) != AX_REG
20647 && peep2_reg_dead_p (1, operands[2])"
20648 [(parallel [(set (match_dup 0)
20657 (set (zero_extract:SI (match_dup 2)
20668 ;; Don't do logical operations with memory inputs.
20670 [(match_scratch:SI 2 "r")
20671 (parallel [(set (match_operand:SI 0 "register_operand" "")
20672 (match_operator:SI 3 "arith_or_logical_operator"
20674 (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 0) (match_dup 2)]))
20680 (clobber (reg:CC FLAGS_REG))])]
20684 [(match_scratch:SI 2 "r")
20685 (parallel [(set (match_operand:SI 0 "register_operand" "")
20686 (match_operator:SI 3 "arith_or_logical_operator"
20687 [(match_operand:SI 1 "memory_operand" "")
20689 (clobber (reg:CC FLAGS_REG))])]
20690 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20691 [(set (match_dup 2) (match_dup 1))
20692 (parallel [(set (match_dup 0)
20693 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20694 (clobber (reg:CC FLAGS_REG))])]
20697 ; Don't do logical operations with memory outputs
20699 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20700 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20701 ; the same decoder scheduling characteristics as the original.
20704 [(match_scratch:SI 2 "r")
20705 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20706 (match_operator:SI 3 "arith_or_logical_operator"
20708 (match_operand:SI 1 "nonmemory_operand" "")]))
20709 (clobber (reg:CC FLAGS_REG))])]
20710 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20711 [(set (match_dup 2) (match_dup 0))
20712 (parallel [(set (match_dup 2)
20713 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20714 (clobber (reg:CC FLAGS_REG))])
20715 (set (match_dup 0) (match_dup 2))]
20719 [(match_scratch:SI 2 "r")
20720 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20721 (match_operator:SI 3 "arith_or_logical_operator"
20722 [(match_operand:SI 1 "nonmemory_operand" "")
20724 (clobber (reg:CC FLAGS_REG))])]
20725 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20726 [(set (match_dup 2) (match_dup 0))
20727 (parallel [(set (match_dup 2)
20728 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20729 (clobber (reg:CC FLAGS_REG))])
20730 (set (match_dup 0) (match_dup 2))]
20733 ;; Attempt to always use XOR for zeroing registers.
20735 [(set (match_operand 0 "register_operand" "")
20736 (match_operand 1 "const0_operand" ""))]
20737 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20738 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20739 && GENERAL_REG_P (operands[0])
20740 && peep2_regno_dead_p (0, FLAGS_REG)"
20741 [(parallel [(set (match_dup 0) (const_int 0))
20742 (clobber (reg:CC FLAGS_REG))])]
20744 operands[0] = gen_lowpart (word_mode, operands[0]);
20748 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20750 "(GET_MODE (operands[0]) == QImode
20751 || GET_MODE (operands[0]) == HImode)
20752 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20753 && peep2_regno_dead_p (0, FLAGS_REG)"
20754 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20755 (clobber (reg:CC FLAGS_REG))])])
20757 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20759 [(set (match_operand 0 "register_operand" "")
20761 "(GET_MODE (operands[0]) == HImode
20762 || GET_MODE (operands[0]) == SImode
20763 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20764 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20765 && peep2_regno_dead_p (0, FLAGS_REG)"
20766 [(parallel [(set (match_dup 0) (const_int -1))
20767 (clobber (reg:CC FLAGS_REG))])]
20768 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20771 ;; Attempt to convert simple leas to adds. These can be created by
20774 [(set (match_operand:SI 0 "register_operand" "")
20775 (plus:SI (match_dup 0)
20776 (match_operand:SI 1 "nonmemory_operand" "")))]
20777 "peep2_regno_dead_p (0, FLAGS_REG)"
20778 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20779 (clobber (reg:CC FLAGS_REG))])]
20783 [(set (match_operand:SI 0 "register_operand" "")
20784 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20785 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20786 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20787 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20788 (clobber (reg:CC FLAGS_REG))])]
20789 "operands[2] = gen_lowpart (SImode, operands[2]);")
20792 [(set (match_operand:DI 0 "register_operand" "")
20793 (plus:DI (match_dup 0)
20794 (match_operand:DI 1 "x86_64_general_operand" "")))]
20795 "peep2_regno_dead_p (0, FLAGS_REG)"
20796 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20797 (clobber (reg:CC FLAGS_REG))])]
20801 [(set (match_operand:SI 0 "register_operand" "")
20802 (mult:SI (match_dup 0)
20803 (match_operand:SI 1 "const_int_operand" "")))]
20804 "exact_log2 (INTVAL (operands[1])) >= 0
20805 && peep2_regno_dead_p (0, FLAGS_REG)"
20806 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20807 (clobber (reg:CC FLAGS_REG))])]
20808 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20811 [(set (match_operand:DI 0 "register_operand" "")
20812 (mult:DI (match_dup 0)
20813 (match_operand:DI 1 "const_int_operand" "")))]
20814 "exact_log2 (INTVAL (operands[1])) >= 0
20815 && peep2_regno_dead_p (0, FLAGS_REG)"
20816 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20817 (clobber (reg:CC FLAGS_REG))])]
20818 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20821 [(set (match_operand:SI 0 "register_operand" "")
20822 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20823 (match_operand:DI 2 "const_int_operand" "")) 0))]
20824 "exact_log2 (INTVAL (operands[2])) >= 0
20825 && REGNO (operands[0]) == REGNO (operands[1])
20826 && peep2_regno_dead_p (0, FLAGS_REG)"
20827 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20828 (clobber (reg:CC FLAGS_REG))])]
20829 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20831 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20832 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20833 ;; many CPUs it is also faster, since special hardware to avoid esp
20834 ;; dependencies is present.
20836 ;; While some of these conversions may be done using splitters, we use peepholes
20837 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20839 ;; Convert prologue esp subtractions to push.
20840 ;; We need register to push. In order to keep verify_flow_info happy we have
20842 ;; - use scratch and clobber it in order to avoid dependencies
20843 ;; - use already live register
20844 ;; We can't use the second way right now, since there is no reliable way how to
20845 ;; verify that given register is live. First choice will also most likely in
20846 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20847 ;; call clobbered registers are dead. We may want to use base pointer as an
20848 ;; alternative when no register is available later.
20851 [(match_scratch:SI 0 "r")
20852 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20853 (clobber (reg:CC FLAGS_REG))
20854 (clobber (mem:BLK (scratch)))])]
20855 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20856 [(clobber (match_dup 0))
20857 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20858 (clobber (mem:BLK (scratch)))])])
20861 [(match_scratch:SI 0 "r")
20862 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20863 (clobber (reg:CC FLAGS_REG))
20864 (clobber (mem:BLK (scratch)))])]
20865 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20866 [(clobber (match_dup 0))
20867 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20868 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20869 (clobber (mem:BLK (scratch)))])])
20871 ;; Convert esp subtractions to push.
20873 [(match_scratch:SI 0 "r")
20874 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20875 (clobber (reg:CC FLAGS_REG))])]
20876 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20877 [(clobber (match_dup 0))
20878 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20881 [(match_scratch:SI 0 "r")
20882 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20883 (clobber (reg:CC FLAGS_REG))])]
20884 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20885 [(clobber (match_dup 0))
20886 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20887 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20889 ;; Convert epilogue deallocator to pop.
20891 [(match_scratch:SI 0 "r")
20892 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20893 (clobber (reg:CC FLAGS_REG))
20894 (clobber (mem:BLK (scratch)))])]
20895 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
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)))])]
20901 ;; Two pops case is tricky, since pop causes dependency on destination register.
20902 ;; We use two registers if available.
20904 [(match_scratch:SI 0 "r")
20905 (match_scratch:SI 1 "r")
20906 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20907 (clobber (reg:CC FLAGS_REG))
20908 (clobber (mem:BLK (scratch)))])]
20909 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20910 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20911 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20912 (clobber (mem:BLK (scratch)))])
20913 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20914 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20918 [(match_scratch:SI 0 "r")
20919 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20920 (clobber (reg:CC FLAGS_REG))
20921 (clobber (mem:BLK (scratch)))])]
20922 "optimize_insn_for_size_p ()"
20923 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20924 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20925 (clobber (mem:BLK (scratch)))])
20926 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20927 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20930 ;; Convert esp additions to pop.
20932 [(match_scratch:SI 0 "r")
20933 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20934 (clobber (reg:CC FLAGS_REG))])]
20936 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20937 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20940 ;; Two pops case is tricky, since pop causes dependency on destination register.
20941 ;; We use two registers if available.
20943 [(match_scratch:SI 0 "r")
20944 (match_scratch:SI 1 "r")
20945 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20946 (clobber (reg:CC FLAGS_REG))])]
20948 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20949 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20950 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20951 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20955 [(match_scratch:SI 0 "r")
20956 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20957 (clobber (reg:CC FLAGS_REG))])]
20958 "optimize_insn_for_size_p ()"
20959 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20960 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20961 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20962 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20965 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20966 ;; required and register dies. Similarly for 128 to -128.
20968 [(set (match_operand 0 "flags_reg_operand" "")
20969 (match_operator 1 "compare_operator"
20970 [(match_operand 2 "register_operand" "")
20971 (match_operand 3 "const_int_operand" "")]))]
20972 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20973 && incdec_operand (operands[3], GET_MODE (operands[3])))
20974 || (!TARGET_FUSE_CMP_AND_BRANCH
20975 && INTVAL (operands[3]) == 128))
20976 && ix86_match_ccmode (insn, CCGCmode)
20977 && peep2_reg_dead_p (1, operands[2])"
20978 [(parallel [(set (match_dup 0)
20979 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20980 (clobber (match_dup 2))])]
20984 [(match_scratch:DI 0 "r")
20985 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20986 (clobber (reg:CC FLAGS_REG))
20987 (clobber (mem:BLK (scratch)))])]
20988 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20989 [(clobber (match_dup 0))
20990 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20991 (clobber (mem:BLK (scratch)))])])
20994 [(match_scratch:DI 0 "r")
20995 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20996 (clobber (reg:CC FLAGS_REG))
20997 (clobber (mem:BLK (scratch)))])]
20998 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20999 [(clobber (match_dup 0))
21000 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21001 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21002 (clobber (mem:BLK (scratch)))])])
21004 ;; Convert esp subtractions to push.
21006 [(match_scratch:DI 0 "r")
21007 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21008 (clobber (reg:CC FLAGS_REG))])]
21009 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21010 [(clobber (match_dup 0))
21011 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21014 [(match_scratch:DI 0 "r")
21015 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21016 (clobber (reg:CC FLAGS_REG))])]
21017 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21018 [(clobber (match_dup 0))
21019 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21020 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21022 ;; Convert epilogue deallocator to pop.
21024 [(match_scratch:DI 0 "r")
21025 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21026 (clobber (reg:CC FLAGS_REG))
21027 (clobber (mem:BLK (scratch)))])]
21028 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
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)))])]
21034 ;; Two pops case is tricky, since pop causes dependency on destination register.
21035 ;; We use two registers if available.
21037 [(match_scratch:DI 0 "r")
21038 (match_scratch:DI 1 "r")
21039 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21040 (clobber (reg:CC FLAGS_REG))
21041 (clobber (mem:BLK (scratch)))])]
21042 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21043 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21044 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21045 (clobber (mem:BLK (scratch)))])
21046 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21047 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21051 [(match_scratch:DI 0 "r")
21052 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21053 (clobber (reg:CC FLAGS_REG))
21054 (clobber (mem:BLK (scratch)))])]
21055 "optimize_insn_for_size_p ()"
21056 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21057 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21058 (clobber (mem:BLK (scratch)))])
21059 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21060 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21063 ;; Convert esp additions to pop.
21065 [(match_scratch:DI 0 "r")
21066 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21067 (clobber (reg:CC FLAGS_REG))])]
21069 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21070 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21073 ;; Two pops case is tricky, since pop causes dependency on destination register.
21074 ;; We use two registers if available.
21076 [(match_scratch:DI 0 "r")
21077 (match_scratch:DI 1 "r")
21078 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21079 (clobber (reg:CC FLAGS_REG))])]
21081 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21082 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21083 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21084 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21088 [(match_scratch:DI 0 "r")
21089 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21090 (clobber (reg:CC FLAGS_REG))])]
21091 "optimize_insn_for_size_p ()"
21092 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21093 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21094 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21095 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21098 ;; Convert imul by three, five and nine into lea
21101 [(set (match_operand:SI 0 "register_operand" "")
21102 (mult:SI (match_operand:SI 1 "register_operand" "")
21103 (match_operand:SI 2 "const_int_operand" "")))
21104 (clobber (reg:CC FLAGS_REG))])]
21105 "INTVAL (operands[2]) == 3
21106 || INTVAL (operands[2]) == 5
21107 || INTVAL (operands[2]) == 9"
21108 [(set (match_dup 0)
21109 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21111 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21115 [(set (match_operand:SI 0 "register_operand" "")
21116 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21117 (match_operand:SI 2 "const_int_operand" "")))
21118 (clobber (reg:CC FLAGS_REG))])]
21119 "optimize_insn_for_speed_p ()
21120 && (INTVAL (operands[2]) == 3
21121 || INTVAL (operands[2]) == 5
21122 || INTVAL (operands[2]) == 9)"
21123 [(set (match_dup 0) (match_dup 1))
21125 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21127 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21131 [(set (match_operand:DI 0 "register_operand" "")
21132 (mult:DI (match_operand:DI 1 "register_operand" "")
21133 (match_operand:DI 2 "const_int_operand" "")))
21134 (clobber (reg:CC FLAGS_REG))])]
21136 && (INTVAL (operands[2]) == 3
21137 || INTVAL (operands[2]) == 5
21138 || INTVAL (operands[2]) == 9)"
21139 [(set (match_dup 0)
21140 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21142 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21146 [(set (match_operand:DI 0 "register_operand" "")
21147 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21148 (match_operand:DI 2 "const_int_operand" "")))
21149 (clobber (reg:CC FLAGS_REG))])]
21151 && optimize_insn_for_speed_p ()
21152 && (INTVAL (operands[2]) == 3
21153 || INTVAL (operands[2]) == 5
21154 || INTVAL (operands[2]) == 9)"
21155 [(set (match_dup 0) (match_dup 1))
21157 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21159 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21161 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21162 ;; imul $32bit_imm, reg, reg is direct decoded.
21164 [(match_scratch:DI 3 "r")
21165 (parallel [(set (match_operand:DI 0 "register_operand" "")
21166 (mult:DI (match_operand:DI 1 "memory_operand" "")
21167 (match_operand:DI 2 "immediate_operand" "")))
21168 (clobber (reg:CC FLAGS_REG))])]
21169 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21170 && !satisfies_constraint_K (operands[2])"
21171 [(set (match_dup 3) (match_dup 1))
21172 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21173 (clobber (reg:CC FLAGS_REG))])]
21177 [(match_scratch:SI 3 "r")
21178 (parallel [(set (match_operand:SI 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) (mult:SI (match_dup 3) (match_dup 2)))
21186 (clobber (reg:CC FLAGS_REG))])]
21190 [(match_scratch:SI 3 "r")
21191 (parallel [(set (match_operand:DI 0 "register_operand" "")
21193 (mult:SI (match_operand:SI 1 "memory_operand" "")
21194 (match_operand:SI 2 "immediate_operand" ""))))
21195 (clobber (reg:CC FLAGS_REG))])]
21196 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21197 && !satisfies_constraint_K (operands[2])"
21198 [(set (match_dup 3) (match_dup 1))
21199 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21200 (clobber (reg:CC FLAGS_REG))])]
21203 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21204 ;; Convert it into imul reg, reg
21205 ;; It would be better to force assembler to encode instruction using long
21206 ;; immediate, but there is apparently no way to do so.
21208 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21209 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21210 (match_operand:DI 2 "const_int_operand" "")))
21211 (clobber (reg:CC FLAGS_REG))])
21212 (match_scratch:DI 3 "r")]
21213 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21214 && satisfies_constraint_K (operands[2])"
21215 [(set (match_dup 3) (match_dup 2))
21216 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21217 (clobber (reg:CC FLAGS_REG))])]
21219 if (!rtx_equal_p (operands[0], operands[1]))
21220 emit_move_insn (operands[0], operands[1]);
21224 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21225 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21226 (match_operand:SI 2 "const_int_operand" "")))
21227 (clobber (reg:CC FLAGS_REG))])
21228 (match_scratch:SI 3 "r")]
21229 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21230 && satisfies_constraint_K (operands[2])"
21231 [(set (match_dup 3) (match_dup 2))
21232 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21233 (clobber (reg:CC FLAGS_REG))])]
21235 if (!rtx_equal_p (operands[0], operands[1]))
21236 emit_move_insn (operands[0], operands[1]);
21240 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21241 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21242 (match_operand:HI 2 "immediate_operand" "")))
21243 (clobber (reg:CC FLAGS_REG))])
21244 (match_scratch:HI 3 "r")]
21245 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21246 [(set (match_dup 3) (match_dup 2))
21247 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21248 (clobber (reg:CC FLAGS_REG))])]
21250 if (!rtx_equal_p (operands[0], operands[1]))
21251 emit_move_insn (operands[0], operands[1]);
21254 ;; After splitting up read-modify operations, array accesses with memory
21255 ;; operands might end up in form:
21257 ;; movl 4(%esp), %edx
21259 ;; instead of pre-splitting:
21261 ;; addl 4(%esp), %eax
21263 ;; movl 4(%esp), %edx
21264 ;; leal (%edx,%eax,4), %eax
21267 [(parallel [(set (match_operand 0 "register_operand" "")
21268 (ashift (match_operand 1 "register_operand" "")
21269 (match_operand 2 "const_int_operand" "")))
21270 (clobber (reg:CC FLAGS_REG))])
21271 (set (match_operand 3 "register_operand")
21272 (match_operand 4 "x86_64_general_operand" ""))
21273 (parallel [(set (match_operand 5 "register_operand" "")
21274 (plus (match_operand 6 "register_operand" "")
21275 (match_operand 7 "register_operand" "")))
21276 (clobber (reg:CC FLAGS_REG))])]
21277 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21278 /* Validate MODE for lea. */
21279 && ((!TARGET_PARTIAL_REG_STALL
21280 && (GET_MODE (operands[0]) == QImode
21281 || GET_MODE (operands[0]) == HImode))
21282 || GET_MODE (operands[0]) == SImode
21283 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21284 /* We reorder load and the shift. */
21285 && !rtx_equal_p (operands[1], operands[3])
21286 && !reg_overlap_mentioned_p (operands[0], operands[4])
21287 /* Last PLUS must consist of operand 0 and 3. */
21288 && !rtx_equal_p (operands[0], operands[3])
21289 && (rtx_equal_p (operands[3], operands[6])
21290 || rtx_equal_p (operands[3], operands[7]))
21291 && (rtx_equal_p (operands[0], operands[6])
21292 || rtx_equal_p (operands[0], operands[7]))
21293 /* The intermediate operand 0 must die or be same as output. */
21294 && (rtx_equal_p (operands[0], operands[5])
21295 || peep2_reg_dead_p (3, operands[0]))"
21296 [(set (match_dup 3) (match_dup 4))
21297 (set (match_dup 0) (match_dup 1))]
21299 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21300 int scale = 1 << INTVAL (operands[2]);
21301 rtx index = gen_lowpart (Pmode, operands[1]);
21302 rtx base = gen_lowpart (Pmode, operands[3]);
21303 rtx dest = gen_lowpart (mode, operands[5]);
21305 operands[1] = gen_rtx_PLUS (Pmode, base,
21306 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21308 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21309 operands[0] = dest;
21312 ;; Call-value patterns last so that the wildcard operand does not
21313 ;; disrupt insn-recog's switch tables.
21315 (define_insn "*call_value_pop_0"
21316 [(set (match_operand 0 "" "")
21317 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21318 (match_operand:SI 2 "" "")))
21319 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21320 (match_operand:SI 3 "immediate_operand" "")))]
21323 if (SIBLING_CALL_P (insn))
21326 return "call\t%P1";
21328 [(set_attr "type" "callv")])
21330 (define_insn "*call_value_pop_1"
21331 [(set (match_operand 0 "" "")
21332 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21333 (match_operand:SI 2 "" "")))
21334 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21335 (match_operand:SI 3 "immediate_operand" "i")))]
21338 if (constant_call_address_operand (operands[1], Pmode))
21340 if (SIBLING_CALL_P (insn))
21343 return "call\t%P1";
21345 if (SIBLING_CALL_P (insn))
21348 return "call\t%A1";
21350 [(set_attr "type" "callv")])
21352 (define_insn "*call_value_0"
21353 [(set (match_operand 0 "" "")
21354 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21355 (match_operand:SI 2 "" "")))]
21358 if (SIBLING_CALL_P (insn))
21361 return "call\t%P1";
21363 [(set_attr "type" "callv")])
21365 (define_insn "*call_value_0_rex64"
21366 [(set (match_operand 0 "" "")
21367 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21368 (match_operand:DI 2 "const_int_operand" "")))]
21371 if (SIBLING_CALL_P (insn))
21374 return "call\t%P1";
21376 [(set_attr "type" "callv")])
21378 (define_insn "*call_value_0_rex64_ms_sysv"
21379 [(set (match_operand 0 "" "")
21380 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21381 (match_operand:DI 2 "const_int_operand" "")))
21382 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21383 (clobber (reg:DI SI_REG))
21384 (clobber (reg:DI DI_REG))]
21385 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21387 if (SIBLING_CALL_P (insn))
21390 return "call\t%P1";
21392 [(set_attr "type" "callv")])
21394 (define_insn "*call_value_1"
21395 [(set (match_operand 0 "" "")
21396 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21397 (match_operand:SI 2 "" "")))]
21398 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21400 if (constant_call_address_operand (operands[1], Pmode))
21401 return "call\t%P1";
21402 return "call\t%A1";
21404 [(set_attr "type" "callv")])
21406 (define_insn "*sibcall_value_1"
21407 [(set (match_operand 0 "" "")
21408 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21409 (match_operand:SI 2 "" "")))]
21410 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21412 if (constant_call_address_operand (operands[1], Pmode))
21416 [(set_attr "type" "callv")])
21418 (define_insn "*call_value_1_rex64"
21419 [(set (match_operand 0 "" "")
21420 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21421 (match_operand:DI 2 "" "")))]
21422 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21423 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21425 if (constant_call_address_operand (operands[1], Pmode))
21426 return "call\t%P1";
21427 return "call\t%A1";
21429 [(set_attr "type" "callv")])
21431 (define_insn "*call_value_1_rex64_ms_sysv"
21432 [(set (match_operand 0 "" "")
21433 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21434 (match_operand:DI 2 "" "")))
21435 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21436 (clobber (reg:DI SI_REG))
21437 (clobber (reg:DI DI_REG))]
21438 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21440 if (constant_call_address_operand (operands[1], Pmode))
21441 return "call\t%P1";
21442 return "call\t%A1";
21444 [(set_attr "type" "callv")])
21446 (define_insn "*call_value_1_rex64_large"
21447 [(set (match_operand 0 "" "")
21448 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21449 (match_operand:DI 2 "" "")))]
21450 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21452 [(set_attr "type" "callv")])
21454 (define_insn "*sibcall_value_1_rex64"
21455 [(set (match_operand 0 "" "")
21456 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21457 (match_operand:DI 2 "" "")))]
21458 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21460 [(set_attr "type" "callv")])
21462 (define_insn "*sibcall_value_1_rex64_v"
21463 [(set (match_operand 0 "" "")
21464 (call (mem:QI (reg:DI R11_REG))
21465 (match_operand:DI 1 "" "")))]
21466 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21468 [(set_attr "type" "callv")])
21470 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21471 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21472 ;; caught for use by garbage collectors and the like. Using an insn that
21473 ;; maps to SIGILL makes it more likely the program will rightfully die.
21474 ;; Keeping with tradition, "6" is in honor of #UD.
21475 (define_insn "trap"
21476 [(trap_if (const_int 1) (const_int 6))]
21478 { return ASM_SHORT "0x0b0f"; }
21479 [(set_attr "length" "2")])
21481 (define_expand "sse_prologue_save"
21482 [(parallel [(set (match_operand:BLK 0 "" "")
21483 (unspec:BLK [(reg:DI 21)
21490 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21491 (use (match_operand:DI 1 "register_operand" ""))
21492 (use (match_operand:DI 2 "immediate_operand" ""))
21493 (use (label_ref:DI (match_operand 3 "" "")))])]
21497 (define_insn "*sse_prologue_save_insn"
21498 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21499 (match_operand:DI 4 "const_int_operand" "n")))
21500 (unspec:BLK [(reg:DI 21)
21507 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21508 (use (match_operand:DI 1 "register_operand" "r"))
21509 (use (match_operand:DI 2 "const_int_operand" "i"))
21510 (use (label_ref:DI (match_operand 3 "" "X")))]
21512 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21513 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21516 operands[0] = gen_rtx_MEM (Pmode,
21517 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21518 /* VEX instruction with a REX prefix will #UD. */
21519 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21520 gcc_unreachable ();
21522 output_asm_insn ("jmp\t%A1", operands);
21523 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21525 operands[4] = adjust_address (operands[0], DImode, i*16);
21526 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21527 PUT_MODE (operands[4], TImode);
21528 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21529 output_asm_insn ("rex", operands);
21530 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21532 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21533 CODE_LABEL_NUMBER (operands[3]));
21536 [(set_attr "type" "other")
21537 (set_attr "length_immediate" "0")
21538 (set_attr "length_address" "0")
21539 (set (attr "length")
21541 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21542 (const_string "34")
21543 (const_string "42")))
21544 (set_attr "memory" "store")
21545 (set_attr "modrm" "0")
21546 (set_attr "prefix" "maybe_vex")
21547 (set_attr "mode" "DI")])
21549 (define_expand "prefetch"
21550 [(prefetch (match_operand 0 "address_operand" "")
21551 (match_operand:SI 1 "const_int_operand" "")
21552 (match_operand:SI 2 "const_int_operand" ""))]
21553 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21555 int rw = INTVAL (operands[1]);
21556 int locality = INTVAL (operands[2]);
21558 gcc_assert (rw == 0 || rw == 1);
21559 gcc_assert (locality >= 0 && locality <= 3);
21560 gcc_assert (GET_MODE (operands[0]) == Pmode
21561 || GET_MODE (operands[0]) == VOIDmode);
21563 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21564 supported by SSE counterpart or the SSE prefetch is not available
21565 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21567 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21568 operands[2] = GEN_INT (3);
21570 operands[1] = const0_rtx;
21573 (define_insn "*prefetch_sse"
21574 [(prefetch (match_operand:SI 0 "address_operand" "p")
21576 (match_operand:SI 1 "const_int_operand" ""))]
21577 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21579 static const char * const patterns[4] = {
21580 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21583 int locality = INTVAL (operands[1]);
21584 gcc_assert (locality >= 0 && locality <= 3);
21586 return patterns[locality];
21588 [(set_attr "type" "sse")
21589 (set_attr "memory" "none")])
21591 (define_insn "*prefetch_sse_rex"
21592 [(prefetch (match_operand:DI 0 "address_operand" "p")
21594 (match_operand:SI 1 "const_int_operand" ""))]
21595 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21597 static const char * const patterns[4] = {
21598 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21601 int locality = INTVAL (operands[1]);
21602 gcc_assert (locality >= 0 && locality <= 3);
21604 return patterns[locality];
21606 [(set_attr "type" "sse")
21607 (set_attr "memory" "none")])
21609 (define_insn "*prefetch_3dnow"
21610 [(prefetch (match_operand:SI 0 "address_operand" "p")
21611 (match_operand:SI 1 "const_int_operand" "n")
21613 "TARGET_3DNOW && !TARGET_64BIT"
21615 if (INTVAL (operands[1]) == 0)
21616 return "prefetch\t%a0";
21618 return "prefetchw\t%a0";
21620 [(set_attr "type" "mmx")
21621 (set_attr "memory" "none")])
21623 (define_insn "*prefetch_3dnow_rex"
21624 [(prefetch (match_operand:DI 0 "address_operand" "p")
21625 (match_operand:SI 1 "const_int_operand" "n")
21627 "TARGET_3DNOW && TARGET_64BIT"
21629 if (INTVAL (operands[1]) == 0)
21630 return "prefetch\t%a0";
21632 return "prefetchw\t%a0";
21634 [(set_attr "type" "mmx")
21635 (set_attr "memory" "none")])
21637 (define_expand "stack_protect_set"
21638 [(match_operand 0 "memory_operand" "")
21639 (match_operand 1 "memory_operand" "")]
21642 #ifdef TARGET_THREAD_SSP_OFFSET
21644 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21645 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21647 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21648 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21651 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21653 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21658 (define_insn "stack_protect_set_si"
21659 [(set (match_operand:SI 0 "memory_operand" "=m")
21660 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21661 (set (match_scratch:SI 2 "=&r") (const_int 0))
21662 (clobber (reg:CC FLAGS_REG))]
21664 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21665 [(set_attr "type" "multi")])
21667 (define_insn "stack_protect_set_di"
21668 [(set (match_operand:DI 0 "memory_operand" "=m")
21669 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21670 (set (match_scratch:DI 2 "=&r") (const_int 0))
21671 (clobber (reg:CC FLAGS_REG))]
21673 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21674 [(set_attr "type" "multi")])
21676 (define_insn "stack_tls_protect_set_si"
21677 [(set (match_operand:SI 0 "memory_operand" "=m")
21678 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21679 (set (match_scratch:SI 2 "=&r") (const_int 0))
21680 (clobber (reg:CC FLAGS_REG))]
21682 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21683 [(set_attr "type" "multi")])
21685 (define_insn "stack_tls_protect_set_di"
21686 [(set (match_operand:DI 0 "memory_operand" "=m")
21687 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21688 (set (match_scratch:DI 2 "=&r") (const_int 0))
21689 (clobber (reg:CC FLAGS_REG))]
21692 /* The kernel uses a different segment register for performance reasons; a
21693 system call would not have to trash the userspace segment register,
21694 which would be expensive */
21695 if (ix86_cmodel != CM_KERNEL)
21696 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21698 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21700 [(set_attr "type" "multi")])
21702 (define_expand "stack_protect_test"
21703 [(match_operand 0 "memory_operand" "")
21704 (match_operand 1 "memory_operand" "")
21705 (match_operand 2 "" "")]
21708 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21709 ix86_compare_op0 = operands[0];
21710 ix86_compare_op1 = operands[1];
21711 ix86_compare_emitted = flags;
21713 #ifdef TARGET_THREAD_SSP_OFFSET
21715 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21716 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21718 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21719 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21722 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21724 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21726 emit_jump_insn (gen_beq (operands[2]));
21730 (define_insn "stack_protect_test_si"
21731 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21732 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21733 (match_operand:SI 2 "memory_operand" "m")]
21735 (clobber (match_scratch:SI 3 "=&r"))]
21737 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21738 [(set_attr "type" "multi")])
21740 (define_insn "stack_protect_test_di"
21741 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21742 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21743 (match_operand:DI 2 "memory_operand" "m")]
21745 (clobber (match_scratch:DI 3 "=&r"))]
21747 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21748 [(set_attr "type" "multi")])
21750 (define_insn "stack_tls_protect_test_si"
21751 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21752 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21753 (match_operand:SI 2 "const_int_operand" "i")]
21754 UNSPEC_SP_TLS_TEST))
21755 (clobber (match_scratch:SI 3 "=r"))]
21757 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21758 [(set_attr "type" "multi")])
21760 (define_insn "stack_tls_protect_test_di"
21761 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21762 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21763 (match_operand:DI 2 "const_int_operand" "i")]
21764 UNSPEC_SP_TLS_TEST))
21765 (clobber (match_scratch:DI 3 "=r"))]
21768 /* The kernel uses a different segment register for performance reasons; a
21769 system call would not have to trash the userspace segment register,
21770 which would be expensive */
21771 if (ix86_cmodel != CM_KERNEL)
21772 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21774 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21776 [(set_attr "type" "multi")])
21778 (define_mode_iterator CRC32MODE [QI HI SI])
21779 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21780 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21782 (define_insn "sse4_2_crc32<mode>"
21783 [(set (match_operand:SI 0 "register_operand" "=r")
21785 [(match_operand:SI 1 "register_operand" "0")
21786 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21789 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21790 [(set_attr "type" "sselog1")
21791 (set_attr "prefix_rep" "1")
21792 (set_attr "prefix_extra" "1")
21793 (set_attr "mode" "SI")])
21795 (define_insn "sse4_2_crc32di"
21796 [(set (match_operand:DI 0 "register_operand" "=r")
21798 [(match_operand:DI 1 "register_operand" "0")
21799 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21801 "TARGET_SSE4_2 && TARGET_64BIT"
21802 "crc32q\t{%2, %0|%0, %2}"
21803 [(set_attr "type" "sselog1")
21804 (set_attr "prefix_rep" "1")
21805 (set_attr "prefix_extra" "1")
21806 (set_attr "mode" "DI")])
21810 (include "sync.md")