1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
108 ; Generic math support
110 (UNSPEC_IEEE_MIN 51) ; not commutative
111 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
136 (UNSPEC_XTRACT_FRACT 84)
137 (UNSPEC_XTRACT_EXP 85)
138 (UNSPEC_FSCALE_FRACT 86)
139 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 (UNSPEC_INSERTPS 135)
168 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_PHMINPOSUW 139)
176 (UNSPEC_PCMPESTR 144)
177 (UNSPEC_PCMPISTR 145)
180 (UNSPEC_SSE5_INTRINSIC 150)
181 (UNSPEC_SSE5_UNSIGNED_CMP 151)
182 (UNSPEC_SSE5_TRUEFALSE 152)
183 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_CVTPH2PS 155)
186 (UNSPEC_CVTPS2PH 156)
190 (UNSPEC_AESENCLAST 160)
192 (UNSPEC_AESDECLAST 162)
194 (UNSPEC_AESKEYGENASSIST 164)
201 [(UNSPECV_BLOCKAGE 0)
202 (UNSPECV_STACK_PROBE 1)
211 (UNSPECV_CMPXCHG_1 10)
212 (UNSPECV_CMPXCHG_2 11)
215 (UNSPECV_PROLOGUE_USE 14)
219 ;; Constants to represent pcomtrue/pcomfalse variants
229 ;; Constants used in the SSE5 pperm instruction
231 [(PPERM_SRC 0x00) /* copy source */
232 (PPERM_INVERT 0x20) /* invert source */
233 (PPERM_REVERSE 0x40) /* bit reverse source */
234 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
235 (PPERM_ZERO 0x80) /* all 0's */
236 (PPERM_ONES 0xa0) /* all 1's */
237 (PPERM_SIGN 0xc0) /* propagate sign bit */
238 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
239 (PPERM_SRC1 0x00) /* use first source byte */
240 (PPERM_SRC2 0x10) /* use second source byte */
243 ;; Registers by name.
259 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
262 ;; In C guard expressions, put expressions which may be compile-time
263 ;; constants first. This allows for better optimization. For
264 ;; example, write "TARGET_64BIT && reload_completed", not
265 ;; "reload_completed && TARGET_64BIT".
268 ;; Processor type. This attribute must exactly match the processor_type
269 ;; enumeration in i386.h.
270 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
271 nocona,core2,generic32,generic64,amdfam10"
272 (const (symbol_ref "ix86_tune")))
274 ;; A basic instruction type. Refinements due to arguments to be
275 ;; provided in other attributes.
278 alu,alu1,negnot,imov,imovx,lea,
279 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
280 icmp,test,ibr,setcc,icmov,
281 push,pop,call,callv,leave,
283 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
284 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
285 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
287 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
288 (const_string "other"))
290 ;; Main data type used by the insn
292 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
293 (const_string "unknown"))
295 ;; The CPU unit operations uses.
296 (define_attr "unit" "integer,i387,sse,mmx,unknown"
297 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
298 (const_string "i387")
299 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
300 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
301 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
303 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
305 (eq_attr "type" "other")
306 (const_string "unknown")]
307 (const_string "integer")))
309 ;; The (bounding maximum) length of an instruction immediate.
310 (define_attr "length_immediate" ""
311 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
314 (eq_attr "unit" "i387,sse,mmx")
316 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
318 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
319 (eq_attr "type" "imov,test")
320 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
321 (eq_attr "type" "call")
322 (if_then_else (match_operand 0 "constant_call_address_operand" "")
325 (eq_attr "type" "callv")
326 (if_then_else (match_operand 1 "constant_call_address_operand" "")
329 ;; We don't know the size before shorten_branches. Expect
330 ;; the instruction to fit for better scheduling.
331 (eq_attr "type" "ibr")
334 (symbol_ref "/* Update immediate_length and other attributes! */
335 gcc_unreachable (),1")))
337 ;; The (bounding maximum) length of an instruction address.
338 (define_attr "length_address" ""
339 (cond [(eq_attr "type" "str,other,multi,fxch")
341 (and (eq_attr "type" "call")
342 (match_operand 0 "constant_call_address_operand" ""))
344 (and (eq_attr "type" "callv")
345 (match_operand 1 "constant_call_address_operand" ""))
348 (symbol_ref "ix86_attr_length_address_default (insn)")))
350 ;; Set when length prefix is used.
351 (define_attr "prefix_data16" ""
352 (if_then_else (ior (eq_attr "mode" "HI")
353 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
357 ;; Set when string REP prefix is used.
358 (define_attr "prefix_rep" ""
359 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
363 ;; Set when 0f opcode prefix is used.
364 (define_attr "prefix_0f" ""
366 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
367 (eq_attr "unit" "sse,mmx"))
371 ;; Set when REX opcode prefix is used.
372 (define_attr "prefix_rex" ""
373 (cond [(and (eq_attr "mode" "DI")
374 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
376 (and (eq_attr "mode" "QI")
377 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
380 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
386 ;; There are also additional prefixes in SSSE3.
387 (define_attr "prefix_extra" "" (const_int 0))
389 ;; Set when modrm byte is used.
390 (define_attr "modrm" ""
391 (cond [(eq_attr "type" "str,leave")
393 (eq_attr "unit" "i387")
395 (and (eq_attr "type" "incdec")
396 (ior (match_operand:SI 1 "register_operand" "")
397 (match_operand:HI 1 "register_operand" "")))
399 (and (eq_attr "type" "push")
400 (not (match_operand 1 "memory_operand" "")))
402 (and (eq_attr "type" "pop")
403 (not (match_operand 0 "memory_operand" "")))
405 (and (eq_attr "type" "imov")
406 (ior (and (match_operand 0 "register_operand" "")
407 (match_operand 1 "immediate_operand" ""))
408 (ior (and (match_operand 0 "ax_reg_operand" "")
409 (match_operand 1 "memory_displacement_only_operand" ""))
410 (and (match_operand 0 "memory_displacement_only_operand" "")
411 (match_operand 1 "ax_reg_operand" "")))))
413 (and (eq_attr "type" "call")
414 (match_operand 0 "constant_call_address_operand" ""))
416 (and (eq_attr "type" "callv")
417 (match_operand 1 "constant_call_address_operand" ""))
422 ;; The (bounding maximum) length of an instruction in bytes.
423 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
424 ;; Later we may want to split them and compute proper length as for
426 (define_attr "length" ""
427 (cond [(eq_attr "type" "other,multi,fistp,frndint")
429 (eq_attr "type" "fcmp")
431 (eq_attr "unit" "i387")
433 (plus (attr "prefix_data16")
434 (attr "length_address")))]
435 (plus (plus (attr "modrm")
436 (plus (attr "prefix_0f")
437 (plus (attr "prefix_rex")
438 (plus (attr "prefix_extra")
440 (plus (attr "prefix_rep")
441 (plus (attr "prefix_data16")
442 (plus (attr "length_immediate")
443 (attr "length_address")))))))
445 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
446 ;; `store' if there is a simple memory reference therein, or `unknown'
447 ;; if the instruction is complex.
449 (define_attr "memory" "none,load,store,both,unknown"
450 (cond [(eq_attr "type" "other,multi,str")
451 (const_string "unknown")
452 (eq_attr "type" "lea,fcmov,fpspc")
453 (const_string "none")
454 (eq_attr "type" "fistp,leave")
455 (const_string "both")
456 (eq_attr "type" "frndint")
457 (const_string "load")
458 (eq_attr "type" "push")
459 (if_then_else (match_operand 1 "memory_operand" "")
460 (const_string "both")
461 (const_string "store"))
462 (eq_attr "type" "pop")
463 (if_then_else (match_operand 0 "memory_operand" "")
464 (const_string "both")
465 (const_string "load"))
466 (eq_attr "type" "setcc")
467 (if_then_else (match_operand 0 "memory_operand" "")
468 (const_string "store")
469 (const_string "none"))
470 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
471 (if_then_else (ior (match_operand 0 "memory_operand" "")
472 (match_operand 1 "memory_operand" ""))
473 (const_string "load")
474 (const_string "none"))
475 (eq_attr "type" "ibr")
476 (if_then_else (match_operand 0 "memory_operand" "")
477 (const_string "load")
478 (const_string "none"))
479 (eq_attr "type" "call")
480 (if_then_else (match_operand 0 "constant_call_address_operand" "")
481 (const_string "none")
482 (const_string "load"))
483 (eq_attr "type" "callv")
484 (if_then_else (match_operand 1 "constant_call_address_operand" "")
485 (const_string "none")
486 (const_string "load"))
487 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
488 (match_operand 1 "memory_operand" ""))
489 (const_string "both")
490 (and (match_operand 0 "memory_operand" "")
491 (match_operand 1 "memory_operand" ""))
492 (const_string "both")
493 (match_operand 0 "memory_operand" "")
494 (const_string "store")
495 (match_operand 1 "memory_operand" "")
496 (const_string "load")
498 "!alu1,negnot,ishift1,
499 imov,imovx,icmp,test,bitmanip,
501 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
502 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
503 (match_operand 2 "memory_operand" ""))
504 (const_string "load")
505 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
506 (match_operand 3 "memory_operand" ""))
507 (const_string "load")
509 (const_string "none")))
511 ;; Indicates if an instruction has both an immediate and a displacement.
513 (define_attr "imm_disp" "false,true,unknown"
514 (cond [(eq_attr "type" "other,multi")
515 (const_string "unknown")
516 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
517 (and (match_operand 0 "memory_displacement_operand" "")
518 (match_operand 1 "immediate_operand" "")))
519 (const_string "true")
520 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
521 (and (match_operand 0 "memory_displacement_operand" "")
522 (match_operand 2 "immediate_operand" "")))
523 (const_string "true")
525 (const_string "false")))
527 ;; Indicates if an FP operation has an integer source.
529 (define_attr "fp_int_src" "false,true"
530 (const_string "false"))
532 ;; Defines rounding mode of an FP operation.
534 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
535 (const_string "any"))
537 ;; Describe a user's asm statement.
538 (define_asm_attributes
539 [(set_attr "length" "128")
540 (set_attr "type" "multi")])
542 ;; All integer comparison codes.
543 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
545 ;; All floating-point comparison codes.
546 (define_code_iterator fp_cond [unordered ordered
547 uneq unge ungt unle unlt ltgt ])
549 (define_code_iterator plusminus [plus minus])
551 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
553 ;; Base name for define_insn
554 (define_code_attr plusminus_insn
555 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
556 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
558 ;; Base name for insn mnemonic.
559 (define_code_attr plusminus_mnemonic
560 [(plus "add") (ss_plus "adds") (us_plus "addus")
561 (minus "sub") (ss_minus "subs") (us_minus "subus")])
563 ;; Mark commutative operators as such in constraints.
564 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
565 (minus "") (ss_minus "") (us_minus "")])
567 ;; Mapping of signed max and min
568 (define_code_iterator smaxmin [smax smin])
570 ;; Mapping of unsigned max and min
571 (define_code_iterator umaxmin [umax umin])
573 ;; Base name for integer and FP insn mnemonic
574 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
575 (umax "maxu") (umin "minu")])
576 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
578 ;; Mapping of parallel logic operators
579 (define_code_iterator plogic [and ior xor])
581 ;; Base name for insn mnemonic.
582 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
584 ;; Mapping of abs neg operators
585 (define_code_iterator absneg [abs neg])
587 ;; Base name for x87 insn mnemonic.
588 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
590 ;; All single word integer modes.
591 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
593 ;; Instruction suffix for integer modes.
594 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
596 ;; Register class for integer modes.
597 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
599 ;; Immediate operand constraint for integer modes.
600 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
602 ;; General operand predicate for integer modes.
603 (define_mode_attr general_operand
604 [(QI "general_operand")
605 (HI "general_operand")
606 (SI "general_operand")
607 (DI "x86_64_general_operand")])
609 ;; SSE and x87 SFmode and DFmode floating point modes
610 (define_mode_iterator MODEF [SF DF])
612 ;; All x87 floating point modes
613 (define_mode_iterator X87MODEF [SF DF XF])
615 ;; All integer modes handled by x87 fisttp operator.
616 (define_mode_iterator X87MODEI [HI SI DI])
618 ;; All integer modes handled by integer x87 operators.
619 (define_mode_iterator X87MODEI12 [HI SI])
621 ;; All integer modes handled by SSE cvtts?2si* operators.
622 (define_mode_iterator SSEMODEI24 [SI DI])
624 ;; SSE asm suffix for floating point modes
625 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
627 ;; SSE vector mode corresponding to a scalar mode
628 (define_mode_attr ssevecmode
629 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
631 ;; Instruction suffix for REX 64bit operators.
632 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
634 ;; This mode iterator allows :P to be used for patterns that operate on
635 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
636 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
639 ;; Scheduling descriptions
641 (include "pentium.md")
644 (include "athlon.md")
648 ;; Operand and operator predicates and constraints
650 (include "predicates.md")
651 (include "constraints.md")
654 ;; Compare instructions.
656 ;; All compare insns have expanders that save the operands away without
657 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
658 ;; after the cmp) will actually emit the cmpM.
660 (define_expand "cmpti"
661 [(set (reg:CC FLAGS_REG)
662 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
663 (match_operand:TI 1 "x86_64_general_operand" "")))]
666 if (MEM_P (operands[0]) && MEM_P (operands[1]))
667 operands[0] = force_reg (TImode, operands[0]);
668 ix86_compare_op0 = operands[0];
669 ix86_compare_op1 = operands[1];
673 (define_expand "cmpdi"
674 [(set (reg:CC FLAGS_REG)
675 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
676 (match_operand:DI 1 "x86_64_general_operand" "")))]
679 if (MEM_P (operands[0]) && MEM_P (operands[1]))
680 operands[0] = force_reg (DImode, operands[0]);
681 ix86_compare_op0 = operands[0];
682 ix86_compare_op1 = operands[1];
686 (define_expand "cmpsi"
687 [(set (reg:CC FLAGS_REG)
688 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
689 (match_operand:SI 1 "general_operand" "")))]
692 if (MEM_P (operands[0]) && MEM_P (operands[1]))
693 operands[0] = force_reg (SImode, operands[0]);
694 ix86_compare_op0 = operands[0];
695 ix86_compare_op1 = operands[1];
699 (define_expand "cmphi"
700 [(set (reg:CC FLAGS_REG)
701 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
702 (match_operand:HI 1 "general_operand" "")))]
705 if (MEM_P (operands[0]) && MEM_P (operands[1]))
706 operands[0] = force_reg (HImode, operands[0]);
707 ix86_compare_op0 = operands[0];
708 ix86_compare_op1 = operands[1];
712 (define_expand "cmpqi"
713 [(set (reg:CC FLAGS_REG)
714 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
715 (match_operand:QI 1 "general_operand" "")))]
718 if (MEM_P (operands[0]) && MEM_P (operands[1]))
719 operands[0] = force_reg (QImode, operands[0]);
720 ix86_compare_op0 = operands[0];
721 ix86_compare_op1 = operands[1];
725 (define_insn "cmpdi_ccno_1_rex64"
726 [(set (reg FLAGS_REG)
727 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
728 (match_operand:DI 1 "const0_operand" "")))]
729 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
732 cmp{q}\t{%1, %0|%0, %1}"
733 [(set_attr "type" "test,icmp")
734 (set_attr "length_immediate" "0,1")
735 (set_attr "mode" "DI")])
737 (define_insn "*cmpdi_minus_1_rex64"
738 [(set (reg FLAGS_REG)
739 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
740 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
743 "cmp{q}\t{%1, %0|%0, %1}"
744 [(set_attr "type" "icmp")
745 (set_attr "mode" "DI")])
747 (define_expand "cmpdi_1_rex64"
748 [(set (reg:CC FLAGS_REG)
749 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
750 (match_operand:DI 1 "general_operand" "")))]
754 (define_insn "cmpdi_1_insn_rex64"
755 [(set (reg FLAGS_REG)
756 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
757 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
758 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759 "cmp{q}\t{%1, %0|%0, %1}"
760 [(set_attr "type" "icmp")
761 (set_attr "mode" "DI")])
764 (define_insn "*cmpsi_ccno_1"
765 [(set (reg FLAGS_REG)
766 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
767 (match_operand:SI 1 "const0_operand" "")))]
768 "ix86_match_ccmode (insn, CCNOmode)"
771 cmp{l}\t{%1, %0|%0, %1}"
772 [(set_attr "type" "test,icmp")
773 (set_attr "length_immediate" "0,1")
774 (set_attr "mode" "SI")])
776 (define_insn "*cmpsi_minus_1"
777 [(set (reg FLAGS_REG)
778 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
779 (match_operand:SI 1 "general_operand" "ri,mr"))
781 "ix86_match_ccmode (insn, CCGOCmode)"
782 "cmp{l}\t{%1, %0|%0, %1}"
783 [(set_attr "type" "icmp")
784 (set_attr "mode" "SI")])
786 (define_expand "cmpsi_1"
787 [(set (reg:CC FLAGS_REG)
788 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
789 (match_operand:SI 1 "general_operand" "")))]
793 (define_insn "*cmpsi_1_insn"
794 [(set (reg FLAGS_REG)
795 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
796 (match_operand:SI 1 "general_operand" "ri,mr")))]
797 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
798 && ix86_match_ccmode (insn, CCmode)"
799 "cmp{l}\t{%1, %0|%0, %1}"
800 [(set_attr "type" "icmp")
801 (set_attr "mode" "SI")])
803 (define_insn "*cmphi_ccno_1"
804 [(set (reg FLAGS_REG)
805 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
806 (match_operand:HI 1 "const0_operand" "")))]
807 "ix86_match_ccmode (insn, CCNOmode)"
810 cmp{w}\t{%1, %0|%0, %1}"
811 [(set_attr "type" "test,icmp")
812 (set_attr "length_immediate" "0,1")
813 (set_attr "mode" "HI")])
815 (define_insn "*cmphi_minus_1"
816 [(set (reg FLAGS_REG)
817 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
818 (match_operand:HI 1 "general_operand" "rn,mr"))
820 "ix86_match_ccmode (insn, CCGOCmode)"
821 "cmp{w}\t{%1, %0|%0, %1}"
822 [(set_attr "type" "icmp")
823 (set_attr "mode" "HI")])
825 (define_insn "*cmphi_1"
826 [(set (reg FLAGS_REG)
827 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
828 (match_operand:HI 1 "general_operand" "rn,mr")))]
829 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
830 && ix86_match_ccmode (insn, CCmode)"
831 "cmp{w}\t{%1, %0|%0, %1}"
832 [(set_attr "type" "icmp")
833 (set_attr "mode" "HI")])
835 (define_insn "*cmpqi_ccno_1"
836 [(set (reg FLAGS_REG)
837 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
838 (match_operand:QI 1 "const0_operand" "")))]
839 "ix86_match_ccmode (insn, CCNOmode)"
842 cmp{b}\t{$0, %0|%0, 0}"
843 [(set_attr "type" "test,icmp")
844 (set_attr "length_immediate" "0,1")
845 (set_attr "mode" "QI")])
847 (define_insn "*cmpqi_1"
848 [(set (reg FLAGS_REG)
849 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
850 (match_operand:QI 1 "general_operand" "qn,mq")))]
851 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
852 && ix86_match_ccmode (insn, CCmode)"
853 "cmp{b}\t{%1, %0|%0, %1}"
854 [(set_attr "type" "icmp")
855 (set_attr "mode" "QI")])
857 (define_insn "*cmpqi_minus_1"
858 [(set (reg FLAGS_REG)
859 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
860 (match_operand:QI 1 "general_operand" "qn,mq"))
862 "ix86_match_ccmode (insn, CCGOCmode)"
863 "cmp{b}\t{%1, %0|%0, %1}"
864 [(set_attr "type" "icmp")
865 (set_attr "mode" "QI")])
867 (define_insn "*cmpqi_ext_1"
868 [(set (reg FLAGS_REG)
870 (match_operand:QI 0 "general_operand" "Qm")
873 (match_operand 1 "ext_register_operand" "Q")
876 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
877 "cmp{b}\t{%h1, %0|%0, %h1}"
878 [(set_attr "type" "icmp")
879 (set_attr "mode" "QI")])
881 (define_insn "*cmpqi_ext_1_rex64"
882 [(set (reg FLAGS_REG)
884 (match_operand:QI 0 "register_operand" "Q")
887 (match_operand 1 "ext_register_operand" "Q")
890 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
891 "cmp{b}\t{%h1, %0|%0, %h1}"
892 [(set_attr "type" "icmp")
893 (set_attr "mode" "QI")])
895 (define_insn "*cmpqi_ext_2"
896 [(set (reg FLAGS_REG)
900 (match_operand 0 "ext_register_operand" "Q")
903 (match_operand:QI 1 "const0_operand" "")))]
904 "ix86_match_ccmode (insn, CCNOmode)"
906 [(set_attr "type" "test")
907 (set_attr "length_immediate" "0")
908 (set_attr "mode" "QI")])
910 (define_expand "cmpqi_ext_3"
911 [(set (reg:CC FLAGS_REG)
915 (match_operand 0 "ext_register_operand" "")
918 (match_operand:QI 1 "general_operand" "")))]
922 (define_insn "cmpqi_ext_3_insn"
923 [(set (reg FLAGS_REG)
927 (match_operand 0 "ext_register_operand" "Q")
930 (match_operand:QI 1 "general_operand" "Qmn")))]
931 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
932 "cmp{b}\t{%1, %h0|%h0, %1}"
933 [(set_attr "type" "icmp")
934 (set_attr "mode" "QI")])
936 (define_insn "cmpqi_ext_3_insn_rex64"
937 [(set (reg FLAGS_REG)
941 (match_operand 0 "ext_register_operand" "Q")
944 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
945 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
946 "cmp{b}\t{%1, %h0|%h0, %1}"
947 [(set_attr "type" "icmp")
948 (set_attr "mode" "QI")])
950 (define_insn "*cmpqi_ext_4"
951 [(set (reg FLAGS_REG)
955 (match_operand 0 "ext_register_operand" "Q")
960 (match_operand 1 "ext_register_operand" "Q")
963 "ix86_match_ccmode (insn, CCmode)"
964 "cmp{b}\t{%h1, %h0|%h0, %h1}"
965 [(set_attr "type" "icmp")
966 (set_attr "mode" "QI")])
968 ;; These implement float point compares.
969 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
970 ;; which would allow mix and match FP modes on the compares. Which is what
971 ;; the old patterns did, but with many more of them.
973 (define_expand "cmpxf"
974 [(set (reg:CC FLAGS_REG)
975 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
976 (match_operand:XF 1 "nonmemory_operand" "")))]
979 ix86_compare_op0 = operands[0];
980 ix86_compare_op1 = operands[1];
984 (define_expand "cmp<mode>"
985 [(set (reg:CC FLAGS_REG)
986 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
987 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
988 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
990 ix86_compare_op0 = operands[0];
991 ix86_compare_op1 = operands[1];
995 ;; FP compares, step 1:
996 ;; Set the FP condition codes.
998 ;; CCFPmode compare with exceptions
999 ;; CCFPUmode compare with no exceptions
1001 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1002 ;; used to manage the reg stack popping would not be preserved.
1004 (define_insn "*cmpfp_0"
1005 [(set (match_operand:HI 0 "register_operand" "=a")
1008 (match_operand 1 "register_operand" "f")
1009 (match_operand 2 "const0_operand" ""))]
1011 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1012 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1013 "* return output_fp_compare (insn, operands, 0, 0);"
1014 [(set_attr "type" "multi")
1015 (set_attr "unit" "i387")
1017 (cond [(match_operand:SF 1 "" "")
1019 (match_operand:DF 1 "" "")
1022 (const_string "XF")))])
1024 (define_insn_and_split "*cmpfp_0_cc"
1025 [(set (reg:CCFP FLAGS_REG)
1027 (match_operand 1 "register_operand" "f")
1028 (match_operand 2 "const0_operand" "")))
1029 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1030 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1031 && TARGET_SAHF && !TARGET_CMOVE
1032 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1034 "&& reload_completed"
1037 [(compare:CCFP (match_dup 1)(match_dup 2))]
1039 (set (reg:CC FLAGS_REG)
1040 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1042 [(set_attr "type" "multi")
1043 (set_attr "unit" "i387")
1045 (cond [(match_operand:SF 1 "" "")
1047 (match_operand:DF 1 "" "")
1050 (const_string "XF")))])
1052 (define_insn "*cmpfp_xf"
1053 [(set (match_operand:HI 0 "register_operand" "=a")
1056 (match_operand:XF 1 "register_operand" "f")
1057 (match_operand:XF 2 "register_operand" "f"))]
1060 "* return output_fp_compare (insn, operands, 0, 0);"
1061 [(set_attr "type" "multi")
1062 (set_attr "unit" "i387")
1063 (set_attr "mode" "XF")])
1065 (define_insn_and_split "*cmpfp_xf_cc"
1066 [(set (reg:CCFP FLAGS_REG)
1068 (match_operand:XF 1 "register_operand" "f")
1069 (match_operand:XF 2 "register_operand" "f")))
1070 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1072 && TARGET_SAHF && !TARGET_CMOVE"
1074 "&& reload_completed"
1077 [(compare:CCFP (match_dup 1)(match_dup 2))]
1079 (set (reg:CC FLAGS_REG)
1080 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1082 [(set_attr "type" "multi")
1083 (set_attr "unit" "i387")
1084 (set_attr "mode" "XF")])
1086 (define_insn "*cmpfp_<mode>"
1087 [(set (match_operand:HI 0 "register_operand" "=a")
1090 (match_operand:MODEF 1 "register_operand" "f")
1091 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1094 "* return output_fp_compare (insn, operands, 0, 0);"
1095 [(set_attr "type" "multi")
1096 (set_attr "unit" "i387")
1097 (set_attr "mode" "<MODE>")])
1099 (define_insn_and_split "*cmpfp_<mode>_cc"
1100 [(set (reg:CCFP FLAGS_REG)
1102 (match_operand:MODEF 1 "register_operand" "f")
1103 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1104 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1106 && TARGET_SAHF && !TARGET_CMOVE"
1108 "&& reload_completed"
1111 [(compare:CCFP (match_dup 1)(match_dup 2))]
1113 (set (reg:CC FLAGS_REG)
1114 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1116 [(set_attr "type" "multi")
1117 (set_attr "unit" "i387")
1118 (set_attr "mode" "<MODE>")])
1120 (define_insn "*cmpfp_u"
1121 [(set (match_operand:HI 0 "register_operand" "=a")
1124 (match_operand 1 "register_operand" "f")
1125 (match_operand 2 "register_operand" "f"))]
1127 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1128 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1129 "* return output_fp_compare (insn, operands, 0, 1);"
1130 [(set_attr "type" "multi")
1131 (set_attr "unit" "i387")
1133 (cond [(match_operand:SF 1 "" "")
1135 (match_operand:DF 1 "" "")
1138 (const_string "XF")))])
1140 (define_insn_and_split "*cmpfp_u_cc"
1141 [(set (reg:CCFPU FLAGS_REG)
1143 (match_operand 1 "register_operand" "f")
1144 (match_operand 2 "register_operand" "f")))
1145 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1146 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1147 && TARGET_SAHF && !TARGET_CMOVE
1148 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1150 "&& reload_completed"
1153 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1155 (set (reg:CC FLAGS_REG)
1156 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1158 [(set_attr "type" "multi")
1159 (set_attr "unit" "i387")
1161 (cond [(match_operand:SF 1 "" "")
1163 (match_operand:DF 1 "" "")
1166 (const_string "XF")))])
1168 (define_insn "*cmpfp_<mode>"
1169 [(set (match_operand:HI 0 "register_operand" "=a")
1172 (match_operand 1 "register_operand" "f")
1173 (match_operator 3 "float_operator"
1174 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1176 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1177 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1178 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1179 "* return output_fp_compare (insn, operands, 0, 0);"
1180 [(set_attr "type" "multi")
1181 (set_attr "unit" "i387")
1182 (set_attr "fp_int_src" "true")
1183 (set_attr "mode" "<MODE>")])
1185 (define_insn_and_split "*cmpfp_<mode>_cc"
1186 [(set (reg:CCFP FLAGS_REG)
1188 (match_operand 1 "register_operand" "f")
1189 (match_operator 3 "float_operator"
1190 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1191 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1192 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1193 && TARGET_SAHF && !TARGET_CMOVE
1194 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1195 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1197 "&& reload_completed"
1202 (match_op_dup 3 [(match_dup 2)]))]
1204 (set (reg:CC FLAGS_REG)
1205 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1207 [(set_attr "type" "multi")
1208 (set_attr "unit" "i387")
1209 (set_attr "fp_int_src" "true")
1210 (set_attr "mode" "<MODE>")])
1212 ;; FP compares, step 2
1213 ;; Move the fpsw to ax.
1215 (define_insn "x86_fnstsw_1"
1216 [(set (match_operand:HI 0 "register_operand" "=a")
1217 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1220 [(set_attr "length" "2")
1221 (set_attr "mode" "SI")
1222 (set_attr "unit" "i387")])
1224 ;; FP compares, step 3
1225 ;; Get ax into flags, general case.
1227 (define_insn "x86_sahf_1"
1228 [(set (reg:CC FLAGS_REG)
1229 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1233 #ifdef HAVE_AS_IX86_SAHF
1236 return ".byte\t0x9e";
1239 [(set_attr "length" "1")
1240 (set_attr "athlon_decode" "vector")
1241 (set_attr "amdfam10_decode" "direct")
1242 (set_attr "mode" "SI")])
1244 ;; Pentium Pro can do steps 1 through 3 in one go.
1245 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1246 (define_insn "*cmpfp_i_mixed"
1247 [(set (reg:CCFP FLAGS_REG)
1248 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1249 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1250 "TARGET_MIX_SSE_I387
1251 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1252 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1253 "* return output_fp_compare (insn, operands, 1, 0);"
1254 [(set_attr "type" "fcmp,ssecomi")
1256 (if_then_else (match_operand:SF 1 "" "")
1258 (const_string "DF")))
1259 (set_attr "athlon_decode" "vector")
1260 (set_attr "amdfam10_decode" "direct")])
1262 (define_insn "*cmpfp_i_sse"
1263 [(set (reg:CCFP FLAGS_REG)
1264 (compare:CCFP (match_operand 0 "register_operand" "x")
1265 (match_operand 1 "nonimmediate_operand" "xm")))]
1267 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1268 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1269 "* return output_fp_compare (insn, operands, 1, 0);"
1270 [(set_attr "type" "ssecomi")
1272 (if_then_else (match_operand:SF 1 "" "")
1274 (const_string "DF")))
1275 (set_attr "athlon_decode" "vector")
1276 (set_attr "amdfam10_decode" "direct")])
1278 (define_insn "*cmpfp_i_i387"
1279 [(set (reg:CCFP FLAGS_REG)
1280 (compare:CCFP (match_operand 0 "register_operand" "f")
1281 (match_operand 1 "register_operand" "f")))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1284 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1285 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1286 "* return output_fp_compare (insn, operands, 1, 0);"
1287 [(set_attr "type" "fcmp")
1289 (cond [(match_operand:SF 1 "" "")
1291 (match_operand:DF 1 "" "")
1294 (const_string "XF")))
1295 (set_attr "athlon_decode" "vector")
1296 (set_attr "amdfam10_decode" "direct")])
1298 (define_insn "*cmpfp_iu_mixed"
1299 [(set (reg:CCFPU FLAGS_REG)
1300 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1301 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1302 "TARGET_MIX_SSE_I387
1303 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1304 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1305 "* return output_fp_compare (insn, operands, 1, 1);"
1306 [(set_attr "type" "fcmp,ssecomi")
1308 (if_then_else (match_operand:SF 1 "" "")
1310 (const_string "DF")))
1311 (set_attr "athlon_decode" "vector")
1312 (set_attr "amdfam10_decode" "direct")])
1314 (define_insn "*cmpfp_iu_sse"
1315 [(set (reg:CCFPU FLAGS_REG)
1316 (compare:CCFPU (match_operand 0 "register_operand" "x")
1317 (match_operand 1 "nonimmediate_operand" "xm")))]
1319 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1320 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1321 "* return output_fp_compare (insn, operands, 1, 1);"
1322 [(set_attr "type" "ssecomi")
1324 (if_then_else (match_operand:SF 1 "" "")
1326 (const_string "DF")))
1327 (set_attr "athlon_decode" "vector")
1328 (set_attr "amdfam10_decode" "direct")])
1330 (define_insn "*cmpfp_iu_387"
1331 [(set (reg:CCFPU FLAGS_REG)
1332 (compare:CCFPU (match_operand 0 "register_operand" "f")
1333 (match_operand 1 "register_operand" "f")))]
1334 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1336 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1337 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1338 "* return output_fp_compare (insn, operands, 1, 1);"
1339 [(set_attr "type" "fcmp")
1341 (cond [(match_operand:SF 1 "" "")
1343 (match_operand:DF 1 "" "")
1346 (const_string "XF")))
1347 (set_attr "athlon_decode" "vector")
1348 (set_attr "amdfam10_decode" "direct")])
1350 ;; Move instructions.
1352 ;; General case of fullword move.
1354 (define_expand "movsi"
1355 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1356 (match_operand:SI 1 "general_operand" ""))]
1358 "ix86_expand_move (SImode, operands); DONE;")
1360 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1363 ;; %%% We don't use a post-inc memory reference because x86 is not a
1364 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1365 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1366 ;; targets without our curiosities, and it is just as easy to represent
1367 ;; this differently.
1369 (define_insn "*pushsi2"
1370 [(set (match_operand:SI 0 "push_operand" "=<")
1371 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1374 [(set_attr "type" "push")
1375 (set_attr "mode" "SI")])
1377 ;; For 64BIT abi we always round up to 8 bytes.
1378 (define_insn "*pushsi2_rex64"
1379 [(set (match_operand:SI 0 "push_operand" "=X")
1380 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1383 [(set_attr "type" "push")
1384 (set_attr "mode" "SI")])
1386 (define_insn "*pushsi2_prologue"
1387 [(set (match_operand:SI 0 "push_operand" "=<")
1388 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1389 (clobber (mem:BLK (scratch)))]
1392 [(set_attr "type" "push")
1393 (set_attr "mode" "SI")])
1395 (define_insn "*popsi1_epilogue"
1396 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1397 (mem:SI (reg:SI SP_REG)))
1398 (set (reg:SI SP_REG)
1399 (plus:SI (reg:SI SP_REG) (const_int 4)))
1400 (clobber (mem:BLK (scratch)))]
1403 [(set_attr "type" "pop")
1404 (set_attr "mode" "SI")])
1406 (define_insn "popsi1"
1407 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1408 (mem:SI (reg:SI SP_REG)))
1409 (set (reg:SI SP_REG)
1410 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1413 [(set_attr "type" "pop")
1414 (set_attr "mode" "SI")])
1416 (define_insn "*movsi_xor"
1417 [(set (match_operand:SI 0 "register_operand" "=r")
1418 (match_operand:SI 1 "const0_operand" ""))
1419 (clobber (reg:CC FLAGS_REG))]
1420 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1422 [(set_attr "type" "alu1")
1423 (set_attr "mode" "SI")
1424 (set_attr "length_immediate" "0")])
1426 (define_insn "*movsi_or"
1427 [(set (match_operand:SI 0 "register_operand" "=r")
1428 (match_operand:SI 1 "immediate_operand" "i"))
1429 (clobber (reg:CC FLAGS_REG))]
1431 && operands[1] == constm1_rtx
1432 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1434 operands[1] = constm1_rtx;
1435 return "or{l}\t{%1, %0|%0, %1}";
1437 [(set_attr "type" "alu1")
1438 (set_attr "mode" "SI")
1439 (set_attr "length_immediate" "1")])
1441 (define_insn "*movsi_1"
1442 [(set (match_operand:SI 0 "nonimmediate_operand"
1443 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1444 (match_operand:SI 1 "general_operand"
1445 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1446 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1448 switch (get_attr_type (insn))
1451 if (get_attr_mode (insn) == MODE_TI)
1452 return "pxor\t%0, %0";
1453 return "xorps\t%0, %0";
1456 switch (get_attr_mode (insn))
1459 return "movdqa\t{%1, %0|%0, %1}";
1461 return "movaps\t{%1, %0|%0, %1}";
1463 return "movd\t{%1, %0|%0, %1}";
1465 return "movss\t{%1, %0|%0, %1}";
1471 return "pxor\t%0, %0";
1474 if (get_attr_mode (insn) == MODE_DI)
1475 return "movq\t{%1, %0|%0, %1}";
1476 return "movd\t{%1, %0|%0, %1}";
1479 return "lea{l}\t{%1, %0|%0, %1}";
1482 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1483 return "mov{l}\t{%1, %0|%0, %1}";
1487 (cond [(eq_attr "alternative" "2")
1488 (const_string "mmxadd")
1489 (eq_attr "alternative" "3,4,5")
1490 (const_string "mmxmov")
1491 (eq_attr "alternative" "6")
1492 (const_string "sselog1")
1493 (eq_attr "alternative" "7,8,9,10,11")
1494 (const_string "ssemov")
1495 (match_operand:DI 1 "pic_32bit_operand" "")
1496 (const_string "lea")
1498 (const_string "imov")))
1500 (cond [(eq_attr "alternative" "2,3")
1502 (eq_attr "alternative" "6,7")
1504 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1505 (const_string "V4SF")
1506 (const_string "TI"))
1507 (and (eq_attr "alternative" "8,9,10,11")
1508 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1511 (const_string "SI")))])
1513 ;; Stores and loads of ax to arbitrary constant address.
1514 ;; We fake an second form of instruction to force reload to load address
1515 ;; into register when rax is not available
1516 (define_insn "*movabssi_1_rex64"
1517 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1518 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1519 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1521 movabs{l}\t{%1, %P0|%P0, %1}
1522 mov{l}\t{%1, %a0|%a0, %1}"
1523 [(set_attr "type" "imov")
1524 (set_attr "modrm" "0,*")
1525 (set_attr "length_address" "8,0")
1526 (set_attr "length_immediate" "0,*")
1527 (set_attr "memory" "store")
1528 (set_attr "mode" "SI")])
1530 (define_insn "*movabssi_2_rex64"
1531 [(set (match_operand:SI 0 "register_operand" "=a,r")
1532 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1533 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1535 movabs{l}\t{%P1, %0|%0, %P1}
1536 mov{l}\t{%a1, %0|%0, %a1}"
1537 [(set_attr "type" "imov")
1538 (set_attr "modrm" "0,*")
1539 (set_attr "length_address" "8,0")
1540 (set_attr "length_immediate" "0")
1541 (set_attr "memory" "load")
1542 (set_attr "mode" "SI")])
1544 (define_insn "*swapsi"
1545 [(set (match_operand:SI 0 "register_operand" "+r")
1546 (match_operand:SI 1 "register_operand" "+r"))
1551 [(set_attr "type" "imov")
1552 (set_attr "mode" "SI")
1553 (set_attr "pent_pair" "np")
1554 (set_attr "athlon_decode" "vector")
1555 (set_attr "amdfam10_decode" "double")])
1557 (define_expand "movhi"
1558 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1559 (match_operand:HI 1 "general_operand" ""))]
1561 "ix86_expand_move (HImode, operands); DONE;")
1563 (define_insn "*pushhi2"
1564 [(set (match_operand:HI 0 "push_operand" "=X")
1565 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1568 [(set_attr "type" "push")
1569 (set_attr "mode" "SI")])
1571 ;; For 64BIT abi we always round up to 8 bytes.
1572 (define_insn "*pushhi2_rex64"
1573 [(set (match_operand:HI 0 "push_operand" "=X")
1574 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1577 [(set_attr "type" "push")
1578 (set_attr "mode" "DI")])
1580 (define_insn "*movhi_1"
1581 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1582 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1583 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1585 switch (get_attr_type (insn))
1588 /* movzwl is faster than movw on p2 due to partial word stalls,
1589 though not as fast as an aligned movl. */
1590 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1592 if (get_attr_mode (insn) == MODE_SI)
1593 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1595 return "mov{w}\t{%1, %0|%0, %1}";
1599 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1600 (const_string "imov")
1601 (and (eq_attr "alternative" "0")
1602 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1604 (eq (symbol_ref "TARGET_HIMODE_MATH")
1606 (const_string "imov")
1607 (and (eq_attr "alternative" "1,2")
1608 (match_operand:HI 1 "aligned_operand" ""))
1609 (const_string "imov")
1610 (and (ne (symbol_ref "TARGET_MOVX")
1612 (eq_attr "alternative" "0,2"))
1613 (const_string "imovx")
1615 (const_string "imov")))
1617 (cond [(eq_attr "type" "imovx")
1619 (and (eq_attr "alternative" "1,2")
1620 (match_operand:HI 1 "aligned_operand" ""))
1622 (and (eq_attr "alternative" "0")
1623 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1625 (eq (symbol_ref "TARGET_HIMODE_MATH")
1629 (const_string "HI")))])
1631 ;; Stores and loads of ax to arbitrary constant address.
1632 ;; We fake an second form of instruction to force reload to load address
1633 ;; into register when rax is not available
1634 (define_insn "*movabshi_1_rex64"
1635 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1636 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1637 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1639 movabs{w}\t{%1, %P0|%P0, %1}
1640 mov{w}\t{%1, %a0|%a0, %1}"
1641 [(set_attr "type" "imov")
1642 (set_attr "modrm" "0,*")
1643 (set_attr "length_address" "8,0")
1644 (set_attr "length_immediate" "0,*")
1645 (set_attr "memory" "store")
1646 (set_attr "mode" "HI")])
1648 (define_insn "*movabshi_2_rex64"
1649 [(set (match_operand:HI 0 "register_operand" "=a,r")
1650 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1651 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1653 movabs{w}\t{%P1, %0|%0, %P1}
1654 mov{w}\t{%a1, %0|%0, %a1}"
1655 [(set_attr "type" "imov")
1656 (set_attr "modrm" "0,*")
1657 (set_attr "length_address" "8,0")
1658 (set_attr "length_immediate" "0")
1659 (set_attr "memory" "load")
1660 (set_attr "mode" "HI")])
1662 (define_insn "*swaphi_1"
1663 [(set (match_operand:HI 0 "register_operand" "+r")
1664 (match_operand:HI 1 "register_operand" "+r"))
1667 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1669 [(set_attr "type" "imov")
1670 (set_attr "mode" "SI")
1671 (set_attr "pent_pair" "np")
1672 (set_attr "athlon_decode" "vector")
1673 (set_attr "amdfam10_decode" "double")])
1675 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1676 (define_insn "*swaphi_2"
1677 [(set (match_operand:HI 0 "register_operand" "+r")
1678 (match_operand:HI 1 "register_operand" "+r"))
1681 "TARGET_PARTIAL_REG_STALL"
1683 [(set_attr "type" "imov")
1684 (set_attr "mode" "HI")
1685 (set_attr "pent_pair" "np")
1686 (set_attr "athlon_decode" "vector")])
1688 (define_expand "movstricthi"
1689 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1690 (match_operand:HI 1 "general_operand" ""))]
1691 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1693 /* Don't generate memory->memory moves, go through a register */
1694 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1695 operands[1] = force_reg (HImode, operands[1]);
1698 (define_insn "*movstricthi_1"
1699 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1700 (match_operand:HI 1 "general_operand" "rn,m"))]
1701 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1702 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1703 "mov{w}\t{%1, %0|%0, %1}"
1704 [(set_attr "type" "imov")
1705 (set_attr "mode" "HI")])
1707 (define_insn "*movstricthi_xor"
1708 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1709 (match_operand:HI 1 "const0_operand" ""))
1710 (clobber (reg:CC FLAGS_REG))]
1712 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1714 [(set_attr "type" "alu1")
1715 (set_attr "mode" "HI")
1716 (set_attr "length_immediate" "0")])
1718 (define_expand "movqi"
1719 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1720 (match_operand:QI 1 "general_operand" ""))]
1722 "ix86_expand_move (QImode, operands); DONE;")
1724 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1725 ;; "push a byte". But actually we use pushl, which has the effect
1726 ;; of rounding the amount pushed up to a word.
1728 (define_insn "*pushqi2"
1729 [(set (match_operand:QI 0 "push_operand" "=X")
1730 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1733 [(set_attr "type" "push")
1734 (set_attr "mode" "SI")])
1736 ;; For 64BIT abi we always round up to 8 bytes.
1737 (define_insn "*pushqi2_rex64"
1738 [(set (match_operand:QI 0 "push_operand" "=X")
1739 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1745 ;; Situation is quite tricky about when to choose full sized (SImode) move
1746 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1747 ;; partial register dependency machines (such as AMD Athlon), where QImode
1748 ;; moves issue extra dependency and for partial register stalls machines
1749 ;; that don't use QImode patterns (and QImode move cause stall on the next
1752 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1753 ;; register stall machines with, where we use QImode instructions, since
1754 ;; partial register stall can be caused there. Then we use movzx.
1755 (define_insn "*movqi_1"
1756 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1757 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1758 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1760 switch (get_attr_type (insn))
1763 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1764 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1766 if (get_attr_mode (insn) == MODE_SI)
1767 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1769 return "mov{b}\t{%1, %0|%0, %1}";
1773 (cond [(and (eq_attr "alternative" "5")
1774 (not (match_operand:QI 1 "aligned_operand" "")))
1775 (const_string "imovx")
1776 (ne (symbol_ref "optimize_size") (const_int 0))
1777 (const_string "imov")
1778 (and (eq_attr "alternative" "3")
1779 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1781 (eq (symbol_ref "TARGET_QIMODE_MATH")
1783 (const_string "imov")
1784 (eq_attr "alternative" "3,5")
1785 (const_string "imovx")
1786 (and (ne (symbol_ref "TARGET_MOVX")
1788 (eq_attr "alternative" "2"))
1789 (const_string "imovx")
1791 (const_string "imov")))
1793 (cond [(eq_attr "alternative" "3,4,5")
1795 (eq_attr "alternative" "6")
1797 (eq_attr "type" "imovx")
1799 (and (eq_attr "type" "imov")
1800 (and (eq_attr "alternative" "0,1")
1801 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1803 (and (eq (symbol_ref "optimize_size")
1805 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1808 ;; Avoid partial register stalls when not using QImode arithmetic
1809 (and (eq_attr "type" "imov")
1810 (and (eq_attr "alternative" "0,1")
1811 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1813 (eq (symbol_ref "TARGET_QIMODE_MATH")
1817 (const_string "QI")))])
1819 (define_insn "*swapqi_1"
1820 [(set (match_operand:QI 0 "register_operand" "+r")
1821 (match_operand:QI 1 "register_operand" "+r"))
1824 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1826 [(set_attr "type" "imov")
1827 (set_attr "mode" "SI")
1828 (set_attr "pent_pair" "np")
1829 (set_attr "athlon_decode" "vector")
1830 (set_attr "amdfam10_decode" "vector")])
1832 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1833 (define_insn "*swapqi_2"
1834 [(set (match_operand:QI 0 "register_operand" "+q")
1835 (match_operand:QI 1 "register_operand" "+q"))
1838 "TARGET_PARTIAL_REG_STALL"
1840 [(set_attr "type" "imov")
1841 (set_attr "mode" "QI")
1842 (set_attr "pent_pair" "np")
1843 (set_attr "athlon_decode" "vector")])
1845 (define_expand "movstrictqi"
1846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1847 (match_operand:QI 1 "general_operand" ""))]
1848 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1850 /* Don't generate memory->memory moves, go through a register. */
1851 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1852 operands[1] = force_reg (QImode, operands[1]);
1855 (define_insn "*movstrictqi_1"
1856 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1857 (match_operand:QI 1 "general_operand" "*qn,m"))]
1858 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1859 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1860 "mov{b}\t{%1, %0|%0, %1}"
1861 [(set_attr "type" "imov")
1862 (set_attr "mode" "QI")])
1864 (define_insn "*movstrictqi_xor"
1865 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1866 (match_operand:QI 1 "const0_operand" ""))
1867 (clobber (reg:CC FLAGS_REG))]
1868 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1870 [(set_attr "type" "alu1")
1871 (set_attr "mode" "QI")
1872 (set_attr "length_immediate" "0")])
1874 (define_insn "*movsi_extv_1"
1875 [(set (match_operand:SI 0 "register_operand" "=R")
1876 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1880 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1881 [(set_attr "type" "imovx")
1882 (set_attr "mode" "SI")])
1884 (define_insn "*movhi_extv_1"
1885 [(set (match_operand:HI 0 "register_operand" "=R")
1886 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1890 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1891 [(set_attr "type" "imovx")
1892 (set_attr "mode" "SI")])
1894 (define_insn "*movqi_extv_1"
1895 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1896 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1901 switch (get_attr_type (insn))
1904 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1906 return "mov{b}\t{%h1, %0|%0, %h1}";
1910 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1911 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1912 (ne (symbol_ref "TARGET_MOVX")
1914 (const_string "imovx")
1915 (const_string "imov")))
1917 (if_then_else (eq_attr "type" "imovx")
1919 (const_string "QI")))])
1921 (define_insn "*movqi_extv_1_rex64"
1922 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1923 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1928 switch (get_attr_type (insn))
1931 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1933 return "mov{b}\t{%h1, %0|%0, %h1}";
1937 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1938 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1939 (ne (symbol_ref "TARGET_MOVX")
1941 (const_string "imovx")
1942 (const_string "imov")))
1944 (if_then_else (eq_attr "type" "imovx")
1946 (const_string "QI")))])
1948 ;; Stores and loads of ax to arbitrary constant address.
1949 ;; We fake an second form of instruction to force reload to load address
1950 ;; into register when rax is not available
1951 (define_insn "*movabsqi_1_rex64"
1952 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1953 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1954 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1956 movabs{b}\t{%1, %P0|%P0, %1}
1957 mov{b}\t{%1, %a0|%a0, %1}"
1958 [(set_attr "type" "imov")
1959 (set_attr "modrm" "0,*")
1960 (set_attr "length_address" "8,0")
1961 (set_attr "length_immediate" "0,*")
1962 (set_attr "memory" "store")
1963 (set_attr "mode" "QI")])
1965 (define_insn "*movabsqi_2_rex64"
1966 [(set (match_operand:QI 0 "register_operand" "=a,r")
1967 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1968 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1970 movabs{b}\t{%P1, %0|%0, %P1}
1971 mov{b}\t{%a1, %0|%0, %a1}"
1972 [(set_attr "type" "imov")
1973 (set_attr "modrm" "0,*")
1974 (set_attr "length_address" "8,0")
1975 (set_attr "length_immediate" "0")
1976 (set_attr "memory" "load")
1977 (set_attr "mode" "QI")])
1979 (define_insn "*movdi_extzv_1"
1980 [(set (match_operand:DI 0 "register_operand" "=R")
1981 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1985 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1986 [(set_attr "type" "imovx")
1987 (set_attr "mode" "DI")])
1989 (define_insn "*movsi_extzv_1"
1990 [(set (match_operand:SI 0 "register_operand" "=R")
1991 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1995 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1996 [(set_attr "type" "imovx")
1997 (set_attr "mode" "SI")])
1999 (define_insn "*movqi_extzv_2"
2000 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2001 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2006 switch (get_attr_type (insn))
2009 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2011 return "mov{b}\t{%h1, %0|%0, %h1}";
2015 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2016 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2017 (ne (symbol_ref "TARGET_MOVX")
2019 (const_string "imovx")
2020 (const_string "imov")))
2022 (if_then_else (eq_attr "type" "imovx")
2024 (const_string "QI")))])
2026 (define_insn "*movqi_extzv_2_rex64"
2027 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2028 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2033 switch (get_attr_type (insn))
2036 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2038 return "mov{b}\t{%h1, %0|%0, %h1}";
2042 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2043 (ne (symbol_ref "TARGET_MOVX")
2045 (const_string "imovx")
2046 (const_string "imov")))
2048 (if_then_else (eq_attr "type" "imovx")
2050 (const_string "QI")))])
2052 (define_insn "movsi_insv_1"
2053 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2056 (match_operand:SI 1 "general_operand" "Qmn"))]
2058 "mov{b}\t{%b1, %h0|%h0, %b1}"
2059 [(set_attr "type" "imov")
2060 (set_attr "mode" "QI")])
2062 (define_insn "*movsi_insv_1_rex64"
2063 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2066 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2068 "mov{b}\t{%b1, %h0|%h0, %b1}"
2069 [(set_attr "type" "imov")
2070 (set_attr "mode" "QI")])
2072 (define_insn "movdi_insv_1_rex64"
2073 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2076 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2078 "mov{b}\t{%b1, %h0|%h0, %b1}"
2079 [(set_attr "type" "imov")
2080 (set_attr "mode" "QI")])
2082 (define_insn "*movqi_insv_2"
2083 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2086 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2089 "mov{b}\t{%h1, %h0|%h0, %h1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "mode" "QI")])
2093 (define_expand "movdi"
2094 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2095 (match_operand:DI 1 "general_operand" ""))]
2097 "ix86_expand_move (DImode, operands); DONE;")
2099 (define_insn "*pushdi"
2100 [(set (match_operand:DI 0 "push_operand" "=<")
2101 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2105 (define_insn "*pushdi2_rex64"
2106 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2107 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2112 [(set_attr "type" "push,multi")
2113 (set_attr "mode" "DI")])
2115 ;; Convert impossible pushes of immediate to existing instructions.
2116 ;; First try to get scratch register and go through it. In case this
2117 ;; fails, push sign extended lower part first and then overwrite
2118 ;; upper part by 32bit move.
2120 [(match_scratch:DI 2 "r")
2121 (set (match_operand:DI 0 "push_operand" "")
2122 (match_operand:DI 1 "immediate_operand" ""))]
2123 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2124 && !x86_64_immediate_operand (operands[1], DImode)"
2125 [(set (match_dup 2) (match_dup 1))
2126 (set (match_dup 0) (match_dup 2))]
2129 ;; We need to define this as both peepholer and splitter for case
2130 ;; peephole2 pass is not run.
2131 ;; "&& 1" is needed to keep it from matching the previous pattern.
2133 [(set (match_operand:DI 0 "push_operand" "")
2134 (match_operand:DI 1 "immediate_operand" ""))]
2135 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2137 [(set (match_dup 0) (match_dup 1))
2138 (set (match_dup 2) (match_dup 3))]
2139 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2140 operands[1] = gen_lowpart (DImode, operands[2]);
2141 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2146 [(set (match_operand:DI 0 "push_operand" "")
2147 (match_operand:DI 1 "immediate_operand" ""))]
2148 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2149 ? epilogue_completed : reload_completed)
2150 && !symbolic_operand (operands[1], DImode)
2151 && !x86_64_immediate_operand (operands[1], DImode)"
2152 [(set (match_dup 0) (match_dup 1))
2153 (set (match_dup 2) (match_dup 3))]
2154 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2155 operands[1] = gen_lowpart (DImode, operands[2]);
2156 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2160 (define_insn "*pushdi2_prologue_rex64"
2161 [(set (match_operand:DI 0 "push_operand" "=<")
2162 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2163 (clobber (mem:BLK (scratch)))]
2166 [(set_attr "type" "push")
2167 (set_attr "mode" "DI")])
2169 (define_insn "*popdi1_epilogue_rex64"
2170 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2171 (mem:DI (reg:DI SP_REG)))
2172 (set (reg:DI SP_REG)
2173 (plus:DI (reg:DI SP_REG) (const_int 8)))
2174 (clobber (mem:BLK (scratch)))]
2177 [(set_attr "type" "pop")
2178 (set_attr "mode" "DI")])
2180 (define_insn "popdi1"
2181 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2182 (mem:DI (reg:DI SP_REG)))
2183 (set (reg:DI SP_REG)
2184 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2187 [(set_attr "type" "pop")
2188 (set_attr "mode" "DI")])
2190 (define_insn "*movdi_xor_rex64"
2191 [(set (match_operand:DI 0 "register_operand" "=r")
2192 (match_operand:DI 1 "const0_operand" ""))
2193 (clobber (reg:CC FLAGS_REG))]
2194 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2195 && reload_completed"
2197 [(set_attr "type" "alu1")
2198 (set_attr "mode" "SI")
2199 (set_attr "length_immediate" "0")])
2201 (define_insn "*movdi_or_rex64"
2202 [(set (match_operand:DI 0 "register_operand" "=r")
2203 (match_operand:DI 1 "const_int_operand" "i"))
2204 (clobber (reg:CC FLAGS_REG))]
2205 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2207 && operands[1] == constm1_rtx"
2209 operands[1] = constm1_rtx;
2210 return "or{q}\t{%1, %0|%0, %1}";
2212 [(set_attr "type" "alu1")
2213 (set_attr "mode" "DI")
2214 (set_attr "length_immediate" "1")])
2216 (define_insn "*movdi_2"
2217 [(set (match_operand:DI 0 "nonimmediate_operand"
2218 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2219 (match_operand:DI 1 "general_operand"
2220 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2221 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2226 movq\t{%1, %0|%0, %1}
2227 movq\t{%1, %0|%0, %1}
2229 movq\t{%1, %0|%0, %1}
2230 movdqa\t{%1, %0|%0, %1}
2231 movq\t{%1, %0|%0, %1}
2233 movlps\t{%1, %0|%0, %1}
2234 movaps\t{%1, %0|%0, %1}
2235 movlps\t{%1, %0|%0, %1}"
2236 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2237 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2240 [(set (match_operand:DI 0 "push_operand" "")
2241 (match_operand:DI 1 "general_operand" ""))]
2242 "!TARGET_64BIT && reload_completed
2243 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2245 "ix86_split_long_move (operands); DONE;")
2247 ;; %%% This multiword shite has got to go.
2249 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2250 (match_operand:DI 1 "general_operand" ""))]
2251 "!TARGET_64BIT && reload_completed
2252 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2253 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2255 "ix86_split_long_move (operands); DONE;")
2257 (define_insn "*movdi_1_rex64"
2258 [(set (match_operand:DI 0 "nonimmediate_operand"
2259 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2260 (match_operand:DI 1 "general_operand"
2261 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2262 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2264 switch (get_attr_type (insn))
2267 if (SSE_REG_P (operands[0]))
2268 return "movq2dq\t{%1, %0|%0, %1}";
2270 return "movdq2q\t{%1, %0|%0, %1}";
2273 if (get_attr_mode (insn) == MODE_TI)
2274 return "movdqa\t{%1, %0|%0, %1}";
2278 /* Moves from and into integer register is done using movd
2279 opcode with REX prefix. */
2280 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2281 return "movd\t{%1, %0|%0, %1}";
2282 return "movq\t{%1, %0|%0, %1}";
2286 return "pxor\t%0, %0";
2292 return "lea{q}\t{%a1, %0|%0, %a1}";
2295 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2296 if (get_attr_mode (insn) == MODE_SI)
2297 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2298 else if (which_alternative == 2)
2299 return "movabs{q}\t{%1, %0|%0, %1}";
2301 return "mov{q}\t{%1, %0|%0, %1}";
2305 (cond [(eq_attr "alternative" "5")
2306 (const_string "mmxadd")
2307 (eq_attr "alternative" "6,7,8,9,10")
2308 (const_string "mmxmov")
2309 (eq_attr "alternative" "11")
2310 (const_string "sselog1")
2311 (eq_attr "alternative" "12,13,14,15,16")
2312 (const_string "ssemov")
2313 (eq_attr "alternative" "17,18")
2314 (const_string "ssecvt")
2315 (eq_attr "alternative" "4")
2316 (const_string "multi")
2317 (match_operand:DI 1 "pic_32bit_operand" "")
2318 (const_string "lea")
2320 (const_string "imov")))
2321 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2322 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2323 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2325 ;; Stores and loads of ax to arbitrary constant address.
2326 ;; We fake an second form of instruction to force reload to load address
2327 ;; into register when rax is not available
2328 (define_insn "*movabsdi_1_rex64"
2329 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2330 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2331 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2333 movabs{q}\t{%1, %P0|%P0, %1}
2334 mov{q}\t{%1, %a0|%a0, %1}"
2335 [(set_attr "type" "imov")
2336 (set_attr "modrm" "0,*")
2337 (set_attr "length_address" "8,0")
2338 (set_attr "length_immediate" "0,*")
2339 (set_attr "memory" "store")
2340 (set_attr "mode" "DI")])
2342 (define_insn "*movabsdi_2_rex64"
2343 [(set (match_operand:DI 0 "register_operand" "=a,r")
2344 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2345 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2347 movabs{q}\t{%P1, %0|%0, %P1}
2348 mov{q}\t{%a1, %0|%0, %a1}"
2349 [(set_attr "type" "imov")
2350 (set_attr "modrm" "0,*")
2351 (set_attr "length_address" "8,0")
2352 (set_attr "length_immediate" "0")
2353 (set_attr "memory" "load")
2354 (set_attr "mode" "DI")])
2356 ;; Convert impossible stores of immediate to existing instructions.
2357 ;; First try to get scratch register and go through it. In case this
2358 ;; fails, move by 32bit parts.
2360 [(match_scratch:DI 2 "r")
2361 (set (match_operand:DI 0 "memory_operand" "")
2362 (match_operand:DI 1 "immediate_operand" ""))]
2363 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2364 && !x86_64_immediate_operand (operands[1], DImode)"
2365 [(set (match_dup 2) (match_dup 1))
2366 (set (match_dup 0) (match_dup 2))]
2369 ;; We need to define this as both peepholer and splitter for case
2370 ;; peephole2 pass is not run.
2371 ;; "&& 1" is needed to keep it from matching the previous pattern.
2373 [(set (match_operand:DI 0 "memory_operand" "")
2374 (match_operand:DI 1 "immediate_operand" ""))]
2375 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2376 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2377 [(set (match_dup 2) (match_dup 3))
2378 (set (match_dup 4) (match_dup 5))]
2379 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2382 [(set (match_operand:DI 0 "memory_operand" "")
2383 (match_operand:DI 1 "immediate_operand" ""))]
2384 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2385 ? epilogue_completed : reload_completed)
2386 && !symbolic_operand (operands[1], DImode)
2387 && !x86_64_immediate_operand (operands[1], DImode)"
2388 [(set (match_dup 2) (match_dup 3))
2389 (set (match_dup 4) (match_dup 5))]
2390 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2392 (define_insn "*swapdi_rex64"
2393 [(set (match_operand:DI 0 "register_operand" "+r")
2394 (match_operand:DI 1 "register_operand" "+r"))
2399 [(set_attr "type" "imov")
2400 (set_attr "mode" "DI")
2401 (set_attr "pent_pair" "np")
2402 (set_attr "athlon_decode" "vector")
2403 (set_attr "amdfam10_decode" "double")])
2405 (define_expand "movti"
2406 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2407 (match_operand:TI 1 "nonimmediate_operand" ""))]
2408 "TARGET_SSE || TARGET_64BIT"
2411 ix86_expand_move (TImode, operands);
2412 else if (push_operand (operands[0], TImode))
2413 ix86_expand_push (TImode, operands[1]);
2415 ix86_expand_vector_move (TImode, operands);
2419 (define_insn "*movti_internal"
2420 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2421 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2422 "TARGET_SSE && !TARGET_64BIT
2423 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2425 switch (which_alternative)
2428 if (get_attr_mode (insn) == MODE_V4SF)
2429 return "xorps\t%0, %0";
2431 return "pxor\t%0, %0";
2434 /* TDmode values are passed as TImode on the stack. Moving them
2435 to stack may result in unaligned memory access. */
2436 if (misaligned_operand (operands[0], TImode)
2437 || misaligned_operand (operands[1], TImode))
2439 if (get_attr_mode (insn) == MODE_V4SF)
2440 return "movups\t{%1, %0|%0, %1}";
2442 return "movdqu\t{%1, %0|%0, %1}";
2446 if (get_attr_mode (insn) == MODE_V4SF)
2447 return "movaps\t{%1, %0|%0, %1}";
2449 return "movdqa\t{%1, %0|%0, %1}";
2455 [(set_attr "type" "sselog1,ssemov,ssemov")
2457 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2458 (ne (symbol_ref "optimize_size") (const_int 0)))
2459 (const_string "V4SF")
2460 (and (eq_attr "alternative" "2")
2461 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2463 (const_string "V4SF")]
2464 (const_string "TI")))])
2466 (define_insn "*movti_rex64"
2467 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2468 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2470 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2472 switch (which_alternative)
2478 if (get_attr_mode (insn) == MODE_V4SF)
2479 return "xorps\t%0, %0";
2481 return "pxor\t%0, %0";
2484 /* TDmode values are passed as TImode on the stack. Moving them
2485 to stack may result in unaligned memory access. */
2486 if (misaligned_operand (operands[0], TImode)
2487 || misaligned_operand (operands[1], TImode))
2489 if (get_attr_mode (insn) == MODE_V4SF)
2490 return "movups\t{%1, %0|%0, %1}";
2492 return "movdqu\t{%1, %0|%0, %1}";
2496 if (get_attr_mode (insn) == MODE_V4SF)
2497 return "movaps\t{%1, %0|%0, %1}";
2499 return "movdqa\t{%1, %0|%0, %1}";
2505 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2507 (cond [(eq_attr "alternative" "2,3")
2509 (ne (symbol_ref "optimize_size")
2511 (const_string "V4SF")
2512 (const_string "TI"))
2513 (eq_attr "alternative" "4")
2515 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2517 (ne (symbol_ref "optimize_size")
2519 (const_string "V4SF")
2520 (const_string "TI"))]
2521 (const_string "DI")))])
2524 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2525 (match_operand:TI 1 "general_operand" ""))]
2526 "reload_completed && !SSE_REG_P (operands[0])
2527 && !SSE_REG_P (operands[1])"
2529 "ix86_split_long_move (operands); DONE;")
2531 ;; This expands to what emit_move_complex would generate if we didn't
2532 ;; have a movti pattern. Having this avoids problems with reload on
2533 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2534 ;; to have around all the time.
2535 (define_expand "movcdi"
2536 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2537 (match_operand:CDI 1 "general_operand" ""))]
2540 if (push_operand (operands[0], CDImode))
2541 emit_move_complex_push (CDImode, operands[0], operands[1]);
2543 emit_move_complex_parts (operands[0], operands[1]);
2547 (define_expand "movsf"
2548 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2549 (match_operand:SF 1 "general_operand" ""))]
2551 "ix86_expand_move (SFmode, operands); DONE;")
2553 (define_insn "*pushsf"
2554 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2555 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2558 /* Anything else should be already split before reg-stack. */
2559 gcc_assert (which_alternative == 1);
2560 return "push{l}\t%1";
2562 [(set_attr "type" "multi,push,multi")
2563 (set_attr "unit" "i387,*,*")
2564 (set_attr "mode" "SF,SI,SF")])
2566 (define_insn "*pushsf_rex64"
2567 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2568 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2571 /* Anything else should be already split before reg-stack. */
2572 gcc_assert (which_alternative == 1);
2573 return "push{q}\t%q1";
2575 [(set_attr "type" "multi,push,multi")
2576 (set_attr "unit" "i387,*,*")
2577 (set_attr "mode" "SF,DI,SF")])
2580 [(set (match_operand:SF 0 "push_operand" "")
2581 (match_operand:SF 1 "memory_operand" ""))]
2583 && MEM_P (operands[1])
2584 && (operands[2] = find_constant_src (insn))"
2589 ;; %%% Kill this when call knows how to work this out.
2591 [(set (match_operand:SF 0 "push_operand" "")
2592 (match_operand:SF 1 "any_fp_register_operand" ""))]
2594 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2595 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2598 [(set (match_operand:SF 0 "push_operand" "")
2599 (match_operand:SF 1 "any_fp_register_operand" ""))]
2601 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2602 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2604 (define_insn "*movsf_1"
2605 [(set (match_operand:SF 0 "nonimmediate_operand"
2606 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2607 (match_operand:SF 1 "general_operand"
2608 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2609 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2610 && (reload_in_progress || reload_completed
2611 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2612 || (!TARGET_SSE_MATH && optimize_size
2613 && standard_80387_constant_p (operands[1]))
2614 || GET_CODE (operands[1]) != CONST_DOUBLE
2615 || memory_operand (operands[0], SFmode))"
2617 switch (which_alternative)
2621 return output_387_reg_move (insn, operands);
2624 return standard_80387_constant_opcode (operands[1]);
2628 return "mov{l}\t{%1, %0|%0, %1}";
2630 if (get_attr_mode (insn) == MODE_TI)
2631 return "pxor\t%0, %0";
2633 return "xorps\t%0, %0";
2635 if (get_attr_mode (insn) == MODE_V4SF)
2636 return "movaps\t{%1, %0|%0, %1}";
2638 return "movss\t{%1, %0|%0, %1}";
2640 return "movss\t{%1, %0|%0, %1}";
2643 case 12: case 13: case 14: case 15:
2644 return "movd\t{%1, %0|%0, %1}";
2647 return "movq\t{%1, %0|%0, %1}";
2653 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2655 (cond [(eq_attr "alternative" "3,4,9,10")
2657 (eq_attr "alternative" "5")
2659 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2661 (ne (symbol_ref "TARGET_SSE2")
2663 (eq (symbol_ref "optimize_size")
2666 (const_string "V4SF"))
2667 /* For architectures resolving dependencies on
2668 whole SSE registers use APS move to break dependency
2669 chains, otherwise use short move to avoid extra work.
2671 Do the same for architectures resolving dependencies on
2672 the parts. While in DF mode it is better to always handle
2673 just register parts, the SF mode is different due to lack
2674 of instructions to load just part of the register. It is
2675 better to maintain the whole registers in single format
2676 to avoid problems on using packed logical operations. */
2677 (eq_attr "alternative" "6")
2679 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2681 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2683 (const_string "V4SF")
2684 (const_string "SF"))
2685 (eq_attr "alternative" "11")
2686 (const_string "DI")]
2687 (const_string "SF")))])
2689 (define_insn "*swapsf"
2690 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2691 (match_operand:SF 1 "fp_register_operand" "+f"))
2694 "reload_completed || TARGET_80387"
2696 if (STACK_TOP_P (operands[0]))
2701 [(set_attr "type" "fxch")
2702 (set_attr "mode" "SF")])
2704 (define_expand "movdf"
2705 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2706 (match_operand:DF 1 "general_operand" ""))]
2708 "ix86_expand_move (DFmode, operands); DONE;")
2710 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2711 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2712 ;; On the average, pushdf using integers can be still shorter. Allow this
2713 ;; pattern for optimize_size too.
2715 (define_insn "*pushdf_nointeger"
2716 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2717 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2718 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2720 /* This insn should be already split before reg-stack. */
2723 [(set_attr "type" "multi")
2724 (set_attr "unit" "i387,*,*,*")
2725 (set_attr "mode" "DF,SI,SI,DF")])
2727 (define_insn "*pushdf_integer"
2728 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2729 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2730 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2732 /* This insn should be already split before reg-stack. */
2735 [(set_attr "type" "multi")
2736 (set_attr "unit" "i387,*,*")
2737 (set_attr "mode" "DF,SI,DF")])
2739 ;; %%% Kill this when call knows how to work this out.
2741 [(set (match_operand:DF 0 "push_operand" "")
2742 (match_operand:DF 1 "any_fp_register_operand" ""))]
2744 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2745 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2749 [(set (match_operand:DF 0 "push_operand" "")
2750 (match_operand:DF 1 "general_operand" ""))]
2753 "ix86_split_long_move (operands); DONE;")
2755 ;; Moving is usually shorter when only FP registers are used. This separate
2756 ;; movdf pattern avoids the use of integer registers for FP operations
2757 ;; when optimizing for size.
2759 (define_insn "*movdf_nointeger"
2760 [(set (match_operand:DF 0 "nonimmediate_operand"
2761 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2762 (match_operand:DF 1 "general_operand"
2763 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2764 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2765 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2766 && (reload_in_progress || reload_completed
2767 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2768 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2769 && !memory_operand (operands[0], DFmode)
2770 && standard_80387_constant_p (operands[1]))
2771 || GET_CODE (operands[1]) != CONST_DOUBLE
2773 || !TARGET_MEMORY_MISMATCH_STALL
2774 || reload_in_progress || reload_completed)
2775 && memory_operand (operands[0], DFmode)))"
2777 switch (which_alternative)
2781 return output_387_reg_move (insn, operands);
2784 return standard_80387_constant_opcode (operands[1]);
2790 switch (get_attr_mode (insn))
2793 return "xorps\t%0, %0";
2795 return "xorpd\t%0, %0";
2797 return "pxor\t%0, %0";
2804 switch (get_attr_mode (insn))
2807 return "movaps\t{%1, %0|%0, %1}";
2809 return "movapd\t{%1, %0|%0, %1}";
2811 return "movdqa\t{%1, %0|%0, %1}";
2813 return "movq\t{%1, %0|%0, %1}";
2815 return "movsd\t{%1, %0|%0, %1}";
2817 return "movlpd\t{%1, %0|%0, %1}";
2819 return "movlps\t{%1, %0|%0, %1}";
2828 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2830 (cond [(eq_attr "alternative" "0,1,2")
2832 (eq_attr "alternative" "3,4")
2835 /* For SSE1, we have many fewer alternatives. */
2836 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2837 (cond [(eq_attr "alternative" "5,6")
2838 (const_string "V4SF")
2840 (const_string "V2SF"))
2842 /* xorps is one byte shorter. */
2843 (eq_attr "alternative" "5")
2844 (cond [(ne (symbol_ref "optimize_size")
2846 (const_string "V4SF")
2847 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2851 (const_string "V2DF"))
2853 /* For architectures resolving dependencies on
2854 whole SSE registers use APD move to break dependency
2855 chains, otherwise use short move to avoid extra work.
2857 movaps encodes one byte shorter. */
2858 (eq_attr "alternative" "6")
2860 [(ne (symbol_ref "optimize_size")
2862 (const_string "V4SF")
2863 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2865 (const_string "V2DF")
2867 (const_string "DF"))
2868 /* For architectures resolving dependencies on register
2869 parts we may avoid extra work to zero out upper part
2871 (eq_attr "alternative" "7")
2873 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2875 (const_string "V1DF")
2876 (const_string "DF"))
2878 (const_string "DF")))])
2880 (define_insn "*movdf_integer_rex64"
2881 [(set (match_operand:DF 0 "nonimmediate_operand"
2882 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2883 (match_operand:DF 1 "general_operand"
2884 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2885 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2886 && (reload_in_progress || reload_completed
2887 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2888 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2889 && standard_80387_constant_p (operands[1]))
2890 || GET_CODE (operands[1]) != CONST_DOUBLE
2891 || memory_operand (operands[0], DFmode))"
2893 switch (which_alternative)
2897 return output_387_reg_move (insn, operands);
2900 return standard_80387_constant_opcode (operands[1]);
2907 switch (get_attr_mode (insn))
2910 return "xorps\t%0, %0";
2912 return "xorpd\t%0, %0";
2914 return "pxor\t%0, %0";
2921 switch (get_attr_mode (insn))
2924 return "movaps\t{%1, %0|%0, %1}";
2926 return "movapd\t{%1, %0|%0, %1}";
2928 return "movdqa\t{%1, %0|%0, %1}";
2930 return "movq\t{%1, %0|%0, %1}";
2932 return "movsd\t{%1, %0|%0, %1}";
2934 return "movlpd\t{%1, %0|%0, %1}";
2936 return "movlps\t{%1, %0|%0, %1}";
2943 return "movd\t{%1, %0|%0, %1}";
2949 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2951 (cond [(eq_attr "alternative" "0,1,2")
2953 (eq_attr "alternative" "3,4,9,10")
2956 /* For SSE1, we have many fewer alternatives. */
2957 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2958 (cond [(eq_attr "alternative" "5,6")
2959 (const_string "V4SF")
2961 (const_string "V2SF"))
2963 /* xorps is one byte shorter. */
2964 (eq_attr "alternative" "5")
2965 (cond [(ne (symbol_ref "optimize_size")
2967 (const_string "V4SF")
2968 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2972 (const_string "V2DF"))
2974 /* For architectures resolving dependencies on
2975 whole SSE registers use APD move to break dependency
2976 chains, otherwise use short move to avoid extra work.
2978 movaps encodes one byte shorter. */
2979 (eq_attr "alternative" "6")
2981 [(ne (symbol_ref "optimize_size")
2983 (const_string "V4SF")
2984 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2986 (const_string "V2DF")
2988 (const_string "DF"))
2989 /* For architectures resolving dependencies on register
2990 parts we may avoid extra work to zero out upper part
2992 (eq_attr "alternative" "7")
2994 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2996 (const_string "V1DF")
2997 (const_string "DF"))
2999 (const_string "DF")))])
3001 (define_insn "*movdf_integer"
3002 [(set (match_operand:DF 0 "nonimmediate_operand"
3003 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3004 (match_operand:DF 1 "general_operand"
3005 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3006 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3007 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3008 && (reload_in_progress || reload_completed
3009 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3010 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3011 && standard_80387_constant_p (operands[1]))
3012 || GET_CODE (operands[1]) != CONST_DOUBLE
3013 || memory_operand (operands[0], DFmode))"
3015 switch (which_alternative)
3019 return output_387_reg_move (insn, operands);
3022 return standard_80387_constant_opcode (operands[1]);
3029 switch (get_attr_mode (insn))
3032 return "xorps\t%0, %0";
3034 return "xorpd\t%0, %0";
3036 return "pxor\t%0, %0";
3043 switch (get_attr_mode (insn))
3046 return "movaps\t{%1, %0|%0, %1}";
3048 return "movapd\t{%1, %0|%0, %1}";
3050 return "movdqa\t{%1, %0|%0, %1}";
3052 return "movq\t{%1, %0|%0, %1}";
3054 return "movsd\t{%1, %0|%0, %1}";
3056 return "movlpd\t{%1, %0|%0, %1}";
3058 return "movlps\t{%1, %0|%0, %1}";
3067 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3069 (cond [(eq_attr "alternative" "0,1,2")
3071 (eq_attr "alternative" "3,4")
3074 /* For SSE1, we have many fewer alternatives. */
3075 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3076 (cond [(eq_attr "alternative" "5,6")
3077 (const_string "V4SF")
3079 (const_string "V2SF"))
3081 /* xorps is one byte shorter. */
3082 (eq_attr "alternative" "5")
3083 (cond [(ne (symbol_ref "optimize_size")
3085 (const_string "V4SF")
3086 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3090 (const_string "V2DF"))
3092 /* For architectures resolving dependencies on
3093 whole SSE registers use APD move to break dependency
3094 chains, otherwise use short move to avoid extra work.
3096 movaps encodes one byte shorter. */
3097 (eq_attr "alternative" "6")
3099 [(ne (symbol_ref "optimize_size")
3101 (const_string "V4SF")
3102 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3104 (const_string "V2DF")
3106 (const_string "DF"))
3107 /* For architectures resolving dependencies on register
3108 parts we may avoid extra work to zero out upper part
3110 (eq_attr "alternative" "7")
3112 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3114 (const_string "V1DF")
3115 (const_string "DF"))
3117 (const_string "DF")))])
3120 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3121 (match_operand:DF 1 "general_operand" ""))]
3123 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3124 && ! (ANY_FP_REG_P (operands[0]) ||
3125 (GET_CODE (operands[0]) == SUBREG
3126 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3127 && ! (ANY_FP_REG_P (operands[1]) ||
3128 (GET_CODE (operands[1]) == SUBREG
3129 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3131 "ix86_split_long_move (operands); DONE;")
3133 (define_insn "*swapdf"
3134 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3135 (match_operand:DF 1 "fp_register_operand" "+f"))
3138 "reload_completed || TARGET_80387"
3140 if (STACK_TOP_P (operands[0]))
3145 [(set_attr "type" "fxch")
3146 (set_attr "mode" "DF")])
3148 (define_expand "movxf"
3149 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3150 (match_operand:XF 1 "general_operand" ""))]
3152 "ix86_expand_move (XFmode, operands); DONE;")
3154 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3155 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3156 ;; Pushing using integer instructions is longer except for constants
3157 ;; and direct memory references.
3158 ;; (assuming that any given constant is pushed only once, but this ought to be
3159 ;; handled elsewhere).
3161 (define_insn "*pushxf_nointeger"
3162 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3163 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3166 /* This insn should be already split before reg-stack. */
3169 [(set_attr "type" "multi")
3170 (set_attr "unit" "i387,*,*")
3171 (set_attr "mode" "XF,SI,SI")])
3173 (define_insn "*pushxf_integer"
3174 [(set (match_operand:XF 0 "push_operand" "=<,<")
3175 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3178 /* This insn should be already split before reg-stack. */
3181 [(set_attr "type" "multi")
3182 (set_attr "unit" "i387,*")
3183 (set_attr "mode" "XF,SI")])
3186 [(set (match_operand 0 "push_operand" "")
3187 (match_operand 1 "general_operand" ""))]
3189 && (GET_MODE (operands[0]) == XFmode
3190 || GET_MODE (operands[0]) == DFmode)
3191 && !ANY_FP_REG_P (operands[1])"
3193 "ix86_split_long_move (operands); DONE;")
3196 [(set (match_operand:XF 0 "push_operand" "")
3197 (match_operand:XF 1 "any_fp_register_operand" ""))]
3199 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3200 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3201 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3203 ;; Do not use integer registers when optimizing for size
3204 (define_insn "*movxf_nointeger"
3205 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3206 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3208 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3209 && (reload_in_progress || reload_completed
3210 || (optimize_size && standard_80387_constant_p (operands[1]))
3211 || GET_CODE (operands[1]) != CONST_DOUBLE
3212 || memory_operand (operands[0], XFmode))"
3214 switch (which_alternative)
3218 return output_387_reg_move (insn, operands);
3221 return standard_80387_constant_opcode (operands[1]);
3229 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3230 (set_attr "mode" "XF,XF,XF,SI,SI")])
3232 (define_insn "*movxf_integer"
3233 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3234 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3236 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3237 && (reload_in_progress || reload_completed
3238 || (optimize_size && standard_80387_constant_p (operands[1]))
3239 || GET_CODE (operands[1]) != CONST_DOUBLE
3240 || memory_operand (operands[0], XFmode))"
3242 switch (which_alternative)
3246 return output_387_reg_move (insn, operands);
3249 return standard_80387_constant_opcode (operands[1]);
3258 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3259 (set_attr "mode" "XF,XF,XF,SI,SI")])
3261 (define_expand "movtf"
3262 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3263 (match_operand:TF 1 "nonimmediate_operand" ""))]
3266 ix86_expand_move (TFmode, operands);
3270 (define_insn "*movtf_internal"
3271 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3272 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3274 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3276 switch (which_alternative)
3280 if (get_attr_mode (insn) == MODE_V4SF)
3281 return "movaps\t{%1, %0|%0, %1}";
3283 return "movdqa\t{%1, %0|%0, %1}";
3285 if (get_attr_mode (insn) == MODE_V4SF)
3286 return "xorps\t%0, %0";
3288 return "pxor\t%0, %0";
3296 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3298 (cond [(eq_attr "alternative" "0,2")
3300 (ne (symbol_ref "optimize_size")
3302 (const_string "V4SF")
3303 (const_string "TI"))
3304 (eq_attr "alternative" "1")
3306 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3308 (ne (symbol_ref "optimize_size")
3310 (const_string "V4SF")
3311 (const_string "TI"))]
3312 (const_string "DI")))])
3315 [(set (match_operand 0 "nonimmediate_operand" "")
3316 (match_operand 1 "general_operand" ""))]
3318 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3319 && GET_MODE (operands[0]) == XFmode
3320 && ! (ANY_FP_REG_P (operands[0]) ||
3321 (GET_CODE (operands[0]) == SUBREG
3322 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3323 && ! (ANY_FP_REG_P (operands[1]) ||
3324 (GET_CODE (operands[1]) == SUBREG
3325 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3327 "ix86_split_long_move (operands); DONE;")
3330 [(set (match_operand 0 "register_operand" "")
3331 (match_operand 1 "memory_operand" ""))]
3333 && MEM_P (operands[1])
3334 && (GET_MODE (operands[0]) == TFmode
3335 || GET_MODE (operands[0]) == XFmode
3336 || GET_MODE (operands[0]) == SFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && (operands[2] = find_constant_src (insn))"
3339 [(set (match_dup 0) (match_dup 2))]
3341 rtx c = operands[2];
3342 rtx r = operands[0];
3344 if (GET_CODE (r) == SUBREG)
3349 if (!standard_sse_constant_p (c))
3352 else if (FP_REG_P (r))
3354 if (!standard_80387_constant_p (c))
3357 else if (MMX_REG_P (r))
3362 [(set (match_operand 0 "register_operand" "")
3363 (float_extend (match_operand 1 "memory_operand" "")))]
3365 && MEM_P (operands[1])
3366 && (GET_MODE (operands[0]) == TFmode
3367 || GET_MODE (operands[0]) == XFmode
3368 || GET_MODE (operands[0]) == SFmode
3369 || GET_MODE (operands[0]) == DFmode)
3370 && (operands[2] = find_constant_src (insn))"
3371 [(set (match_dup 0) (match_dup 2))]
3373 rtx c = operands[2];
3374 rtx r = operands[0];
3376 if (GET_CODE (r) == SUBREG)
3381 if (!standard_sse_constant_p (c))
3384 else if (FP_REG_P (r))
3386 if (!standard_80387_constant_p (c))
3389 else if (MMX_REG_P (r))
3393 (define_insn "swapxf"
3394 [(set (match_operand:XF 0 "register_operand" "+f")
3395 (match_operand:XF 1 "register_operand" "+f"))
3400 if (STACK_TOP_P (operands[0]))
3405 [(set_attr "type" "fxch")
3406 (set_attr "mode" "XF")])
3408 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3410 [(set (match_operand:X87MODEF 0 "register_operand" "")
3411 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3412 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3413 && (standard_80387_constant_p (operands[1]) == 8
3414 || standard_80387_constant_p (operands[1]) == 9)"
3415 [(set (match_dup 0)(match_dup 1))
3417 (neg:X87MODEF (match_dup 0)))]
3421 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3422 if (real_isnegzero (&r))
3423 operands[1] = CONST0_RTX (<MODE>mode);
3425 operands[1] = CONST1_RTX (<MODE>mode);
3429 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3430 (match_operand:TF 1 "general_operand" ""))]
3432 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3434 "ix86_split_long_move (operands); DONE;")
3436 ;; Zero extension instructions
3438 (define_expand "zero_extendhisi2"
3439 [(set (match_operand:SI 0 "register_operand" "")
3440 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3443 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3445 operands[1] = force_reg (HImode, operands[1]);
3446 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3451 (define_insn "zero_extendhisi2_and"
3452 [(set (match_operand:SI 0 "register_operand" "=r")
3453 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3454 (clobber (reg:CC FLAGS_REG))]
3455 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3457 [(set_attr "type" "alu1")
3458 (set_attr "mode" "SI")])
3461 [(set (match_operand:SI 0 "register_operand" "")
3462 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3463 (clobber (reg:CC FLAGS_REG))]
3464 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3465 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3466 (clobber (reg:CC FLAGS_REG))])]
3469 (define_insn "*zero_extendhisi2_movzwl"
3470 [(set (match_operand:SI 0 "register_operand" "=r")
3471 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3472 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3473 "movz{wl|x}\t{%1, %0|%0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "SI")])
3477 (define_expand "zero_extendqihi2"
3479 [(set (match_operand:HI 0 "register_operand" "")
3480 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3481 (clobber (reg:CC FLAGS_REG))])]
3485 (define_insn "*zero_extendqihi2_and"
3486 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3487 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3488 (clobber (reg:CC FLAGS_REG))]
3489 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3491 [(set_attr "type" "alu1")
3492 (set_attr "mode" "HI")])
3494 (define_insn "*zero_extendqihi2_movzbw_and"
3495 [(set (match_operand:HI 0 "register_operand" "=r,r")
3496 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3497 (clobber (reg:CC FLAGS_REG))]
3498 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3500 [(set_attr "type" "imovx,alu1")
3501 (set_attr "mode" "HI")])
3503 ; zero extend to SImode here to avoid partial register stalls
3504 (define_insn "*zero_extendqihi2_movzbl"
3505 [(set (match_operand:HI 0 "register_operand" "=r")
3506 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3507 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3508 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3509 [(set_attr "type" "imovx")
3510 (set_attr "mode" "SI")])
3512 ;; For the movzbw case strip only the clobber
3514 [(set (match_operand:HI 0 "register_operand" "")
3515 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3516 (clobber (reg:CC FLAGS_REG))]
3518 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3519 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3520 [(set (match_operand:HI 0 "register_operand" "")
3521 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3523 ;; When source and destination does not overlap, clear destination
3524 ;; first and then do the movb
3526 [(set (match_operand:HI 0 "register_operand" "")
3527 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3528 (clobber (reg:CC FLAGS_REG))]
3530 && ANY_QI_REG_P (operands[0])
3531 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3532 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3533 [(set (match_dup 0) (const_int 0))
3534 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3535 "operands[2] = gen_lowpart (QImode, operands[0]);")
3537 ;; Rest is handled by single and.
3539 [(set (match_operand:HI 0 "register_operand" "")
3540 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3541 (clobber (reg:CC FLAGS_REG))]
3543 && true_regnum (operands[0]) == true_regnum (operands[1])"
3544 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3545 (clobber (reg:CC FLAGS_REG))])]
3548 (define_expand "zero_extendqisi2"
3550 [(set (match_operand:SI 0 "register_operand" "")
3551 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3552 (clobber (reg:CC FLAGS_REG))])]
3556 (define_insn "*zero_extendqisi2_and"
3557 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3558 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3559 (clobber (reg:CC FLAGS_REG))]
3560 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3562 [(set_attr "type" "alu1")
3563 (set_attr "mode" "SI")])
3565 (define_insn "*zero_extendqisi2_movzbw_and"
3566 [(set (match_operand:SI 0 "register_operand" "=r,r")
3567 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3568 (clobber (reg:CC FLAGS_REG))]
3569 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3571 [(set_attr "type" "imovx,alu1")
3572 (set_attr "mode" "SI")])
3574 (define_insn "*zero_extendqisi2_movzbw"
3575 [(set (match_operand:SI 0 "register_operand" "=r")
3576 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3577 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3578 "movz{bl|x}\t{%1, %0|%0, %1}"
3579 [(set_attr "type" "imovx")
3580 (set_attr "mode" "SI")])
3582 ;; For the movzbl case strip only the clobber
3584 [(set (match_operand:SI 0 "register_operand" "")
3585 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3586 (clobber (reg:CC FLAGS_REG))]
3588 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3589 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3591 (zero_extend:SI (match_dup 1)))])
3593 ;; When source and destination does not overlap, clear destination
3594 ;; first and then do the movb
3596 [(set (match_operand:SI 0 "register_operand" "")
3597 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3598 (clobber (reg:CC FLAGS_REG))]
3600 && ANY_QI_REG_P (operands[0])
3601 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3602 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3603 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3604 [(set (match_dup 0) (const_int 0))
3605 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3606 "operands[2] = gen_lowpart (QImode, operands[0]);")
3608 ;; Rest is handled by single and.
3610 [(set (match_operand:SI 0 "register_operand" "")
3611 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))]
3614 && true_regnum (operands[0]) == true_regnum (operands[1])"
3615 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3616 (clobber (reg:CC FLAGS_REG))])]
3619 ;; %%% Kill me once multi-word ops are sane.
3620 (define_expand "zero_extendsidi2"
3621 [(set (match_operand:DI 0 "register_operand" "")
3622 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3627 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3632 (define_insn "zero_extendsidi2_32"
3633 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3635 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3636 (clobber (reg:CC FLAGS_REG))]
3642 movd\t{%1, %0|%0, %1}
3643 movd\t{%1, %0|%0, %1}
3644 movd\t{%1, %0|%0, %1}
3645 movd\t{%1, %0|%0, %1}"
3646 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3647 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3649 (define_insn "zero_extendsidi2_rex64"
3650 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3652 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3655 mov\t{%k1, %k0|%k0, %k1}
3657 movd\t{%1, %0|%0, %1}
3658 movd\t{%1, %0|%0, %1}
3659 movd\t{%1, %0|%0, %1}
3660 movd\t{%1, %0|%0, %1}"
3661 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3662 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3665 [(set (match_operand:DI 0 "memory_operand" "")
3666 (zero_extend:DI (match_dup 0)))]
3668 [(set (match_dup 4) (const_int 0))]
3669 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3672 [(set (match_operand:DI 0 "register_operand" "")
3673 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3674 (clobber (reg:CC FLAGS_REG))]
3675 "!TARGET_64BIT && reload_completed
3676 && true_regnum (operands[0]) == true_regnum (operands[1])"
3677 [(set (match_dup 4) (const_int 0))]
3678 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3681 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3682 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3683 (clobber (reg:CC FLAGS_REG))]
3684 "!TARGET_64BIT && reload_completed
3685 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3686 [(set (match_dup 3) (match_dup 1))
3687 (set (match_dup 4) (const_int 0))]
3688 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3690 (define_insn "zero_extendhidi2"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3692 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3694 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "DI")])
3698 (define_insn "zero_extendqidi2"
3699 [(set (match_operand:DI 0 "register_operand" "=r")
3700 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3702 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3703 [(set_attr "type" "imovx")
3704 (set_attr "mode" "DI")])
3706 ;; Sign extension instructions
3708 (define_expand "extendsidi2"
3709 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3710 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711 (clobber (reg:CC FLAGS_REG))
3712 (clobber (match_scratch:SI 2 ""))])]
3717 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3722 (define_insn "*extendsidi2_1"
3723 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3724 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3725 (clobber (reg:CC FLAGS_REG))
3726 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3730 (define_insn "extendsidi2_rex64"
3731 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3732 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3736 movs{lq|x}\t{%1,%0|%0, %1}"
3737 [(set_attr "type" "imovx")
3738 (set_attr "mode" "DI")
3739 (set_attr "prefix_0f" "0")
3740 (set_attr "modrm" "0,1")])
3742 (define_insn "extendhidi2"
3743 [(set (match_operand:DI 0 "register_operand" "=r")
3744 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3746 "movs{wq|x}\t{%1,%0|%0, %1}"
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "DI")])
3750 (define_insn "extendqidi2"
3751 [(set (match_operand:DI 0 "register_operand" "=r")
3752 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3754 "movs{bq|x}\t{%1,%0|%0, %1}"
3755 [(set_attr "type" "imovx")
3756 (set_attr "mode" "DI")])
3758 ;; Extend to memory case when source register does die.
3760 [(set (match_operand:DI 0 "memory_operand" "")
3761 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3762 (clobber (reg:CC FLAGS_REG))
3763 (clobber (match_operand:SI 2 "register_operand" ""))]
3765 && dead_or_set_p (insn, operands[1])
3766 && !reg_mentioned_p (operands[1], operands[0]))"
3767 [(set (match_dup 3) (match_dup 1))
3768 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3769 (clobber (reg:CC FLAGS_REG))])
3770 (set (match_dup 4) (match_dup 1))]
3771 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3773 ;; Extend to memory case when source register does not die.
3775 [(set (match_operand:DI 0 "memory_operand" "")
3776 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3777 (clobber (reg:CC FLAGS_REG))
3778 (clobber (match_operand:SI 2 "register_operand" ""))]
3782 split_di (&operands[0], 1, &operands[3], &operands[4]);
3784 emit_move_insn (operands[3], operands[1]);
3786 /* Generate a cltd if possible and doing so it profitable. */
3787 if ((optimize_size || TARGET_USE_CLTD)
3788 && true_regnum (operands[1]) == AX_REG
3789 && true_regnum (operands[2]) == DX_REG)
3791 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3795 emit_move_insn (operands[2], operands[1]);
3796 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3798 emit_move_insn (operands[4], operands[2]);
3802 ;; Extend to register case. Optimize case where source and destination
3803 ;; registers match and cases where we can use cltd.
3805 [(set (match_operand:DI 0 "register_operand" "")
3806 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3807 (clobber (reg:CC FLAGS_REG))
3808 (clobber (match_scratch:SI 2 ""))]
3812 split_di (&operands[0], 1, &operands[3], &operands[4]);
3814 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3815 emit_move_insn (operands[3], operands[1]);
3817 /* Generate a cltd if possible and doing so it profitable. */
3818 if ((optimize_size || TARGET_USE_CLTD)
3819 && true_regnum (operands[3]) == AX_REG)
3821 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3825 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3826 emit_move_insn (operands[4], operands[1]);
3828 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3832 (define_insn "extendhisi2"
3833 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3834 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3837 switch (get_attr_prefix_0f (insn))
3840 return "{cwtl|cwde}";
3842 return "movs{wl|x}\t{%1,%0|%0, %1}";
3845 [(set_attr "type" "imovx")
3846 (set_attr "mode" "SI")
3847 (set (attr "prefix_0f")
3848 ;; movsx is short decodable while cwtl is vector decoded.
3849 (if_then_else (and (eq_attr "cpu" "!k6")
3850 (eq_attr "alternative" "0"))
3852 (const_string "1")))
3854 (if_then_else (eq_attr "prefix_0f" "0")
3856 (const_string "1")))])
3858 (define_insn "*extendhisi2_zext"
3859 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3861 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3864 switch (get_attr_prefix_0f (insn))
3867 return "{cwtl|cwde}";
3869 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3872 [(set_attr "type" "imovx")
3873 (set_attr "mode" "SI")
3874 (set (attr "prefix_0f")
3875 ;; movsx is short decodable while cwtl is vector decoded.
3876 (if_then_else (and (eq_attr "cpu" "!k6")
3877 (eq_attr "alternative" "0"))
3879 (const_string "1")))
3881 (if_then_else (eq_attr "prefix_0f" "0")
3883 (const_string "1")))])
3885 (define_insn "extendqihi2"
3886 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3887 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3890 switch (get_attr_prefix_0f (insn))
3893 return "{cbtw|cbw}";
3895 return "movs{bw|x}\t{%1,%0|%0, %1}";
3898 [(set_attr "type" "imovx")
3899 (set_attr "mode" "HI")
3900 (set (attr "prefix_0f")
3901 ;; movsx is short decodable while cwtl is vector decoded.
3902 (if_then_else (and (eq_attr "cpu" "!k6")
3903 (eq_attr "alternative" "0"))
3905 (const_string "1")))
3907 (if_then_else (eq_attr "prefix_0f" "0")
3909 (const_string "1")))])
3911 (define_insn "extendqisi2"
3912 [(set (match_operand:SI 0 "register_operand" "=r")
3913 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3915 "movs{bl|x}\t{%1,%0|%0, %1}"
3916 [(set_attr "type" "imovx")
3917 (set_attr "mode" "SI")])
3919 (define_insn "*extendqisi2_zext"
3920 [(set (match_operand:DI 0 "register_operand" "=r")
3922 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3924 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3925 [(set_attr "type" "imovx")
3926 (set_attr "mode" "SI")])
3928 ;; Conversions between float and double.
3930 ;; These are all no-ops in the model used for the 80387. So just
3933 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3934 (define_insn "*dummy_extendsfdf2"
3935 [(set (match_operand:DF 0 "push_operand" "=<")
3936 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3941 [(set (match_operand:DF 0 "push_operand" "")
3942 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3944 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3945 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3947 (define_insn "*dummy_extendsfxf2"
3948 [(set (match_operand:XF 0 "push_operand" "=<")
3949 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3954 [(set (match_operand:XF 0 "push_operand" "")
3955 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3957 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3958 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3959 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3962 [(set (match_operand:XF 0 "push_operand" "")
3963 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3965 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3966 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3967 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3969 (define_expand "extendsfdf2"
3970 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3971 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3972 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3974 /* ??? Needed for compress_float_constant since all fp constants
3975 are LEGITIMATE_CONSTANT_P. */
3976 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3978 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3979 && standard_80387_constant_p (operands[1]) > 0)
3981 operands[1] = simplify_const_unary_operation
3982 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3983 emit_move_insn_1 (operands[0], operands[1]);
3986 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3990 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3992 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3994 We do the conversion post reload to avoid producing of 128bit spills
3995 that might lead to ICE on 32bit target. The sequence unlikely combine
3998 [(set (match_operand:DF 0 "register_operand" "")
4000 (match_operand:SF 1 "nonimmediate_operand" "")))]
4001 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4002 && reload_completed && SSE_REG_P (operands[0])"
4007 (parallel [(const_int 0) (const_int 1)]))))]
4009 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4010 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4011 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4012 Try to avoid move when unpacking can be done in source. */
4013 if (REG_P (operands[1]))
4015 /* If it is unsafe to overwrite upper half of source, we need
4016 to move to destination and unpack there. */
4017 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4018 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4019 && true_regnum (operands[0]) != true_regnum (operands[1]))
4021 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4022 emit_move_insn (tmp, operands[1]);
4025 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4026 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4029 emit_insn (gen_vec_setv4sf_0 (operands[3],
4030 CONST0_RTX (V4SFmode), operands[1]));
4033 (define_insn "*extendsfdf2_mixed"
4034 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4036 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4037 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4039 switch (which_alternative)
4043 return output_387_reg_move (insn, operands);
4046 return "cvtss2sd\t{%1, %0|%0, %1}";
4052 [(set_attr "type" "fmov,fmov,ssecvt")
4053 (set_attr "mode" "SF,XF,DF")])
4055 (define_insn "*extendsfdf2_sse"
4056 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4057 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4058 "TARGET_SSE2 && TARGET_SSE_MATH"
4059 "cvtss2sd\t{%1, %0|%0, %1}"
4060 [(set_attr "type" "ssecvt")
4061 (set_attr "mode" "DF")])
4063 (define_insn "*extendsfdf2_i387"
4064 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4065 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4067 "* return output_387_reg_move (insn, operands);"
4068 [(set_attr "type" "fmov")
4069 (set_attr "mode" "SF,XF")])
4071 (define_expand "extend<mode>xf2"
4072 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4073 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4076 /* ??? Needed for compress_float_constant since all fp constants
4077 are LEGITIMATE_CONSTANT_P. */
4078 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4080 if (standard_80387_constant_p (operands[1]) > 0)
4082 operands[1] = simplify_const_unary_operation
4083 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4084 emit_move_insn_1 (operands[0], operands[1]);
4087 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4091 (define_insn "*extend<mode>xf2_i387"
4092 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4094 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4096 "* return output_387_reg_move (insn, operands);"
4097 [(set_attr "type" "fmov")
4098 (set_attr "mode" "<MODE>,XF")])
4100 ;; %%% This seems bad bad news.
4101 ;; This cannot output into an f-reg because there is no way to be sure
4102 ;; of truncating in that case. Otherwise this is just like a simple move
4103 ;; insn. So we pretend we can output to a reg in order to get better
4104 ;; register preferencing, but we really use a stack slot.
4106 ;; Conversion from DFmode to SFmode.
4108 (define_expand "truncdfsf2"
4109 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4111 (match_operand:DF 1 "nonimmediate_operand" "")))]
4112 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4114 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4116 else if (flag_unsafe_math_optimizations)
4120 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4121 rtx temp = assign_386_stack_local (SFmode, slot);
4122 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4127 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4129 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4131 We do the conversion post reload to avoid producing of 128bit spills
4132 that might lead to ICE on 32bit target. The sequence unlikely combine
4135 [(set (match_operand:SF 0 "register_operand" "")
4137 (match_operand:DF 1 "nonimmediate_operand" "")))]
4138 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4139 && reload_completed && SSE_REG_P (operands[0])"
4142 (float_truncate:V2SF
4146 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4147 operands[3] = CONST0_RTX (V2SFmode);
4148 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4149 /* Use movsd for loading from memory, unpcklpd for registers.
4150 Try to avoid move when unpacking can be done in source, or SSE3
4151 movddup is available. */
4152 if (REG_P (operands[1]))
4155 && true_regnum (operands[0]) != true_regnum (operands[1])
4156 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4157 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4159 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4160 emit_move_insn (tmp, operands[1]);
4163 else if (!TARGET_SSE3)
4164 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4165 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4168 emit_insn (gen_sse2_loadlpd (operands[4],
4169 CONST0_RTX (V2DFmode), operands[1]));
4172 (define_expand "truncdfsf2_with_temp"
4173 [(parallel [(set (match_operand:SF 0 "" "")
4174 (float_truncate:SF (match_operand:DF 1 "" "")))
4175 (clobber (match_operand:SF 2 "" ""))])]
4178 (define_insn "*truncdfsf_fast_mixed"
4179 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4181 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4182 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4184 switch (which_alternative)
4187 return output_387_reg_move (insn, operands);
4189 return "cvtsd2ss\t{%1, %0|%0, %1}";
4194 [(set_attr "type" "fmov,ssecvt")
4195 (set_attr "mode" "SF")])
4197 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4198 ;; because nothing we do here is unsafe.
4199 (define_insn "*truncdfsf_fast_sse"
4200 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4202 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4203 "TARGET_SSE2 && TARGET_SSE_MATH"
4204 "cvtsd2ss\t{%1, %0|%0, %1}"
4205 [(set_attr "type" "ssecvt")
4206 (set_attr "mode" "SF")])
4208 (define_insn "*truncdfsf_fast_i387"
4209 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4211 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4212 "TARGET_80387 && flag_unsafe_math_optimizations"
4213 "* return output_387_reg_move (insn, operands);"
4214 [(set_attr "type" "fmov")
4215 (set_attr "mode" "SF")])
4217 (define_insn "*truncdfsf_mixed"
4218 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4220 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4221 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4222 "TARGET_MIX_SSE_I387"
4224 switch (which_alternative)
4227 return output_387_reg_move (insn, operands);
4232 return "cvtsd2ss\t{%1, %0|%0, %1}";
4237 [(set_attr "type" "fmov,multi,ssecvt")
4238 (set_attr "unit" "*,i387,*")
4239 (set_attr "mode" "SF")])
4241 (define_insn "*truncdfsf_i387"
4242 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4244 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4245 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4248 switch (which_alternative)
4251 return output_387_reg_move (insn, operands);
4259 [(set_attr "type" "fmov,multi")
4260 (set_attr "unit" "*,i387")
4261 (set_attr "mode" "SF")])
4263 (define_insn "*truncdfsf2_i387_1"
4264 [(set (match_operand:SF 0 "memory_operand" "=m")
4266 (match_operand:DF 1 "register_operand" "f")))]
4268 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4269 && !TARGET_MIX_SSE_I387"
4270 "* return output_387_reg_move (insn, operands);"
4271 [(set_attr "type" "fmov")
4272 (set_attr "mode" "SF")])
4275 [(set (match_operand:SF 0 "register_operand" "")
4277 (match_operand:DF 1 "fp_register_operand" "")))
4278 (clobber (match_operand 2 "" ""))]
4280 [(set (match_dup 2) (match_dup 1))
4281 (set (match_dup 0) (match_dup 2))]
4283 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4286 ;; Conversion from XFmode to {SF,DF}mode
4288 (define_expand "truncxf<mode>2"
4289 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4290 (float_truncate:MODEF
4291 (match_operand:XF 1 "register_operand" "")))
4292 (clobber (match_dup 2))])]
4295 if (flag_unsafe_math_optimizations)
4297 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4298 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4299 if (reg != operands[0])
4300 emit_move_insn (operands[0], reg);
4305 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4306 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4310 (define_insn "*truncxfsf2_mixed"
4311 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4313 (match_operand:XF 1 "register_operand" "f,f")))
4314 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4317 gcc_assert (!which_alternative);
4318 return output_387_reg_move (insn, operands);
4320 [(set_attr "type" "fmov,multi")
4321 (set_attr "unit" "*,i387")
4322 (set_attr "mode" "SF")])
4324 (define_insn "*truncxfdf2_mixed"
4325 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4327 (match_operand:XF 1 "register_operand" "f,f")))
4328 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4331 gcc_assert (!which_alternative);
4332 return output_387_reg_move (insn, operands);
4334 [(set_attr "type" "fmov,multi")
4335 (set_attr "unit" "*,i387")
4336 (set_attr "mode" "DF")])
4338 (define_insn "truncxf<mode>2_i387_noop"
4339 [(set (match_operand:MODEF 0 "register_operand" "=f")
4340 (float_truncate:MODEF
4341 (match_operand:XF 1 "register_operand" "f")))]
4342 "TARGET_80387 && flag_unsafe_math_optimizations"
4343 "* return output_387_reg_move (insn, operands);"
4344 [(set_attr "type" "fmov")
4345 (set_attr "mode" "<MODE>")])
4347 (define_insn "*truncxf<mode>2_i387"
4348 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4349 (float_truncate:MODEF
4350 (match_operand:XF 1 "register_operand" "f")))]
4352 "* return output_387_reg_move (insn, operands);"
4353 [(set_attr "type" "fmov")
4354 (set_attr "mode" "<MODE>")])
4357 [(set (match_operand:MODEF 0 "register_operand" "")
4358 (float_truncate:MODEF
4359 (match_operand:XF 1 "register_operand" "")))
4360 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4361 "TARGET_80387 && reload_completed"
4362 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4363 (set (match_dup 0) (match_dup 2))]
4367 [(set (match_operand:MODEF 0 "memory_operand" "")
4368 (float_truncate:MODEF
4369 (match_operand:XF 1 "register_operand" "")))
4370 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4372 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4375 ;; Signed conversion to DImode.
4377 (define_expand "fix_truncxfdi2"
4378 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4379 (fix:DI (match_operand:XF 1 "register_operand" "")))
4380 (clobber (reg:CC FLAGS_REG))])]
4385 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4390 (define_expand "fix_trunc<mode>di2"
4391 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4392 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4393 (clobber (reg:CC FLAGS_REG))])]
4394 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4397 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4399 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4402 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4404 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4405 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4406 if (out != operands[0])
4407 emit_move_insn (operands[0], out);
4412 ;; Signed conversion to SImode.
4414 (define_expand "fix_truncxfsi2"
4415 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4416 (fix:SI (match_operand:XF 1 "register_operand" "")))
4417 (clobber (reg:CC FLAGS_REG))])]
4422 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4427 (define_expand "fix_trunc<mode>si2"
4428 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4429 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4430 (clobber (reg:CC FLAGS_REG))])]
4431 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4434 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4436 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4439 if (SSE_FLOAT_MODE_P (<MODE>mode))
4441 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4442 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4443 if (out != operands[0])
4444 emit_move_insn (operands[0], out);
4449 ;; Signed conversion to HImode.
4451 (define_expand "fix_trunc<mode>hi2"
4452 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4453 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4454 (clobber (reg:CC FLAGS_REG))])]
4456 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4460 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4465 ;; Unsigned conversion to SImode.
4467 (define_expand "fixuns_trunc<mode>si2"
4469 [(set (match_operand:SI 0 "register_operand" "")
4471 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4473 (clobber (match_scratch:<ssevecmode> 3 ""))
4474 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4475 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4477 enum machine_mode mode = <MODE>mode;
4478 enum machine_mode vecmode = <ssevecmode>mode;
4479 REAL_VALUE_TYPE TWO31r;
4482 real_ldexp (&TWO31r, &dconst1, 31);
4483 two31 = const_double_from_real_value (TWO31r, mode);
4484 two31 = ix86_build_const_vector (mode, true, two31);
4485 operands[2] = force_reg (vecmode, two31);
4488 (define_insn_and_split "*fixuns_trunc<mode>_1"
4489 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4491 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4492 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4493 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4494 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4495 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4497 "&& reload_completed"
4500 ix86_split_convert_uns_si_sse (operands);
4504 ;; Unsigned conversion to HImode.
4505 ;; Without these patterns, we'll try the unsigned SI conversion which
4506 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4508 (define_expand "fixuns_trunc<mode>hi2"
4510 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4511 (set (match_operand:HI 0 "nonimmediate_operand" "")
4512 (subreg:HI (match_dup 2) 0))]
4513 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4514 "operands[2] = gen_reg_rtx (SImode);")
4516 ;; When SSE is available, it is always faster to use it!
4517 (define_insn "fix_trunc<mode>di_sse"
4518 [(set (match_operand:DI 0 "register_operand" "=r,r")
4519 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4520 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4521 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4522 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4523 [(set_attr "type" "sseicvt")
4524 (set_attr "mode" "<MODE>")
4525 (set_attr "athlon_decode" "double,vector")
4526 (set_attr "amdfam10_decode" "double,double")])
4528 (define_insn "fix_trunc<mode>si_sse"
4529 [(set (match_operand:SI 0 "register_operand" "=r,r")
4530 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4531 "SSE_FLOAT_MODE_P (<MODE>mode)
4532 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4533 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4534 [(set_attr "type" "sseicvt")
4535 (set_attr "mode" "<MODE>")
4536 (set_attr "athlon_decode" "double,vector")
4537 (set_attr "amdfam10_decode" "double,double")])
4539 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4541 [(set (match_operand:MODEF 0 "register_operand" "")
4542 (match_operand:MODEF 1 "memory_operand" ""))
4543 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4544 (fix:SSEMODEI24 (match_dup 0)))]
4545 "TARGET_SHORTEN_X87_SSE
4546 && peep2_reg_dead_p (2, operands[0])"
4547 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4550 ;; Avoid vector decoded forms of the instruction.
4552 [(match_scratch:DF 2 "Y2")
4553 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4554 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4555 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4556 [(set (match_dup 2) (match_dup 1))
4557 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4561 [(match_scratch:SF 2 "x")
4562 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4563 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4564 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4565 [(set (match_dup 2) (match_dup 1))
4566 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4569 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4570 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4571 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4572 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4574 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4575 && (TARGET_64BIT || <MODE>mode != DImode))
4577 && !(reload_completed || reload_in_progress)"
4582 if (memory_operand (operands[0], VOIDmode))
4583 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4586 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4587 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4593 [(set_attr "type" "fisttp")
4594 (set_attr "mode" "<MODE>")])
4596 (define_insn "fix_trunc<mode>_i387_fisttp"
4597 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4598 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4599 (clobber (match_scratch:XF 2 "=&1f"))]
4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4602 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4603 && (TARGET_64BIT || <MODE>mode != DImode))
4604 && TARGET_SSE_MATH)"
4605 "* return output_fix_trunc (insn, operands, 1);"
4606 [(set_attr "type" "fisttp")
4607 (set_attr "mode" "<MODE>")])
4609 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4610 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4611 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4612 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4613 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && (TARGET_64BIT || <MODE>mode != DImode))
4618 && TARGET_SSE_MATH)"
4620 [(set_attr "type" "fisttp")
4621 (set_attr "mode" "<MODE>")])
4624 [(set (match_operand:X87MODEI 0 "register_operand" "")
4625 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4626 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4627 (clobber (match_scratch 3 ""))]
4629 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4630 (clobber (match_dup 3))])
4631 (set (match_dup 0) (match_dup 2))]
4635 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4636 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4637 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4638 (clobber (match_scratch 3 ""))]
4640 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4641 (clobber (match_dup 3))])]
4644 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4645 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4646 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4647 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4648 ;; function in i386.c.
4649 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4650 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4651 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4652 (clobber (reg:CC FLAGS_REG))]
4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4656 && (TARGET_64BIT || <MODE>mode != DImode))
4657 && !(reload_completed || reload_in_progress)"
4662 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4664 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4665 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4666 if (memory_operand (operands[0], VOIDmode))
4667 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4668 operands[2], operands[3]));
4671 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4672 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4673 operands[2], operands[3],
4678 [(set_attr "type" "fistp")
4679 (set_attr "i387_cw" "trunc")
4680 (set_attr "mode" "<MODE>")])
4682 (define_insn "fix_truncdi_i387"
4683 [(set (match_operand:DI 0 "memory_operand" "=m")
4684 (fix:DI (match_operand 1 "register_operand" "f")))
4685 (use (match_operand:HI 2 "memory_operand" "m"))
4686 (use (match_operand:HI 3 "memory_operand" "m"))
4687 (clobber (match_scratch:XF 4 "=&1f"))]
4688 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4690 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4691 "* return output_fix_trunc (insn, operands, 0);"
4692 [(set_attr "type" "fistp")
4693 (set_attr "i387_cw" "trunc")
4694 (set_attr "mode" "DI")])
4696 (define_insn "fix_truncdi_i387_with_temp"
4697 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4698 (fix:DI (match_operand 1 "register_operand" "f,f")))
4699 (use (match_operand:HI 2 "memory_operand" "m,m"))
4700 (use (match_operand:HI 3 "memory_operand" "m,m"))
4701 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4702 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4703 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4705 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4707 [(set_attr "type" "fistp")
4708 (set_attr "i387_cw" "trunc")
4709 (set_attr "mode" "DI")])
4712 [(set (match_operand:DI 0 "register_operand" "")
4713 (fix:DI (match_operand 1 "register_operand" "")))
4714 (use (match_operand:HI 2 "memory_operand" ""))
4715 (use (match_operand:HI 3 "memory_operand" ""))
4716 (clobber (match_operand:DI 4 "memory_operand" ""))
4717 (clobber (match_scratch 5 ""))]
4719 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4722 (clobber (match_dup 5))])
4723 (set (match_dup 0) (match_dup 4))]
4727 [(set (match_operand:DI 0 "memory_operand" "")
4728 (fix:DI (match_operand 1 "register_operand" "")))
4729 (use (match_operand:HI 2 "memory_operand" ""))
4730 (use (match_operand:HI 3 "memory_operand" ""))
4731 (clobber (match_operand:DI 4 "memory_operand" ""))
4732 (clobber (match_scratch 5 ""))]
4734 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4737 (clobber (match_dup 5))])]
4740 (define_insn "fix_trunc<mode>_i387"
4741 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4742 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4743 (use (match_operand:HI 2 "memory_operand" "m"))
4744 (use (match_operand:HI 3 "memory_operand" "m"))]
4745 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4747 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4748 "* return output_fix_trunc (insn, operands, 0);"
4749 [(set_attr "type" "fistp")
4750 (set_attr "i387_cw" "trunc")
4751 (set_attr "mode" "<MODE>")])
4753 (define_insn "fix_trunc<mode>_i387_with_temp"
4754 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4755 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4756 (use (match_operand:HI 2 "memory_operand" "m,m"))
4757 (use (match_operand:HI 3 "memory_operand" "m,m"))
4758 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4759 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4761 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4763 [(set_attr "type" "fistp")
4764 (set_attr "i387_cw" "trunc")
4765 (set_attr "mode" "<MODE>")])
4768 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4769 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4770 (use (match_operand:HI 2 "memory_operand" ""))
4771 (use (match_operand:HI 3 "memory_operand" ""))
4772 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4774 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4776 (use (match_dup 3))])
4777 (set (match_dup 0) (match_dup 4))]
4781 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4782 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4783 (use (match_operand:HI 2 "memory_operand" ""))
4784 (use (match_operand:HI 3 "memory_operand" ""))
4785 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4787 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4789 (use (match_dup 3))])]
4792 (define_insn "x86_fnstcw_1"
4793 [(set (match_operand:HI 0 "memory_operand" "=m")
4794 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4797 [(set_attr "length" "2")
4798 (set_attr "mode" "HI")
4799 (set_attr "unit" "i387")])
4801 (define_insn "x86_fldcw_1"
4802 [(set (reg:HI FPCR_REG)
4803 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4806 [(set_attr "length" "2")
4807 (set_attr "mode" "HI")
4808 (set_attr "unit" "i387")
4809 (set_attr "athlon_decode" "vector")
4810 (set_attr "amdfam10_decode" "vector")])
4812 ;; Conversion between fixed point and floating point.
4814 ;; Even though we only accept memory inputs, the backend _really_
4815 ;; wants to be able to do this between registers.
4817 (define_expand "floathi<mode>2"
4818 [(set (match_operand:X87MODEF 0 "register_operand" "")
4819 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4821 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4822 || TARGET_MIX_SSE_I387)"
4825 ;; Pre-reload splitter to add memory clobber to the pattern.
4826 (define_insn_and_split "*floathi<mode>2_1"
4827 [(set (match_operand:X87MODEF 0 "register_operand" "")
4828 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4831 || TARGET_MIX_SSE_I387)
4832 && !(reload_completed || reload_in_progress)"
4835 [(parallel [(set (match_dup 0)
4836 (float:X87MODEF (match_dup 1)))
4837 (clobber (match_dup 2))])]
4838 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4840 (define_insn "*floathi<mode>2_i387_with_temp"
4841 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4842 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4843 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4846 || TARGET_MIX_SSE_I387)"
4848 [(set_attr "type" "fmov,multi")
4849 (set_attr "mode" "<MODE>")
4850 (set_attr "unit" "*,i387")
4851 (set_attr "fp_int_src" "true")])
4853 (define_insn "*floathi<mode>2_i387"
4854 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4855 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4858 || TARGET_MIX_SSE_I387)"
4860 [(set_attr "type" "fmov")
4861 (set_attr "mode" "<MODE>")
4862 (set_attr "fp_int_src" "true")])
4865 [(set (match_operand:X87MODEF 0 "register_operand" "")
4866 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4867 (clobber (match_operand:HI 2 "memory_operand" ""))]
4869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870 || TARGET_MIX_SSE_I387)
4871 && reload_completed"
4872 [(set (match_dup 2) (match_dup 1))
4873 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4877 [(set (match_operand:X87MODEF 0 "register_operand" "")
4878 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4879 (clobber (match_operand:HI 2 "memory_operand" ""))]
4881 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4882 || TARGET_MIX_SSE_I387)
4883 && reload_completed"
4884 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4887 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4888 [(set (match_operand:X87MODEF 0 "register_operand" "")
4890 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4892 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4893 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4896 ;; Pre-reload splitter to add memory clobber to the pattern.
4897 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4898 [(set (match_operand:X87MODEF 0 "register_operand" "")
4899 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4901 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4902 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4903 || TARGET_MIX_SSE_I387))
4904 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4906 && ((<SSEMODEI24:MODE>mode == SImode
4907 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4908 && flag_trapping_math)
4909 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4910 && !(reload_completed || reload_in_progress)"
4913 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4914 (clobber (match_dup 2))])]
4916 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4918 /* Avoid store forwarding (partial memory) stall penalty
4919 by passing DImode value through XMM registers. */
4920 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4921 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4924 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4931 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4932 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4934 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4935 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4936 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4937 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4939 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4940 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4941 (set_attr "unit" "*,i387,*,*,*")
4942 (set_attr "athlon_decode" "*,*,double,direct,double")
4943 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4944 (set_attr "fp_int_src" "true")])
4946 (define_insn "*floatsi<mode>2_vector_mixed"
4947 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4948 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4949 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4950 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4954 [(set_attr "type" "fmov,sseicvt")
4955 (set_attr "mode" "<MODE>,<ssevecmode>")
4956 (set_attr "unit" "i387,*")
4957 (set_attr "athlon_decode" "*,direct")
4958 (set_attr "amdfam10_decode" "*,double")
4959 (set_attr "fp_int_src" "true")])
4961 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4962 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4964 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4965 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4966 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4967 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4969 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4970 (set_attr "mode" "<MODEF:MODE>")
4971 (set_attr "unit" "*,i387,*,*")
4972 (set_attr "athlon_decode" "*,*,double,direct")
4973 (set_attr "amdfam10_decode" "*,*,vector,double")
4974 (set_attr "fp_int_src" "true")])
4977 [(set (match_operand:MODEF 0 "register_operand" "")
4978 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4979 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4980 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4981 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4982 && TARGET_INTER_UNIT_CONVERSIONS
4984 && (SSE_REG_P (operands[0])
4985 || (GET_CODE (operands[0]) == SUBREG
4986 && SSE_REG_P (operands[0])))"
4987 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
4991 [(set (match_operand:MODEF 0 "register_operand" "")
4992 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4993 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4994 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4995 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4996 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
4998 && (SSE_REG_P (operands[0])
4999 || (GET_CODE (operands[0]) == SUBREG
5000 && SSE_REG_P (operands[0])))"
5001 [(set (match_dup 2) (match_dup 1))
5002 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5005 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5006 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5008 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5009 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5010 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5011 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5014 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5015 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5016 [(set_attr "type" "fmov,sseicvt,sseicvt")
5017 (set_attr "mode" "<MODEF:MODE>")
5018 (set_attr "unit" "i387,*,*")
5019 (set_attr "athlon_decode" "*,double,direct")
5020 (set_attr "amdfam10_decode" "*,vector,double")
5021 (set_attr "fp_int_src" "true")])
5023 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5024 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5026 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5027 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5028 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5029 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5032 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5033 [(set_attr "type" "fmov,sseicvt")
5034 (set_attr "mode" "<MODEF:MODE>")
5035 (set_attr "athlon_decode" "*,direct")
5036 (set_attr "amdfam10_decode" "*,double")
5037 (set_attr "fp_int_src" "true")])
5039 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5040 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5042 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5043 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5044 "TARGET_SSE2 && TARGET_SSE_MATH
5045 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5047 [(set_attr "type" "sseicvt")
5048 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5049 (set_attr "athlon_decode" "double,direct,double")
5050 (set_attr "amdfam10_decode" "vector,double,double")
5051 (set_attr "fp_int_src" "true")])
5053 (define_insn "*floatsi<mode>2_vector_sse"
5054 [(set (match_operand:MODEF 0 "register_operand" "=x")
5055 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5056 "TARGET_SSE2 && TARGET_SSE_MATH
5057 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5059 [(set_attr "type" "sseicvt")
5060 (set_attr "mode" "<MODE>")
5061 (set_attr "athlon_decode" "direct")
5062 (set_attr "amdfam10_decode" "double")
5063 (set_attr "fp_int_src" "true")])
5066 [(set (match_operand:MODEF 0 "register_operand" "")
5067 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5068 (clobber (match_operand:SI 2 "memory_operand" ""))]
5069 "TARGET_SSE2 && TARGET_SSE_MATH
5070 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5072 && (SSE_REG_P (operands[0])
5073 || (GET_CODE (operands[0]) == SUBREG
5074 && SSE_REG_P (operands[0])))"
5077 rtx op1 = operands[1];
5079 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5081 if (GET_CODE (op1) == SUBREG)
5082 op1 = SUBREG_REG (op1);
5084 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5086 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5087 emit_insn (gen_sse2_loadld (operands[4],
5088 CONST0_RTX (V4SImode), operands[1]));
5090 /* We can ignore possible trapping value in the
5091 high part of SSE register for non-trapping math. */
5092 else if (SSE_REG_P (op1) && !flag_trapping_math)
5093 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5096 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5097 emit_move_insn (operands[2], operands[1]);
5098 emit_insn (gen_sse2_loadld (operands[4],
5099 CONST0_RTX (V4SImode), operands[2]));
5102 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5107 [(set (match_operand:MODEF 0 "register_operand" "")
5108 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5109 (clobber (match_operand:SI 2 "memory_operand" ""))]
5110 "TARGET_SSE2 && TARGET_SSE_MATH
5111 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5113 && (SSE_REG_P (operands[0])
5114 || (GET_CODE (operands[0]) == SUBREG
5115 && SSE_REG_P (operands[0])))"
5118 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5120 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5122 emit_insn (gen_sse2_loadld (operands[4],
5123 CONST0_RTX (V4SImode), operands[1]));
5125 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5130 [(set (match_operand:MODEF 0 "register_operand" "")
5131 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5132 "TARGET_SSE2 && TARGET_SSE_MATH
5133 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5135 && (SSE_REG_P (operands[0])
5136 || (GET_CODE (operands[0]) == SUBREG
5137 && SSE_REG_P (operands[0])))"
5140 rtx op1 = operands[1];
5142 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5144 if (GET_CODE (op1) == SUBREG)
5145 op1 = SUBREG_REG (op1);
5147 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5149 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5150 emit_insn (gen_sse2_loadld (operands[4],
5151 CONST0_RTX (V4SImode), operands[1]));
5153 /* We can ignore possible trapping value in the
5154 high part of SSE register for non-trapping math. */
5155 else if (SSE_REG_P (op1) && !flag_trapping_math)
5156 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5162 [(set (match_operand:MODEF 0 "register_operand" "")
5163 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5164 "TARGET_SSE2 && TARGET_SSE_MATH
5165 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5167 && (SSE_REG_P (operands[0])
5168 || (GET_CODE (operands[0]) == SUBREG
5169 && SSE_REG_P (operands[0])))"
5172 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5174 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5176 emit_insn (gen_sse2_loadld (operands[4],
5177 CONST0_RTX (V4SImode), operands[1]));
5179 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5183 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5184 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5186 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5187 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5188 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5189 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5191 [(set_attr "type" "sseicvt")
5192 (set_attr "mode" "<MODEF:MODE>")
5193 (set_attr "athlon_decode" "double,direct")
5194 (set_attr "amdfam10_decode" "vector,double")
5195 (set_attr "fp_int_src" "true")])
5197 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5198 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5200 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5201 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5203 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5204 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5205 [(set_attr "type" "sseicvt")
5206 (set_attr "mode" "<MODEF:MODE>")
5207 (set_attr "athlon_decode" "double,direct")
5208 (set_attr "amdfam10_decode" "vector,double")
5209 (set_attr "fp_int_src" "true")])
5212 [(set (match_operand:MODEF 0 "register_operand" "")
5213 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5214 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5215 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5216 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5217 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5219 && (SSE_REG_P (operands[0])
5220 || (GET_CODE (operands[0]) == SUBREG
5221 && SSE_REG_P (operands[0])))"
5222 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5225 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5226 [(set (match_operand:MODEF 0 "register_operand" "=x")
5228 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5229 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5230 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5231 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5232 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5233 [(set_attr "type" "sseicvt")
5234 (set_attr "mode" "<MODEF:MODE>")
5235 (set_attr "athlon_decode" "direct")
5236 (set_attr "amdfam10_decode" "double")
5237 (set_attr "fp_int_src" "true")])
5240 [(set (match_operand:MODEF 0 "register_operand" "")
5241 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5242 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5243 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5244 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5245 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5247 && (SSE_REG_P (operands[0])
5248 || (GET_CODE (operands[0]) == SUBREG
5249 && SSE_REG_P (operands[0])))"
5250 [(set (match_dup 2) (match_dup 1))
5251 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5255 [(set (match_operand:MODEF 0 "register_operand" "")
5256 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5257 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5258 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5259 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5261 && (SSE_REG_P (operands[0])
5262 || (GET_CODE (operands[0]) == SUBREG
5263 && SSE_REG_P (operands[0])))"
5264 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5267 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5268 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5270 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5271 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5276 [(set_attr "type" "fmov,multi")
5277 (set_attr "mode" "<X87MODEF:MODE>")
5278 (set_attr "unit" "*,i387")
5279 (set_attr "fp_int_src" "true")])
5281 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5282 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5284 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5287 [(set_attr "type" "fmov")
5288 (set_attr "mode" "<X87MODEF:MODE>")
5289 (set_attr "fp_int_src" "true")])
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5294 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5297 && FP_REG_P (operands[0])"
5298 [(set (match_dup 2) (match_dup 1))
5299 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5303 [(set (match_operand:X87MODEF 0 "register_operand" "")
5304 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5305 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5308 && FP_REG_P (operands[0])"
5309 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5312 ;; Avoid store forwarding (partial memory) stall penalty
5313 ;; by passing DImode value through XMM registers. */
5315 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5316 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5318 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5319 (clobber (match_scratch:V4SI 3 "=X,x"))
5320 (clobber (match_scratch:V4SI 4 "=X,x"))
5321 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5322 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5323 && !TARGET_64BIT && !optimize_size"
5325 [(set_attr "type" "multi")
5326 (set_attr "mode" "<X87MODEF:MODE>")
5327 (set_attr "unit" "i387")
5328 (set_attr "fp_int_src" "true")])
5331 [(set (match_operand:X87MODEF 0 "register_operand" "")
5332 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5333 (clobber (match_scratch:V4SI 3 ""))
5334 (clobber (match_scratch:V4SI 4 ""))
5335 (clobber (match_operand:DI 2 "memory_operand" ""))]
5336 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5337 && !TARGET_64BIT && !optimize_size
5339 && FP_REG_P (operands[0])"
5340 [(set (match_dup 2) (match_dup 3))
5341 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5343 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5344 Assemble the 64-bit DImode value in an xmm register. */
5345 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5346 gen_rtx_SUBREG (SImode, operands[1], 0)));
5347 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5348 gen_rtx_SUBREG (SImode, operands[1], 4)));
5349 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5351 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5355 [(set (match_operand:X87MODEF 0 "register_operand" "")
5356 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5357 (clobber (match_scratch:V4SI 3 ""))
5358 (clobber (match_scratch:V4SI 4 ""))
5359 (clobber (match_operand:DI 2 "memory_operand" ""))]
5360 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5361 && !TARGET_64BIT && !optimize_size
5363 && FP_REG_P (operands[0])"
5364 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5367 ;; Avoid store forwarding (partial memory) stall penalty by extending
5368 ;; SImode value to DImode through XMM register instead of pushing two
5369 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5370 ;; targets benefit from this optimization. Also note that fild
5371 ;; loads from memory only.
5373 (define_insn "*floatunssi<mode>2_1"
5374 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5375 (unsigned_float:X87MODEF
5376 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5377 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5378 (clobber (match_scratch:SI 3 "=X,x"))]
5380 && TARGET_80387 && TARGET_SSE"
5382 [(set_attr "type" "multi")
5383 (set_attr "mode" "<MODE>")])
5386 [(set (match_operand:X87MODEF 0 "register_operand" "")
5387 (unsigned_float:X87MODEF
5388 (match_operand:SI 1 "register_operand" "")))
5389 (clobber (match_operand:DI 2 "memory_operand" ""))
5390 (clobber (match_scratch:SI 3 ""))]
5392 && TARGET_80387 && TARGET_SSE
5393 && reload_completed"
5394 [(set (match_dup 2) (match_dup 1))
5396 (float:X87MODEF (match_dup 2)))]
5397 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5400 [(set (match_operand:X87MODEF 0 "register_operand" "")
5401 (unsigned_float:X87MODEF
5402 (match_operand:SI 1 "memory_operand" "")))
5403 (clobber (match_operand:DI 2 "memory_operand" ""))
5404 (clobber (match_scratch:SI 3 ""))]
5406 && TARGET_80387 && TARGET_SSE
5407 && reload_completed"
5408 [(set (match_dup 2) (match_dup 3))
5410 (float:X87MODEF (match_dup 2)))]
5412 emit_move_insn (operands[3], operands[1]);
5413 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5416 (define_expand "floatunssi<mode>2"
5418 [(set (match_operand:X87MODEF 0 "register_operand" "")
5419 (unsigned_float:X87MODEF
5420 (match_operand:SI 1 "nonimmediate_operand" "")))
5421 (clobber (match_dup 2))
5422 (clobber (match_scratch:SI 3 ""))])]
5424 && ((TARGET_80387 && TARGET_SSE)
5425 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5427 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5429 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5434 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5435 operands[2] = assign_386_stack_local (DImode, slot);
5439 (define_expand "floatunsdisf2"
5440 [(use (match_operand:SF 0 "register_operand" ""))
5441 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5442 "TARGET_64BIT && TARGET_SSE_MATH"
5443 "x86_emit_floatuns (operands); DONE;")
5445 (define_expand "floatunsdidf2"
5446 [(use (match_operand:DF 0 "register_operand" ""))
5447 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5448 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5449 && TARGET_SSE2 && TARGET_SSE_MATH"
5452 x86_emit_floatuns (operands);
5454 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5460 ;; %%% splits for addditi3
5462 (define_expand "addti3"
5463 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5464 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5465 (match_operand:TI 2 "x86_64_general_operand" "")))]
5467 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5469 (define_insn "*addti3_1"
5470 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5471 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5472 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5473 (clobber (reg:CC FLAGS_REG))]
5474 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5478 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5479 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5480 (match_operand:TI 2 "x86_64_general_operand" "")))
5481 (clobber (reg:CC FLAGS_REG))]
5482 "TARGET_64BIT && reload_completed"
5483 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5485 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5486 (parallel [(set (match_dup 3)
5487 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5490 (clobber (reg:CC FLAGS_REG))])]
5491 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5493 ;; %%% splits for addsidi3
5494 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5495 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5496 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5498 (define_expand "adddi3"
5499 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5500 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5501 (match_operand:DI 2 "x86_64_general_operand" "")))]
5503 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5505 (define_insn "*adddi3_1"
5506 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5507 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5508 (match_operand:DI 2 "general_operand" "roiF,riF")))
5509 (clobber (reg:CC FLAGS_REG))]
5510 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5514 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5515 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5516 (match_operand:DI 2 "general_operand" "")))
5517 (clobber (reg:CC FLAGS_REG))]
5518 "!TARGET_64BIT && reload_completed"
5519 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5521 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5522 (parallel [(set (match_dup 3)
5523 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5526 (clobber (reg:CC FLAGS_REG))])]
5527 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5529 (define_insn "adddi3_carry_rex64"
5530 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5531 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5532 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5533 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5534 (clobber (reg:CC FLAGS_REG))]
5535 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5536 "adc{q}\t{%2, %0|%0, %2}"
5537 [(set_attr "type" "alu")
5538 (set_attr "pent_pair" "pu")
5539 (set_attr "mode" "DI")])
5541 (define_insn "*adddi3_cc_rex64"
5542 [(set (reg:CC FLAGS_REG)
5543 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5544 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5546 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5547 (plus:DI (match_dup 1) (match_dup 2)))]
5548 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5549 "add{q}\t{%2, %0|%0, %2}"
5550 [(set_attr "type" "alu")
5551 (set_attr "mode" "DI")])
5553 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5554 [(set (reg:CCC FLAGS_REG)
5557 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5558 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5560 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5561 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5562 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5563 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5564 [(set_attr "type" "alu")
5565 (set_attr "mode" "<MODE>")])
5567 (define_insn "*add<mode>3_cconly_overflow"
5568 [(set (reg:CCC FLAGS_REG)
5570 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5571 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5573 (clobber (match_scratch:SWI 0 "=<r>"))]
5574 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5575 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5576 [(set_attr "type" "alu")
5577 (set_attr "mode" "<MODE>")])
5579 (define_insn "*sub<mode>3_cconly_overflow"
5580 [(set (reg:CCC FLAGS_REG)
5582 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5583 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5586 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5587 [(set_attr "type" "icmp")
5588 (set_attr "mode" "<MODE>")])
5590 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5591 [(set (reg:CCC FLAGS_REG)
5593 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5594 (match_operand:SI 2 "general_operand" "g"))
5596 (set (match_operand:DI 0 "register_operand" "=r")
5597 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5598 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5599 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5600 [(set_attr "type" "alu")
5601 (set_attr "mode" "SI")])
5603 (define_insn "addqi3_carry"
5604 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5605 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5606 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5607 (match_operand:QI 2 "general_operand" "qn,qm")))
5608 (clobber (reg:CC FLAGS_REG))]
5609 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5610 "adc{b}\t{%2, %0|%0, %2}"
5611 [(set_attr "type" "alu")
5612 (set_attr "pent_pair" "pu")
5613 (set_attr "mode" "QI")])
5615 (define_insn "addhi3_carry"
5616 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5617 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5618 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5619 (match_operand:HI 2 "general_operand" "rn,rm")))
5620 (clobber (reg:CC FLAGS_REG))]
5621 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5622 "adc{w}\t{%2, %0|%0, %2}"
5623 [(set_attr "type" "alu")
5624 (set_attr "pent_pair" "pu")
5625 (set_attr "mode" "HI")])
5627 (define_insn "addsi3_carry"
5628 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5629 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5630 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5631 (match_operand:SI 2 "general_operand" "ri,rm")))
5632 (clobber (reg:CC FLAGS_REG))]
5633 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5634 "adc{l}\t{%2, %0|%0, %2}"
5635 [(set_attr "type" "alu")
5636 (set_attr "pent_pair" "pu")
5637 (set_attr "mode" "SI")])
5639 (define_insn "*addsi3_carry_zext"
5640 [(set (match_operand:DI 0 "register_operand" "=r")
5642 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5643 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5644 (match_operand:SI 2 "general_operand" "g"))))
5645 (clobber (reg:CC FLAGS_REG))]
5646 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5647 "adc{l}\t{%2, %k0|%k0, %2}"
5648 [(set_attr "type" "alu")
5649 (set_attr "pent_pair" "pu")
5650 (set_attr "mode" "SI")])
5652 (define_insn "*addsi3_cc"
5653 [(set (reg:CC FLAGS_REG)
5654 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5655 (match_operand:SI 2 "general_operand" "ri,rm")]
5657 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5658 (plus:SI (match_dup 1) (match_dup 2)))]
5659 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5660 "add{l}\t{%2, %0|%0, %2}"
5661 [(set_attr "type" "alu")
5662 (set_attr "mode" "SI")])
5664 (define_insn "addqi3_cc"
5665 [(set (reg:CC FLAGS_REG)
5666 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5667 (match_operand:QI 2 "general_operand" "qn,qm")]
5669 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5670 (plus:QI (match_dup 1) (match_dup 2)))]
5671 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5672 "add{b}\t{%2, %0|%0, %2}"
5673 [(set_attr "type" "alu")
5674 (set_attr "mode" "QI")])
5676 (define_expand "addsi3"
5677 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5678 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5679 (match_operand:SI 2 "general_operand" "")))]
5681 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5683 (define_insn "*lea_1"
5684 [(set (match_operand:SI 0 "register_operand" "=r")
5685 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5687 "lea{l}\t{%a1, %0|%0, %a1}"
5688 [(set_attr "type" "lea")
5689 (set_attr "mode" "SI")])
5691 (define_insn "*lea_1_rex64"
5692 [(set (match_operand:SI 0 "register_operand" "=r")
5693 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5695 "lea{l}\t{%a1, %0|%0, %a1}"
5696 [(set_attr "type" "lea")
5697 (set_attr "mode" "SI")])
5699 (define_insn "*lea_1_zext"
5700 [(set (match_operand:DI 0 "register_operand" "=r")
5702 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5704 "lea{l}\t{%a1, %k0|%k0, %a1}"
5705 [(set_attr "type" "lea")
5706 (set_attr "mode" "SI")])
5708 (define_insn "*lea_2_rex64"
5709 [(set (match_operand:DI 0 "register_operand" "=r")
5710 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5712 "lea{q}\t{%a1, %0|%0, %a1}"
5713 [(set_attr "type" "lea")
5714 (set_attr "mode" "DI")])
5716 ;; The lea patterns for non-Pmodes needs to be matched by several
5717 ;; insns converted to real lea by splitters.
5719 (define_insn_and_split "*lea_general_1"
5720 [(set (match_operand 0 "register_operand" "=r")
5721 (plus (plus (match_operand 1 "index_register_operand" "l")
5722 (match_operand 2 "register_operand" "r"))
5723 (match_operand 3 "immediate_operand" "i")))]
5724 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5725 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5726 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5727 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5728 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5729 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5730 || GET_MODE (operands[3]) == VOIDmode)"
5732 "&& reload_completed"
5736 operands[0] = gen_lowpart (SImode, operands[0]);
5737 operands[1] = gen_lowpart (Pmode, operands[1]);
5738 operands[2] = gen_lowpart (Pmode, operands[2]);
5739 operands[3] = gen_lowpart (Pmode, operands[3]);
5740 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5742 if (Pmode != SImode)
5743 pat = gen_rtx_SUBREG (SImode, pat, 0);
5744 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5747 [(set_attr "type" "lea")
5748 (set_attr "mode" "SI")])
5750 (define_insn_and_split "*lea_general_1_zext"
5751 [(set (match_operand:DI 0 "register_operand" "=r")
5753 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5754 (match_operand:SI 2 "register_operand" "r"))
5755 (match_operand:SI 3 "immediate_operand" "i"))))]
5758 "&& reload_completed"
5760 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5762 (match_dup 3)) 0)))]
5764 operands[1] = gen_lowpart (Pmode, operands[1]);
5765 operands[2] = gen_lowpart (Pmode, operands[2]);
5766 operands[3] = gen_lowpart (Pmode, operands[3]);
5768 [(set_attr "type" "lea")
5769 (set_attr "mode" "SI")])
5771 (define_insn_and_split "*lea_general_2"
5772 [(set (match_operand 0 "register_operand" "=r")
5773 (plus (mult (match_operand 1 "index_register_operand" "l")
5774 (match_operand 2 "const248_operand" "i"))
5775 (match_operand 3 "nonmemory_operand" "ri")))]
5776 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5777 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5778 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5779 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5780 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5781 || GET_MODE (operands[3]) == VOIDmode)"
5783 "&& reload_completed"
5787 operands[0] = gen_lowpart (SImode, operands[0]);
5788 operands[1] = gen_lowpart (Pmode, operands[1]);
5789 operands[3] = gen_lowpart (Pmode, operands[3]);
5790 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5792 if (Pmode != SImode)
5793 pat = gen_rtx_SUBREG (SImode, pat, 0);
5794 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5797 [(set_attr "type" "lea")
5798 (set_attr "mode" "SI")])
5800 (define_insn_and_split "*lea_general_2_zext"
5801 [(set (match_operand:DI 0 "register_operand" "=r")
5803 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5804 (match_operand:SI 2 "const248_operand" "n"))
5805 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5808 "&& reload_completed"
5810 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5812 (match_dup 3)) 0)))]
5814 operands[1] = gen_lowpart (Pmode, operands[1]);
5815 operands[3] = gen_lowpart (Pmode, operands[3]);
5817 [(set_attr "type" "lea")
5818 (set_attr "mode" "SI")])
5820 (define_insn_and_split "*lea_general_3"
5821 [(set (match_operand 0 "register_operand" "=r")
5822 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5823 (match_operand 2 "const248_operand" "i"))
5824 (match_operand 3 "register_operand" "r"))
5825 (match_operand 4 "immediate_operand" "i")))]
5826 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5827 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5828 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5829 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5830 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5832 "&& reload_completed"
5836 operands[0] = gen_lowpart (SImode, operands[0]);
5837 operands[1] = gen_lowpart (Pmode, operands[1]);
5838 operands[3] = gen_lowpart (Pmode, operands[3]);
5839 operands[4] = gen_lowpart (Pmode, operands[4]);
5840 pat = gen_rtx_PLUS (Pmode,
5841 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5845 if (Pmode != SImode)
5846 pat = gen_rtx_SUBREG (SImode, pat, 0);
5847 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5850 [(set_attr "type" "lea")
5851 (set_attr "mode" "SI")])
5853 (define_insn_and_split "*lea_general_3_zext"
5854 [(set (match_operand:DI 0 "register_operand" "=r")
5856 (plus:SI (plus:SI (mult:SI
5857 (match_operand:SI 1 "index_register_operand" "l")
5858 (match_operand:SI 2 "const248_operand" "n"))
5859 (match_operand:SI 3 "register_operand" "r"))
5860 (match_operand:SI 4 "immediate_operand" "i"))))]
5863 "&& reload_completed"
5865 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5868 (match_dup 4)) 0)))]
5870 operands[1] = gen_lowpart (Pmode, operands[1]);
5871 operands[3] = gen_lowpart (Pmode, operands[3]);
5872 operands[4] = gen_lowpart (Pmode, operands[4]);
5874 [(set_attr "type" "lea")
5875 (set_attr "mode" "SI")])
5877 (define_insn "*adddi_1_rex64"
5878 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5879 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5880 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5881 (clobber (reg:CC FLAGS_REG))]
5882 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5884 switch (get_attr_type (insn))
5887 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5888 return "lea{q}\t{%a2, %0|%0, %a2}";
5891 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5892 if (operands[2] == const1_rtx)
5893 return "inc{q}\t%0";
5896 gcc_assert (operands[2] == constm1_rtx);
5897 return "dec{q}\t%0";
5901 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5903 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5904 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5905 if (CONST_INT_P (operands[2])
5906 /* Avoid overflows. */
5907 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5908 && (INTVAL (operands[2]) == 128
5909 || (INTVAL (operands[2]) < 0
5910 && INTVAL (operands[2]) != -128)))
5912 operands[2] = GEN_INT (-INTVAL (operands[2]));
5913 return "sub{q}\t{%2, %0|%0, %2}";
5915 return "add{q}\t{%2, %0|%0, %2}";
5919 (cond [(eq_attr "alternative" "2")
5920 (const_string "lea")
5921 ; Current assemblers are broken and do not allow @GOTOFF in
5922 ; ought but a memory context.
5923 (match_operand:DI 2 "pic_symbolic_operand" "")
5924 (const_string "lea")
5925 (match_operand:DI 2 "incdec_operand" "")
5926 (const_string "incdec")
5928 (const_string "alu")))
5929 (set_attr "mode" "DI")])
5931 ;; Convert lea to the lea pattern to avoid flags dependency.
5933 [(set (match_operand:DI 0 "register_operand" "")
5934 (plus:DI (match_operand:DI 1 "register_operand" "")
5935 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5936 (clobber (reg:CC FLAGS_REG))]
5937 "TARGET_64BIT && reload_completed
5938 && true_regnum (operands[0]) != true_regnum (operands[1])"
5940 (plus:DI (match_dup 1)
5944 (define_insn "*adddi_2_rex64"
5945 [(set (reg FLAGS_REG)
5947 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5948 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5950 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5951 (plus:DI (match_dup 1) (match_dup 2)))]
5952 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5953 && ix86_binary_operator_ok (PLUS, DImode, operands)
5954 /* Current assemblers are broken and do not allow @GOTOFF in
5955 ought but a memory context. */
5956 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5958 switch (get_attr_type (insn))
5961 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962 if (operands[2] == const1_rtx)
5963 return "inc{q}\t%0";
5966 gcc_assert (operands[2] == constm1_rtx);
5967 return "dec{q}\t%0";
5971 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5972 /* ???? We ought to handle there the 32bit case too
5973 - do we need new constraint? */
5974 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5976 if (CONST_INT_P (operands[2])
5977 /* Avoid overflows. */
5978 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5979 && (INTVAL (operands[2]) == 128
5980 || (INTVAL (operands[2]) < 0
5981 && INTVAL (operands[2]) != -128)))
5983 operands[2] = GEN_INT (-INTVAL (operands[2]));
5984 return "sub{q}\t{%2, %0|%0, %2}";
5986 return "add{q}\t{%2, %0|%0, %2}";
5990 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5991 (const_string "incdec")
5992 (const_string "alu")))
5993 (set_attr "mode" "DI")])
5995 (define_insn "*adddi_3_rex64"
5996 [(set (reg FLAGS_REG)
5997 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5998 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5999 (clobber (match_scratch:DI 0 "=r"))]
6001 && ix86_match_ccmode (insn, CCZmode)
6002 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6003 /* Current assemblers are broken and do not allow @GOTOFF in
6004 ought but a memory context. */
6005 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6007 switch (get_attr_type (insn))
6010 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6011 if (operands[2] == const1_rtx)
6012 return "inc{q}\t%0";
6015 gcc_assert (operands[2] == constm1_rtx);
6016 return "dec{q}\t%0";
6020 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6021 /* ???? We ought to handle there the 32bit case too
6022 - do we need new constraint? */
6023 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6025 if (CONST_INT_P (operands[2])
6026 /* Avoid overflows. */
6027 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6028 && (INTVAL (operands[2]) == 128
6029 || (INTVAL (operands[2]) < 0
6030 && INTVAL (operands[2]) != -128)))
6032 operands[2] = GEN_INT (-INTVAL (operands[2]));
6033 return "sub{q}\t{%2, %0|%0, %2}";
6035 return "add{q}\t{%2, %0|%0, %2}";
6039 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6040 (const_string "incdec")
6041 (const_string "alu")))
6042 (set_attr "mode" "DI")])
6044 ; For comparisons against 1, -1 and 128, we may generate better code
6045 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6046 ; is matched then. We can't accept general immediate, because for
6047 ; case of overflows, the result is messed up.
6048 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6050 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6051 ; only for comparisons not depending on it.
6052 (define_insn "*adddi_4_rex64"
6053 [(set (reg FLAGS_REG)
6054 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6055 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6056 (clobber (match_scratch:DI 0 "=rm"))]
6058 && ix86_match_ccmode (insn, CCGCmode)"
6060 switch (get_attr_type (insn))
6063 if (operands[2] == constm1_rtx)
6064 return "inc{q}\t%0";
6067 gcc_assert (operands[2] == const1_rtx);
6068 return "dec{q}\t%0";
6072 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6073 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6074 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6075 if ((INTVAL (operands[2]) == -128
6076 || (INTVAL (operands[2]) > 0
6077 && INTVAL (operands[2]) != 128))
6078 /* Avoid overflows. */
6079 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6080 return "sub{q}\t{%2, %0|%0, %2}";
6081 operands[2] = GEN_INT (-INTVAL (operands[2]));
6082 return "add{q}\t{%2, %0|%0, %2}";
6086 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6087 (const_string "incdec")
6088 (const_string "alu")))
6089 (set_attr "mode" "DI")])
6091 (define_insn "*adddi_5_rex64"
6092 [(set (reg FLAGS_REG)
6094 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6095 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6097 (clobber (match_scratch:DI 0 "=r"))]
6099 && ix86_match_ccmode (insn, CCGOCmode)
6100 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6101 /* Current assemblers are broken and do not allow @GOTOFF in
6102 ought but a memory context. */
6103 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6105 switch (get_attr_type (insn))
6108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6109 if (operands[2] == const1_rtx)
6110 return "inc{q}\t%0";
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{q}\t%0";
6118 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6119 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6120 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6121 if (CONST_INT_P (operands[2])
6122 /* Avoid overflows. */
6123 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6124 && (INTVAL (operands[2]) == 128
6125 || (INTVAL (operands[2]) < 0
6126 && INTVAL (operands[2]) != -128)))
6128 operands[2] = GEN_INT (-INTVAL (operands[2]));
6129 return "sub{q}\t{%2, %0|%0, %2}";
6131 return "add{q}\t{%2, %0|%0, %2}";
6135 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6136 (const_string "incdec")
6137 (const_string "alu")))
6138 (set_attr "mode" "DI")])
6141 (define_insn "*addsi_1"
6142 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6143 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6144 (match_operand:SI 2 "general_operand" "g,ri,li")))
6145 (clobber (reg:CC FLAGS_REG))]
6146 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6148 switch (get_attr_type (insn))
6151 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6152 return "lea{l}\t{%a2, %0|%0, %a2}";
6155 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6156 if (operands[2] == const1_rtx)
6157 return "inc{l}\t%0";
6160 gcc_assert (operands[2] == constm1_rtx);
6161 return "dec{l}\t%0";
6165 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6167 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6168 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6169 if (CONST_INT_P (operands[2])
6170 && (INTVAL (operands[2]) == 128
6171 || (INTVAL (operands[2]) < 0
6172 && INTVAL (operands[2]) != -128)))
6174 operands[2] = GEN_INT (-INTVAL (operands[2]));
6175 return "sub{l}\t{%2, %0|%0, %2}";
6177 return "add{l}\t{%2, %0|%0, %2}";
6181 (cond [(eq_attr "alternative" "2")
6182 (const_string "lea")
6183 ; Current assemblers are broken and do not allow @GOTOFF in
6184 ; ought but a memory context.
6185 (match_operand:SI 2 "pic_symbolic_operand" "")
6186 (const_string "lea")
6187 (match_operand:SI 2 "incdec_operand" "")
6188 (const_string "incdec")
6190 (const_string "alu")))
6191 (set_attr "mode" "SI")])
6193 ;; Convert lea to the lea pattern to avoid flags dependency.
6195 [(set (match_operand 0 "register_operand" "")
6196 (plus (match_operand 1 "register_operand" "")
6197 (match_operand 2 "nonmemory_operand" "")))
6198 (clobber (reg:CC FLAGS_REG))]
6200 && true_regnum (operands[0]) != true_regnum (operands[1])"
6204 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6205 may confuse gen_lowpart. */
6206 if (GET_MODE (operands[0]) != Pmode)
6208 operands[1] = gen_lowpart (Pmode, operands[1]);
6209 operands[2] = gen_lowpart (Pmode, operands[2]);
6211 operands[0] = gen_lowpart (SImode, operands[0]);
6212 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6213 if (Pmode != SImode)
6214 pat = gen_rtx_SUBREG (SImode, pat, 0);
6215 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6219 ;; It may seem that nonimmediate operand is proper one for operand 1.
6220 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6221 ;; we take care in ix86_binary_operator_ok to not allow two memory
6222 ;; operands so proper swapping will be done in reload. This allow
6223 ;; patterns constructed from addsi_1 to match.
6224 (define_insn "addsi_1_zext"
6225 [(set (match_operand:DI 0 "register_operand" "=r,r")
6227 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6228 (match_operand:SI 2 "general_operand" "g,li"))))
6229 (clobber (reg:CC FLAGS_REG))]
6230 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6232 switch (get_attr_type (insn))
6235 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6236 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6239 if (operands[2] == const1_rtx)
6240 return "inc{l}\t%k0";
6243 gcc_assert (operands[2] == constm1_rtx);
6244 return "dec{l}\t%k0";
6248 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6249 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6250 if (CONST_INT_P (operands[2])
6251 && (INTVAL (operands[2]) == 128
6252 || (INTVAL (operands[2]) < 0
6253 && INTVAL (operands[2]) != -128)))
6255 operands[2] = GEN_INT (-INTVAL (operands[2]));
6256 return "sub{l}\t{%2, %k0|%k0, %2}";
6258 return "add{l}\t{%2, %k0|%k0, %2}";
6262 (cond [(eq_attr "alternative" "1")
6263 (const_string "lea")
6264 ; Current assemblers are broken and do not allow @GOTOFF in
6265 ; ought but a memory context.
6266 (match_operand:SI 2 "pic_symbolic_operand" "")
6267 (const_string "lea")
6268 (match_operand:SI 2 "incdec_operand" "")
6269 (const_string "incdec")
6271 (const_string "alu")))
6272 (set_attr "mode" "SI")])
6274 ;; Convert lea to the lea pattern to avoid flags dependency.
6276 [(set (match_operand:DI 0 "register_operand" "")
6278 (plus:SI (match_operand:SI 1 "register_operand" "")
6279 (match_operand:SI 2 "nonmemory_operand" ""))))
6280 (clobber (reg:CC FLAGS_REG))]
6281 "TARGET_64BIT && reload_completed
6282 && true_regnum (operands[0]) != true_regnum (operands[1])"
6284 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6286 operands[1] = gen_lowpart (Pmode, operands[1]);
6287 operands[2] = gen_lowpart (Pmode, operands[2]);
6290 (define_insn "*addsi_2"
6291 [(set (reg FLAGS_REG)
6293 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6294 (match_operand:SI 2 "general_operand" "g,ri"))
6296 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6297 (plus:SI (match_dup 1) (match_dup 2)))]
6298 "ix86_match_ccmode (insn, CCGOCmode)
6299 && ix86_binary_operator_ok (PLUS, SImode, operands)
6300 /* Current assemblers are broken and do not allow @GOTOFF in
6301 ought but a memory context. */
6302 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6304 switch (get_attr_type (insn))
6307 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6308 if (operands[2] == const1_rtx)
6309 return "inc{l}\t%0";
6312 gcc_assert (operands[2] == constm1_rtx);
6313 return "dec{l}\t%0";
6317 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6318 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6319 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6320 if (CONST_INT_P (operands[2])
6321 && (INTVAL (operands[2]) == 128
6322 || (INTVAL (operands[2]) < 0
6323 && INTVAL (operands[2]) != -128)))
6325 operands[2] = GEN_INT (-INTVAL (operands[2]));
6326 return "sub{l}\t{%2, %0|%0, %2}";
6328 return "add{l}\t{%2, %0|%0, %2}";
6332 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6333 (const_string "incdec")
6334 (const_string "alu")))
6335 (set_attr "mode" "SI")])
6337 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6338 (define_insn "*addsi_2_zext"
6339 [(set (reg FLAGS_REG)
6341 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6342 (match_operand:SI 2 "general_operand" "g"))
6344 (set (match_operand:DI 0 "register_operand" "=r")
6345 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6346 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6347 && ix86_binary_operator_ok (PLUS, SImode, operands)
6348 /* Current assemblers are broken and do not allow @GOTOFF in
6349 ought but a memory context. */
6350 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6352 switch (get_attr_type (insn))
6355 if (operands[2] == const1_rtx)
6356 return "inc{l}\t%k0";
6359 gcc_assert (operands[2] == constm1_rtx);
6360 return "dec{l}\t%k0";
6364 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6365 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6366 if (CONST_INT_P (operands[2])
6367 && (INTVAL (operands[2]) == 128
6368 || (INTVAL (operands[2]) < 0
6369 && INTVAL (operands[2]) != -128)))
6371 operands[2] = GEN_INT (-INTVAL (operands[2]));
6372 return "sub{l}\t{%2, %k0|%k0, %2}";
6374 return "add{l}\t{%2, %k0|%k0, %2}";
6378 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6379 (const_string "incdec")
6380 (const_string "alu")))
6381 (set_attr "mode" "SI")])
6383 (define_insn "*addsi_3"
6384 [(set (reg FLAGS_REG)
6385 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6386 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6387 (clobber (match_scratch:SI 0 "=r"))]
6388 "ix86_match_ccmode (insn, CCZmode)
6389 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6390 /* Current assemblers are broken and do not allow @GOTOFF in
6391 ought but a memory context. */
6392 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6394 switch (get_attr_type (insn))
6397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6398 if (operands[2] == const1_rtx)
6399 return "inc{l}\t%0";
6402 gcc_assert (operands[2] == constm1_rtx);
6403 return "dec{l}\t%0";
6407 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6408 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6409 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6410 if (CONST_INT_P (operands[2])
6411 && (INTVAL (operands[2]) == 128
6412 || (INTVAL (operands[2]) < 0
6413 && INTVAL (operands[2]) != -128)))
6415 operands[2] = GEN_INT (-INTVAL (operands[2]));
6416 return "sub{l}\t{%2, %0|%0, %2}";
6418 return "add{l}\t{%2, %0|%0, %2}";
6422 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6423 (const_string "incdec")
6424 (const_string "alu")))
6425 (set_attr "mode" "SI")])
6427 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6428 (define_insn "*addsi_3_zext"
6429 [(set (reg FLAGS_REG)
6430 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6431 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6432 (set (match_operand:DI 0 "register_operand" "=r")
6433 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6434 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6435 && ix86_binary_operator_ok (PLUS, SImode, operands)
6436 /* Current assemblers are broken and do not allow @GOTOFF in
6437 ought but a memory context. */
6438 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6440 switch (get_attr_type (insn))
6443 if (operands[2] == const1_rtx)
6444 return "inc{l}\t%k0";
6447 gcc_assert (operands[2] == constm1_rtx);
6448 return "dec{l}\t%k0";
6452 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6453 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6454 if (CONST_INT_P (operands[2])
6455 && (INTVAL (operands[2]) == 128
6456 || (INTVAL (operands[2]) < 0
6457 && INTVAL (operands[2]) != -128)))
6459 operands[2] = GEN_INT (-INTVAL (operands[2]));
6460 return "sub{l}\t{%2, %k0|%k0, %2}";
6462 return "add{l}\t{%2, %k0|%k0, %2}";
6466 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6467 (const_string "incdec")
6468 (const_string "alu")))
6469 (set_attr "mode" "SI")])
6471 ; For comparisons against 1, -1 and 128, we may generate better code
6472 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6473 ; is matched then. We can't accept general immediate, because for
6474 ; case of overflows, the result is messed up.
6475 ; This pattern also don't hold of 0x80000000, since the value overflows
6477 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6478 ; only for comparisons not depending on it.
6479 (define_insn "*addsi_4"
6480 [(set (reg FLAGS_REG)
6481 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6482 (match_operand:SI 2 "const_int_operand" "n")))
6483 (clobber (match_scratch:SI 0 "=rm"))]
6484 "ix86_match_ccmode (insn, CCGCmode)
6485 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6487 switch (get_attr_type (insn))
6490 if (operands[2] == constm1_rtx)
6491 return "inc{l}\t%0";
6494 gcc_assert (operands[2] == const1_rtx);
6495 return "dec{l}\t%0";
6499 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6500 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6501 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6502 if ((INTVAL (operands[2]) == -128
6503 || (INTVAL (operands[2]) > 0
6504 && INTVAL (operands[2]) != 128)))
6505 return "sub{l}\t{%2, %0|%0, %2}";
6506 operands[2] = GEN_INT (-INTVAL (operands[2]));
6507 return "add{l}\t{%2, %0|%0, %2}";
6511 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6512 (const_string "incdec")
6513 (const_string "alu")))
6514 (set_attr "mode" "SI")])
6516 (define_insn "*addsi_5"
6517 [(set (reg FLAGS_REG)
6519 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6520 (match_operand:SI 2 "general_operand" "g"))
6522 (clobber (match_scratch:SI 0 "=r"))]
6523 "ix86_match_ccmode (insn, CCGOCmode)
6524 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6525 /* Current assemblers are broken and do not allow @GOTOFF in
6526 ought but a memory context. */
6527 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6529 switch (get_attr_type (insn))
6532 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6533 if (operands[2] == const1_rtx)
6534 return "inc{l}\t%0";
6537 gcc_assert (operands[2] == constm1_rtx);
6538 return "dec{l}\t%0";
6542 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6543 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6544 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6545 if (CONST_INT_P (operands[2])
6546 && (INTVAL (operands[2]) == 128
6547 || (INTVAL (operands[2]) < 0
6548 && INTVAL (operands[2]) != -128)))
6550 operands[2] = GEN_INT (-INTVAL (operands[2]));
6551 return "sub{l}\t{%2, %0|%0, %2}";
6553 return "add{l}\t{%2, %0|%0, %2}";
6557 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6558 (const_string "incdec")
6559 (const_string "alu")))
6560 (set_attr "mode" "SI")])
6562 (define_expand "addhi3"
6563 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6564 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6565 (match_operand:HI 2 "general_operand" "")))]
6566 "TARGET_HIMODE_MATH"
6567 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6569 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6570 ;; type optimizations enabled by define-splits. This is not important
6571 ;; for PII, and in fact harmful because of partial register stalls.
6573 (define_insn "*addhi_1_lea"
6574 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6575 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6576 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6577 (clobber (reg:CC FLAGS_REG))]
6578 "!TARGET_PARTIAL_REG_STALL
6579 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6581 switch (get_attr_type (insn))
6586 if (operands[2] == const1_rtx)
6587 return "inc{w}\t%0";
6590 gcc_assert (operands[2] == constm1_rtx);
6591 return "dec{w}\t%0";
6595 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6596 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6597 if (CONST_INT_P (operands[2])
6598 && (INTVAL (operands[2]) == 128
6599 || (INTVAL (operands[2]) < 0
6600 && INTVAL (operands[2]) != -128)))
6602 operands[2] = GEN_INT (-INTVAL (operands[2]));
6603 return "sub{w}\t{%2, %0|%0, %2}";
6605 return "add{w}\t{%2, %0|%0, %2}";
6609 (if_then_else (eq_attr "alternative" "2")
6610 (const_string "lea")
6611 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6612 (const_string "incdec")
6613 (const_string "alu"))))
6614 (set_attr "mode" "HI,HI,SI")])
6616 (define_insn "*addhi_1"
6617 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6618 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6619 (match_operand:HI 2 "general_operand" "rn,rm")))
6620 (clobber (reg:CC FLAGS_REG))]
6621 "TARGET_PARTIAL_REG_STALL
6622 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6624 switch (get_attr_type (insn))
6627 if (operands[2] == const1_rtx)
6628 return "inc{w}\t%0";
6631 gcc_assert (operands[2] == constm1_rtx);
6632 return "dec{w}\t%0";
6636 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6637 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6638 if (CONST_INT_P (operands[2])
6639 && (INTVAL (operands[2]) == 128
6640 || (INTVAL (operands[2]) < 0
6641 && INTVAL (operands[2]) != -128)))
6643 operands[2] = GEN_INT (-INTVAL (operands[2]));
6644 return "sub{w}\t{%2, %0|%0, %2}";
6646 return "add{w}\t{%2, %0|%0, %2}";
6650 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6651 (const_string "incdec")
6652 (const_string "alu")))
6653 (set_attr "mode" "HI")])
6655 (define_insn "*addhi_2"
6656 [(set (reg FLAGS_REG)
6658 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6659 (match_operand:HI 2 "general_operand" "rmn,rn"))
6661 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6662 (plus:HI (match_dup 1) (match_dup 2)))]
6663 "ix86_match_ccmode (insn, CCGOCmode)
6664 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6666 switch (get_attr_type (insn))
6669 if (operands[2] == const1_rtx)
6670 return "inc{w}\t%0";
6673 gcc_assert (operands[2] == constm1_rtx);
6674 return "dec{w}\t%0";
6678 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6679 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6680 if (CONST_INT_P (operands[2])
6681 && (INTVAL (operands[2]) == 128
6682 || (INTVAL (operands[2]) < 0
6683 && INTVAL (operands[2]) != -128)))
6685 operands[2] = GEN_INT (-INTVAL (operands[2]));
6686 return "sub{w}\t{%2, %0|%0, %2}";
6688 return "add{w}\t{%2, %0|%0, %2}";
6692 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6693 (const_string "incdec")
6694 (const_string "alu")))
6695 (set_attr "mode" "HI")])
6697 (define_insn "*addhi_3"
6698 [(set (reg FLAGS_REG)
6699 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6700 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6701 (clobber (match_scratch:HI 0 "=r"))]
6702 "ix86_match_ccmode (insn, CCZmode)
6703 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705 switch (get_attr_type (insn))
6708 if (operands[2] == const1_rtx)
6709 return "inc{w}\t%0";
6712 gcc_assert (operands[2] == constm1_rtx);
6713 return "dec{w}\t%0";
6717 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6718 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6719 if (CONST_INT_P (operands[2])
6720 && (INTVAL (operands[2]) == 128
6721 || (INTVAL (operands[2]) < 0
6722 && INTVAL (operands[2]) != -128)))
6724 operands[2] = GEN_INT (-INTVAL (operands[2]));
6725 return "sub{w}\t{%2, %0|%0, %2}";
6727 return "add{w}\t{%2, %0|%0, %2}";
6731 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6732 (const_string "incdec")
6733 (const_string "alu")))
6734 (set_attr "mode" "HI")])
6736 ; See comments above addsi_4 for details.
6737 (define_insn "*addhi_4"
6738 [(set (reg FLAGS_REG)
6739 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6740 (match_operand:HI 2 "const_int_operand" "n")))
6741 (clobber (match_scratch:HI 0 "=rm"))]
6742 "ix86_match_ccmode (insn, CCGCmode)
6743 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6745 switch (get_attr_type (insn))
6748 if (operands[2] == constm1_rtx)
6749 return "inc{w}\t%0";
6752 gcc_assert (operands[2] == const1_rtx);
6753 return "dec{w}\t%0";
6757 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6758 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6759 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6760 if ((INTVAL (operands[2]) == -128
6761 || (INTVAL (operands[2]) > 0
6762 && INTVAL (operands[2]) != 128)))
6763 return "sub{w}\t{%2, %0|%0, %2}";
6764 operands[2] = GEN_INT (-INTVAL (operands[2]));
6765 return "add{w}\t{%2, %0|%0, %2}";
6769 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6770 (const_string "incdec")
6771 (const_string "alu")))
6772 (set_attr "mode" "SI")])
6775 (define_insn "*addhi_5"
6776 [(set (reg FLAGS_REG)
6778 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6779 (match_operand:HI 2 "general_operand" "rmn"))
6781 (clobber (match_scratch:HI 0 "=r"))]
6782 "ix86_match_ccmode (insn, CCGOCmode)
6783 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6785 switch (get_attr_type (insn))
6788 if (operands[2] == const1_rtx)
6789 return "inc{w}\t%0";
6792 gcc_assert (operands[2] == constm1_rtx);
6793 return "dec{w}\t%0";
6797 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6798 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6799 if (CONST_INT_P (operands[2])
6800 && (INTVAL (operands[2]) == 128
6801 || (INTVAL (operands[2]) < 0
6802 && INTVAL (operands[2]) != -128)))
6804 operands[2] = GEN_INT (-INTVAL (operands[2]));
6805 return "sub{w}\t{%2, %0|%0, %2}";
6807 return "add{w}\t{%2, %0|%0, %2}";
6811 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6812 (const_string "incdec")
6813 (const_string "alu")))
6814 (set_attr "mode" "HI")])
6816 (define_expand "addqi3"
6817 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6818 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6819 (match_operand:QI 2 "general_operand" "")))]
6820 "TARGET_QIMODE_MATH"
6821 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6823 ;; %%% Potential partial reg stall on alternative 2. What to do?
6824 (define_insn "*addqi_1_lea"
6825 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6826 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6827 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6828 (clobber (reg:CC FLAGS_REG))]
6829 "!TARGET_PARTIAL_REG_STALL
6830 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6832 int widen = (which_alternative == 2);
6833 switch (get_attr_type (insn))
6838 if (operands[2] == const1_rtx)
6839 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6842 gcc_assert (operands[2] == constm1_rtx);
6843 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6847 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6848 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6849 if (CONST_INT_P (operands[2])
6850 && (INTVAL (operands[2]) == 128
6851 || (INTVAL (operands[2]) < 0
6852 && INTVAL (operands[2]) != -128)))
6854 operands[2] = GEN_INT (-INTVAL (operands[2]));
6856 return "sub{l}\t{%2, %k0|%k0, %2}";
6858 return "sub{b}\t{%2, %0|%0, %2}";
6861 return "add{l}\t{%k2, %k0|%k0, %k2}";
6863 return "add{b}\t{%2, %0|%0, %2}";
6867 (if_then_else (eq_attr "alternative" "3")
6868 (const_string "lea")
6869 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6870 (const_string "incdec")
6871 (const_string "alu"))))
6872 (set_attr "mode" "QI,QI,SI,SI")])
6874 (define_insn "*addqi_1"
6875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6876 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6877 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6878 (clobber (reg:CC FLAGS_REG))]
6879 "TARGET_PARTIAL_REG_STALL
6880 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6882 int widen = (which_alternative == 2);
6883 switch (get_attr_type (insn))
6886 if (operands[2] == const1_rtx)
6887 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6890 gcc_assert (operands[2] == constm1_rtx);
6891 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6895 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6896 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6897 if (CONST_INT_P (operands[2])
6898 && (INTVAL (operands[2]) == 128
6899 || (INTVAL (operands[2]) < 0
6900 && INTVAL (operands[2]) != -128)))
6902 operands[2] = GEN_INT (-INTVAL (operands[2]));
6904 return "sub{l}\t{%2, %k0|%k0, %2}";
6906 return "sub{b}\t{%2, %0|%0, %2}";
6909 return "add{l}\t{%k2, %k0|%k0, %k2}";
6911 return "add{b}\t{%2, %0|%0, %2}";
6915 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6916 (const_string "incdec")
6917 (const_string "alu")))
6918 (set_attr "mode" "QI,QI,SI")])
6920 (define_insn "*addqi_1_slp"
6921 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6922 (plus:QI (match_dup 0)
6923 (match_operand:QI 1 "general_operand" "qn,qnm")))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6926 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6928 switch (get_attr_type (insn))
6931 if (operands[1] == const1_rtx)
6932 return "inc{b}\t%0";
6935 gcc_assert (operands[1] == constm1_rtx);
6936 return "dec{b}\t%0";
6940 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6941 if (CONST_INT_P (operands[1])
6942 && INTVAL (operands[1]) < 0)
6944 operands[1] = GEN_INT (-INTVAL (operands[1]));
6945 return "sub{b}\t{%1, %0|%0, %1}";
6947 return "add{b}\t{%1, %0|%0, %1}";
6951 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6952 (const_string "incdec")
6953 (const_string "alu1")))
6954 (set (attr "memory")
6955 (if_then_else (match_operand 1 "memory_operand" "")
6956 (const_string "load")
6957 (const_string "none")))
6958 (set_attr "mode" "QI")])
6960 (define_insn "*addqi_2"
6961 [(set (reg FLAGS_REG)
6963 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6964 (match_operand:QI 2 "general_operand" "qmn,qn"))
6966 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6967 (plus:QI (match_dup 1) (match_dup 2)))]
6968 "ix86_match_ccmode (insn, CCGOCmode)
6969 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6971 switch (get_attr_type (insn))
6974 if (operands[2] == const1_rtx)
6975 return "inc{b}\t%0";
6978 gcc_assert (operands[2] == constm1_rtx
6979 || (CONST_INT_P (operands[2])
6980 && INTVAL (operands[2]) == 255));
6981 return "dec{b}\t%0";
6985 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6986 if (CONST_INT_P (operands[2])
6987 && INTVAL (operands[2]) < 0)
6989 operands[2] = GEN_INT (-INTVAL (operands[2]));
6990 return "sub{b}\t{%2, %0|%0, %2}";
6992 return "add{b}\t{%2, %0|%0, %2}";
6996 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6997 (const_string "incdec")
6998 (const_string "alu")))
6999 (set_attr "mode" "QI")])
7001 (define_insn "*addqi_3"
7002 [(set (reg FLAGS_REG)
7003 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7004 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7005 (clobber (match_scratch:QI 0 "=q"))]
7006 "ix86_match_ccmode (insn, CCZmode)
7007 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7009 switch (get_attr_type (insn))
7012 if (operands[2] == const1_rtx)
7013 return "inc{b}\t%0";
7016 gcc_assert (operands[2] == constm1_rtx
7017 || (CONST_INT_P (operands[2])
7018 && INTVAL (operands[2]) == 255));
7019 return "dec{b}\t%0";
7023 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7024 if (CONST_INT_P (operands[2])
7025 && INTVAL (operands[2]) < 0)
7027 operands[2] = GEN_INT (-INTVAL (operands[2]));
7028 return "sub{b}\t{%2, %0|%0, %2}";
7030 return "add{b}\t{%2, %0|%0, %2}";
7034 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7035 (const_string "incdec")
7036 (const_string "alu")))
7037 (set_attr "mode" "QI")])
7039 ; See comments above addsi_4 for details.
7040 (define_insn "*addqi_4"
7041 [(set (reg FLAGS_REG)
7042 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7043 (match_operand:QI 2 "const_int_operand" "n")))
7044 (clobber (match_scratch:QI 0 "=qm"))]
7045 "ix86_match_ccmode (insn, CCGCmode)
7046 && (INTVAL (operands[2]) & 0xff) != 0x80"
7048 switch (get_attr_type (insn))
7051 if (operands[2] == constm1_rtx
7052 || (CONST_INT_P (operands[2])
7053 && INTVAL (operands[2]) == 255))
7054 return "inc{b}\t%0";
7057 gcc_assert (operands[2] == const1_rtx);
7058 return "dec{b}\t%0";
7062 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7063 if (INTVAL (operands[2]) < 0)
7065 operands[2] = GEN_INT (-INTVAL (operands[2]));
7066 return "add{b}\t{%2, %0|%0, %2}";
7068 return "sub{b}\t{%2, %0|%0, %2}";
7072 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7073 (const_string "incdec")
7074 (const_string "alu")))
7075 (set_attr "mode" "QI")])
7078 (define_insn "*addqi_5"
7079 [(set (reg FLAGS_REG)
7081 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7082 (match_operand:QI 2 "general_operand" "qmn"))
7084 (clobber (match_scratch:QI 0 "=q"))]
7085 "ix86_match_ccmode (insn, CCGOCmode)
7086 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7088 switch (get_attr_type (insn))
7091 if (operands[2] == const1_rtx)
7092 return "inc{b}\t%0";
7095 gcc_assert (operands[2] == constm1_rtx
7096 || (CONST_INT_P (operands[2])
7097 && INTVAL (operands[2]) == 255));
7098 return "dec{b}\t%0";
7102 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7103 if (CONST_INT_P (operands[2])
7104 && INTVAL (operands[2]) < 0)
7106 operands[2] = GEN_INT (-INTVAL (operands[2]));
7107 return "sub{b}\t{%2, %0|%0, %2}";
7109 return "add{b}\t{%2, %0|%0, %2}";
7113 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7114 (const_string "incdec")
7115 (const_string "alu")))
7116 (set_attr "mode" "QI")])
7119 (define_insn "addqi_ext_1"
7120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7125 (match_operand 1 "ext_register_operand" "0")
7128 (match_operand:QI 2 "general_operand" "Qmn")))
7129 (clobber (reg:CC FLAGS_REG))]
7132 switch (get_attr_type (insn))
7135 if (operands[2] == const1_rtx)
7136 return "inc{b}\t%h0";
7139 gcc_assert (operands[2] == constm1_rtx
7140 || (CONST_INT_P (operands[2])
7141 && INTVAL (operands[2]) == 255));
7142 return "dec{b}\t%h0";
7146 return "add{b}\t{%2, %h0|%h0, %2}";
7150 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7151 (const_string "incdec")
7152 (const_string "alu")))
7153 (set_attr "mode" "QI")])
7155 (define_insn "*addqi_ext_1_rex64"
7156 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7161 (match_operand 1 "ext_register_operand" "0")
7164 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7165 (clobber (reg:CC FLAGS_REG))]
7168 switch (get_attr_type (insn))
7171 if (operands[2] == const1_rtx)
7172 return "inc{b}\t%h0";
7175 gcc_assert (operands[2] == constm1_rtx
7176 || (CONST_INT_P (operands[2])
7177 && INTVAL (operands[2]) == 255));
7178 return "dec{b}\t%h0";
7182 return "add{b}\t{%2, %h0|%h0, %2}";
7186 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7187 (const_string "incdec")
7188 (const_string "alu")))
7189 (set_attr "mode" "QI")])
7191 (define_insn "*addqi_ext_2"
7192 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7197 (match_operand 1 "ext_register_operand" "%0")
7201 (match_operand 2 "ext_register_operand" "Q")
7204 (clobber (reg:CC FLAGS_REG))]
7206 "add{b}\t{%h2, %h0|%h0, %h2}"
7207 [(set_attr "type" "alu")
7208 (set_attr "mode" "QI")])
7210 ;; The patterns that match these are at the end of this file.
7212 (define_expand "addxf3"
7213 [(set (match_operand:XF 0 "register_operand" "")
7214 (plus:XF (match_operand:XF 1 "register_operand" "")
7215 (match_operand:XF 2 "register_operand" "")))]
7219 (define_expand "add<mode>3"
7220 [(set (match_operand:MODEF 0 "register_operand" "")
7221 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7222 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7223 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7226 ;; Subtract instructions
7228 ;; %%% splits for subditi3
7230 (define_expand "subti3"
7231 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7232 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7233 (match_operand:TI 2 "x86_64_general_operand" "")))]
7235 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7237 (define_insn "*subti3_1"
7238 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7239 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7240 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7241 (clobber (reg:CC FLAGS_REG))]
7242 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7246 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7247 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7248 (match_operand:TI 2 "x86_64_general_operand" "")))
7249 (clobber (reg:CC FLAGS_REG))]
7250 "TARGET_64BIT && reload_completed"
7251 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7252 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7253 (parallel [(set (match_dup 3)
7254 (minus:DI (match_dup 4)
7255 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7257 (clobber (reg:CC FLAGS_REG))])]
7258 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7260 ;; %%% splits for subsidi3
7262 (define_expand "subdi3"
7263 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7264 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7265 (match_operand:DI 2 "x86_64_general_operand" "")))]
7267 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7269 (define_insn "*subdi3_1"
7270 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7271 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7272 (match_operand:DI 2 "general_operand" "roiF,riF")))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7278 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7279 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7280 (match_operand:DI 2 "general_operand" "")))
7281 (clobber (reg:CC FLAGS_REG))]
7282 "!TARGET_64BIT && reload_completed"
7283 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7284 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7285 (parallel [(set (match_dup 3)
7286 (minus:SI (match_dup 4)
7287 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7289 (clobber (reg:CC FLAGS_REG))])]
7290 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7292 (define_insn "subdi3_carry_rex64"
7293 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7294 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7295 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7296 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7297 (clobber (reg:CC FLAGS_REG))]
7298 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7299 "sbb{q}\t{%2, %0|%0, %2}"
7300 [(set_attr "type" "alu")
7301 (set_attr "pent_pair" "pu")
7302 (set_attr "mode" "DI")])
7304 (define_insn "*subdi_1_rex64"
7305 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7306 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7307 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7308 (clobber (reg:CC FLAGS_REG))]
7309 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7310 "sub{q}\t{%2, %0|%0, %2}"
7311 [(set_attr "type" "alu")
7312 (set_attr "mode" "DI")])
7314 (define_insn "*subdi_2_rex64"
7315 [(set (reg FLAGS_REG)
7317 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7318 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7320 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7321 (minus:DI (match_dup 1) (match_dup 2)))]
7322 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7323 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7324 "sub{q}\t{%2, %0|%0, %2}"
7325 [(set_attr "type" "alu")
7326 (set_attr "mode" "DI")])
7328 (define_insn "*subdi_3_rex63"
7329 [(set (reg FLAGS_REG)
7330 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7331 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7332 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7333 (minus:DI (match_dup 1) (match_dup 2)))]
7334 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7335 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7336 "sub{q}\t{%2, %0|%0, %2}"
7337 [(set_attr "type" "alu")
7338 (set_attr "mode" "DI")])
7340 (define_insn "subqi3_carry"
7341 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7342 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7343 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7344 (match_operand:QI 2 "general_operand" "qn,qm"))))
7345 (clobber (reg:CC FLAGS_REG))]
7346 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7347 "sbb{b}\t{%2, %0|%0, %2}"
7348 [(set_attr "type" "alu")
7349 (set_attr "pent_pair" "pu")
7350 (set_attr "mode" "QI")])
7352 (define_insn "subhi3_carry"
7353 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7354 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7355 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7356 (match_operand:HI 2 "general_operand" "rn,rm"))))
7357 (clobber (reg:CC FLAGS_REG))]
7358 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7359 "sbb{w}\t{%2, %0|%0, %2}"
7360 [(set_attr "type" "alu")
7361 (set_attr "pent_pair" "pu")
7362 (set_attr "mode" "HI")])
7364 (define_insn "subsi3_carry"
7365 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7366 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7367 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7368 (match_operand:SI 2 "general_operand" "ri,rm"))))
7369 (clobber (reg:CC FLAGS_REG))]
7370 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7371 "sbb{l}\t{%2, %0|%0, %2}"
7372 [(set_attr "type" "alu")
7373 (set_attr "pent_pair" "pu")
7374 (set_attr "mode" "SI")])
7376 (define_insn "subsi3_carry_zext"
7377 [(set (match_operand:DI 0 "register_operand" "=r")
7379 (minus:SI (match_operand:SI 1 "register_operand" "0")
7380 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7381 (match_operand:SI 2 "general_operand" "g")))))
7382 (clobber (reg:CC FLAGS_REG))]
7383 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7384 "sbb{l}\t{%2, %k0|%k0, %2}"
7385 [(set_attr "type" "alu")
7386 (set_attr "pent_pair" "pu")
7387 (set_attr "mode" "SI")])
7389 (define_expand "subsi3"
7390 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7391 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7392 (match_operand:SI 2 "general_operand" "")))]
7394 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7396 (define_insn "*subsi_1"
7397 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7398 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7399 (match_operand:SI 2 "general_operand" "ri,rm")))
7400 (clobber (reg:CC FLAGS_REG))]
7401 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7402 "sub{l}\t{%2, %0|%0, %2}"
7403 [(set_attr "type" "alu")
7404 (set_attr "mode" "SI")])
7406 (define_insn "*subsi_1_zext"
7407 [(set (match_operand:DI 0 "register_operand" "=r")
7409 (minus:SI (match_operand:SI 1 "register_operand" "0")
7410 (match_operand:SI 2 "general_operand" "g"))))
7411 (clobber (reg:CC FLAGS_REG))]
7412 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7413 "sub{l}\t{%2, %k0|%k0, %2}"
7414 [(set_attr "type" "alu")
7415 (set_attr "mode" "SI")])
7417 (define_insn "*subsi_2"
7418 [(set (reg FLAGS_REG)
7420 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7421 (match_operand:SI 2 "general_operand" "ri,rm"))
7423 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7424 (minus:SI (match_dup 1) (match_dup 2)))]
7425 "ix86_match_ccmode (insn, CCGOCmode)
7426 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7427 "sub{l}\t{%2, %0|%0, %2}"
7428 [(set_attr "type" "alu")
7429 (set_attr "mode" "SI")])
7431 (define_insn "*subsi_2_zext"
7432 [(set (reg FLAGS_REG)
7434 (minus:SI (match_operand:SI 1 "register_operand" "0")
7435 (match_operand:SI 2 "general_operand" "g"))
7437 (set (match_operand:DI 0 "register_operand" "=r")
7439 (minus:SI (match_dup 1)
7441 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7442 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7443 "sub{l}\t{%2, %k0|%k0, %2}"
7444 [(set_attr "type" "alu")
7445 (set_attr "mode" "SI")])
7447 (define_insn "*subsi_3"
7448 [(set (reg FLAGS_REG)
7449 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7450 (match_operand:SI 2 "general_operand" "ri,rm")))
7451 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7452 (minus:SI (match_dup 1) (match_dup 2)))]
7453 "ix86_match_ccmode (insn, CCmode)
7454 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7455 "sub{l}\t{%2, %0|%0, %2}"
7456 [(set_attr "type" "alu")
7457 (set_attr "mode" "SI")])
7459 (define_insn "*subsi_3_zext"
7460 [(set (reg FLAGS_REG)
7461 (compare (match_operand:SI 1 "register_operand" "0")
7462 (match_operand:SI 2 "general_operand" "g")))
7463 (set (match_operand:DI 0 "register_operand" "=r")
7465 (minus:SI (match_dup 1)
7467 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7468 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7469 "sub{l}\t{%2, %1|%1, %2}"
7470 [(set_attr "type" "alu")
7471 (set_attr "mode" "DI")])
7473 (define_expand "subhi3"
7474 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7475 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7476 (match_operand:HI 2 "general_operand" "")))]
7477 "TARGET_HIMODE_MATH"
7478 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7480 (define_insn "*subhi_1"
7481 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7482 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7483 (match_operand:HI 2 "general_operand" "rn,rm")))
7484 (clobber (reg:CC FLAGS_REG))]
7485 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7486 "sub{w}\t{%2, %0|%0, %2}"
7487 [(set_attr "type" "alu")
7488 (set_attr "mode" "HI")])
7490 (define_insn "*subhi_2"
7491 [(set (reg FLAGS_REG)
7493 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7494 (match_operand:HI 2 "general_operand" "rn,rm"))
7496 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7497 (minus:HI (match_dup 1) (match_dup 2)))]
7498 "ix86_match_ccmode (insn, CCGOCmode)
7499 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7500 "sub{w}\t{%2, %0|%0, %2}"
7501 [(set_attr "type" "alu")
7502 (set_attr "mode" "HI")])
7504 (define_insn "*subhi_3"
7505 [(set (reg FLAGS_REG)
7506 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7507 (match_operand:HI 2 "general_operand" "rn,rm")))
7508 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7509 (minus:HI (match_dup 1) (match_dup 2)))]
7510 "ix86_match_ccmode (insn, CCmode)
7511 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7512 "sub{w}\t{%2, %0|%0, %2}"
7513 [(set_attr "type" "alu")
7514 (set_attr "mode" "HI")])
7516 (define_expand "subqi3"
7517 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7518 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7519 (match_operand:QI 2 "general_operand" "")))]
7520 "TARGET_QIMODE_MATH"
7521 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7523 (define_insn "*subqi_1"
7524 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7525 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7526 (match_operand:QI 2 "general_operand" "qn,qm")))
7527 (clobber (reg:CC FLAGS_REG))]
7528 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7529 "sub{b}\t{%2, %0|%0, %2}"
7530 [(set_attr "type" "alu")
7531 (set_attr "mode" "QI")])
7533 (define_insn "*subqi_1_slp"
7534 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7535 (minus:QI (match_dup 0)
7536 (match_operand:QI 1 "general_operand" "qn,qm")))
7537 (clobber (reg:CC FLAGS_REG))]
7538 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7539 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7540 "sub{b}\t{%1, %0|%0, %1}"
7541 [(set_attr "type" "alu1")
7542 (set_attr "mode" "QI")])
7544 (define_insn "*subqi_2"
7545 [(set (reg FLAGS_REG)
7547 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7548 (match_operand:QI 2 "general_operand" "qn,qm"))
7550 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7551 (minus:QI (match_dup 1) (match_dup 2)))]
7552 "ix86_match_ccmode (insn, CCGOCmode)
7553 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7554 "sub{b}\t{%2, %0|%0, %2}"
7555 [(set_attr "type" "alu")
7556 (set_attr "mode" "QI")])
7558 (define_insn "*subqi_3"
7559 [(set (reg FLAGS_REG)
7560 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7561 (match_operand:QI 2 "general_operand" "qn,qm")))
7562 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7563 (minus:QI (match_dup 1) (match_dup 2)))]
7564 "ix86_match_ccmode (insn, CCmode)
7565 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7566 "sub{b}\t{%2, %0|%0, %2}"
7567 [(set_attr "type" "alu")
7568 (set_attr "mode" "QI")])
7570 ;; The patterns that match these are at the end of this file.
7572 (define_expand "subxf3"
7573 [(set (match_operand:XF 0 "register_operand" "")
7574 (minus:XF (match_operand:XF 1 "register_operand" "")
7575 (match_operand:XF 2 "register_operand" "")))]
7579 (define_expand "sub<mode>3"
7580 [(set (match_operand:MODEF 0 "register_operand" "")
7581 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7582 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7583 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7586 ;; Multiply instructions
7588 (define_expand "muldi3"
7589 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7590 (mult:DI (match_operand:DI 1 "register_operand" "")
7591 (match_operand:DI 2 "x86_64_general_operand" "")))
7592 (clobber (reg:CC FLAGS_REG))])]
7597 ;; IMUL reg64, reg64, imm8 Direct
7598 ;; IMUL reg64, mem64, imm8 VectorPath
7599 ;; IMUL reg64, reg64, imm32 Direct
7600 ;; IMUL reg64, mem64, imm32 VectorPath
7601 ;; IMUL reg64, reg64 Direct
7602 ;; IMUL reg64, mem64 Direct
7604 (define_insn "*muldi3_1_rex64"
7605 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7606 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7607 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7608 (clobber (reg:CC FLAGS_REG))]
7610 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7612 imul{q}\t{%2, %1, %0|%0, %1, %2}
7613 imul{q}\t{%2, %1, %0|%0, %1, %2}
7614 imul{q}\t{%2, %0|%0, %2}"
7615 [(set_attr "type" "imul")
7616 (set_attr "prefix_0f" "0,0,1")
7617 (set (attr "athlon_decode")
7618 (cond [(eq_attr "cpu" "athlon")
7619 (const_string "vector")
7620 (eq_attr "alternative" "1")
7621 (const_string "vector")
7622 (and (eq_attr "alternative" "2")
7623 (match_operand 1 "memory_operand" ""))
7624 (const_string "vector")]
7625 (const_string "direct")))
7626 (set (attr "amdfam10_decode")
7627 (cond [(and (eq_attr "alternative" "0,1")
7628 (match_operand 1 "memory_operand" ""))
7629 (const_string "vector")]
7630 (const_string "direct")))
7631 (set_attr "mode" "DI")])
7633 (define_expand "mulsi3"
7634 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7635 (mult:SI (match_operand:SI 1 "register_operand" "")
7636 (match_operand:SI 2 "general_operand" "")))
7637 (clobber (reg:CC FLAGS_REG))])]
7642 ;; IMUL reg32, reg32, imm8 Direct
7643 ;; IMUL reg32, mem32, imm8 VectorPath
7644 ;; IMUL reg32, reg32, imm32 Direct
7645 ;; IMUL reg32, mem32, imm32 VectorPath
7646 ;; IMUL reg32, reg32 Direct
7647 ;; IMUL reg32, mem32 Direct
7649 (define_insn "*mulsi3_1"
7650 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7651 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7652 (match_operand:SI 2 "general_operand" "K,i,mr")))
7653 (clobber (reg:CC FLAGS_REG))]
7654 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7656 imul{l}\t{%2, %1, %0|%0, %1, %2}
7657 imul{l}\t{%2, %1, %0|%0, %1, %2}
7658 imul{l}\t{%2, %0|%0, %2}"
7659 [(set_attr "type" "imul")
7660 (set_attr "prefix_0f" "0,0,1")
7661 (set (attr "athlon_decode")
7662 (cond [(eq_attr "cpu" "athlon")
7663 (const_string "vector")
7664 (eq_attr "alternative" "1")
7665 (const_string "vector")
7666 (and (eq_attr "alternative" "2")
7667 (match_operand 1 "memory_operand" ""))
7668 (const_string "vector")]
7669 (const_string "direct")))
7670 (set (attr "amdfam10_decode")
7671 (cond [(and (eq_attr "alternative" "0,1")
7672 (match_operand 1 "memory_operand" ""))
7673 (const_string "vector")]
7674 (const_string "direct")))
7675 (set_attr "mode" "SI")])
7677 (define_insn "*mulsi3_1_zext"
7678 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7680 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7681 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7682 (clobber (reg:CC FLAGS_REG))]
7684 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7686 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7687 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7688 imul{l}\t{%2, %k0|%k0, %2}"
7689 [(set_attr "type" "imul")
7690 (set_attr "prefix_0f" "0,0,1")
7691 (set (attr "athlon_decode")
7692 (cond [(eq_attr "cpu" "athlon")
7693 (const_string "vector")
7694 (eq_attr "alternative" "1")
7695 (const_string "vector")
7696 (and (eq_attr "alternative" "2")
7697 (match_operand 1 "memory_operand" ""))
7698 (const_string "vector")]
7699 (const_string "direct")))
7700 (set (attr "amdfam10_decode")
7701 (cond [(and (eq_attr "alternative" "0,1")
7702 (match_operand 1 "memory_operand" ""))
7703 (const_string "vector")]
7704 (const_string "direct")))
7705 (set_attr "mode" "SI")])
7707 (define_expand "mulhi3"
7708 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7709 (mult:HI (match_operand:HI 1 "register_operand" "")
7710 (match_operand:HI 2 "general_operand" "")))
7711 (clobber (reg:CC FLAGS_REG))])]
7712 "TARGET_HIMODE_MATH"
7716 ;; IMUL reg16, reg16, imm8 VectorPath
7717 ;; IMUL reg16, mem16, imm8 VectorPath
7718 ;; IMUL reg16, reg16, imm16 VectorPath
7719 ;; IMUL reg16, mem16, imm16 VectorPath
7720 ;; IMUL reg16, reg16 Direct
7721 ;; IMUL reg16, mem16 Direct
7722 (define_insn "*mulhi3_1"
7723 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7724 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7725 (match_operand:HI 2 "general_operand" "K,n,mr")))
7726 (clobber (reg:CC FLAGS_REG))]
7727 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7729 imul{w}\t{%2, %1, %0|%0, %1, %2}
7730 imul{w}\t{%2, %1, %0|%0, %1, %2}
7731 imul{w}\t{%2, %0|%0, %2}"
7732 [(set_attr "type" "imul")
7733 (set_attr "prefix_0f" "0,0,1")
7734 (set (attr "athlon_decode")
7735 (cond [(eq_attr "cpu" "athlon")
7736 (const_string "vector")
7737 (eq_attr "alternative" "1,2")
7738 (const_string "vector")]
7739 (const_string "direct")))
7740 (set (attr "amdfam10_decode")
7741 (cond [(eq_attr "alternative" "0,1")
7742 (const_string "vector")]
7743 (const_string "direct")))
7744 (set_attr "mode" "HI")])
7746 (define_expand "mulqi3"
7747 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7748 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7749 (match_operand:QI 2 "register_operand" "")))
7750 (clobber (reg:CC FLAGS_REG))])]
7751 "TARGET_QIMODE_MATH"
7758 (define_insn "*mulqi3_1"
7759 [(set (match_operand:QI 0 "register_operand" "=a")
7760 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7761 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7762 (clobber (reg:CC FLAGS_REG))]
7764 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7766 [(set_attr "type" "imul")
7767 (set_attr "length_immediate" "0")
7768 (set (attr "athlon_decode")
7769 (if_then_else (eq_attr "cpu" "athlon")
7770 (const_string "vector")
7771 (const_string "direct")))
7772 (set_attr "amdfam10_decode" "direct")
7773 (set_attr "mode" "QI")])
7775 (define_expand "umulqihi3"
7776 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7777 (mult:HI (zero_extend:HI
7778 (match_operand:QI 1 "nonimmediate_operand" ""))
7780 (match_operand:QI 2 "register_operand" ""))))
7781 (clobber (reg:CC FLAGS_REG))])]
7782 "TARGET_QIMODE_MATH"
7785 (define_insn "*umulqihi3_1"
7786 [(set (match_operand:HI 0 "register_operand" "=a")
7787 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7788 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7789 (clobber (reg:CC FLAGS_REG))]
7791 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7793 [(set_attr "type" "imul")
7794 (set_attr "length_immediate" "0")
7795 (set (attr "athlon_decode")
7796 (if_then_else (eq_attr "cpu" "athlon")
7797 (const_string "vector")
7798 (const_string "direct")))
7799 (set_attr "amdfam10_decode" "direct")
7800 (set_attr "mode" "QI")])
7802 (define_expand "mulqihi3"
7803 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7804 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7805 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7806 (clobber (reg:CC FLAGS_REG))])]
7807 "TARGET_QIMODE_MATH"
7810 (define_insn "*mulqihi3_insn"
7811 [(set (match_operand:HI 0 "register_operand" "=a")
7812 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7813 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7814 (clobber (reg:CC FLAGS_REG))]
7816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7818 [(set_attr "type" "imul")
7819 (set_attr "length_immediate" "0")
7820 (set (attr "athlon_decode")
7821 (if_then_else (eq_attr "cpu" "athlon")
7822 (const_string "vector")
7823 (const_string "direct")))
7824 (set_attr "amdfam10_decode" "direct")
7825 (set_attr "mode" "QI")])
7827 (define_expand "umulditi3"
7828 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7829 (mult:TI (zero_extend:TI
7830 (match_operand:DI 1 "nonimmediate_operand" ""))
7832 (match_operand:DI 2 "register_operand" ""))))
7833 (clobber (reg:CC FLAGS_REG))])]
7837 (define_insn "*umulditi3_insn"
7838 [(set (match_operand:TI 0 "register_operand" "=A")
7839 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7840 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7841 (clobber (reg:CC FLAGS_REG))]
7843 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7845 [(set_attr "type" "imul")
7846 (set_attr "length_immediate" "0")
7847 (set (attr "athlon_decode")
7848 (if_then_else (eq_attr "cpu" "athlon")
7849 (const_string "vector")
7850 (const_string "double")))
7851 (set_attr "amdfam10_decode" "double")
7852 (set_attr "mode" "DI")])
7854 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7855 (define_expand "umulsidi3"
7856 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7857 (mult:DI (zero_extend:DI
7858 (match_operand:SI 1 "nonimmediate_operand" ""))
7860 (match_operand:SI 2 "register_operand" ""))))
7861 (clobber (reg:CC FLAGS_REG))])]
7865 (define_insn "*umulsidi3_insn"
7866 [(set (match_operand:DI 0 "register_operand" "=A")
7867 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7868 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7869 (clobber (reg:CC FLAGS_REG))]
7871 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7873 [(set_attr "type" "imul")
7874 (set_attr "length_immediate" "0")
7875 (set (attr "athlon_decode")
7876 (if_then_else (eq_attr "cpu" "athlon")
7877 (const_string "vector")
7878 (const_string "double")))
7879 (set_attr "amdfam10_decode" "double")
7880 (set_attr "mode" "SI")])
7882 (define_expand "mulditi3"
7883 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7884 (mult:TI (sign_extend:TI
7885 (match_operand:DI 1 "nonimmediate_operand" ""))
7887 (match_operand:DI 2 "register_operand" ""))))
7888 (clobber (reg:CC FLAGS_REG))])]
7892 (define_insn "*mulditi3_insn"
7893 [(set (match_operand:TI 0 "register_operand" "=A")
7894 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7895 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7896 (clobber (reg:CC FLAGS_REG))]
7898 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7900 [(set_attr "type" "imul")
7901 (set_attr "length_immediate" "0")
7902 (set (attr "athlon_decode")
7903 (if_then_else (eq_attr "cpu" "athlon")
7904 (const_string "vector")
7905 (const_string "double")))
7906 (set_attr "amdfam10_decode" "double")
7907 (set_attr "mode" "DI")])
7909 (define_expand "mulsidi3"
7910 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7911 (mult:DI (sign_extend:DI
7912 (match_operand:SI 1 "nonimmediate_operand" ""))
7914 (match_operand:SI 2 "register_operand" ""))))
7915 (clobber (reg:CC FLAGS_REG))])]
7919 (define_insn "*mulsidi3_insn"
7920 [(set (match_operand:DI 0 "register_operand" "=A")
7921 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7922 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7923 (clobber (reg:CC FLAGS_REG))]
7925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7927 [(set_attr "type" "imul")
7928 (set_attr "length_immediate" "0")
7929 (set (attr "athlon_decode")
7930 (if_then_else (eq_attr "cpu" "athlon")
7931 (const_string "vector")
7932 (const_string "double")))
7933 (set_attr "amdfam10_decode" "double")
7934 (set_attr "mode" "SI")])
7936 (define_expand "umuldi3_highpart"
7937 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7940 (mult:TI (zero_extend:TI
7941 (match_operand:DI 1 "nonimmediate_operand" ""))
7943 (match_operand:DI 2 "register_operand" "")))
7945 (clobber (match_scratch:DI 3 ""))
7946 (clobber (reg:CC FLAGS_REG))])]
7950 (define_insn "*umuldi3_highpart_rex64"
7951 [(set (match_operand:DI 0 "register_operand" "=d")
7954 (mult:TI (zero_extend:TI
7955 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7957 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7959 (clobber (match_scratch:DI 3 "=1"))
7960 (clobber (reg:CC FLAGS_REG))]
7962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7964 [(set_attr "type" "imul")
7965 (set_attr "length_immediate" "0")
7966 (set (attr "athlon_decode")
7967 (if_then_else (eq_attr "cpu" "athlon")
7968 (const_string "vector")
7969 (const_string "double")))
7970 (set_attr "amdfam10_decode" "double")
7971 (set_attr "mode" "DI")])
7973 (define_expand "umulsi3_highpart"
7974 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7977 (mult:DI (zero_extend:DI
7978 (match_operand:SI 1 "nonimmediate_operand" ""))
7980 (match_operand:SI 2 "register_operand" "")))
7982 (clobber (match_scratch:SI 3 ""))
7983 (clobber (reg:CC FLAGS_REG))])]
7987 (define_insn "*umulsi3_highpart_insn"
7988 [(set (match_operand:SI 0 "register_operand" "=d")
7991 (mult:DI (zero_extend:DI
7992 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7994 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7996 (clobber (match_scratch:SI 3 "=1"))
7997 (clobber (reg:CC FLAGS_REG))]
7998 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8000 [(set_attr "type" "imul")
8001 (set_attr "length_immediate" "0")
8002 (set (attr "athlon_decode")
8003 (if_then_else (eq_attr "cpu" "athlon")
8004 (const_string "vector")
8005 (const_string "double")))
8006 (set_attr "amdfam10_decode" "double")
8007 (set_attr "mode" "SI")])
8009 (define_insn "*umulsi3_highpart_zext"
8010 [(set (match_operand:DI 0 "register_operand" "=d")
8011 (zero_extend:DI (truncate:SI
8013 (mult:DI (zero_extend:DI
8014 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8016 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8018 (clobber (match_scratch:SI 3 "=1"))
8019 (clobber (reg:CC FLAGS_REG))]
8021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8023 [(set_attr "type" "imul")
8024 (set_attr "length_immediate" "0")
8025 (set (attr "athlon_decode")
8026 (if_then_else (eq_attr "cpu" "athlon")
8027 (const_string "vector")
8028 (const_string "double")))
8029 (set_attr "amdfam10_decode" "double")
8030 (set_attr "mode" "SI")])
8032 (define_expand "smuldi3_highpart"
8033 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8036 (mult:TI (sign_extend:TI
8037 (match_operand:DI 1 "nonimmediate_operand" ""))
8039 (match_operand:DI 2 "register_operand" "")))
8041 (clobber (match_scratch:DI 3 ""))
8042 (clobber (reg:CC FLAGS_REG))])]
8046 (define_insn "*smuldi3_highpart_rex64"
8047 [(set (match_operand:DI 0 "register_operand" "=d")
8050 (mult:TI (sign_extend:TI
8051 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8053 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8055 (clobber (match_scratch:DI 3 "=1"))
8056 (clobber (reg:CC FLAGS_REG))]
8058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8060 [(set_attr "type" "imul")
8061 (set (attr "athlon_decode")
8062 (if_then_else (eq_attr "cpu" "athlon")
8063 (const_string "vector")
8064 (const_string "double")))
8065 (set_attr "amdfam10_decode" "double")
8066 (set_attr "mode" "DI")])
8068 (define_expand "smulsi3_highpart"
8069 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8072 (mult:DI (sign_extend:DI
8073 (match_operand:SI 1 "nonimmediate_operand" ""))
8075 (match_operand:SI 2 "register_operand" "")))
8077 (clobber (match_scratch:SI 3 ""))
8078 (clobber (reg:CC FLAGS_REG))])]
8082 (define_insn "*smulsi3_highpart_insn"
8083 [(set (match_operand:SI 0 "register_operand" "=d")
8086 (mult:DI (sign_extend:DI
8087 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8089 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8091 (clobber (match_scratch:SI 3 "=1"))
8092 (clobber (reg:CC FLAGS_REG))]
8093 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8095 [(set_attr "type" "imul")
8096 (set (attr "athlon_decode")
8097 (if_then_else (eq_attr "cpu" "athlon")
8098 (const_string "vector")
8099 (const_string "double")))
8100 (set_attr "amdfam10_decode" "double")
8101 (set_attr "mode" "SI")])
8103 (define_insn "*smulsi3_highpart_zext"
8104 [(set (match_operand:DI 0 "register_operand" "=d")
8105 (zero_extend:DI (truncate:SI
8107 (mult:DI (sign_extend:DI
8108 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8110 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8112 (clobber (match_scratch:SI 3 "=1"))
8113 (clobber (reg:CC FLAGS_REG))]
8115 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8117 [(set_attr "type" "imul")
8118 (set (attr "athlon_decode")
8119 (if_then_else (eq_attr "cpu" "athlon")
8120 (const_string "vector")
8121 (const_string "double")))
8122 (set_attr "amdfam10_decode" "double")
8123 (set_attr "mode" "SI")])
8125 ;; The patterns that match these are at the end of this file.
8127 (define_expand "mulxf3"
8128 [(set (match_operand:XF 0 "register_operand" "")
8129 (mult:XF (match_operand:XF 1 "register_operand" "")
8130 (match_operand:XF 2 "register_operand" "")))]
8134 (define_expand "mul<mode>3"
8135 [(set (match_operand:MODEF 0 "register_operand" "")
8136 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8137 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8138 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8141 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8144 ;; Divide instructions
8146 (define_insn "divqi3"
8147 [(set (match_operand:QI 0 "register_operand" "=a")
8148 (div:QI (match_operand:HI 1 "register_operand" "0")
8149 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8150 (clobber (reg:CC FLAGS_REG))]
8151 "TARGET_QIMODE_MATH"
8153 [(set_attr "type" "idiv")
8154 (set_attr "mode" "QI")])
8156 (define_insn "udivqi3"
8157 [(set (match_operand:QI 0 "register_operand" "=a")
8158 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8159 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8160 (clobber (reg:CC FLAGS_REG))]
8161 "TARGET_QIMODE_MATH"
8163 [(set_attr "type" "idiv")
8164 (set_attr "mode" "QI")])
8166 ;; The patterns that match these are at the end of this file.
8168 (define_expand "divxf3"
8169 [(set (match_operand:XF 0 "register_operand" "")
8170 (div:XF (match_operand:XF 1 "register_operand" "")
8171 (match_operand:XF 2 "register_operand" "")))]
8175 (define_expand "divdf3"
8176 [(set (match_operand:DF 0 "register_operand" "")
8177 (div:DF (match_operand:DF 1 "register_operand" "")
8178 (match_operand:DF 2 "nonimmediate_operand" "")))]
8179 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8182 (define_expand "divsf3"
8183 [(set (match_operand:SF 0 "register_operand" "")
8184 (div:SF (match_operand:SF 1 "register_operand" "")
8185 (match_operand:SF 2 "nonimmediate_operand" "")))]
8186 "TARGET_80387 || TARGET_SSE_MATH"
8188 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8189 && flag_finite_math_only && !flag_trapping_math
8190 && flag_unsafe_math_optimizations)
8192 ix86_emit_swdivsf (operands[0], operands[1],
8193 operands[2], SFmode);
8198 ;; Remainder instructions.
8200 (define_expand "divmoddi4"
8201 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8202 (div:DI (match_operand:DI 1 "register_operand" "")
8203 (match_operand:DI 2 "nonimmediate_operand" "")))
8204 (set (match_operand:DI 3 "register_operand" "")
8205 (mod:DI (match_dup 1) (match_dup 2)))
8206 (clobber (reg:CC FLAGS_REG))])]
8210 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8211 ;; Penalize eax case slightly because it results in worse scheduling
8213 (define_insn "*divmoddi4_nocltd_rex64"
8214 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8215 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8216 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8217 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8218 (mod:DI (match_dup 2) (match_dup 3)))
8219 (clobber (reg:CC FLAGS_REG))]
8220 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8222 [(set_attr "type" "multi")])
8224 (define_insn "*divmoddi4_cltd_rex64"
8225 [(set (match_operand:DI 0 "register_operand" "=a")
8226 (div:DI (match_operand:DI 2 "register_operand" "a")
8227 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8228 (set (match_operand:DI 1 "register_operand" "=&d")
8229 (mod:DI (match_dup 2) (match_dup 3)))
8230 (clobber (reg:CC FLAGS_REG))]
8231 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8233 [(set_attr "type" "multi")])
8235 (define_insn "*divmoddi_noext_rex64"
8236 [(set (match_operand:DI 0 "register_operand" "=a")
8237 (div:DI (match_operand:DI 1 "register_operand" "0")
8238 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8239 (set (match_operand:DI 3 "register_operand" "=d")
8240 (mod:DI (match_dup 1) (match_dup 2)))
8241 (use (match_operand:DI 4 "register_operand" "3"))
8242 (clobber (reg:CC FLAGS_REG))]
8245 [(set_attr "type" "idiv")
8246 (set_attr "mode" "DI")])
8249 [(set (match_operand:DI 0 "register_operand" "")
8250 (div:DI (match_operand:DI 1 "register_operand" "")
8251 (match_operand:DI 2 "nonimmediate_operand" "")))
8252 (set (match_operand:DI 3 "register_operand" "")
8253 (mod:DI (match_dup 1) (match_dup 2)))
8254 (clobber (reg:CC FLAGS_REG))]
8255 "TARGET_64BIT && reload_completed"
8256 [(parallel [(set (match_dup 3)
8257 (ashiftrt:DI (match_dup 4) (const_int 63)))
8258 (clobber (reg:CC FLAGS_REG))])
8259 (parallel [(set (match_dup 0)
8260 (div:DI (reg:DI 0) (match_dup 2)))
8262 (mod:DI (reg:DI 0) (match_dup 2)))
8264 (clobber (reg:CC FLAGS_REG))])]
8266 /* Avoid use of cltd in favor of a mov+shift. */
8267 if (!TARGET_USE_CLTD && !optimize_size)
8269 if (true_regnum (operands[1]))
8270 emit_move_insn (operands[0], operands[1]);
8272 emit_move_insn (operands[3], operands[1]);
8273 operands[4] = operands[3];
8277 gcc_assert (!true_regnum (operands[1]));
8278 operands[4] = operands[1];
8283 (define_expand "divmodsi4"
8284 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8285 (div:SI (match_operand:SI 1 "register_operand" "")
8286 (match_operand:SI 2 "nonimmediate_operand" "")))
8287 (set (match_operand:SI 3 "register_operand" "")
8288 (mod:SI (match_dup 1) (match_dup 2)))
8289 (clobber (reg:CC FLAGS_REG))])]
8293 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8294 ;; Penalize eax case slightly because it results in worse scheduling
8296 (define_insn "*divmodsi4_nocltd"
8297 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8298 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8299 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8300 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8301 (mod:SI (match_dup 2) (match_dup 3)))
8302 (clobber (reg:CC FLAGS_REG))]
8303 "!optimize_size && !TARGET_USE_CLTD"
8305 [(set_attr "type" "multi")])
8307 (define_insn "*divmodsi4_cltd"
8308 [(set (match_operand:SI 0 "register_operand" "=a")
8309 (div:SI (match_operand:SI 2 "register_operand" "a")
8310 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8311 (set (match_operand:SI 1 "register_operand" "=&d")
8312 (mod:SI (match_dup 2) (match_dup 3)))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "optimize_size || TARGET_USE_CLTD"
8316 [(set_attr "type" "multi")])
8318 (define_insn "*divmodsi_noext"
8319 [(set (match_operand:SI 0 "register_operand" "=a")
8320 (div:SI (match_operand:SI 1 "register_operand" "0")
8321 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8322 (set (match_operand:SI 3 "register_operand" "=d")
8323 (mod:SI (match_dup 1) (match_dup 2)))
8324 (use (match_operand:SI 4 "register_operand" "3"))
8325 (clobber (reg:CC FLAGS_REG))]
8328 [(set_attr "type" "idiv")
8329 (set_attr "mode" "SI")])
8332 [(set (match_operand:SI 0 "register_operand" "")
8333 (div:SI (match_operand:SI 1 "register_operand" "")
8334 (match_operand:SI 2 "nonimmediate_operand" "")))
8335 (set (match_operand:SI 3 "register_operand" "")
8336 (mod:SI (match_dup 1) (match_dup 2)))
8337 (clobber (reg:CC FLAGS_REG))]
8339 [(parallel [(set (match_dup 3)
8340 (ashiftrt:SI (match_dup 4) (const_int 31)))
8341 (clobber (reg:CC FLAGS_REG))])
8342 (parallel [(set (match_dup 0)
8343 (div:SI (reg:SI 0) (match_dup 2)))
8345 (mod:SI (reg:SI 0) (match_dup 2)))
8347 (clobber (reg:CC FLAGS_REG))])]
8349 /* Avoid use of cltd in favor of a mov+shift. */
8350 if (!TARGET_USE_CLTD && !optimize_size)
8352 if (true_regnum (operands[1]))
8353 emit_move_insn (operands[0], operands[1]);
8355 emit_move_insn (operands[3], operands[1]);
8356 operands[4] = operands[3];
8360 gcc_assert (!true_regnum (operands[1]));
8361 operands[4] = operands[1];
8365 (define_insn "divmodhi4"
8366 [(set (match_operand:HI 0 "register_operand" "=a")
8367 (div:HI (match_operand:HI 1 "register_operand" "0")
8368 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8369 (set (match_operand:HI 3 "register_operand" "=&d")
8370 (mod:HI (match_dup 1) (match_dup 2)))
8371 (clobber (reg:CC FLAGS_REG))]
8372 "TARGET_HIMODE_MATH"
8374 [(set_attr "type" "multi")
8375 (set_attr "length_immediate" "0")
8376 (set_attr "mode" "SI")])
8378 (define_insn "udivmoddi4"
8379 [(set (match_operand:DI 0 "register_operand" "=a")
8380 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8381 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8382 (set (match_operand:DI 3 "register_operand" "=&d")
8383 (umod:DI (match_dup 1) (match_dup 2)))
8384 (clobber (reg:CC FLAGS_REG))]
8386 "xor{q}\t%3, %3\;div{q}\t%2"
8387 [(set_attr "type" "multi")
8388 (set_attr "length_immediate" "0")
8389 (set_attr "mode" "DI")])
8391 (define_insn "*udivmoddi4_noext"
8392 [(set (match_operand:DI 0 "register_operand" "=a")
8393 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8394 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8395 (set (match_operand:DI 3 "register_operand" "=d")
8396 (umod:DI (match_dup 1) (match_dup 2)))
8398 (clobber (reg:CC FLAGS_REG))]
8401 [(set_attr "type" "idiv")
8402 (set_attr "mode" "DI")])
8405 [(set (match_operand:DI 0 "register_operand" "")
8406 (udiv:DI (match_operand:DI 1 "register_operand" "")
8407 (match_operand:DI 2 "nonimmediate_operand" "")))
8408 (set (match_operand:DI 3 "register_operand" "")
8409 (umod:DI (match_dup 1) (match_dup 2)))
8410 (clobber (reg:CC FLAGS_REG))]
8411 "TARGET_64BIT && reload_completed"
8412 [(set (match_dup 3) (const_int 0))
8413 (parallel [(set (match_dup 0)
8414 (udiv:DI (match_dup 1) (match_dup 2)))
8416 (umod:DI (match_dup 1) (match_dup 2)))
8418 (clobber (reg:CC FLAGS_REG))])]
8421 (define_insn "udivmodsi4"
8422 [(set (match_operand:SI 0 "register_operand" "=a")
8423 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8424 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8425 (set (match_operand:SI 3 "register_operand" "=&d")
8426 (umod:SI (match_dup 1) (match_dup 2)))
8427 (clobber (reg:CC FLAGS_REG))]
8429 "xor{l}\t%3, %3\;div{l}\t%2"
8430 [(set_attr "type" "multi")
8431 (set_attr "length_immediate" "0")
8432 (set_attr "mode" "SI")])
8434 (define_insn "*udivmodsi4_noext"
8435 [(set (match_operand:SI 0 "register_operand" "=a")
8436 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8437 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8438 (set (match_operand:SI 3 "register_operand" "=d")
8439 (umod:SI (match_dup 1) (match_dup 2)))
8441 (clobber (reg:CC FLAGS_REG))]
8444 [(set_attr "type" "idiv")
8445 (set_attr "mode" "SI")])
8448 [(set (match_operand:SI 0 "register_operand" "")
8449 (udiv:SI (match_operand:SI 1 "register_operand" "")
8450 (match_operand:SI 2 "nonimmediate_operand" "")))
8451 (set (match_operand:SI 3 "register_operand" "")
8452 (umod:SI (match_dup 1) (match_dup 2)))
8453 (clobber (reg:CC FLAGS_REG))]
8455 [(set (match_dup 3) (const_int 0))
8456 (parallel [(set (match_dup 0)
8457 (udiv:SI (match_dup 1) (match_dup 2)))
8459 (umod:SI (match_dup 1) (match_dup 2)))
8461 (clobber (reg:CC FLAGS_REG))])]
8464 (define_expand "udivmodhi4"
8465 [(set (match_dup 4) (const_int 0))
8466 (parallel [(set (match_operand:HI 0 "register_operand" "")
8467 (udiv:HI (match_operand:HI 1 "register_operand" "")
8468 (match_operand:HI 2 "nonimmediate_operand" "")))
8469 (set (match_operand:HI 3 "register_operand" "")
8470 (umod:HI (match_dup 1) (match_dup 2)))
8472 (clobber (reg:CC FLAGS_REG))])]
8473 "TARGET_HIMODE_MATH"
8474 "operands[4] = gen_reg_rtx (HImode);")
8476 (define_insn "*udivmodhi_noext"
8477 [(set (match_operand:HI 0 "register_operand" "=a")
8478 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8479 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8480 (set (match_operand:HI 3 "register_operand" "=d")
8481 (umod:HI (match_dup 1) (match_dup 2)))
8482 (use (match_operand:HI 4 "register_operand" "3"))
8483 (clobber (reg:CC FLAGS_REG))]
8486 [(set_attr "type" "idiv")
8487 (set_attr "mode" "HI")])
8489 ;; We cannot use div/idiv for double division, because it causes
8490 ;; "division by zero" on the overflow and that's not what we expect
8491 ;; from truncate. Because true (non truncating) double division is
8492 ;; never generated, we can't create this insn anyway.
8495 ; [(set (match_operand:SI 0 "register_operand" "=a")
8497 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8499 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8500 ; (set (match_operand:SI 3 "register_operand" "=d")
8502 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8503 ; (clobber (reg:CC FLAGS_REG))]
8505 ; "div{l}\t{%2, %0|%0, %2}"
8506 ; [(set_attr "type" "idiv")])
8508 ;;- Logical AND instructions
8510 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8511 ;; Note that this excludes ah.
8513 (define_insn "*testdi_1_rex64"
8514 [(set (reg FLAGS_REG)
8516 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8517 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8519 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8520 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8522 test{l}\t{%k1, %k0|%k0, %k1}
8523 test{l}\t{%k1, %k0|%k0, %k1}
8524 test{q}\t{%1, %0|%0, %1}
8525 test{q}\t{%1, %0|%0, %1}
8526 test{q}\t{%1, %0|%0, %1}"
8527 [(set_attr "type" "test")
8528 (set_attr "modrm" "0,1,0,1,1")
8529 (set_attr "mode" "SI,SI,DI,DI,DI")
8530 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8532 (define_insn "testsi_1"
8533 [(set (reg FLAGS_REG)
8535 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8536 (match_operand:SI 1 "general_operand" "i,i,ri"))
8538 "ix86_match_ccmode (insn, CCNOmode)
8539 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8540 "test{l}\t{%1, %0|%0, %1}"
8541 [(set_attr "type" "test")
8542 (set_attr "modrm" "0,1,1")
8543 (set_attr "mode" "SI")
8544 (set_attr "pent_pair" "uv,np,uv")])
8546 (define_expand "testsi_ccno_1"
8547 [(set (reg:CCNO FLAGS_REG)
8549 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8550 (match_operand:SI 1 "nonmemory_operand" ""))
8555 (define_insn "*testhi_1"
8556 [(set (reg FLAGS_REG)
8557 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8558 (match_operand:HI 1 "general_operand" "n,n,rn"))
8560 "ix86_match_ccmode (insn, CCNOmode)
8561 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8562 "test{w}\t{%1, %0|%0, %1}"
8563 [(set_attr "type" "test")
8564 (set_attr "modrm" "0,1,1")
8565 (set_attr "mode" "HI")
8566 (set_attr "pent_pair" "uv,np,uv")])
8568 (define_expand "testqi_ccz_1"
8569 [(set (reg:CCZ FLAGS_REG)
8570 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8571 (match_operand:QI 1 "nonmemory_operand" ""))
8576 (define_insn "*testqi_1_maybe_si"
8577 [(set (reg FLAGS_REG)
8580 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8581 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8583 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8584 && ix86_match_ccmode (insn,
8585 CONST_INT_P (operands[1])
8586 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8588 if (which_alternative == 3)
8590 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8591 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8592 return "test{l}\t{%1, %k0|%k0, %1}";
8594 return "test{b}\t{%1, %0|%0, %1}";
8596 [(set_attr "type" "test")
8597 (set_attr "modrm" "0,1,1,1")
8598 (set_attr "mode" "QI,QI,QI,SI")
8599 (set_attr "pent_pair" "uv,np,uv,np")])
8601 (define_insn "*testqi_1"
8602 [(set (reg FLAGS_REG)
8605 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8606 (match_operand:QI 1 "general_operand" "n,n,qn"))
8608 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8609 && ix86_match_ccmode (insn, CCNOmode)"
8610 "test{b}\t{%1, %0|%0, %1}"
8611 [(set_attr "type" "test")
8612 (set_attr "modrm" "0,1,1")
8613 (set_attr "mode" "QI")
8614 (set_attr "pent_pair" "uv,np,uv")])
8616 (define_expand "testqi_ext_ccno_0"
8617 [(set (reg:CCNO FLAGS_REG)
8621 (match_operand 0 "ext_register_operand" "")
8624 (match_operand 1 "const_int_operand" ""))
8629 (define_insn "*testqi_ext_0"
8630 [(set (reg FLAGS_REG)
8634 (match_operand 0 "ext_register_operand" "Q")
8637 (match_operand 1 "const_int_operand" "n"))
8639 "ix86_match_ccmode (insn, CCNOmode)"
8640 "test{b}\t{%1, %h0|%h0, %1}"
8641 [(set_attr "type" "test")
8642 (set_attr "mode" "QI")
8643 (set_attr "length_immediate" "1")
8644 (set_attr "pent_pair" "np")])
8646 (define_insn "*testqi_ext_1"
8647 [(set (reg FLAGS_REG)
8651 (match_operand 0 "ext_register_operand" "Q")
8655 (match_operand:QI 1 "general_operand" "Qm")))
8657 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8658 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8659 "test{b}\t{%1, %h0|%h0, %1}"
8660 [(set_attr "type" "test")
8661 (set_attr "mode" "QI")])
8663 (define_insn "*testqi_ext_1_rex64"
8664 [(set (reg FLAGS_REG)
8668 (match_operand 0 "ext_register_operand" "Q")
8672 (match_operand:QI 1 "register_operand" "Q")))
8674 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8675 "test{b}\t{%1, %h0|%h0, %1}"
8676 [(set_attr "type" "test")
8677 (set_attr "mode" "QI")])
8679 (define_insn "*testqi_ext_2"
8680 [(set (reg FLAGS_REG)
8684 (match_operand 0 "ext_register_operand" "Q")
8688 (match_operand 1 "ext_register_operand" "Q")
8692 "ix86_match_ccmode (insn, CCNOmode)"
8693 "test{b}\t{%h1, %h0|%h0, %h1}"
8694 [(set_attr "type" "test")
8695 (set_attr "mode" "QI")])
8697 ;; Combine likes to form bit extractions for some tests. Humor it.
8698 (define_insn "*testqi_ext_3"
8699 [(set (reg FLAGS_REG)
8700 (compare (zero_extract:SI
8701 (match_operand 0 "nonimmediate_operand" "rm")
8702 (match_operand:SI 1 "const_int_operand" "")
8703 (match_operand:SI 2 "const_int_operand" ""))
8705 "ix86_match_ccmode (insn, CCNOmode)
8706 && INTVAL (operands[1]) > 0
8707 && INTVAL (operands[2]) >= 0
8708 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8709 && (GET_MODE (operands[0]) == SImode
8710 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8711 || GET_MODE (operands[0]) == HImode
8712 || GET_MODE (operands[0]) == QImode)"
8715 (define_insn "*testqi_ext_3_rex64"
8716 [(set (reg FLAGS_REG)
8717 (compare (zero_extract:DI
8718 (match_operand 0 "nonimmediate_operand" "rm")
8719 (match_operand:DI 1 "const_int_operand" "")
8720 (match_operand:DI 2 "const_int_operand" ""))
8723 && ix86_match_ccmode (insn, CCNOmode)
8724 && INTVAL (operands[1]) > 0
8725 && INTVAL (operands[2]) >= 0
8726 /* Ensure that resulting mask is zero or sign extended operand. */
8727 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8728 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8729 && INTVAL (operands[1]) > 32))
8730 && (GET_MODE (operands[0]) == SImode
8731 || GET_MODE (operands[0]) == DImode
8732 || GET_MODE (operands[0]) == HImode
8733 || GET_MODE (operands[0]) == QImode)"
8737 [(set (match_operand 0 "flags_reg_operand" "")
8738 (match_operator 1 "compare_operator"
8740 (match_operand 2 "nonimmediate_operand" "")
8741 (match_operand 3 "const_int_operand" "")
8742 (match_operand 4 "const_int_operand" ""))
8744 "ix86_match_ccmode (insn, CCNOmode)"
8745 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8747 rtx val = operands[2];
8748 HOST_WIDE_INT len = INTVAL (operands[3]);
8749 HOST_WIDE_INT pos = INTVAL (operands[4]);
8751 enum machine_mode mode, submode;
8753 mode = GET_MODE (val);
8756 /* ??? Combine likes to put non-volatile mem extractions in QImode
8757 no matter the size of the test. So find a mode that works. */
8758 if (! MEM_VOLATILE_P (val))
8760 mode = smallest_mode_for_size (pos + len, MODE_INT);
8761 val = adjust_address (val, mode, 0);
8764 else if (GET_CODE (val) == SUBREG
8765 && (submode = GET_MODE (SUBREG_REG (val)),
8766 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8767 && pos + len <= GET_MODE_BITSIZE (submode))
8769 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8771 val = SUBREG_REG (val);
8773 else if (mode == HImode && pos + len <= 8)
8775 /* Small HImode tests can be converted to QImode. */
8777 val = gen_lowpart (QImode, val);
8780 if (len == HOST_BITS_PER_WIDE_INT)
8783 mask = ((HOST_WIDE_INT)1 << len) - 1;
8786 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8789 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8790 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8791 ;; this is relatively important trick.
8792 ;; Do the conversion only post-reload to avoid limiting of the register class
8795 [(set (match_operand 0 "flags_reg_operand" "")
8796 (match_operator 1 "compare_operator"
8797 [(and (match_operand 2 "register_operand" "")
8798 (match_operand 3 "const_int_operand" ""))
8801 && QI_REG_P (operands[2])
8802 && GET_MODE (operands[2]) != QImode
8803 && ((ix86_match_ccmode (insn, CCZmode)
8804 && !(INTVAL (operands[3]) & ~(255 << 8)))
8805 || (ix86_match_ccmode (insn, CCNOmode)
8806 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8809 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8812 "operands[2] = gen_lowpart (SImode, operands[2]);
8813 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8816 [(set (match_operand 0 "flags_reg_operand" "")
8817 (match_operator 1 "compare_operator"
8818 [(and (match_operand 2 "nonimmediate_operand" "")
8819 (match_operand 3 "const_int_operand" ""))
8822 && GET_MODE (operands[2]) != QImode
8823 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8824 && ((ix86_match_ccmode (insn, CCZmode)
8825 && !(INTVAL (operands[3]) & ~255))
8826 || (ix86_match_ccmode (insn, CCNOmode)
8827 && !(INTVAL (operands[3]) & ~127)))"
8829 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8831 "operands[2] = gen_lowpart (QImode, operands[2]);
8832 operands[3] = gen_lowpart (QImode, operands[3]);")
8835 ;; %%% This used to optimize known byte-wide and operations to memory,
8836 ;; and sometimes to QImode registers. If this is considered useful,
8837 ;; it should be done with splitters.
8839 (define_expand "anddi3"
8840 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8841 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8842 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8844 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8846 (define_insn "*anddi_1_rex64"
8847 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8848 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8849 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8850 (clobber (reg:CC FLAGS_REG))]
8851 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8853 switch (get_attr_type (insn))
8857 enum machine_mode mode;
8859 gcc_assert (CONST_INT_P (operands[2]));
8860 if (INTVAL (operands[2]) == 0xff)
8864 gcc_assert (INTVAL (operands[2]) == 0xffff);
8868 operands[1] = gen_lowpart (mode, operands[1]);
8870 return "movz{bq|x}\t{%1,%0|%0, %1}";
8872 return "movz{wq|x}\t{%1,%0|%0, %1}";
8876 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8877 if (get_attr_mode (insn) == MODE_SI)
8878 return "and{l}\t{%k2, %k0|%k0, %k2}";
8880 return "and{q}\t{%2, %0|%0, %2}";
8883 [(set_attr "type" "alu,alu,alu,imovx")
8884 (set_attr "length_immediate" "*,*,*,0")
8885 (set_attr "mode" "SI,DI,DI,DI")])
8887 (define_insn "*anddi_2"
8888 [(set (reg FLAGS_REG)
8889 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8890 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8892 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8893 (and:DI (match_dup 1) (match_dup 2)))]
8894 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8895 && ix86_binary_operator_ok (AND, DImode, operands)"
8897 and{l}\t{%k2, %k0|%k0, %k2}
8898 and{q}\t{%2, %0|%0, %2}
8899 and{q}\t{%2, %0|%0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "SI,DI,DI")])
8903 (define_expand "andsi3"
8904 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8905 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8906 (match_operand:SI 2 "general_operand" "")))]
8908 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8910 (define_insn "*andsi_1"
8911 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8912 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8913 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8914 (clobber (reg:CC FLAGS_REG))]
8915 "ix86_binary_operator_ok (AND, SImode, operands)"
8917 switch (get_attr_type (insn))
8921 enum machine_mode mode;
8923 gcc_assert (CONST_INT_P (operands[2]));
8924 if (INTVAL (operands[2]) == 0xff)
8928 gcc_assert (INTVAL (operands[2]) == 0xffff);
8932 operands[1] = gen_lowpart (mode, operands[1]);
8934 return "movz{bl|x}\t{%1,%0|%0, %1}";
8936 return "movz{wl|x}\t{%1,%0|%0, %1}";
8940 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8941 return "and{l}\t{%2, %0|%0, %2}";
8944 [(set_attr "type" "alu,alu,imovx")
8945 (set_attr "length_immediate" "*,*,0")
8946 (set_attr "mode" "SI")])
8949 [(set (match_operand 0 "register_operand" "")
8951 (const_int -65536)))
8952 (clobber (reg:CC FLAGS_REG))]
8953 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8954 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8955 "operands[1] = gen_lowpart (HImode, operands[0]);")
8958 [(set (match_operand 0 "ext_register_operand" "")
8961 (clobber (reg:CC FLAGS_REG))]
8962 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8963 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8964 "operands[1] = gen_lowpart (QImode, operands[0]);")
8967 [(set (match_operand 0 "ext_register_operand" "")
8969 (const_int -65281)))
8970 (clobber (reg:CC FLAGS_REG))]
8971 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8972 [(parallel [(set (zero_extract:SI (match_dup 0)
8976 (zero_extract:SI (match_dup 0)
8979 (zero_extract:SI (match_dup 0)
8982 (clobber (reg:CC FLAGS_REG))])]
8983 "operands[0] = gen_lowpart (SImode, operands[0]);")
8985 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8986 (define_insn "*andsi_1_zext"
8987 [(set (match_operand:DI 0 "register_operand" "=r")
8989 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8990 (match_operand:SI 2 "general_operand" "g"))))
8991 (clobber (reg:CC FLAGS_REG))]
8992 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8993 "and{l}\t{%2, %k0|%k0, %2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "SI")])
8997 (define_insn "*andsi_2"
8998 [(set (reg FLAGS_REG)
8999 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9000 (match_operand:SI 2 "general_operand" "g,ri"))
9002 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9003 (and:SI (match_dup 1) (match_dup 2)))]
9004 "ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_binary_operator_ok (AND, SImode, operands)"
9006 "and{l}\t{%2, %0|%0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "SI")])
9010 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9011 (define_insn "*andsi_2_zext"
9012 [(set (reg FLAGS_REG)
9013 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9014 (match_operand:SI 2 "general_operand" "g"))
9016 (set (match_operand:DI 0 "register_operand" "=r")
9017 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9018 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9019 && ix86_binary_operator_ok (AND, SImode, operands)"
9020 "and{l}\t{%2, %k0|%k0, %2}"
9021 [(set_attr "type" "alu")
9022 (set_attr "mode" "SI")])
9024 (define_expand "andhi3"
9025 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9026 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9027 (match_operand:HI 2 "general_operand" "")))]
9028 "TARGET_HIMODE_MATH"
9029 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9031 (define_insn "*andhi_1"
9032 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9033 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9034 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9035 (clobber (reg:CC FLAGS_REG))]
9036 "ix86_binary_operator_ok (AND, HImode, operands)"
9038 switch (get_attr_type (insn))
9041 gcc_assert (CONST_INT_P (operands[2]));
9042 gcc_assert (INTVAL (operands[2]) == 0xff);
9043 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9046 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9048 return "and{w}\t{%2, %0|%0, %2}";
9051 [(set_attr "type" "alu,alu,imovx")
9052 (set_attr "length_immediate" "*,*,0")
9053 (set_attr "mode" "HI,HI,SI")])
9055 (define_insn "*andhi_2"
9056 [(set (reg FLAGS_REG)
9057 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9058 (match_operand:HI 2 "general_operand" "rmn,rn"))
9060 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9061 (and:HI (match_dup 1) (match_dup 2)))]
9062 "ix86_match_ccmode (insn, CCNOmode)
9063 && ix86_binary_operator_ok (AND, HImode, operands)"
9064 "and{w}\t{%2, %0|%0, %2}"
9065 [(set_attr "type" "alu")
9066 (set_attr "mode" "HI")])
9068 (define_expand "andqi3"
9069 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9070 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9071 (match_operand:QI 2 "general_operand" "")))]
9072 "TARGET_QIMODE_MATH"
9073 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9075 ;; %%% Potential partial reg stall on alternative 2. What to do?
9076 (define_insn "*andqi_1"
9077 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9078 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9079 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9080 (clobber (reg:CC FLAGS_REG))]
9081 "ix86_binary_operator_ok (AND, QImode, operands)"
9083 and{b}\t{%2, %0|%0, %2}
9084 and{b}\t{%2, %0|%0, %2}
9085 and{l}\t{%k2, %k0|%k0, %k2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "mode" "QI,QI,SI")])
9089 (define_insn "*andqi_1_slp"
9090 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9091 (and:QI (match_dup 0)
9092 (match_operand:QI 1 "general_operand" "qn,qmn")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9095 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9096 "and{b}\t{%1, %0|%0, %1}"
9097 [(set_attr "type" "alu1")
9098 (set_attr "mode" "QI")])
9100 (define_insn "*andqi_2_maybe_si"
9101 [(set (reg FLAGS_REG)
9103 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9104 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9106 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9107 (and:QI (match_dup 1) (match_dup 2)))]
9108 "ix86_binary_operator_ok (AND, QImode, operands)
9109 && ix86_match_ccmode (insn,
9110 CONST_INT_P (operands[2])
9111 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9113 if (which_alternative == 2)
9115 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9116 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9117 return "and{l}\t{%2, %k0|%k0, %2}";
9119 return "and{b}\t{%2, %0|%0, %2}";
9121 [(set_attr "type" "alu")
9122 (set_attr "mode" "QI,QI,SI")])
9124 (define_insn "*andqi_2"
9125 [(set (reg FLAGS_REG)
9127 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9128 (match_operand:QI 2 "general_operand" "qmn,qn"))
9130 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9131 (and:QI (match_dup 1) (match_dup 2)))]
9132 "ix86_match_ccmode (insn, CCNOmode)
9133 && ix86_binary_operator_ok (AND, QImode, operands)"
9134 "and{b}\t{%2, %0|%0, %2}"
9135 [(set_attr "type" "alu")
9136 (set_attr "mode" "QI")])
9138 (define_insn "*andqi_2_slp"
9139 [(set (reg FLAGS_REG)
9141 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9142 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9144 (set (strict_low_part (match_dup 0))
9145 (and:QI (match_dup 0) (match_dup 1)))]
9146 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9147 && ix86_match_ccmode (insn, CCNOmode)
9148 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9149 "and{b}\t{%1, %0|%0, %1}"
9150 [(set_attr "type" "alu1")
9151 (set_attr "mode" "QI")])
9153 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9154 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9155 ;; for a QImode operand, which of course failed.
9157 (define_insn "andqi_ext_0"
9158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9163 (match_operand 1 "ext_register_operand" "0")
9166 (match_operand 2 "const_int_operand" "n")))
9167 (clobber (reg:CC FLAGS_REG))]
9169 "and{b}\t{%2, %h0|%h0, %2}"
9170 [(set_attr "type" "alu")
9171 (set_attr "length_immediate" "1")
9172 (set_attr "mode" "QI")])
9174 ;; Generated by peephole translating test to and. This shows up
9175 ;; often in fp comparisons.
9177 (define_insn "*andqi_ext_0_cc"
9178 [(set (reg FLAGS_REG)
9182 (match_operand 1 "ext_register_operand" "0")
9185 (match_operand 2 "const_int_operand" "n"))
9187 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9196 "ix86_match_ccmode (insn, CCNOmode)"
9197 "and{b}\t{%2, %h0|%h0, %2}"
9198 [(set_attr "type" "alu")
9199 (set_attr "length_immediate" "1")
9200 (set_attr "mode" "QI")])
9202 (define_insn "*andqi_ext_1"
9203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9208 (match_operand 1 "ext_register_operand" "0")
9212 (match_operand:QI 2 "general_operand" "Qm"))))
9213 (clobber (reg:CC FLAGS_REG))]
9215 "and{b}\t{%2, %h0|%h0, %2}"
9216 [(set_attr "type" "alu")
9217 (set_attr "length_immediate" "0")
9218 (set_attr "mode" "QI")])
9220 (define_insn "*andqi_ext_1_rex64"
9221 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9226 (match_operand 1 "ext_register_operand" "0")
9230 (match_operand 2 "ext_register_operand" "Q"))))
9231 (clobber (reg:CC FLAGS_REG))]
9233 "and{b}\t{%2, %h0|%h0, %2}"
9234 [(set_attr "type" "alu")
9235 (set_attr "length_immediate" "0")
9236 (set_attr "mode" "QI")])
9238 (define_insn "*andqi_ext_2"
9239 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9244 (match_operand 1 "ext_register_operand" "%0")
9248 (match_operand 2 "ext_register_operand" "Q")
9251 (clobber (reg:CC FLAGS_REG))]
9253 "and{b}\t{%h2, %h0|%h0, %h2}"
9254 [(set_attr "type" "alu")
9255 (set_attr "length_immediate" "0")
9256 (set_attr "mode" "QI")])
9258 ;; Convert wide AND instructions with immediate operand to shorter QImode
9259 ;; equivalents when possible.
9260 ;; Don't do the splitting with memory operands, since it introduces risk
9261 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9262 ;; for size, but that can (should?) be handled by generic code instead.
9264 [(set (match_operand 0 "register_operand" "")
9265 (and (match_operand 1 "register_operand" "")
9266 (match_operand 2 "const_int_operand" "")))
9267 (clobber (reg:CC FLAGS_REG))]
9269 && QI_REG_P (operands[0])
9270 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9271 && !(~INTVAL (operands[2]) & ~(255 << 8))
9272 && GET_MODE (operands[0]) != QImode"
9273 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9274 (and:SI (zero_extract:SI (match_dup 1)
9275 (const_int 8) (const_int 8))
9277 (clobber (reg:CC FLAGS_REG))])]
9278 "operands[0] = gen_lowpart (SImode, operands[0]);
9279 operands[1] = gen_lowpart (SImode, operands[1]);
9280 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9282 ;; Since AND can be encoded with sign extended immediate, this is only
9283 ;; profitable when 7th bit is not set.
9285 [(set (match_operand 0 "register_operand" "")
9286 (and (match_operand 1 "general_operand" "")
9287 (match_operand 2 "const_int_operand" "")))
9288 (clobber (reg:CC FLAGS_REG))]
9290 && ANY_QI_REG_P (operands[0])
9291 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9292 && !(~INTVAL (operands[2]) & ~255)
9293 && !(INTVAL (operands[2]) & 128)
9294 && GET_MODE (operands[0]) != QImode"
9295 [(parallel [(set (strict_low_part (match_dup 0))
9296 (and:QI (match_dup 1)
9298 (clobber (reg:CC FLAGS_REG))])]
9299 "operands[0] = gen_lowpart (QImode, operands[0]);
9300 operands[1] = gen_lowpart (QImode, operands[1]);
9301 operands[2] = gen_lowpart (QImode, operands[2]);")
9303 ;; Logical inclusive OR instructions
9305 ;; %%% This used to optimize known byte-wide and operations to memory.
9306 ;; If this is considered useful, it should be done with splitters.
9308 (define_expand "iordi3"
9309 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9310 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9311 (match_operand:DI 2 "x86_64_general_operand" "")))]
9313 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9315 (define_insn "*iordi_1_rex64"
9316 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9317 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9318 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9319 (clobber (reg:CC FLAGS_REG))]
9321 && ix86_binary_operator_ok (IOR, DImode, operands)"
9322 "or{q}\t{%2, %0|%0, %2}"
9323 [(set_attr "type" "alu")
9324 (set_attr "mode" "DI")])
9326 (define_insn "*iordi_2_rex64"
9327 [(set (reg FLAGS_REG)
9328 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9329 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9331 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9332 (ior:DI (match_dup 1) (match_dup 2)))]
9334 && ix86_match_ccmode (insn, CCNOmode)
9335 && ix86_binary_operator_ok (IOR, DImode, operands)"
9336 "or{q}\t{%2, %0|%0, %2}"
9337 [(set_attr "type" "alu")
9338 (set_attr "mode" "DI")])
9340 (define_insn "*iordi_3_rex64"
9341 [(set (reg FLAGS_REG)
9342 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9343 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9345 (clobber (match_scratch:DI 0 "=r"))]
9347 && ix86_match_ccmode (insn, CCNOmode)
9348 && ix86_binary_operator_ok (IOR, DImode, operands)"
9349 "or{q}\t{%2, %0|%0, %2}"
9350 [(set_attr "type" "alu")
9351 (set_attr "mode" "DI")])
9354 (define_expand "iorsi3"
9355 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9356 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9357 (match_operand:SI 2 "general_operand" "")))]
9359 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9361 (define_insn "*iorsi_1"
9362 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9363 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9364 (match_operand:SI 2 "general_operand" "ri,g")))
9365 (clobber (reg:CC FLAGS_REG))]
9366 "ix86_binary_operator_ok (IOR, SImode, operands)"
9367 "or{l}\t{%2, %0|%0, %2}"
9368 [(set_attr "type" "alu")
9369 (set_attr "mode" "SI")])
9371 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9372 (define_insn "*iorsi_1_zext"
9373 [(set (match_operand:DI 0 "register_operand" "=r")
9375 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9376 (match_operand:SI 2 "general_operand" "g"))))
9377 (clobber (reg:CC FLAGS_REG))]
9378 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9379 "or{l}\t{%2, %k0|%k0, %2}"
9380 [(set_attr "type" "alu")
9381 (set_attr "mode" "SI")])
9383 (define_insn "*iorsi_1_zext_imm"
9384 [(set (match_operand:DI 0 "register_operand" "=r")
9385 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9386 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9387 (clobber (reg:CC FLAGS_REG))]
9389 "or{l}\t{%2, %k0|%k0, %2}"
9390 [(set_attr "type" "alu")
9391 (set_attr "mode" "SI")])
9393 (define_insn "*iorsi_2"
9394 [(set (reg FLAGS_REG)
9395 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9396 (match_operand:SI 2 "general_operand" "g,ri"))
9398 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9399 (ior:SI (match_dup 1) (match_dup 2)))]
9400 "ix86_match_ccmode (insn, CCNOmode)
9401 && ix86_binary_operator_ok (IOR, SImode, operands)"
9402 "or{l}\t{%2, %0|%0, %2}"
9403 [(set_attr "type" "alu")
9404 (set_attr "mode" "SI")])
9406 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9407 ;; ??? Special case for immediate operand is missing - it is tricky.
9408 (define_insn "*iorsi_2_zext"
9409 [(set (reg FLAGS_REG)
9410 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9411 (match_operand:SI 2 "general_operand" "g"))
9413 (set (match_operand:DI 0 "register_operand" "=r")
9414 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9415 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9416 && ix86_binary_operator_ok (IOR, SImode, operands)"
9417 "or{l}\t{%2, %k0|%k0, %2}"
9418 [(set_attr "type" "alu")
9419 (set_attr "mode" "SI")])
9421 (define_insn "*iorsi_2_zext_imm"
9422 [(set (reg FLAGS_REG)
9423 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9424 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9426 (set (match_operand:DI 0 "register_operand" "=r")
9427 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9428 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9429 && ix86_binary_operator_ok (IOR, SImode, operands)"
9430 "or{l}\t{%2, %k0|%k0, %2}"
9431 [(set_attr "type" "alu")
9432 (set_attr "mode" "SI")])
9434 (define_insn "*iorsi_3"
9435 [(set (reg FLAGS_REG)
9436 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9437 (match_operand:SI 2 "general_operand" "g"))
9439 (clobber (match_scratch:SI 0 "=r"))]
9440 "ix86_match_ccmode (insn, CCNOmode)
9441 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9442 "or{l}\t{%2, %0|%0, %2}"
9443 [(set_attr "type" "alu")
9444 (set_attr "mode" "SI")])
9446 (define_expand "iorhi3"
9447 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9448 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9449 (match_operand:HI 2 "general_operand" "")))]
9450 "TARGET_HIMODE_MATH"
9451 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9453 (define_insn "*iorhi_1"
9454 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9455 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9456 (match_operand:HI 2 "general_operand" "rmn,rn")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "ix86_binary_operator_ok (IOR, HImode, operands)"
9459 "or{w}\t{%2, %0|%0, %2}"
9460 [(set_attr "type" "alu")
9461 (set_attr "mode" "HI")])
9463 (define_insn "*iorhi_2"
9464 [(set (reg FLAGS_REG)
9465 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9466 (match_operand:HI 2 "general_operand" "rmn,rn"))
9468 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9469 (ior:HI (match_dup 1) (match_dup 2)))]
9470 "ix86_match_ccmode (insn, CCNOmode)
9471 && ix86_binary_operator_ok (IOR, HImode, operands)"
9472 "or{w}\t{%2, %0|%0, %2}"
9473 [(set_attr "type" "alu")
9474 (set_attr "mode" "HI")])
9476 (define_insn "*iorhi_3"
9477 [(set (reg FLAGS_REG)
9478 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9479 (match_operand:HI 2 "general_operand" "rmn"))
9481 (clobber (match_scratch:HI 0 "=r"))]
9482 "ix86_match_ccmode (insn, CCNOmode)
9483 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9484 "or{w}\t{%2, %0|%0, %2}"
9485 [(set_attr "type" "alu")
9486 (set_attr "mode" "HI")])
9488 (define_expand "iorqi3"
9489 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9490 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9491 (match_operand:QI 2 "general_operand" "")))]
9492 "TARGET_QIMODE_MATH"
9493 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9495 ;; %%% Potential partial reg stall on alternative 2. What to do?
9496 (define_insn "*iorqi_1"
9497 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9498 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9499 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9500 (clobber (reg:CC FLAGS_REG))]
9501 "ix86_binary_operator_ok (IOR, QImode, operands)"
9503 or{b}\t{%2, %0|%0, %2}
9504 or{b}\t{%2, %0|%0, %2}
9505 or{l}\t{%k2, %k0|%k0, %k2}"
9506 [(set_attr "type" "alu")
9507 (set_attr "mode" "QI,QI,SI")])
9509 (define_insn "*iorqi_1_slp"
9510 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9511 (ior:QI (match_dup 0)
9512 (match_operand:QI 1 "general_operand" "qmn,qn")))
9513 (clobber (reg:CC FLAGS_REG))]
9514 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9515 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9516 "or{b}\t{%1, %0|%0, %1}"
9517 [(set_attr "type" "alu1")
9518 (set_attr "mode" "QI")])
9520 (define_insn "*iorqi_2"
9521 [(set (reg FLAGS_REG)
9522 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9523 (match_operand:QI 2 "general_operand" "qmn,qn"))
9525 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9526 (ior:QI (match_dup 1) (match_dup 2)))]
9527 "ix86_match_ccmode (insn, CCNOmode)
9528 && ix86_binary_operator_ok (IOR, QImode, operands)"
9529 "or{b}\t{%2, %0|%0, %2}"
9530 [(set_attr "type" "alu")
9531 (set_attr "mode" "QI")])
9533 (define_insn "*iorqi_2_slp"
9534 [(set (reg FLAGS_REG)
9535 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9536 (match_operand:QI 1 "general_operand" "qmn,qn"))
9538 (set (strict_low_part (match_dup 0))
9539 (ior:QI (match_dup 0) (match_dup 1)))]
9540 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9541 && ix86_match_ccmode (insn, CCNOmode)
9542 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9543 "or{b}\t{%1, %0|%0, %1}"
9544 [(set_attr "type" "alu1")
9545 (set_attr "mode" "QI")])
9547 (define_insn "*iorqi_3"
9548 [(set (reg FLAGS_REG)
9549 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9550 (match_operand:QI 2 "general_operand" "qmn"))
9552 (clobber (match_scratch:QI 0 "=q"))]
9553 "ix86_match_ccmode (insn, CCNOmode)
9554 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9555 "or{b}\t{%2, %0|%0, %2}"
9556 [(set_attr "type" "alu")
9557 (set_attr "mode" "QI")])
9559 (define_insn "iorqi_ext_0"
9560 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9565 (match_operand 1 "ext_register_operand" "0")
9568 (match_operand 2 "const_int_operand" "n")))
9569 (clobber (reg:CC FLAGS_REG))]
9570 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9571 "or{b}\t{%2, %h0|%h0, %2}"
9572 [(set_attr "type" "alu")
9573 (set_attr "length_immediate" "1")
9574 (set_attr "mode" "QI")])
9576 (define_insn "*iorqi_ext_1"
9577 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9582 (match_operand 1 "ext_register_operand" "0")
9586 (match_operand:QI 2 "general_operand" "Qm"))))
9587 (clobber (reg:CC FLAGS_REG))]
9589 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9590 "or{b}\t{%2, %h0|%h0, %2}"
9591 [(set_attr "type" "alu")
9592 (set_attr "length_immediate" "0")
9593 (set_attr "mode" "QI")])
9595 (define_insn "*iorqi_ext_1_rex64"
9596 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9601 (match_operand 1 "ext_register_operand" "0")
9605 (match_operand 2 "ext_register_operand" "Q"))))
9606 (clobber (reg:CC FLAGS_REG))]
9608 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9609 "or{b}\t{%2, %h0|%h0, %2}"
9610 [(set_attr "type" "alu")
9611 (set_attr "length_immediate" "0")
9612 (set_attr "mode" "QI")])
9614 (define_insn "*iorqi_ext_2"
9615 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9619 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9622 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9625 (clobber (reg:CC FLAGS_REG))]
9626 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9627 "ior{b}\t{%h2, %h0|%h0, %h2}"
9628 [(set_attr "type" "alu")
9629 (set_attr "length_immediate" "0")
9630 (set_attr "mode" "QI")])
9633 [(set (match_operand 0 "register_operand" "")
9634 (ior (match_operand 1 "register_operand" "")
9635 (match_operand 2 "const_int_operand" "")))
9636 (clobber (reg:CC FLAGS_REG))]
9638 && QI_REG_P (operands[0])
9639 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9640 && !(INTVAL (operands[2]) & ~(255 << 8))
9641 && GET_MODE (operands[0]) != QImode"
9642 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9643 (ior:SI (zero_extract:SI (match_dup 1)
9644 (const_int 8) (const_int 8))
9646 (clobber (reg:CC FLAGS_REG))])]
9647 "operands[0] = gen_lowpart (SImode, operands[0]);
9648 operands[1] = gen_lowpart (SImode, operands[1]);
9649 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9651 ;; Since OR can be encoded with sign extended immediate, this is only
9652 ;; profitable when 7th bit is set.
9654 [(set (match_operand 0 "register_operand" "")
9655 (ior (match_operand 1 "general_operand" "")
9656 (match_operand 2 "const_int_operand" "")))
9657 (clobber (reg:CC FLAGS_REG))]
9659 && ANY_QI_REG_P (operands[0])
9660 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9661 && !(INTVAL (operands[2]) & ~255)
9662 && (INTVAL (operands[2]) & 128)
9663 && GET_MODE (operands[0]) != QImode"
9664 [(parallel [(set (strict_low_part (match_dup 0))
9665 (ior:QI (match_dup 1)
9667 (clobber (reg:CC FLAGS_REG))])]
9668 "operands[0] = gen_lowpart (QImode, operands[0]);
9669 operands[1] = gen_lowpart (QImode, operands[1]);
9670 operands[2] = gen_lowpart (QImode, operands[2]);")
9672 ;; Logical XOR instructions
9674 ;; %%% This used to optimize known byte-wide and operations to memory.
9675 ;; If this is considered useful, it should be done with splitters.
9677 (define_expand "xordi3"
9678 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9679 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9680 (match_operand:DI 2 "x86_64_general_operand" "")))]
9682 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9684 (define_insn "*xordi_1_rex64"
9685 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9686 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9687 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9688 (clobber (reg:CC FLAGS_REG))]
9690 && ix86_binary_operator_ok (XOR, DImode, operands)"
9691 "xor{q}\t{%2, %0|%0, %2}"
9692 [(set_attr "type" "alu")
9693 (set_attr "mode" "DI")])
9695 (define_insn "*xordi_2_rex64"
9696 [(set (reg FLAGS_REG)
9697 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9698 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9700 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9701 (xor:DI (match_dup 1) (match_dup 2)))]
9703 && ix86_match_ccmode (insn, CCNOmode)
9704 && ix86_binary_operator_ok (XOR, DImode, operands)"
9705 "xor{q}\t{%2, %0|%0, %2}"
9706 [(set_attr "type" "alu")
9707 (set_attr "mode" "DI")])
9709 (define_insn "*xordi_3_rex64"
9710 [(set (reg FLAGS_REG)
9711 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9712 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9714 (clobber (match_scratch:DI 0 "=r"))]
9716 && ix86_match_ccmode (insn, CCNOmode)
9717 && ix86_binary_operator_ok (XOR, DImode, operands)"
9718 "xor{q}\t{%2, %0|%0, %2}"
9719 [(set_attr "type" "alu")
9720 (set_attr "mode" "DI")])
9722 (define_expand "xorsi3"
9723 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9724 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9725 (match_operand:SI 2 "general_operand" "")))]
9727 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9729 (define_insn "*xorsi_1"
9730 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9731 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9732 (match_operand:SI 2 "general_operand" "ri,rm")))
9733 (clobber (reg:CC FLAGS_REG))]
9734 "ix86_binary_operator_ok (XOR, SImode, operands)"
9735 "xor{l}\t{%2, %0|%0, %2}"
9736 [(set_attr "type" "alu")
9737 (set_attr "mode" "SI")])
9739 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9740 ;; Add speccase for immediates
9741 (define_insn "*xorsi_1_zext"
9742 [(set (match_operand:DI 0 "register_operand" "=r")
9744 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9745 (match_operand:SI 2 "general_operand" "g"))))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9748 "xor{l}\t{%2, %k0|%k0, %2}"
9749 [(set_attr "type" "alu")
9750 (set_attr "mode" "SI")])
9752 (define_insn "*xorsi_1_zext_imm"
9753 [(set (match_operand:DI 0 "register_operand" "=r")
9754 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9755 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9756 (clobber (reg:CC FLAGS_REG))]
9757 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9758 "xor{l}\t{%2, %k0|%k0, %2}"
9759 [(set_attr "type" "alu")
9760 (set_attr "mode" "SI")])
9762 (define_insn "*xorsi_2"
9763 [(set (reg FLAGS_REG)
9764 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9765 (match_operand:SI 2 "general_operand" "g,ri"))
9767 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9768 (xor:SI (match_dup 1) (match_dup 2)))]
9769 "ix86_match_ccmode (insn, CCNOmode)
9770 && ix86_binary_operator_ok (XOR, SImode, operands)"
9771 "xor{l}\t{%2, %0|%0, %2}"
9772 [(set_attr "type" "alu")
9773 (set_attr "mode" "SI")])
9775 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9776 ;; ??? Special case for immediate operand is missing - it is tricky.
9777 (define_insn "*xorsi_2_zext"
9778 [(set (reg FLAGS_REG)
9779 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9780 (match_operand:SI 2 "general_operand" "g"))
9782 (set (match_operand:DI 0 "register_operand" "=r")
9783 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9784 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9785 && ix86_binary_operator_ok (XOR, SImode, operands)"
9786 "xor{l}\t{%2, %k0|%k0, %2}"
9787 [(set_attr "type" "alu")
9788 (set_attr "mode" "SI")])
9790 (define_insn "*xorsi_2_zext_imm"
9791 [(set (reg FLAGS_REG)
9792 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9793 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9795 (set (match_operand:DI 0 "register_operand" "=r")
9796 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9797 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9798 && ix86_binary_operator_ok (XOR, SImode, operands)"
9799 "xor{l}\t{%2, %k0|%k0, %2}"
9800 [(set_attr "type" "alu")
9801 (set_attr "mode" "SI")])
9803 (define_insn "*xorsi_3"
9804 [(set (reg FLAGS_REG)
9805 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9806 (match_operand:SI 2 "general_operand" "g"))
9808 (clobber (match_scratch:SI 0 "=r"))]
9809 "ix86_match_ccmode (insn, CCNOmode)
9810 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9811 "xor{l}\t{%2, %0|%0, %2}"
9812 [(set_attr "type" "alu")
9813 (set_attr "mode" "SI")])
9815 (define_expand "xorhi3"
9816 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9817 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9818 (match_operand:HI 2 "general_operand" "")))]
9819 "TARGET_HIMODE_MATH"
9820 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9822 (define_insn "*xorhi_1"
9823 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9824 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9825 (match_operand:HI 2 "general_operand" "rmn,rn")))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "ix86_binary_operator_ok (XOR, HImode, operands)"
9828 "xor{w}\t{%2, %0|%0, %2}"
9829 [(set_attr "type" "alu")
9830 (set_attr "mode" "HI")])
9832 (define_insn "*xorhi_2"
9833 [(set (reg FLAGS_REG)
9834 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9835 (match_operand:HI 2 "general_operand" "rmn,rn"))
9837 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9838 (xor:HI (match_dup 1) (match_dup 2)))]
9839 "ix86_match_ccmode (insn, CCNOmode)
9840 && ix86_binary_operator_ok (XOR, HImode, operands)"
9841 "xor{w}\t{%2, %0|%0, %2}"
9842 [(set_attr "type" "alu")
9843 (set_attr "mode" "HI")])
9845 (define_insn "*xorhi_3"
9846 [(set (reg FLAGS_REG)
9847 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9848 (match_operand:HI 2 "general_operand" "rmn"))
9850 (clobber (match_scratch:HI 0 "=r"))]
9851 "ix86_match_ccmode (insn, CCNOmode)
9852 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9853 "xor{w}\t{%2, %0|%0, %2}"
9854 [(set_attr "type" "alu")
9855 (set_attr "mode" "HI")])
9857 (define_expand "xorqi3"
9858 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9859 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9860 (match_operand:QI 2 "general_operand" "")))]
9861 "TARGET_QIMODE_MATH"
9862 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9864 ;; %%% Potential partial reg stall on alternative 2. What to do?
9865 (define_insn "*xorqi_1"
9866 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9867 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9868 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9869 (clobber (reg:CC FLAGS_REG))]
9870 "ix86_binary_operator_ok (XOR, QImode, operands)"
9872 xor{b}\t{%2, %0|%0, %2}
9873 xor{b}\t{%2, %0|%0, %2}
9874 xor{l}\t{%k2, %k0|%k0, %k2}"
9875 [(set_attr "type" "alu")
9876 (set_attr "mode" "QI,QI,SI")])
9878 (define_insn "*xorqi_1_slp"
9879 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9880 (xor:QI (match_dup 0)
9881 (match_operand:QI 1 "general_operand" "qn,qmn")))
9882 (clobber (reg:CC FLAGS_REG))]
9883 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9884 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9885 "xor{b}\t{%1, %0|%0, %1}"
9886 [(set_attr "type" "alu1")
9887 (set_attr "mode" "QI")])
9889 (define_insn "xorqi_ext_0"
9890 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9895 (match_operand 1 "ext_register_operand" "0")
9898 (match_operand 2 "const_int_operand" "n")))
9899 (clobber (reg:CC FLAGS_REG))]
9900 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9901 "xor{b}\t{%2, %h0|%h0, %2}"
9902 [(set_attr "type" "alu")
9903 (set_attr "length_immediate" "1")
9904 (set_attr "mode" "QI")])
9906 (define_insn "*xorqi_ext_1"
9907 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9912 (match_operand 1 "ext_register_operand" "0")
9916 (match_operand:QI 2 "general_operand" "Qm"))))
9917 (clobber (reg:CC FLAGS_REG))]
9919 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9920 "xor{b}\t{%2, %h0|%h0, %2}"
9921 [(set_attr "type" "alu")
9922 (set_attr "length_immediate" "0")
9923 (set_attr "mode" "QI")])
9925 (define_insn "*xorqi_ext_1_rex64"
9926 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9931 (match_operand 1 "ext_register_operand" "0")
9935 (match_operand 2 "ext_register_operand" "Q"))))
9936 (clobber (reg:CC FLAGS_REG))]
9938 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9939 "xor{b}\t{%2, %h0|%h0, %2}"
9940 [(set_attr "type" "alu")
9941 (set_attr "length_immediate" "0")
9942 (set_attr "mode" "QI")])
9944 (define_insn "*xorqi_ext_2"
9945 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9949 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9952 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9955 (clobber (reg:CC FLAGS_REG))]
9956 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9957 "xor{b}\t{%h2, %h0|%h0, %h2}"
9958 [(set_attr "type" "alu")
9959 (set_attr "length_immediate" "0")
9960 (set_attr "mode" "QI")])
9962 (define_insn "*xorqi_cc_1"
9963 [(set (reg FLAGS_REG)
9965 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9966 (match_operand:QI 2 "general_operand" "qmn,qn"))
9968 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9969 (xor:QI (match_dup 1) (match_dup 2)))]
9970 "ix86_match_ccmode (insn, CCNOmode)
9971 && ix86_binary_operator_ok (XOR, QImode, operands)"
9972 "xor{b}\t{%2, %0|%0, %2}"
9973 [(set_attr "type" "alu")
9974 (set_attr "mode" "QI")])
9976 (define_insn "*xorqi_2_slp"
9977 [(set (reg FLAGS_REG)
9978 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9979 (match_operand:QI 1 "general_operand" "qmn,qn"))
9981 (set (strict_low_part (match_dup 0))
9982 (xor:QI (match_dup 0) (match_dup 1)))]
9983 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9984 && ix86_match_ccmode (insn, CCNOmode)
9985 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9986 "xor{b}\t{%1, %0|%0, %1}"
9987 [(set_attr "type" "alu1")
9988 (set_attr "mode" "QI")])
9990 (define_insn "*xorqi_cc_2"
9991 [(set (reg FLAGS_REG)
9993 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9994 (match_operand:QI 2 "general_operand" "qmn"))
9996 (clobber (match_scratch:QI 0 "=q"))]
9997 "ix86_match_ccmode (insn, CCNOmode)
9998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9999 "xor{b}\t{%2, %0|%0, %2}"
10000 [(set_attr "type" "alu")
10001 (set_attr "mode" "QI")])
10003 (define_insn "*xorqi_cc_ext_1"
10004 [(set (reg FLAGS_REG)
10008 (match_operand 1 "ext_register_operand" "0")
10011 (match_operand:QI 2 "general_operand" "qmn"))
10013 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10017 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10019 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10020 "xor{b}\t{%2, %h0|%h0, %2}"
10021 [(set_attr "type" "alu")
10022 (set_attr "mode" "QI")])
10024 (define_insn "*xorqi_cc_ext_1_rex64"
10025 [(set (reg FLAGS_REG)
10029 (match_operand 1 "ext_register_operand" "0")
10032 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10034 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10038 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10040 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10041 "xor{b}\t{%2, %h0|%h0, %2}"
10042 [(set_attr "type" "alu")
10043 (set_attr "mode" "QI")])
10045 (define_expand "xorqi_cc_ext_1"
10047 (set (reg:CCNO FLAGS_REG)
10051 (match_operand 1 "ext_register_operand" "")
10054 (match_operand:QI 2 "general_operand" ""))
10056 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10060 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10066 [(set (match_operand 0 "register_operand" "")
10067 (xor (match_operand 1 "register_operand" "")
10068 (match_operand 2 "const_int_operand" "")))
10069 (clobber (reg:CC FLAGS_REG))]
10071 && QI_REG_P (operands[0])
10072 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10073 && !(INTVAL (operands[2]) & ~(255 << 8))
10074 && GET_MODE (operands[0]) != QImode"
10075 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10076 (xor:SI (zero_extract:SI (match_dup 1)
10077 (const_int 8) (const_int 8))
10079 (clobber (reg:CC FLAGS_REG))])]
10080 "operands[0] = gen_lowpart (SImode, operands[0]);
10081 operands[1] = gen_lowpart (SImode, operands[1]);
10082 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10084 ;; Since XOR can be encoded with sign extended immediate, this is only
10085 ;; profitable when 7th bit is set.
10087 [(set (match_operand 0 "register_operand" "")
10088 (xor (match_operand 1 "general_operand" "")
10089 (match_operand 2 "const_int_operand" "")))
10090 (clobber (reg:CC FLAGS_REG))]
10092 && ANY_QI_REG_P (operands[0])
10093 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10094 && !(INTVAL (operands[2]) & ~255)
10095 && (INTVAL (operands[2]) & 128)
10096 && GET_MODE (operands[0]) != QImode"
10097 [(parallel [(set (strict_low_part (match_dup 0))
10098 (xor:QI (match_dup 1)
10100 (clobber (reg:CC FLAGS_REG))])]
10101 "operands[0] = gen_lowpart (QImode, operands[0]);
10102 operands[1] = gen_lowpart (QImode, operands[1]);
10103 operands[2] = gen_lowpart (QImode, operands[2]);")
10105 ;; Negation instructions
10107 (define_expand "negti2"
10108 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10109 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10111 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10113 (define_insn "*negti2_1"
10114 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10115 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10116 (clobber (reg:CC FLAGS_REG))]
10118 && ix86_unary_operator_ok (NEG, TImode, operands)"
10122 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10123 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "TARGET_64BIT && reload_completed"
10127 [(set (reg:CCZ FLAGS_REG)
10128 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10129 (set (match_dup 0) (neg:DI (match_dup 1)))])
10131 [(set (match_dup 2)
10132 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10135 (clobber (reg:CC FLAGS_REG))])
10137 [(set (match_dup 2)
10138 (neg:DI (match_dup 2)))
10139 (clobber (reg:CC FLAGS_REG))])]
10140 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10142 (define_expand "negdi2"
10143 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10144 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10146 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10148 (define_insn "*negdi2_1"
10149 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10150 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10151 (clobber (reg:CC FLAGS_REG))]
10153 && ix86_unary_operator_ok (NEG, DImode, operands)"
10157 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10158 (neg:DI (match_operand:DI 1 "general_operand" "")))
10159 (clobber (reg:CC FLAGS_REG))]
10160 "!TARGET_64BIT && reload_completed"
10162 [(set (reg:CCZ FLAGS_REG)
10163 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10164 (set (match_dup 0) (neg:SI (match_dup 1)))])
10166 [(set (match_dup 2)
10167 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10170 (clobber (reg:CC FLAGS_REG))])
10172 [(set (match_dup 2)
10173 (neg:SI (match_dup 2)))
10174 (clobber (reg:CC FLAGS_REG))])]
10175 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10177 (define_insn "*negdi2_1_rex64"
10178 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10179 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10183 [(set_attr "type" "negnot")
10184 (set_attr "mode" "DI")])
10186 ;; The problem with neg is that it does not perform (compare x 0),
10187 ;; it really performs (compare 0 x), which leaves us with the zero
10188 ;; flag being the only useful item.
10190 (define_insn "*negdi2_cmpz_rex64"
10191 [(set (reg:CCZ FLAGS_REG)
10192 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10194 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10195 (neg:DI (match_dup 1)))]
10196 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10198 [(set_attr "type" "negnot")
10199 (set_attr "mode" "DI")])
10202 (define_expand "negsi2"
10203 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10204 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10206 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10208 (define_insn "*negsi2_1"
10209 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10210 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10211 (clobber (reg:CC FLAGS_REG))]
10212 "ix86_unary_operator_ok (NEG, SImode, operands)"
10214 [(set_attr "type" "negnot")
10215 (set_attr "mode" "SI")])
10217 ;; Combine is quite creative about this pattern.
10218 (define_insn "*negsi2_1_zext"
10219 [(set (match_operand:DI 0 "register_operand" "=r")
10220 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10223 (clobber (reg:CC FLAGS_REG))]
10224 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10226 [(set_attr "type" "negnot")
10227 (set_attr "mode" "SI")])
10229 ;; The problem with neg is that it does not perform (compare x 0),
10230 ;; it really performs (compare 0 x), which leaves us with the zero
10231 ;; flag being the only useful item.
10233 (define_insn "*negsi2_cmpz"
10234 [(set (reg:CCZ FLAGS_REG)
10235 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10237 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10238 (neg:SI (match_dup 1)))]
10239 "ix86_unary_operator_ok (NEG, SImode, operands)"
10241 [(set_attr "type" "negnot")
10242 (set_attr "mode" "SI")])
10244 (define_insn "*negsi2_cmpz_zext"
10245 [(set (reg:CCZ FLAGS_REG)
10246 (compare:CCZ (lshiftrt:DI
10248 (match_operand:DI 1 "register_operand" "0")
10252 (set (match_operand:DI 0 "register_operand" "=r")
10253 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10256 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10258 [(set_attr "type" "negnot")
10259 (set_attr "mode" "SI")])
10261 (define_expand "neghi2"
10262 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10263 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10264 "TARGET_HIMODE_MATH"
10265 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10267 (define_insn "*neghi2_1"
10268 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10269 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10270 (clobber (reg:CC FLAGS_REG))]
10271 "ix86_unary_operator_ok (NEG, HImode, operands)"
10273 [(set_attr "type" "negnot")
10274 (set_attr "mode" "HI")])
10276 (define_insn "*neghi2_cmpz"
10277 [(set (reg:CCZ FLAGS_REG)
10278 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10280 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10281 (neg:HI (match_dup 1)))]
10282 "ix86_unary_operator_ok (NEG, HImode, operands)"
10284 [(set_attr "type" "negnot")
10285 (set_attr "mode" "HI")])
10287 (define_expand "negqi2"
10288 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10289 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10290 "TARGET_QIMODE_MATH"
10291 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10293 (define_insn "*negqi2_1"
10294 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10295 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "ix86_unary_operator_ok (NEG, QImode, operands)"
10299 [(set_attr "type" "negnot")
10300 (set_attr "mode" "QI")])
10302 (define_insn "*negqi2_cmpz"
10303 [(set (reg:CCZ FLAGS_REG)
10304 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10306 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10307 (neg:QI (match_dup 1)))]
10308 "ix86_unary_operator_ok (NEG, QImode, operands)"
10310 [(set_attr "type" "negnot")
10311 (set_attr "mode" "QI")])
10313 ;; Changing of sign for FP values is doable using integer unit too.
10315 (define_expand "<code><mode>2"
10316 [(set (match_operand:X87MODEF 0 "register_operand" "")
10317 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10318 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10319 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10321 (define_insn "*absneg<mode>2_mixed"
10322 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10323 (match_operator:MODEF 3 "absneg_operator"
10324 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10325 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10326 (clobber (reg:CC FLAGS_REG))]
10327 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10330 (define_insn "*absneg<mode>2_sse"
10331 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10332 (match_operator:MODEF 3 "absneg_operator"
10333 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10334 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10339 (define_insn "*absneg<mode>2_i387"
10340 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10341 (match_operator:X87MODEF 3 "absneg_operator"
10342 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10343 (use (match_operand 2 "" ""))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10348 (define_expand "<code>tf2"
10349 [(set (match_operand:TF 0 "register_operand" "")
10350 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10352 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10354 (define_insn "*absnegtf2_sse"
10355 [(set (match_operand:TF 0 "register_operand" "=x,x")
10356 (match_operator:TF 3 "absneg_operator"
10357 [(match_operand:TF 1 "register_operand" "0,x")]))
10358 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10359 (clobber (reg:CC FLAGS_REG))]
10363 ;; Splitters for fp abs and neg.
10366 [(set (match_operand 0 "fp_register_operand" "")
10367 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10368 (use (match_operand 2 "" ""))
10369 (clobber (reg:CC FLAGS_REG))]
10371 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10374 [(set (match_operand 0 "register_operand" "")
10375 (match_operator 3 "absneg_operator"
10376 [(match_operand 1 "register_operand" "")]))
10377 (use (match_operand 2 "nonimmediate_operand" ""))
10378 (clobber (reg:CC FLAGS_REG))]
10379 "reload_completed && SSE_REG_P (operands[0])"
10380 [(set (match_dup 0) (match_dup 3))]
10382 enum machine_mode mode = GET_MODE (operands[0]);
10383 enum machine_mode vmode = GET_MODE (operands[2]);
10386 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10387 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10388 if (operands_match_p (operands[0], operands[2]))
10391 operands[1] = operands[2];
10394 if (GET_CODE (operands[3]) == ABS)
10395 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10397 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10402 [(set (match_operand:SF 0 "register_operand" "")
10403 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10404 (use (match_operand:V4SF 2 "" ""))
10405 (clobber (reg:CC FLAGS_REG))]
10407 [(parallel [(set (match_dup 0) (match_dup 1))
10408 (clobber (reg:CC FLAGS_REG))])]
10411 operands[0] = gen_lowpart (SImode, operands[0]);
10412 if (GET_CODE (operands[1]) == ABS)
10414 tmp = gen_int_mode (0x7fffffff, SImode);
10415 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10419 tmp = gen_int_mode (0x80000000, SImode);
10420 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10426 [(set (match_operand:DF 0 "register_operand" "")
10427 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10428 (use (match_operand 2 "" ""))
10429 (clobber (reg:CC FLAGS_REG))]
10431 [(parallel [(set (match_dup 0) (match_dup 1))
10432 (clobber (reg:CC FLAGS_REG))])]
10437 tmp = gen_lowpart (DImode, operands[0]);
10438 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10441 if (GET_CODE (operands[1]) == ABS)
10444 tmp = gen_rtx_NOT (DImode, tmp);
10448 operands[0] = gen_highpart (SImode, operands[0]);
10449 if (GET_CODE (operands[1]) == ABS)
10451 tmp = gen_int_mode (0x7fffffff, SImode);
10452 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10456 tmp = gen_int_mode (0x80000000, SImode);
10457 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10464 [(set (match_operand:XF 0 "register_operand" "")
10465 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10466 (use (match_operand 2 "" ""))
10467 (clobber (reg:CC FLAGS_REG))]
10469 [(parallel [(set (match_dup 0) (match_dup 1))
10470 (clobber (reg:CC FLAGS_REG))])]
10473 operands[0] = gen_rtx_REG (SImode,
10474 true_regnum (operands[0])
10475 + (TARGET_64BIT ? 1 : 2));
10476 if (GET_CODE (operands[1]) == ABS)
10478 tmp = GEN_INT (0x7fff);
10479 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10483 tmp = GEN_INT (0x8000);
10484 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10489 ;; Conditionalize these after reload. If they match before reload, we
10490 ;; lose the clobber and ability to use integer instructions.
10492 (define_insn "*<code><mode>2_1"
10493 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10494 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10496 && (reload_completed
10497 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10499 [(set_attr "type" "fsgn")
10500 (set_attr "mode" "<MODE>")])
10502 (define_insn "*<code>extendsfdf2"
10503 [(set (match_operand:DF 0 "register_operand" "=f")
10504 (absneg:DF (float_extend:DF
10505 (match_operand:SF 1 "register_operand" "0"))))]
10506 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10508 [(set_attr "type" "fsgn")
10509 (set_attr "mode" "DF")])
10511 (define_insn "*<code>extendsfxf2"
10512 [(set (match_operand:XF 0 "register_operand" "=f")
10513 (absneg:XF (float_extend:XF
10514 (match_operand:SF 1 "register_operand" "0"))))]
10517 [(set_attr "type" "fsgn")
10518 (set_attr "mode" "XF")])
10520 (define_insn "*<code>extenddfxf2"
10521 [(set (match_operand:XF 0 "register_operand" "=f")
10522 (absneg:XF (float_extend:XF
10523 (match_operand:DF 1 "register_operand" "0"))))]
10526 [(set_attr "type" "fsgn")
10527 (set_attr "mode" "XF")])
10529 ;; Copysign instructions
10531 (define_mode_iterator CSGNMODE [SF DF TF])
10532 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10534 (define_expand "copysign<mode>3"
10535 [(match_operand:CSGNMODE 0 "register_operand" "")
10536 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10537 (match_operand:CSGNMODE 2 "register_operand" "")]
10538 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10539 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10541 ix86_expand_copysign (operands);
10545 (define_insn_and_split "copysign<mode>3_const"
10546 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10548 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10549 (match_operand:CSGNMODE 2 "register_operand" "0")
10550 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10552 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10553 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10555 "&& reload_completed"
10558 ix86_split_copysign_const (operands);
10562 (define_insn "copysign<mode>3_var"
10563 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10565 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10566 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10567 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10568 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10570 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10571 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10572 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10576 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10578 [(match_operand:CSGNMODE 2 "register_operand" "")
10579 (match_operand:CSGNMODE 3 "register_operand" "")
10580 (match_operand:<CSGNVMODE> 4 "" "")
10581 (match_operand:<CSGNVMODE> 5 "" "")]
10583 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10584 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10585 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10586 && reload_completed"
10589 ix86_split_copysign_var (operands);
10593 ;; One complement instructions
10595 (define_expand "one_cmpldi2"
10596 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10597 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10599 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10601 (define_insn "*one_cmpldi2_1_rex64"
10602 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10603 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10604 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10606 [(set_attr "type" "negnot")
10607 (set_attr "mode" "DI")])
10609 (define_insn "*one_cmpldi2_2_rex64"
10610 [(set (reg FLAGS_REG)
10611 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10613 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10614 (not:DI (match_dup 1)))]
10615 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10616 && ix86_unary_operator_ok (NOT, DImode, operands)"
10618 [(set_attr "type" "alu1")
10619 (set_attr "mode" "DI")])
10622 [(set (match_operand 0 "flags_reg_operand" "")
10623 (match_operator 2 "compare_operator"
10624 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10626 (set (match_operand:DI 1 "nonimmediate_operand" "")
10627 (not:DI (match_dup 3)))]
10628 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10629 [(parallel [(set (match_dup 0)
10631 [(xor:DI (match_dup 3) (const_int -1))
10634 (xor:DI (match_dup 3) (const_int -1)))])]
10637 (define_expand "one_cmplsi2"
10638 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10639 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10641 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10643 (define_insn "*one_cmplsi2_1"
10644 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10645 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10646 "ix86_unary_operator_ok (NOT, SImode, operands)"
10648 [(set_attr "type" "negnot")
10649 (set_attr "mode" "SI")])
10651 ;; ??? Currently never generated - xor is used instead.
10652 (define_insn "*one_cmplsi2_1_zext"
10653 [(set (match_operand:DI 0 "register_operand" "=r")
10654 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10655 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10657 [(set_attr "type" "negnot")
10658 (set_attr "mode" "SI")])
10660 (define_insn "*one_cmplsi2_2"
10661 [(set (reg FLAGS_REG)
10662 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10664 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10665 (not:SI (match_dup 1)))]
10666 "ix86_match_ccmode (insn, CCNOmode)
10667 && ix86_unary_operator_ok (NOT, SImode, operands)"
10669 [(set_attr "type" "alu1")
10670 (set_attr "mode" "SI")])
10673 [(set (match_operand 0 "flags_reg_operand" "")
10674 (match_operator 2 "compare_operator"
10675 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10677 (set (match_operand:SI 1 "nonimmediate_operand" "")
10678 (not:SI (match_dup 3)))]
10679 "ix86_match_ccmode (insn, CCNOmode)"
10680 [(parallel [(set (match_dup 0)
10681 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10684 (xor:SI (match_dup 3) (const_int -1)))])]
10687 ;; ??? Currently never generated - xor is used instead.
10688 (define_insn "*one_cmplsi2_2_zext"
10689 [(set (reg FLAGS_REG)
10690 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10692 (set (match_operand:DI 0 "register_operand" "=r")
10693 (zero_extend:DI (not:SI (match_dup 1))))]
10694 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10695 && ix86_unary_operator_ok (NOT, SImode, operands)"
10697 [(set_attr "type" "alu1")
10698 (set_attr "mode" "SI")])
10701 [(set (match_operand 0 "flags_reg_operand" "")
10702 (match_operator 2 "compare_operator"
10703 [(not:SI (match_operand:SI 3 "register_operand" ""))
10705 (set (match_operand:DI 1 "register_operand" "")
10706 (zero_extend:DI (not:SI (match_dup 3))))]
10707 "ix86_match_ccmode (insn, CCNOmode)"
10708 [(parallel [(set (match_dup 0)
10709 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10712 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10715 (define_expand "one_cmplhi2"
10716 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10717 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10718 "TARGET_HIMODE_MATH"
10719 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10721 (define_insn "*one_cmplhi2_1"
10722 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10723 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10724 "ix86_unary_operator_ok (NOT, HImode, operands)"
10726 [(set_attr "type" "negnot")
10727 (set_attr "mode" "HI")])
10729 (define_insn "*one_cmplhi2_2"
10730 [(set (reg FLAGS_REG)
10731 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10733 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10734 (not:HI (match_dup 1)))]
10735 "ix86_match_ccmode (insn, CCNOmode)
10736 && ix86_unary_operator_ok (NEG, HImode, operands)"
10738 [(set_attr "type" "alu1")
10739 (set_attr "mode" "HI")])
10742 [(set (match_operand 0 "flags_reg_operand" "")
10743 (match_operator 2 "compare_operator"
10744 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10746 (set (match_operand:HI 1 "nonimmediate_operand" "")
10747 (not:HI (match_dup 3)))]
10748 "ix86_match_ccmode (insn, CCNOmode)"
10749 [(parallel [(set (match_dup 0)
10750 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10753 (xor:HI (match_dup 3) (const_int -1)))])]
10756 ;; %%% Potential partial reg stall on alternative 1. What to do?
10757 (define_expand "one_cmplqi2"
10758 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10759 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10760 "TARGET_QIMODE_MATH"
10761 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10763 (define_insn "*one_cmplqi2_1"
10764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10765 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10766 "ix86_unary_operator_ok (NOT, QImode, operands)"
10770 [(set_attr "type" "negnot")
10771 (set_attr "mode" "QI,SI")])
10773 (define_insn "*one_cmplqi2_2"
10774 [(set (reg FLAGS_REG)
10775 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10777 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10778 (not:QI (match_dup 1)))]
10779 "ix86_match_ccmode (insn, CCNOmode)
10780 && ix86_unary_operator_ok (NOT, QImode, operands)"
10782 [(set_attr "type" "alu1")
10783 (set_attr "mode" "QI")])
10786 [(set (match_operand 0 "flags_reg_operand" "")
10787 (match_operator 2 "compare_operator"
10788 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10790 (set (match_operand:QI 1 "nonimmediate_operand" "")
10791 (not:QI (match_dup 3)))]
10792 "ix86_match_ccmode (insn, CCNOmode)"
10793 [(parallel [(set (match_dup 0)
10794 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10797 (xor:QI (match_dup 3) (const_int -1)))])]
10800 ;; Arithmetic shift instructions
10802 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10803 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10804 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10805 ;; from the assembler input.
10807 ;; This instruction shifts the target reg/mem as usual, but instead of
10808 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10809 ;; is a left shift double, bits are taken from the high order bits of
10810 ;; reg, else if the insn is a shift right double, bits are taken from the
10811 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10812 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10814 ;; Since sh[lr]d does not change the `reg' operand, that is done
10815 ;; separately, making all shifts emit pairs of shift double and normal
10816 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10817 ;; support a 63 bit shift, each shift where the count is in a reg expands
10818 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10820 ;; If the shift count is a constant, we need never emit more than one
10821 ;; shift pair, instead using moves and sign extension for counts greater
10824 (define_expand "ashlti3"
10825 [(set (match_operand:TI 0 "register_operand" "")
10826 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10827 (match_operand:QI 2 "nonmemory_operand" "")))]
10829 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10831 ;; This pattern must be defined before *ashlti3_1 to prevent
10832 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10834 (define_insn "sse2_ashlti3"
10835 [(set (match_operand:TI 0 "register_operand" "=x")
10836 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10837 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10840 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10841 return "pslldq\t{%2, %0|%0, %2}";
10843 [(set_attr "type" "sseishft")
10844 (set_attr "prefix_data16" "1")
10845 (set_attr "mode" "TI")])
10847 (define_insn "*ashlti3_1"
10848 [(set (match_operand:TI 0 "register_operand" "=&r,r")
10849 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10850 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10851 (clobber (reg:CC FLAGS_REG))]
10854 [(set_attr "type" "multi")])
10857 [(match_scratch:DI 3 "r")
10858 (parallel [(set (match_operand:TI 0 "register_operand" "")
10859 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10860 (match_operand:QI 2 "nonmemory_operand" "")))
10861 (clobber (reg:CC FLAGS_REG))])
10865 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10868 [(set (match_operand:TI 0 "register_operand" "")
10869 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10870 (match_operand:QI 2 "nonmemory_operand" "")))
10871 (clobber (reg:CC FLAGS_REG))]
10872 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10873 ? epilogue_completed : reload_completed)"
10875 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10877 (define_insn "x86_64_shld"
10878 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10879 (ior:DI (ashift:DI (match_dup 0)
10880 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10881 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10882 (minus:QI (const_int 64) (match_dup 2)))))
10883 (clobber (reg:CC FLAGS_REG))]
10885 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10886 [(set_attr "type" "ishift")
10887 (set_attr "prefix_0f" "1")
10888 (set_attr "mode" "DI")
10889 (set_attr "athlon_decode" "vector")
10890 (set_attr "amdfam10_decode" "vector")])
10892 (define_expand "x86_64_shift_adj"
10893 [(set (reg:CCZ FLAGS_REG)
10894 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10897 (set (match_operand:DI 0 "register_operand" "")
10898 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10899 (match_operand:DI 1 "register_operand" "")
10902 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10903 (match_operand:DI 3 "register_operand" "r")
10908 (define_expand "ashldi3"
10909 [(set (match_operand:DI 0 "shiftdi_operand" "")
10910 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10911 (match_operand:QI 2 "nonmemory_operand" "")))]
10913 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10915 (define_insn "*ashldi3_1_rex64"
10916 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10917 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10918 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10919 (clobber (reg:CC FLAGS_REG))]
10920 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10922 switch (get_attr_type (insn))
10925 gcc_assert (operands[2] == const1_rtx);
10926 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10927 return "add{q}\t%0, %0";
10930 gcc_assert (CONST_INT_P (operands[2]));
10931 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10932 operands[1] = gen_rtx_MULT (DImode, operands[1],
10933 GEN_INT (1 << INTVAL (operands[2])));
10934 return "lea{q}\t{%a1, %0|%0, %a1}";
10937 if (REG_P (operands[2]))
10938 return "sal{q}\t{%b2, %0|%0, %b2}";
10939 else if (operands[2] == const1_rtx
10940 && (TARGET_SHIFT1 || optimize_size))
10941 return "sal{q}\t%0";
10943 return "sal{q}\t{%2, %0|%0, %2}";
10946 [(set (attr "type")
10947 (cond [(eq_attr "alternative" "1")
10948 (const_string "lea")
10949 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10951 (match_operand 0 "register_operand" ""))
10952 (match_operand 2 "const1_operand" ""))
10953 (const_string "alu")
10955 (const_string "ishift")))
10956 (set_attr "mode" "DI")])
10958 ;; Convert lea to the lea pattern to avoid flags dependency.
10960 [(set (match_operand:DI 0 "register_operand" "")
10961 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10962 (match_operand:QI 2 "immediate_operand" "")))
10963 (clobber (reg:CC FLAGS_REG))]
10964 "TARGET_64BIT && reload_completed
10965 && true_regnum (operands[0]) != true_regnum (operands[1])"
10966 [(set (match_dup 0)
10967 (mult:DI (match_dup 1)
10969 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10971 ;; This pattern can't accept a variable shift count, since shifts by
10972 ;; zero don't affect the flags. We assume that shifts by constant
10973 ;; zero are optimized away.
10974 (define_insn "*ashldi3_cmp_rex64"
10975 [(set (reg FLAGS_REG)
10977 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10978 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10980 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10981 (ashift:DI (match_dup 1) (match_dup 2)))]
10984 || !TARGET_PARTIAL_FLAG_REG_STALL
10985 || (operands[2] == const1_rtx
10987 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10988 && ix86_match_ccmode (insn, CCGOCmode)
10989 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10991 switch (get_attr_type (insn))
10994 gcc_assert (operands[2] == const1_rtx);
10995 return "add{q}\t%0, %0";
10998 if (REG_P (operands[2]))
10999 return "sal{q}\t{%b2, %0|%0, %b2}";
11000 else if (operands[2] == const1_rtx
11001 && (TARGET_SHIFT1 || optimize_size))
11002 return "sal{q}\t%0";
11004 return "sal{q}\t{%2, %0|%0, %2}";
11007 [(set (attr "type")
11008 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11010 (match_operand 0 "register_operand" ""))
11011 (match_operand 2 "const1_operand" ""))
11012 (const_string "alu")
11014 (const_string "ishift")))
11015 (set_attr "mode" "DI")])
11017 (define_insn "*ashldi3_cconly_rex64"
11018 [(set (reg FLAGS_REG)
11020 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11021 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11023 (clobber (match_scratch:DI 0 "=r"))]
11026 || !TARGET_PARTIAL_FLAG_REG_STALL
11027 || (operands[2] == const1_rtx
11029 || TARGET_DOUBLE_WITH_ADD)))
11030 && ix86_match_ccmode (insn, CCGOCmode)
11031 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11033 switch (get_attr_type (insn))
11036 gcc_assert (operands[2] == const1_rtx);
11037 return "add{q}\t%0, %0";
11040 if (REG_P (operands[2]))
11041 return "sal{q}\t{%b2, %0|%0, %b2}";
11042 else if (operands[2] == const1_rtx
11043 && (TARGET_SHIFT1 || optimize_size))
11044 return "sal{q}\t%0";
11046 return "sal{q}\t{%2, %0|%0, %2}";
11049 [(set (attr "type")
11050 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11052 (match_operand 0 "register_operand" ""))
11053 (match_operand 2 "const1_operand" ""))
11054 (const_string "alu")
11056 (const_string "ishift")))
11057 (set_attr "mode" "DI")])
11059 (define_insn "*ashldi3_1"
11060 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11061 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11062 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11063 (clobber (reg:CC FLAGS_REG))]
11066 [(set_attr "type" "multi")])
11068 ;; By default we don't ask for a scratch register, because when DImode
11069 ;; values are manipulated, registers are already at a premium. But if
11070 ;; we have one handy, we won't turn it away.
11072 [(match_scratch:SI 3 "r")
11073 (parallel [(set (match_operand:DI 0 "register_operand" "")
11074 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11075 (match_operand:QI 2 "nonmemory_operand" "")))
11076 (clobber (reg:CC FLAGS_REG))])
11078 "!TARGET_64BIT && TARGET_CMOVE"
11080 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11083 [(set (match_operand:DI 0 "register_operand" "")
11084 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11085 (match_operand:QI 2 "nonmemory_operand" "")))
11086 (clobber (reg:CC FLAGS_REG))]
11087 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11088 ? epilogue_completed : reload_completed)"
11090 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11092 (define_insn "x86_shld"
11093 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11094 (ior:SI (ashift:SI (match_dup 0)
11095 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11096 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11097 (minus:QI (const_int 32) (match_dup 2)))))
11098 (clobber (reg:CC FLAGS_REG))]
11100 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11101 [(set_attr "type" "ishift")
11102 (set_attr "prefix_0f" "1")
11103 (set_attr "mode" "SI")
11104 (set_attr "pent_pair" "np")
11105 (set_attr "athlon_decode" "vector")
11106 (set_attr "amdfam10_decode" "vector")])
11108 (define_expand "x86_shift_adj_1"
11109 [(set (reg:CCZ FLAGS_REG)
11110 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11113 (set (match_operand:SI 0 "register_operand" "")
11114 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11115 (match_operand:SI 1 "register_operand" "")
11118 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11119 (match_operand:SI 3 "register_operand" "r")
11124 (define_expand "x86_shift_adj_2"
11125 [(use (match_operand:SI 0 "register_operand" ""))
11126 (use (match_operand:SI 1 "register_operand" ""))
11127 (use (match_operand:QI 2 "register_operand" ""))]
11130 rtx label = gen_label_rtx ();
11133 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11135 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11136 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11137 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11138 gen_rtx_LABEL_REF (VOIDmode, label),
11140 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11141 JUMP_LABEL (tmp) = label;
11143 emit_move_insn (operands[0], operands[1]);
11144 ix86_expand_clear (operands[1]);
11146 emit_label (label);
11147 LABEL_NUSES (label) = 1;
11152 (define_expand "ashlsi3"
11153 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11154 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11155 (match_operand:QI 2 "nonmemory_operand" "")))]
11157 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11159 (define_insn "*ashlsi3_1"
11160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11161 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11162 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11163 (clobber (reg:CC FLAGS_REG))]
11164 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11166 switch (get_attr_type (insn))
11169 gcc_assert (operands[2] == const1_rtx);
11170 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11171 return "add{l}\t%0, %0";
11177 if (REG_P (operands[2]))
11178 return "sal{l}\t{%b2, %0|%0, %b2}";
11179 else if (operands[2] == const1_rtx
11180 && (TARGET_SHIFT1 || optimize_size))
11181 return "sal{l}\t%0";
11183 return "sal{l}\t{%2, %0|%0, %2}";
11186 [(set (attr "type")
11187 (cond [(eq_attr "alternative" "1")
11188 (const_string "lea")
11189 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11191 (match_operand 0 "register_operand" ""))
11192 (match_operand 2 "const1_operand" ""))
11193 (const_string "alu")
11195 (const_string "ishift")))
11196 (set_attr "mode" "SI")])
11198 ;; Convert lea to the lea pattern to avoid flags dependency.
11200 [(set (match_operand 0 "register_operand" "")
11201 (ashift (match_operand 1 "index_register_operand" "")
11202 (match_operand:QI 2 "const_int_operand" "")))
11203 (clobber (reg:CC FLAGS_REG))]
11205 && true_regnum (operands[0]) != true_regnum (operands[1])
11206 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11210 enum machine_mode mode = GET_MODE (operands[0]);
11212 if (GET_MODE_SIZE (mode) < 4)
11213 operands[0] = gen_lowpart (SImode, operands[0]);
11215 operands[1] = gen_lowpart (Pmode, operands[1]);
11216 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11218 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11219 if (Pmode != SImode)
11220 pat = gen_rtx_SUBREG (SImode, pat, 0);
11221 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11225 ;; Rare case of shifting RSP is handled by generating move and shift
11227 [(set (match_operand 0 "register_operand" "")
11228 (ashift (match_operand 1 "register_operand" "")
11229 (match_operand:QI 2 "const_int_operand" "")))
11230 (clobber (reg:CC FLAGS_REG))]
11232 && true_regnum (operands[0]) != true_regnum (operands[1])"
11236 emit_move_insn (operands[0], operands[1]);
11237 pat = gen_rtx_SET (VOIDmode, operands[0],
11238 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11239 operands[0], operands[2]));
11240 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11241 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11245 (define_insn "*ashlsi3_1_zext"
11246 [(set (match_operand:DI 0 "register_operand" "=r,r")
11247 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11248 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11249 (clobber (reg:CC FLAGS_REG))]
11250 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11252 switch (get_attr_type (insn))
11255 gcc_assert (operands[2] == const1_rtx);
11256 return "add{l}\t%k0, %k0";
11262 if (REG_P (operands[2]))
11263 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11264 else if (operands[2] == const1_rtx
11265 && (TARGET_SHIFT1 || optimize_size))
11266 return "sal{l}\t%k0";
11268 return "sal{l}\t{%2, %k0|%k0, %2}";
11271 [(set (attr "type")
11272 (cond [(eq_attr "alternative" "1")
11273 (const_string "lea")
11274 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11276 (match_operand 2 "const1_operand" ""))
11277 (const_string "alu")
11279 (const_string "ishift")))
11280 (set_attr "mode" "SI")])
11282 ;; Convert lea to the lea pattern to avoid flags dependency.
11284 [(set (match_operand:DI 0 "register_operand" "")
11285 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11286 (match_operand:QI 2 "const_int_operand" ""))))
11287 (clobber (reg:CC FLAGS_REG))]
11288 "TARGET_64BIT && reload_completed
11289 && true_regnum (operands[0]) != true_regnum (operands[1])"
11290 [(set (match_dup 0) (zero_extend:DI
11291 (subreg:SI (mult:SI (match_dup 1)
11292 (match_dup 2)) 0)))]
11294 operands[1] = gen_lowpart (Pmode, operands[1]);
11295 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11298 ;; This pattern can't accept a variable shift count, since shifts by
11299 ;; zero don't affect the flags. We assume that shifts by constant
11300 ;; zero are optimized away.
11301 (define_insn "*ashlsi3_cmp"
11302 [(set (reg FLAGS_REG)
11304 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11305 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11307 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11308 (ashift:SI (match_dup 1) (match_dup 2)))]
11310 || !TARGET_PARTIAL_FLAG_REG_STALL
11311 || (operands[2] == const1_rtx
11313 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11314 && ix86_match_ccmode (insn, CCGOCmode)
11315 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11317 switch (get_attr_type (insn))
11320 gcc_assert (operands[2] == const1_rtx);
11321 return "add{l}\t%0, %0";
11324 if (REG_P (operands[2]))
11325 return "sal{l}\t{%b2, %0|%0, %b2}";
11326 else if (operands[2] == const1_rtx
11327 && (TARGET_SHIFT1 || optimize_size))
11328 return "sal{l}\t%0";
11330 return "sal{l}\t{%2, %0|%0, %2}";
11333 [(set (attr "type")
11334 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11336 (match_operand 0 "register_operand" ""))
11337 (match_operand 2 "const1_operand" ""))
11338 (const_string "alu")
11340 (const_string "ishift")))
11341 (set_attr "mode" "SI")])
11343 (define_insn "*ashlsi3_cconly"
11344 [(set (reg FLAGS_REG)
11346 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11347 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11349 (clobber (match_scratch:SI 0 "=r"))]
11351 || !TARGET_PARTIAL_FLAG_REG_STALL
11352 || (operands[2] == const1_rtx
11354 || TARGET_DOUBLE_WITH_ADD)))
11355 && ix86_match_ccmode (insn, CCGOCmode)
11356 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11358 switch (get_attr_type (insn))
11361 gcc_assert (operands[2] == const1_rtx);
11362 return "add{l}\t%0, %0";
11365 if (REG_P (operands[2]))
11366 return "sal{l}\t{%b2, %0|%0, %b2}";
11367 else if (operands[2] == const1_rtx
11368 && (TARGET_SHIFT1 || optimize_size))
11369 return "sal{l}\t%0";
11371 return "sal{l}\t{%2, %0|%0, %2}";
11374 [(set (attr "type")
11375 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11377 (match_operand 0 "register_operand" ""))
11378 (match_operand 2 "const1_operand" ""))
11379 (const_string "alu")
11381 (const_string "ishift")))
11382 (set_attr "mode" "SI")])
11384 (define_insn "*ashlsi3_cmp_zext"
11385 [(set (reg FLAGS_REG)
11387 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11388 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11390 (set (match_operand:DI 0 "register_operand" "=r")
11391 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11394 || !TARGET_PARTIAL_FLAG_REG_STALL
11395 || (operands[2] == const1_rtx
11397 || TARGET_DOUBLE_WITH_ADD)))
11398 && ix86_match_ccmode (insn, CCGOCmode)
11399 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11401 switch (get_attr_type (insn))
11404 gcc_assert (operands[2] == const1_rtx);
11405 return "add{l}\t%k0, %k0";
11408 if (REG_P (operands[2]))
11409 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11410 else if (operands[2] == const1_rtx
11411 && (TARGET_SHIFT1 || optimize_size))
11412 return "sal{l}\t%k0";
11414 return "sal{l}\t{%2, %k0|%k0, %2}";
11417 [(set (attr "type")
11418 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11420 (match_operand 2 "const1_operand" ""))
11421 (const_string "alu")
11423 (const_string "ishift")))
11424 (set_attr "mode" "SI")])
11426 (define_expand "ashlhi3"
11427 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11428 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11429 (match_operand:QI 2 "nonmemory_operand" "")))]
11430 "TARGET_HIMODE_MATH"
11431 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11433 (define_insn "*ashlhi3_1_lea"
11434 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11435 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11436 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11437 (clobber (reg:CC FLAGS_REG))]
11438 "!TARGET_PARTIAL_REG_STALL
11439 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11441 switch (get_attr_type (insn))
11446 gcc_assert (operands[2] == const1_rtx);
11447 return "add{w}\t%0, %0";
11450 if (REG_P (operands[2]))
11451 return "sal{w}\t{%b2, %0|%0, %b2}";
11452 else if (operands[2] == const1_rtx
11453 && (TARGET_SHIFT1 || optimize_size))
11454 return "sal{w}\t%0";
11456 return "sal{w}\t{%2, %0|%0, %2}";
11459 [(set (attr "type")
11460 (cond [(eq_attr "alternative" "1")
11461 (const_string "lea")
11462 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11464 (match_operand 0 "register_operand" ""))
11465 (match_operand 2 "const1_operand" ""))
11466 (const_string "alu")
11468 (const_string "ishift")))
11469 (set_attr "mode" "HI,SI")])
11471 (define_insn "*ashlhi3_1"
11472 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11473 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11474 (match_operand:QI 2 "nonmemory_operand" "cI")))
11475 (clobber (reg:CC FLAGS_REG))]
11476 "TARGET_PARTIAL_REG_STALL
11477 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11479 switch (get_attr_type (insn))
11482 gcc_assert (operands[2] == const1_rtx);
11483 return "add{w}\t%0, %0";
11486 if (REG_P (operands[2]))
11487 return "sal{w}\t{%b2, %0|%0, %b2}";
11488 else if (operands[2] == const1_rtx
11489 && (TARGET_SHIFT1 || optimize_size))
11490 return "sal{w}\t%0";
11492 return "sal{w}\t{%2, %0|%0, %2}";
11495 [(set (attr "type")
11496 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11498 (match_operand 0 "register_operand" ""))
11499 (match_operand 2 "const1_operand" ""))
11500 (const_string "alu")
11502 (const_string "ishift")))
11503 (set_attr "mode" "HI")])
11505 ;; This pattern can't accept a variable shift count, since shifts by
11506 ;; zero don't affect the flags. We assume that shifts by constant
11507 ;; zero are optimized away.
11508 (define_insn "*ashlhi3_cmp"
11509 [(set (reg FLAGS_REG)
11511 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11512 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11514 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11515 (ashift:HI (match_dup 1) (match_dup 2)))]
11517 || !TARGET_PARTIAL_FLAG_REG_STALL
11518 || (operands[2] == const1_rtx
11520 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11521 && ix86_match_ccmode (insn, CCGOCmode)
11522 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11524 switch (get_attr_type (insn))
11527 gcc_assert (operands[2] == const1_rtx);
11528 return "add{w}\t%0, %0";
11531 if (REG_P (operands[2]))
11532 return "sal{w}\t{%b2, %0|%0, %b2}";
11533 else if (operands[2] == const1_rtx
11534 && (TARGET_SHIFT1 || optimize_size))
11535 return "sal{w}\t%0";
11537 return "sal{w}\t{%2, %0|%0, %2}";
11540 [(set (attr "type")
11541 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11543 (match_operand 0 "register_operand" ""))
11544 (match_operand 2 "const1_operand" ""))
11545 (const_string "alu")
11547 (const_string "ishift")))
11548 (set_attr "mode" "HI")])
11550 (define_insn "*ashlhi3_cconly"
11551 [(set (reg FLAGS_REG)
11553 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11554 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11556 (clobber (match_scratch:HI 0 "=r"))]
11558 || !TARGET_PARTIAL_FLAG_REG_STALL
11559 || (operands[2] == const1_rtx
11561 || TARGET_DOUBLE_WITH_ADD)))
11562 && ix86_match_ccmode (insn, CCGOCmode)
11563 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11565 switch (get_attr_type (insn))
11568 gcc_assert (operands[2] == const1_rtx);
11569 return "add{w}\t%0, %0";
11572 if (REG_P (operands[2]))
11573 return "sal{w}\t{%b2, %0|%0, %b2}";
11574 else if (operands[2] == const1_rtx
11575 && (TARGET_SHIFT1 || optimize_size))
11576 return "sal{w}\t%0";
11578 return "sal{w}\t{%2, %0|%0, %2}";
11581 [(set (attr "type")
11582 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11584 (match_operand 0 "register_operand" ""))
11585 (match_operand 2 "const1_operand" ""))
11586 (const_string "alu")
11588 (const_string "ishift")))
11589 (set_attr "mode" "HI")])
11591 (define_expand "ashlqi3"
11592 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11593 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11594 (match_operand:QI 2 "nonmemory_operand" "")))]
11595 "TARGET_QIMODE_MATH"
11596 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11598 ;; %%% Potential partial reg stall on alternative 2. What to do?
11600 (define_insn "*ashlqi3_1_lea"
11601 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11602 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11603 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11604 (clobber (reg:CC FLAGS_REG))]
11605 "!TARGET_PARTIAL_REG_STALL
11606 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11608 switch (get_attr_type (insn))
11613 gcc_assert (operands[2] == const1_rtx);
11614 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11615 return "add{l}\t%k0, %k0";
11617 return "add{b}\t%0, %0";
11620 if (REG_P (operands[2]))
11622 if (get_attr_mode (insn) == MODE_SI)
11623 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11625 return "sal{b}\t{%b2, %0|%0, %b2}";
11627 else if (operands[2] == const1_rtx
11628 && (TARGET_SHIFT1 || optimize_size))
11630 if (get_attr_mode (insn) == MODE_SI)
11631 return "sal{l}\t%0";
11633 return "sal{b}\t%0";
11637 if (get_attr_mode (insn) == MODE_SI)
11638 return "sal{l}\t{%2, %k0|%k0, %2}";
11640 return "sal{b}\t{%2, %0|%0, %2}";
11644 [(set (attr "type")
11645 (cond [(eq_attr "alternative" "2")
11646 (const_string "lea")
11647 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11649 (match_operand 0 "register_operand" ""))
11650 (match_operand 2 "const1_operand" ""))
11651 (const_string "alu")
11653 (const_string "ishift")))
11654 (set_attr "mode" "QI,SI,SI")])
11656 (define_insn "*ashlqi3_1"
11657 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11658 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11659 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11660 (clobber (reg:CC FLAGS_REG))]
11661 "TARGET_PARTIAL_REG_STALL
11662 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11664 switch (get_attr_type (insn))
11667 gcc_assert (operands[2] == const1_rtx);
11668 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11669 return "add{l}\t%k0, %k0";
11671 return "add{b}\t%0, %0";
11674 if (REG_P (operands[2]))
11676 if (get_attr_mode (insn) == MODE_SI)
11677 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11679 return "sal{b}\t{%b2, %0|%0, %b2}";
11681 else if (operands[2] == const1_rtx
11682 && (TARGET_SHIFT1 || optimize_size))
11684 if (get_attr_mode (insn) == MODE_SI)
11685 return "sal{l}\t%0";
11687 return "sal{b}\t%0";
11691 if (get_attr_mode (insn) == MODE_SI)
11692 return "sal{l}\t{%2, %k0|%k0, %2}";
11694 return "sal{b}\t{%2, %0|%0, %2}";
11698 [(set (attr "type")
11699 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11701 (match_operand 0 "register_operand" ""))
11702 (match_operand 2 "const1_operand" ""))
11703 (const_string "alu")
11705 (const_string "ishift")))
11706 (set_attr "mode" "QI,SI")])
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags. We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*ashlqi3_cmp"
11712 [(set (reg FLAGS_REG)
11714 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11715 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11717 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11718 (ashift:QI (match_dup 1) (match_dup 2)))]
11720 || !TARGET_PARTIAL_FLAG_REG_STALL
11721 || (operands[2] == const1_rtx
11723 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11724 && ix86_match_ccmode (insn, CCGOCmode)
11725 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11727 switch (get_attr_type (insn))
11730 gcc_assert (operands[2] == const1_rtx);
11731 return "add{b}\t%0, %0";
11734 if (REG_P (operands[2]))
11735 return "sal{b}\t{%b2, %0|%0, %b2}";
11736 else if (operands[2] == const1_rtx
11737 && (TARGET_SHIFT1 || optimize_size))
11738 return "sal{b}\t%0";
11740 return "sal{b}\t{%2, %0|%0, %2}";
11743 [(set (attr "type")
11744 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11746 (match_operand 0 "register_operand" ""))
11747 (match_operand 2 "const1_operand" ""))
11748 (const_string "alu")
11750 (const_string "ishift")))
11751 (set_attr "mode" "QI")])
11753 (define_insn "*ashlqi3_cconly"
11754 [(set (reg FLAGS_REG)
11756 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11757 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11759 (clobber (match_scratch:QI 0 "=q"))]
11761 || !TARGET_PARTIAL_FLAG_REG_STALL
11762 || (operands[2] == const1_rtx
11764 || TARGET_DOUBLE_WITH_ADD)))
11765 && ix86_match_ccmode (insn, CCGOCmode)
11766 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11768 switch (get_attr_type (insn))
11771 gcc_assert (operands[2] == const1_rtx);
11772 return "add{b}\t%0, %0";
11775 if (REG_P (operands[2]))
11776 return "sal{b}\t{%b2, %0|%0, %b2}";
11777 else if (operands[2] == const1_rtx
11778 && (TARGET_SHIFT1 || optimize_size))
11779 return "sal{b}\t%0";
11781 return "sal{b}\t{%2, %0|%0, %2}";
11784 [(set (attr "type")
11785 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11787 (match_operand 0 "register_operand" ""))
11788 (match_operand 2 "const1_operand" ""))
11789 (const_string "alu")
11791 (const_string "ishift")))
11792 (set_attr "mode" "QI")])
11794 ;; See comment above `ashldi3' about how this works.
11796 (define_expand "ashrti3"
11797 [(set (match_operand:TI 0 "register_operand" "")
11798 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11799 (match_operand:QI 2 "nonmemory_operand" "")))]
11801 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11803 (define_insn "*ashrti3_1"
11804 [(set (match_operand:TI 0 "register_operand" "=r")
11805 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11806 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11807 (clobber (reg:CC FLAGS_REG))]
11810 [(set_attr "type" "multi")])
11813 [(match_scratch:DI 3 "r")
11814 (parallel [(set (match_operand:TI 0 "register_operand" "")
11815 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11816 (match_operand:QI 2 "nonmemory_operand" "")))
11817 (clobber (reg:CC FLAGS_REG))])
11821 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11824 [(set (match_operand:TI 0 "register_operand" "")
11825 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11826 (match_operand:QI 2 "nonmemory_operand" "")))
11827 (clobber (reg:CC FLAGS_REG))]
11828 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11829 ? epilogue_completed : reload_completed)"
11831 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11833 (define_insn "x86_64_shrd"
11834 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11835 (ior:DI (ashiftrt:DI (match_dup 0)
11836 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11837 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11838 (minus:QI (const_int 64) (match_dup 2)))))
11839 (clobber (reg:CC FLAGS_REG))]
11841 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11842 [(set_attr "type" "ishift")
11843 (set_attr "prefix_0f" "1")
11844 (set_attr "mode" "DI")
11845 (set_attr "athlon_decode" "vector")
11846 (set_attr "amdfam10_decode" "vector")])
11848 (define_expand "ashrdi3"
11849 [(set (match_operand:DI 0 "shiftdi_operand" "")
11850 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11851 (match_operand:QI 2 "nonmemory_operand" "")))]
11853 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11855 (define_insn "*ashrdi3_63_rex64"
11856 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11857 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11858 (match_operand:DI 2 "const_int_operand" "i,i")))
11859 (clobber (reg:CC FLAGS_REG))]
11860 "TARGET_64BIT && INTVAL (operands[2]) == 63
11861 && (TARGET_USE_CLTD || optimize_size)
11862 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11865 sar{q}\t{%2, %0|%0, %2}"
11866 [(set_attr "type" "imovx,ishift")
11867 (set_attr "prefix_0f" "0,*")
11868 (set_attr "length_immediate" "0,*")
11869 (set_attr "modrm" "0,1")
11870 (set_attr "mode" "DI")])
11872 (define_insn "*ashrdi3_1_one_bit_rex64"
11873 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11874 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11875 (match_operand:QI 2 "const1_operand" "")))
11876 (clobber (reg:CC FLAGS_REG))]
11878 && (TARGET_SHIFT1 || optimize_size)
11879 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11881 [(set_attr "type" "ishift")
11882 (set (attr "length")
11883 (if_then_else (match_operand:DI 0 "register_operand" "")
11885 (const_string "*")))])
11887 (define_insn "*ashrdi3_1_rex64"
11888 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11889 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11890 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11891 (clobber (reg:CC FLAGS_REG))]
11892 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11894 sar{q}\t{%2, %0|%0, %2}
11895 sar{q}\t{%b2, %0|%0, %b2}"
11896 [(set_attr "type" "ishift")
11897 (set_attr "mode" "DI")])
11899 ;; This pattern can't accept a variable shift count, since shifts by
11900 ;; zero don't affect the flags. We assume that shifts by constant
11901 ;; zero are optimized away.
11902 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11903 [(set (reg FLAGS_REG)
11905 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11906 (match_operand:QI 2 "const1_operand" ""))
11908 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11909 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11911 && (TARGET_SHIFT1 || optimize_size)
11912 && ix86_match_ccmode (insn, CCGOCmode)
11913 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11915 [(set_attr "type" "ishift")
11916 (set (attr "length")
11917 (if_then_else (match_operand:DI 0 "register_operand" "")
11919 (const_string "*")))])
11921 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11922 [(set (reg FLAGS_REG)
11924 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11925 (match_operand:QI 2 "const1_operand" ""))
11927 (clobber (match_scratch:DI 0 "=r"))]
11929 && (TARGET_SHIFT1 || optimize_size)
11930 && ix86_match_ccmode (insn, CCGOCmode)
11931 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11933 [(set_attr "type" "ishift")
11934 (set_attr "length" "2")])
11936 ;; This pattern can't accept a variable shift count, since shifts by
11937 ;; zero don't affect the flags. We assume that shifts by constant
11938 ;; zero are optimized away.
11939 (define_insn "*ashrdi3_cmp_rex64"
11940 [(set (reg FLAGS_REG)
11942 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11943 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11945 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11946 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11948 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11949 && ix86_match_ccmode (insn, CCGOCmode)
11950 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11951 "sar{q}\t{%2, %0|%0, %2}"
11952 [(set_attr "type" "ishift")
11953 (set_attr "mode" "DI")])
11955 (define_insn "*ashrdi3_cconly_rex64"
11956 [(set (reg FLAGS_REG)
11958 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11959 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11961 (clobber (match_scratch:DI 0 "=r"))]
11963 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11964 && ix86_match_ccmode (insn, CCGOCmode)
11965 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11966 "sar{q}\t{%2, %0|%0, %2}"
11967 [(set_attr "type" "ishift")
11968 (set_attr "mode" "DI")])
11970 (define_insn "*ashrdi3_1"
11971 [(set (match_operand:DI 0 "register_operand" "=r")
11972 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11973 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11974 (clobber (reg:CC FLAGS_REG))]
11977 [(set_attr "type" "multi")])
11979 ;; By default we don't ask for a scratch register, because when DImode
11980 ;; values are manipulated, registers are already at a premium. But if
11981 ;; we have one handy, we won't turn it away.
11983 [(match_scratch:SI 3 "r")
11984 (parallel [(set (match_operand:DI 0 "register_operand" "")
11985 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11986 (match_operand:QI 2 "nonmemory_operand" "")))
11987 (clobber (reg:CC FLAGS_REG))])
11989 "!TARGET_64BIT && TARGET_CMOVE"
11991 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11994 [(set (match_operand:DI 0 "register_operand" "")
11995 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11996 (match_operand:QI 2 "nonmemory_operand" "")))
11997 (clobber (reg:CC FLAGS_REG))]
11998 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11999 ? epilogue_completed : reload_completed)"
12001 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12003 (define_insn "x86_shrd"
12004 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12005 (ior:SI (ashiftrt:SI (match_dup 0)
12006 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12007 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12008 (minus:QI (const_int 32) (match_dup 2)))))
12009 (clobber (reg:CC FLAGS_REG))]
12011 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12012 [(set_attr "type" "ishift")
12013 (set_attr "prefix_0f" "1")
12014 (set_attr "pent_pair" "np")
12015 (set_attr "mode" "SI")])
12017 (define_expand "x86_shift_adj_3"
12018 [(use (match_operand:SI 0 "register_operand" ""))
12019 (use (match_operand:SI 1 "register_operand" ""))
12020 (use (match_operand:QI 2 "register_operand" ""))]
12023 rtx label = gen_label_rtx ();
12026 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12028 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12029 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12030 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12031 gen_rtx_LABEL_REF (VOIDmode, label),
12033 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12034 JUMP_LABEL (tmp) = label;
12036 emit_move_insn (operands[0], operands[1]);
12037 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12039 emit_label (label);
12040 LABEL_NUSES (label) = 1;
12045 (define_insn "ashrsi3_31"
12046 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12047 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12048 (match_operand:SI 2 "const_int_operand" "i,i")))
12049 (clobber (reg:CC FLAGS_REG))]
12050 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12051 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12054 sar{l}\t{%2, %0|%0, %2}"
12055 [(set_attr "type" "imovx,ishift")
12056 (set_attr "prefix_0f" "0,*")
12057 (set_attr "length_immediate" "0,*")
12058 (set_attr "modrm" "0,1")
12059 (set_attr "mode" "SI")])
12061 (define_insn "*ashrsi3_31_zext"
12062 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12063 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12064 (match_operand:SI 2 "const_int_operand" "i,i"))))
12065 (clobber (reg:CC FLAGS_REG))]
12066 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12067 && INTVAL (operands[2]) == 31
12068 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12071 sar{l}\t{%2, %k0|%k0, %2}"
12072 [(set_attr "type" "imovx,ishift")
12073 (set_attr "prefix_0f" "0,*")
12074 (set_attr "length_immediate" "0,*")
12075 (set_attr "modrm" "0,1")
12076 (set_attr "mode" "SI")])
12078 (define_expand "ashrsi3"
12079 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12080 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12081 (match_operand:QI 2 "nonmemory_operand" "")))]
12083 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12085 (define_insn "*ashrsi3_1_one_bit"
12086 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12087 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12088 (match_operand:QI 2 "const1_operand" "")))
12089 (clobber (reg:CC FLAGS_REG))]
12090 "(TARGET_SHIFT1 || optimize_size)
12091 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12093 [(set_attr "type" "ishift")
12094 (set (attr "length")
12095 (if_then_else (match_operand:SI 0 "register_operand" "")
12097 (const_string "*")))])
12099 (define_insn "*ashrsi3_1_one_bit_zext"
12100 [(set (match_operand:DI 0 "register_operand" "=r")
12101 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12102 (match_operand:QI 2 "const1_operand" ""))))
12103 (clobber (reg:CC FLAGS_REG))]
12105 && (TARGET_SHIFT1 || optimize_size)
12106 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12108 [(set_attr "type" "ishift")
12109 (set_attr "length" "2")])
12111 (define_insn "*ashrsi3_1"
12112 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12113 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12114 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12115 (clobber (reg:CC FLAGS_REG))]
12116 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12118 sar{l}\t{%2, %0|%0, %2}
12119 sar{l}\t{%b2, %0|%0, %b2}"
12120 [(set_attr "type" "ishift")
12121 (set_attr "mode" "SI")])
12123 (define_insn "*ashrsi3_1_zext"
12124 [(set (match_operand:DI 0 "register_operand" "=r,r")
12125 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12126 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12130 sar{l}\t{%2, %k0|%k0, %2}
12131 sar{l}\t{%b2, %k0|%k0, %b2}"
12132 [(set_attr "type" "ishift")
12133 (set_attr "mode" "SI")])
12135 ;; This pattern can't accept a variable shift count, since shifts by
12136 ;; zero don't affect the flags. We assume that shifts by constant
12137 ;; zero are optimized away.
12138 (define_insn "*ashrsi3_one_bit_cmp"
12139 [(set (reg FLAGS_REG)
12141 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12142 (match_operand:QI 2 "const1_operand" ""))
12144 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12145 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12146 "(TARGET_SHIFT1 || optimize_size)
12147 && ix86_match_ccmode (insn, CCGOCmode)
12148 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12150 [(set_attr "type" "ishift")
12151 (set (attr "length")
12152 (if_then_else (match_operand:SI 0 "register_operand" "")
12154 (const_string "*")))])
12156 (define_insn "*ashrsi3_one_bit_cconly"
12157 [(set (reg FLAGS_REG)
12159 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12160 (match_operand:QI 2 "const1_operand" ""))
12162 (clobber (match_scratch:SI 0 "=r"))]
12163 "(TARGET_SHIFT1 || optimize_size)
12164 && ix86_match_ccmode (insn, CCGOCmode)
12165 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12167 [(set_attr "type" "ishift")
12168 (set_attr "length" "2")])
12170 (define_insn "*ashrsi3_one_bit_cmp_zext"
12171 [(set (reg FLAGS_REG)
12173 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12174 (match_operand:QI 2 "const1_operand" ""))
12176 (set (match_operand:DI 0 "register_operand" "=r")
12177 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12179 && (TARGET_SHIFT1 || optimize_size)
12180 && ix86_match_ccmode (insn, CCmode)
12181 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12183 [(set_attr "type" "ishift")
12184 (set_attr "length" "2")])
12186 ;; This pattern can't accept a variable shift count, since shifts by
12187 ;; zero don't affect the flags. We assume that shifts by constant
12188 ;; zero are optimized away.
12189 (define_insn "*ashrsi3_cmp"
12190 [(set (reg FLAGS_REG)
12192 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12193 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12195 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12196 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12197 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12198 && ix86_match_ccmode (insn, CCGOCmode)
12199 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12200 "sar{l}\t{%2, %0|%0, %2}"
12201 [(set_attr "type" "ishift")
12202 (set_attr "mode" "SI")])
12204 (define_insn "*ashrsi3_cconly"
12205 [(set (reg FLAGS_REG)
12207 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12208 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12210 (clobber (match_scratch:SI 0 "=r"))]
12211 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12212 && ix86_match_ccmode (insn, CCGOCmode)
12213 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12214 "sar{l}\t{%2, %0|%0, %2}"
12215 [(set_attr "type" "ishift")
12216 (set_attr "mode" "SI")])
12218 (define_insn "*ashrsi3_cmp_zext"
12219 [(set (reg FLAGS_REG)
12221 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12222 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12224 (set (match_operand:DI 0 "register_operand" "=r")
12225 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12227 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12228 && ix86_match_ccmode (insn, CCGOCmode)
12229 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12230 "sar{l}\t{%2, %k0|%k0, %2}"
12231 [(set_attr "type" "ishift")
12232 (set_attr "mode" "SI")])
12234 (define_expand "ashrhi3"
12235 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12236 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12237 (match_operand:QI 2 "nonmemory_operand" "")))]
12238 "TARGET_HIMODE_MATH"
12239 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12241 (define_insn "*ashrhi3_1_one_bit"
12242 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12243 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12244 (match_operand:QI 2 "const1_operand" "")))
12245 (clobber (reg:CC FLAGS_REG))]
12246 "(TARGET_SHIFT1 || optimize_size)
12247 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12249 [(set_attr "type" "ishift")
12250 (set (attr "length")
12251 (if_then_else (match_operand 0 "register_operand" "")
12253 (const_string "*")))])
12255 (define_insn "*ashrhi3_1"
12256 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12257 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12258 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12262 sar{w}\t{%2, %0|%0, %2}
12263 sar{w}\t{%b2, %0|%0, %b2}"
12264 [(set_attr "type" "ishift")
12265 (set_attr "mode" "HI")])
12267 ;; This pattern can't accept a variable shift count, since shifts by
12268 ;; zero don't affect the flags. We assume that shifts by constant
12269 ;; zero are optimized away.
12270 (define_insn "*ashrhi3_one_bit_cmp"
12271 [(set (reg FLAGS_REG)
12273 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12274 (match_operand:QI 2 "const1_operand" ""))
12276 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12277 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12278 "(TARGET_SHIFT1 || optimize_size)
12279 && ix86_match_ccmode (insn, CCGOCmode)
12280 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12282 [(set_attr "type" "ishift")
12283 (set (attr "length")
12284 (if_then_else (match_operand 0 "register_operand" "")
12286 (const_string "*")))])
12288 (define_insn "*ashrhi3_one_bit_cconly"
12289 [(set (reg FLAGS_REG)
12291 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12292 (match_operand:QI 2 "const1_operand" ""))
12294 (clobber (match_scratch:HI 0 "=r"))]
12295 "(TARGET_SHIFT1 || optimize_size)
12296 && ix86_match_ccmode (insn, CCGOCmode)
12297 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12299 [(set_attr "type" "ishift")
12300 (set_attr "length" "2")])
12302 ;; This pattern can't accept a variable shift count, since shifts by
12303 ;; zero don't affect the flags. We assume that shifts by constant
12304 ;; zero are optimized away.
12305 (define_insn "*ashrhi3_cmp"
12306 [(set (reg FLAGS_REG)
12308 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12309 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12311 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12312 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12313 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12314 && ix86_match_ccmode (insn, CCGOCmode)
12315 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12316 "sar{w}\t{%2, %0|%0, %2}"
12317 [(set_attr "type" "ishift")
12318 (set_attr "mode" "HI")])
12320 (define_insn "*ashrhi3_cconly"
12321 [(set (reg FLAGS_REG)
12323 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12324 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12326 (clobber (match_scratch:HI 0 "=r"))]
12327 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12328 && ix86_match_ccmode (insn, CCGOCmode)
12329 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12330 "sar{w}\t{%2, %0|%0, %2}"
12331 [(set_attr "type" "ishift")
12332 (set_attr "mode" "HI")])
12334 (define_expand "ashrqi3"
12335 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12336 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12337 (match_operand:QI 2 "nonmemory_operand" "")))]
12338 "TARGET_QIMODE_MATH"
12339 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12341 (define_insn "*ashrqi3_1_one_bit"
12342 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12343 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12344 (match_operand:QI 2 "const1_operand" "")))
12345 (clobber (reg:CC FLAGS_REG))]
12346 "(TARGET_SHIFT1 || optimize_size)
12347 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12349 [(set_attr "type" "ishift")
12350 (set (attr "length")
12351 (if_then_else (match_operand 0 "register_operand" "")
12353 (const_string "*")))])
12355 (define_insn "*ashrqi3_1_one_bit_slp"
12356 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12357 (ashiftrt:QI (match_dup 0)
12358 (match_operand:QI 1 "const1_operand" "")))
12359 (clobber (reg:CC FLAGS_REG))]
12360 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12361 && (TARGET_SHIFT1 || optimize_size)
12362 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12364 [(set_attr "type" "ishift1")
12365 (set (attr "length")
12366 (if_then_else (match_operand 0 "register_operand" "")
12368 (const_string "*")))])
12370 (define_insn "*ashrqi3_1"
12371 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12372 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12373 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12374 (clobber (reg:CC FLAGS_REG))]
12375 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12377 sar{b}\t{%2, %0|%0, %2}
12378 sar{b}\t{%b2, %0|%0, %b2}"
12379 [(set_attr "type" "ishift")
12380 (set_attr "mode" "QI")])
12382 (define_insn "*ashrqi3_1_slp"
12383 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12384 (ashiftrt:QI (match_dup 0)
12385 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12386 (clobber (reg:CC FLAGS_REG))]
12387 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12388 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12390 sar{b}\t{%1, %0|%0, %1}
12391 sar{b}\t{%b1, %0|%0, %b1}"
12392 [(set_attr "type" "ishift1")
12393 (set_attr "mode" "QI")])
12395 ;; This pattern can't accept a variable shift count, since shifts by
12396 ;; zero don't affect the flags. We assume that shifts by constant
12397 ;; zero are optimized away.
12398 (define_insn "*ashrqi3_one_bit_cmp"
12399 [(set (reg FLAGS_REG)
12401 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12402 (match_operand:QI 2 "const1_operand" "I"))
12404 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12405 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12406 "(TARGET_SHIFT1 || optimize_size)
12407 && ix86_match_ccmode (insn, CCGOCmode)
12408 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12410 [(set_attr "type" "ishift")
12411 (set (attr "length")
12412 (if_then_else (match_operand 0 "register_operand" "")
12414 (const_string "*")))])
12416 (define_insn "*ashrqi3_one_bit_cconly"
12417 [(set (reg FLAGS_REG)
12419 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12420 (match_operand:QI 2 "const1_operand" ""))
12422 (clobber (match_scratch:QI 0 "=q"))]
12423 "(TARGET_SHIFT1 || optimize_size)
12424 && ix86_match_ccmode (insn, CCGOCmode)
12425 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12427 [(set_attr "type" "ishift")
12428 (set_attr "length" "2")])
12430 ;; This pattern can't accept a variable shift count, since shifts by
12431 ;; zero don't affect the flags. We assume that shifts by constant
12432 ;; zero are optimized away.
12433 (define_insn "*ashrqi3_cmp"
12434 [(set (reg FLAGS_REG)
12436 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12437 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12439 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12440 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12441 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12442 && ix86_match_ccmode (insn, CCGOCmode)
12443 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12444 "sar{b}\t{%2, %0|%0, %2}"
12445 [(set_attr "type" "ishift")
12446 (set_attr "mode" "QI")])
12448 (define_insn "*ashrqi3_cconly"
12449 [(set (reg FLAGS_REG)
12451 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12452 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12454 (clobber (match_scratch:QI 0 "=q"))]
12455 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12456 && ix86_match_ccmode (insn, CCGOCmode)
12457 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12458 "sar{b}\t{%2, %0|%0, %2}"
12459 [(set_attr "type" "ishift")
12460 (set_attr "mode" "QI")])
12463 ;; Logical shift instructions
12465 ;; See comment above `ashldi3' about how this works.
12467 (define_expand "lshrti3"
12468 [(set (match_operand:TI 0 "register_operand" "")
12469 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12470 (match_operand:QI 2 "nonmemory_operand" "")))]
12472 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12474 ;; This pattern must be defined before *lshrti3_1 to prevent
12475 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12477 (define_insn "sse2_lshrti3"
12478 [(set (match_operand:TI 0 "register_operand" "=x")
12479 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12480 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12483 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12484 return "psrldq\t{%2, %0|%0, %2}";
12486 [(set_attr "type" "sseishft")
12487 (set_attr "prefix_data16" "1")
12488 (set_attr "mode" "TI")])
12490 (define_insn "*lshrti3_1"
12491 [(set (match_operand:TI 0 "register_operand" "=r")
12492 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12493 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12494 (clobber (reg:CC FLAGS_REG))]
12497 [(set_attr "type" "multi")])
12500 [(match_scratch:DI 3 "r")
12501 (parallel [(set (match_operand:TI 0 "register_operand" "")
12502 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12503 (match_operand:QI 2 "nonmemory_operand" "")))
12504 (clobber (reg:CC FLAGS_REG))])
12508 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12511 [(set (match_operand:TI 0 "register_operand" "")
12512 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12513 (match_operand:QI 2 "nonmemory_operand" "")))
12514 (clobber (reg:CC FLAGS_REG))]
12515 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12516 ? epilogue_completed : reload_completed)"
12518 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12520 (define_expand "lshrdi3"
12521 [(set (match_operand:DI 0 "shiftdi_operand" "")
12522 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12523 (match_operand:QI 2 "nonmemory_operand" "")))]
12525 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12527 (define_insn "*lshrdi3_1_one_bit_rex64"
12528 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12529 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12530 (match_operand:QI 2 "const1_operand" "")))
12531 (clobber (reg:CC FLAGS_REG))]
12533 && (TARGET_SHIFT1 || optimize_size)
12534 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12536 [(set_attr "type" "ishift")
12537 (set (attr "length")
12538 (if_then_else (match_operand:DI 0 "register_operand" "")
12540 (const_string "*")))])
12542 (define_insn "*lshrdi3_1_rex64"
12543 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12544 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12545 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12546 (clobber (reg:CC FLAGS_REG))]
12547 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12549 shr{q}\t{%2, %0|%0, %2}
12550 shr{q}\t{%b2, %0|%0, %b2}"
12551 [(set_attr "type" "ishift")
12552 (set_attr "mode" "DI")])
12554 ;; This pattern can't accept a variable shift count, since shifts by
12555 ;; zero don't affect the flags. We assume that shifts by constant
12556 ;; zero are optimized away.
12557 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12558 [(set (reg FLAGS_REG)
12560 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12561 (match_operand:QI 2 "const1_operand" ""))
12563 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12564 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12566 && (TARGET_SHIFT1 || optimize_size)
12567 && ix86_match_ccmode (insn, CCGOCmode)
12568 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12570 [(set_attr "type" "ishift")
12571 (set (attr "length")
12572 (if_then_else (match_operand:DI 0 "register_operand" "")
12574 (const_string "*")))])
12576 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12577 [(set (reg FLAGS_REG)
12579 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12580 (match_operand:QI 2 "const1_operand" ""))
12582 (clobber (match_scratch:DI 0 "=r"))]
12584 && (TARGET_SHIFT1 || optimize_size)
12585 && ix86_match_ccmode (insn, CCGOCmode)
12586 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12588 [(set_attr "type" "ishift")
12589 (set_attr "length" "2")])
12591 ;; This pattern can't accept a variable shift count, since shifts by
12592 ;; zero don't affect the flags. We assume that shifts by constant
12593 ;; zero are optimized away.
12594 (define_insn "*lshrdi3_cmp_rex64"
12595 [(set (reg FLAGS_REG)
12597 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12598 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12600 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12601 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12603 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12604 && ix86_match_ccmode (insn, CCGOCmode)
12605 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12606 "shr{q}\t{%2, %0|%0, %2}"
12607 [(set_attr "type" "ishift")
12608 (set_attr "mode" "DI")])
12610 (define_insn "*lshrdi3_cconly_rex64"
12611 [(set (reg FLAGS_REG)
12613 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12614 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12616 (clobber (match_scratch:DI 0 "=r"))]
12618 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12619 && ix86_match_ccmode (insn, CCGOCmode)
12620 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12621 "shr{q}\t{%2, %0|%0, %2}"
12622 [(set_attr "type" "ishift")
12623 (set_attr "mode" "DI")])
12625 (define_insn "*lshrdi3_1"
12626 [(set (match_operand:DI 0 "register_operand" "=r")
12627 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12628 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12629 (clobber (reg:CC FLAGS_REG))]
12632 [(set_attr "type" "multi")])
12634 ;; By default we don't ask for a scratch register, because when DImode
12635 ;; values are manipulated, registers are already at a premium. But if
12636 ;; we have one handy, we won't turn it away.
12638 [(match_scratch:SI 3 "r")
12639 (parallel [(set (match_operand:DI 0 "register_operand" "")
12640 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12641 (match_operand:QI 2 "nonmemory_operand" "")))
12642 (clobber (reg:CC FLAGS_REG))])
12644 "!TARGET_64BIT && TARGET_CMOVE"
12646 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12649 [(set (match_operand:DI 0 "register_operand" "")
12650 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12651 (match_operand:QI 2 "nonmemory_operand" "")))
12652 (clobber (reg:CC FLAGS_REG))]
12653 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12654 ? epilogue_completed : reload_completed)"
12656 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12658 (define_expand "lshrsi3"
12659 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12660 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12661 (match_operand:QI 2 "nonmemory_operand" "")))]
12663 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12665 (define_insn "*lshrsi3_1_one_bit"
12666 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12667 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12668 (match_operand:QI 2 "const1_operand" "")))
12669 (clobber (reg:CC FLAGS_REG))]
12670 "(TARGET_SHIFT1 || optimize_size)
12671 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12673 [(set_attr "type" "ishift")
12674 (set (attr "length")
12675 (if_then_else (match_operand:SI 0 "register_operand" "")
12677 (const_string "*")))])
12679 (define_insn "*lshrsi3_1_one_bit_zext"
12680 [(set (match_operand:DI 0 "register_operand" "=r")
12681 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12682 (match_operand:QI 2 "const1_operand" "")))
12683 (clobber (reg:CC FLAGS_REG))]
12685 && (TARGET_SHIFT1 || optimize_size)
12686 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12688 [(set_attr "type" "ishift")
12689 (set_attr "length" "2")])
12691 (define_insn "*lshrsi3_1"
12692 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12693 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12694 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12695 (clobber (reg:CC FLAGS_REG))]
12696 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12698 shr{l}\t{%2, %0|%0, %2}
12699 shr{l}\t{%b2, %0|%0, %b2}"
12700 [(set_attr "type" "ishift")
12701 (set_attr "mode" "SI")])
12703 (define_insn "*lshrsi3_1_zext"
12704 [(set (match_operand:DI 0 "register_operand" "=r,r")
12706 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12707 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12708 (clobber (reg:CC FLAGS_REG))]
12709 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12711 shr{l}\t{%2, %k0|%k0, %2}
12712 shr{l}\t{%b2, %k0|%k0, %b2}"
12713 [(set_attr "type" "ishift")
12714 (set_attr "mode" "SI")])
12716 ;; This pattern can't accept a variable shift count, since shifts by
12717 ;; zero don't affect the flags. We assume that shifts by constant
12718 ;; zero are optimized away.
12719 (define_insn "*lshrsi3_one_bit_cmp"
12720 [(set (reg FLAGS_REG)
12722 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12723 (match_operand:QI 2 "const1_operand" ""))
12725 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12726 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12727 "(TARGET_SHIFT1 || optimize_size)
12728 && ix86_match_ccmode (insn, CCGOCmode)
12729 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12731 [(set_attr "type" "ishift")
12732 (set (attr "length")
12733 (if_then_else (match_operand:SI 0 "register_operand" "")
12735 (const_string "*")))])
12737 (define_insn "*lshrsi3_one_bit_cconly"
12738 [(set (reg FLAGS_REG)
12740 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12741 (match_operand:QI 2 "const1_operand" ""))
12743 (clobber (match_scratch:SI 0 "=r"))]
12744 "(TARGET_SHIFT1 || optimize_size)
12745 && ix86_match_ccmode (insn, CCGOCmode)
12746 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12748 [(set_attr "type" "ishift")
12749 (set_attr "length" "2")])
12751 (define_insn "*lshrsi3_cmp_one_bit_zext"
12752 [(set (reg FLAGS_REG)
12754 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12755 (match_operand:QI 2 "const1_operand" ""))
12757 (set (match_operand:DI 0 "register_operand" "=r")
12758 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12760 && (TARGET_SHIFT1 || optimize_size)
12761 && ix86_match_ccmode (insn, CCGOCmode)
12762 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12764 [(set_attr "type" "ishift")
12765 (set_attr "length" "2")])
12767 ;; This pattern can't accept a variable shift count, since shifts by
12768 ;; zero don't affect the flags. We assume that shifts by constant
12769 ;; zero are optimized away.
12770 (define_insn "*lshrsi3_cmp"
12771 [(set (reg FLAGS_REG)
12773 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12774 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12776 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12777 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12778 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12779 && ix86_match_ccmode (insn, CCGOCmode)
12780 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781 "shr{l}\t{%2, %0|%0, %2}"
12782 [(set_attr "type" "ishift")
12783 (set_attr "mode" "SI")])
12785 (define_insn "*lshrsi3_cconly"
12786 [(set (reg FLAGS_REG)
12788 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12789 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12791 (clobber (match_scratch:SI 0 "=r"))]
12792 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12793 && ix86_match_ccmode (insn, CCGOCmode)
12794 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12795 "shr{l}\t{%2, %0|%0, %2}"
12796 [(set_attr "type" "ishift")
12797 (set_attr "mode" "SI")])
12799 (define_insn "*lshrsi3_cmp_zext"
12800 [(set (reg FLAGS_REG)
12802 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12803 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12805 (set (match_operand:DI 0 "register_operand" "=r")
12806 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12808 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12809 && ix86_match_ccmode (insn, CCGOCmode)
12810 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12811 "shr{l}\t{%2, %k0|%k0, %2}"
12812 [(set_attr "type" "ishift")
12813 (set_attr "mode" "SI")])
12815 (define_expand "lshrhi3"
12816 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12817 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12818 (match_operand:QI 2 "nonmemory_operand" "")))]
12819 "TARGET_HIMODE_MATH"
12820 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12822 (define_insn "*lshrhi3_1_one_bit"
12823 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12824 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12825 (match_operand:QI 2 "const1_operand" "")))
12826 (clobber (reg:CC FLAGS_REG))]
12827 "(TARGET_SHIFT1 || optimize_size)
12828 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12830 [(set_attr "type" "ishift")
12831 (set (attr "length")
12832 (if_then_else (match_operand 0 "register_operand" "")
12834 (const_string "*")))])
12836 (define_insn "*lshrhi3_1"
12837 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12838 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12839 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12840 (clobber (reg:CC FLAGS_REG))]
12841 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12843 shr{w}\t{%2, %0|%0, %2}
12844 shr{w}\t{%b2, %0|%0, %b2}"
12845 [(set_attr "type" "ishift")
12846 (set_attr "mode" "HI")])
12848 ;; This pattern can't accept a variable shift count, since shifts by
12849 ;; zero don't affect the flags. We assume that shifts by constant
12850 ;; zero are optimized away.
12851 (define_insn "*lshrhi3_one_bit_cmp"
12852 [(set (reg FLAGS_REG)
12854 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12855 (match_operand:QI 2 "const1_operand" ""))
12857 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12858 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12859 "(TARGET_SHIFT1 || optimize_size)
12860 && ix86_match_ccmode (insn, CCGOCmode)
12861 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12863 [(set_attr "type" "ishift")
12864 (set (attr "length")
12865 (if_then_else (match_operand:SI 0 "register_operand" "")
12867 (const_string "*")))])
12869 (define_insn "*lshrhi3_one_bit_cconly"
12870 [(set (reg FLAGS_REG)
12872 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12873 (match_operand:QI 2 "const1_operand" ""))
12875 (clobber (match_scratch:HI 0 "=r"))]
12876 "(TARGET_SHIFT1 || optimize_size)
12877 && ix86_match_ccmode (insn, CCGOCmode)
12878 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12880 [(set_attr "type" "ishift")
12881 (set_attr "length" "2")])
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 "*lshrhi3_cmp"
12887 [(set (reg FLAGS_REG)
12889 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12890 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12892 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12894 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12895 && ix86_match_ccmode (insn, CCGOCmode)
12896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897 "shr{w}\t{%2, %0|%0, %2}"
12898 [(set_attr "type" "ishift")
12899 (set_attr "mode" "HI")])
12901 (define_insn "*lshrhi3_cconly"
12902 [(set (reg FLAGS_REG)
12904 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12905 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12907 (clobber (match_scratch:HI 0 "=r"))]
12908 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12909 && ix86_match_ccmode (insn, CCGOCmode)
12910 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12911 "shr{w}\t{%2, %0|%0, %2}"
12912 [(set_attr "type" "ishift")
12913 (set_attr "mode" "HI")])
12915 (define_expand "lshrqi3"
12916 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12917 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12918 (match_operand:QI 2 "nonmemory_operand" "")))]
12919 "TARGET_QIMODE_MATH"
12920 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12922 (define_insn "*lshrqi3_1_one_bit"
12923 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12924 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12925 (match_operand:QI 2 "const1_operand" "")))
12926 (clobber (reg:CC FLAGS_REG))]
12927 "(TARGET_SHIFT1 || optimize_size)
12928 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12930 [(set_attr "type" "ishift")
12931 (set (attr "length")
12932 (if_then_else (match_operand 0 "register_operand" "")
12934 (const_string "*")))])
12936 (define_insn "*lshrqi3_1_one_bit_slp"
12937 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12938 (lshiftrt:QI (match_dup 0)
12939 (match_operand:QI 1 "const1_operand" "")))
12940 (clobber (reg:CC FLAGS_REG))]
12941 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12942 && (TARGET_SHIFT1 || optimize_size)"
12944 [(set_attr "type" "ishift1")
12945 (set (attr "length")
12946 (if_then_else (match_operand 0 "register_operand" "")
12948 (const_string "*")))])
12950 (define_insn "*lshrqi3_1"
12951 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12952 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12953 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12954 (clobber (reg:CC FLAGS_REG))]
12955 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12957 shr{b}\t{%2, %0|%0, %2}
12958 shr{b}\t{%b2, %0|%0, %b2}"
12959 [(set_attr "type" "ishift")
12960 (set_attr "mode" "QI")])
12962 (define_insn "*lshrqi3_1_slp"
12963 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12964 (lshiftrt:QI (match_dup 0)
12965 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12966 (clobber (reg:CC FLAGS_REG))]
12967 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12968 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12970 shr{b}\t{%1, %0|%0, %1}
12971 shr{b}\t{%b1, %0|%0, %b1}"
12972 [(set_attr "type" "ishift1")
12973 (set_attr "mode" "QI")])
12975 ;; This pattern can't accept a variable shift count, since shifts by
12976 ;; zero don't affect the flags. We assume that shifts by constant
12977 ;; zero are optimized away.
12978 (define_insn "*lshrqi2_one_bit_cmp"
12979 [(set (reg FLAGS_REG)
12981 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12982 (match_operand:QI 2 "const1_operand" ""))
12984 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12985 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12986 "(TARGET_SHIFT1 || optimize_size)
12987 && ix86_match_ccmode (insn, CCGOCmode)
12988 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12990 [(set_attr "type" "ishift")
12991 (set (attr "length")
12992 (if_then_else (match_operand:SI 0 "register_operand" "")
12994 (const_string "*")))])
12996 (define_insn "*lshrqi2_one_bit_cconly"
12997 [(set (reg FLAGS_REG)
12999 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13000 (match_operand:QI 2 "const1_operand" ""))
13002 (clobber (match_scratch:QI 0 "=q"))]
13003 "(TARGET_SHIFT1 || optimize_size)
13004 && ix86_match_ccmode (insn, CCGOCmode)
13005 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13007 [(set_attr "type" "ishift")
13008 (set_attr "length" "2")])
13010 ;; This pattern can't accept a variable shift count, since shifts by
13011 ;; zero don't affect the flags. We assume that shifts by constant
13012 ;; zero are optimized away.
13013 (define_insn "*lshrqi2_cmp"
13014 [(set (reg FLAGS_REG)
13016 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13017 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13019 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13020 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13021 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13022 && ix86_match_ccmode (insn, CCGOCmode)
13023 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13024 "shr{b}\t{%2, %0|%0, %2}"
13025 [(set_attr "type" "ishift")
13026 (set_attr "mode" "QI")])
13028 (define_insn "*lshrqi2_cconly"
13029 [(set (reg FLAGS_REG)
13031 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13032 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13034 (clobber (match_scratch:QI 0 "=q"))]
13035 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13036 && ix86_match_ccmode (insn, CCGOCmode)
13037 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13038 "shr{b}\t{%2, %0|%0, %2}"
13039 [(set_attr "type" "ishift")
13040 (set_attr "mode" "QI")])
13042 ;; Rotate instructions
13044 (define_expand "rotldi3"
13045 [(set (match_operand:DI 0 "shiftdi_operand" "")
13046 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13047 (match_operand:QI 2 "nonmemory_operand" "")))]
13052 ix86_expand_binary_operator (ROTATE, DImode, operands);
13055 if (!const_1_to_31_operand (operands[2], VOIDmode))
13057 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13061 ;; Implement rotation using two double-precision shift instructions
13062 ;; and a scratch register.
13063 (define_insn_and_split "ix86_rotldi3"
13064 [(set (match_operand:DI 0 "register_operand" "=r")
13065 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13066 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13067 (clobber (reg:CC FLAGS_REG))
13068 (clobber (match_scratch:SI 3 "=&r"))]
13071 "&& reload_completed"
13072 [(set (match_dup 3) (match_dup 4))
13074 [(set (match_dup 4)
13075 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13076 (lshiftrt:SI (match_dup 5)
13077 (minus:QI (const_int 32) (match_dup 2)))))
13078 (clobber (reg:CC FLAGS_REG))])
13080 [(set (match_dup 5)
13081 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13082 (lshiftrt:SI (match_dup 3)
13083 (minus:QI (const_int 32) (match_dup 2)))))
13084 (clobber (reg:CC FLAGS_REG))])]
13085 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13087 (define_insn "*rotlsi3_1_one_bit_rex64"
13088 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13089 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13090 (match_operand:QI 2 "const1_operand" "")))
13091 (clobber (reg:CC FLAGS_REG))]
13093 && (TARGET_SHIFT1 || optimize_size)
13094 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13096 [(set_attr "type" "rotate")
13097 (set (attr "length")
13098 (if_then_else (match_operand:DI 0 "register_operand" "")
13100 (const_string "*")))])
13102 (define_insn "*rotldi3_1_rex64"
13103 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13104 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13105 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13106 (clobber (reg:CC FLAGS_REG))]
13107 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13109 rol{q}\t{%2, %0|%0, %2}
13110 rol{q}\t{%b2, %0|%0, %b2}"
13111 [(set_attr "type" "rotate")
13112 (set_attr "mode" "DI")])
13114 (define_expand "rotlsi3"
13115 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13116 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13117 (match_operand:QI 2 "nonmemory_operand" "")))]
13119 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13121 (define_insn "*rotlsi3_1_one_bit"
13122 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13123 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13124 (match_operand:QI 2 "const1_operand" "")))
13125 (clobber (reg:CC FLAGS_REG))]
13126 "(TARGET_SHIFT1 || optimize_size)
13127 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13129 [(set_attr "type" "rotate")
13130 (set (attr "length")
13131 (if_then_else (match_operand:SI 0 "register_operand" "")
13133 (const_string "*")))])
13135 (define_insn "*rotlsi3_1_one_bit_zext"
13136 [(set (match_operand:DI 0 "register_operand" "=r")
13138 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13139 (match_operand:QI 2 "const1_operand" ""))))
13140 (clobber (reg:CC FLAGS_REG))]
13142 && (TARGET_SHIFT1 || optimize_size)
13143 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13145 [(set_attr "type" "rotate")
13146 (set_attr "length" "2")])
13148 (define_insn "*rotlsi3_1"
13149 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13150 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13151 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13152 (clobber (reg:CC FLAGS_REG))]
13153 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13155 rol{l}\t{%2, %0|%0, %2}
13156 rol{l}\t{%b2, %0|%0, %b2}"
13157 [(set_attr "type" "rotate")
13158 (set_attr "mode" "SI")])
13160 (define_insn "*rotlsi3_1_zext"
13161 [(set (match_operand:DI 0 "register_operand" "=r,r")
13163 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13164 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13165 (clobber (reg:CC FLAGS_REG))]
13166 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13168 rol{l}\t{%2, %k0|%k0, %2}
13169 rol{l}\t{%b2, %k0|%k0, %b2}"
13170 [(set_attr "type" "rotate")
13171 (set_attr "mode" "SI")])
13173 (define_expand "rotlhi3"
13174 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13175 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13176 (match_operand:QI 2 "nonmemory_operand" "")))]
13177 "TARGET_HIMODE_MATH"
13178 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13180 (define_insn "*rotlhi3_1_one_bit"
13181 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13182 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13183 (match_operand:QI 2 "const1_operand" "")))
13184 (clobber (reg:CC FLAGS_REG))]
13185 "(TARGET_SHIFT1 || optimize_size)
13186 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13188 [(set_attr "type" "rotate")
13189 (set (attr "length")
13190 (if_then_else (match_operand 0 "register_operand" "")
13192 (const_string "*")))])
13194 (define_insn "*rotlhi3_1"
13195 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13196 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13197 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13198 (clobber (reg:CC FLAGS_REG))]
13199 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13201 rol{w}\t{%2, %0|%0, %2}
13202 rol{w}\t{%b2, %0|%0, %b2}"
13203 [(set_attr "type" "rotate")
13204 (set_attr "mode" "HI")])
13207 [(set (match_operand:HI 0 "register_operand" "")
13208 (rotate:HI (match_dup 0) (const_int 8)))
13209 (clobber (reg:CC FLAGS_REG))]
13211 [(parallel [(set (strict_low_part (match_dup 0))
13212 (bswap:HI (match_dup 0)))
13213 (clobber (reg:CC FLAGS_REG))])]
13216 (define_expand "rotlqi3"
13217 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13218 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13219 (match_operand:QI 2 "nonmemory_operand" "")))]
13220 "TARGET_QIMODE_MATH"
13221 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13223 (define_insn "*rotlqi3_1_one_bit_slp"
13224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13225 (rotate:QI (match_dup 0)
13226 (match_operand:QI 1 "const1_operand" "")))
13227 (clobber (reg:CC FLAGS_REG))]
13228 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13229 && (TARGET_SHIFT1 || optimize_size)"
13231 [(set_attr "type" "rotate1")
13232 (set (attr "length")
13233 (if_then_else (match_operand 0 "register_operand" "")
13235 (const_string "*")))])
13237 (define_insn "*rotlqi3_1_one_bit"
13238 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13239 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13240 (match_operand:QI 2 "const1_operand" "")))
13241 (clobber (reg:CC FLAGS_REG))]
13242 "(TARGET_SHIFT1 || optimize_size)
13243 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13245 [(set_attr "type" "rotate")
13246 (set (attr "length")
13247 (if_then_else (match_operand 0 "register_operand" "")
13249 (const_string "*")))])
13251 (define_insn "*rotlqi3_1_slp"
13252 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13253 (rotate:QI (match_dup 0)
13254 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13255 (clobber (reg:CC FLAGS_REG))]
13256 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13257 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13259 rol{b}\t{%1, %0|%0, %1}
13260 rol{b}\t{%b1, %0|%0, %b1}"
13261 [(set_attr "type" "rotate1")
13262 (set_attr "mode" "QI")])
13264 (define_insn "*rotlqi3_1"
13265 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13266 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13267 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13268 (clobber (reg:CC FLAGS_REG))]
13269 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13271 rol{b}\t{%2, %0|%0, %2}
13272 rol{b}\t{%b2, %0|%0, %b2}"
13273 [(set_attr "type" "rotate")
13274 (set_attr "mode" "QI")])
13276 (define_expand "rotrdi3"
13277 [(set (match_operand:DI 0 "shiftdi_operand" "")
13278 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13279 (match_operand:QI 2 "nonmemory_operand" "")))]
13284 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13287 if (!const_1_to_31_operand (operands[2], VOIDmode))
13289 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13293 ;; Implement rotation using two double-precision shift instructions
13294 ;; and a scratch register.
13295 (define_insn_and_split "ix86_rotrdi3"
13296 [(set (match_operand:DI 0 "register_operand" "=r")
13297 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13298 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13299 (clobber (reg:CC FLAGS_REG))
13300 (clobber (match_scratch:SI 3 "=&r"))]
13303 "&& reload_completed"
13304 [(set (match_dup 3) (match_dup 4))
13306 [(set (match_dup 4)
13307 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13308 (ashift:SI (match_dup 5)
13309 (minus:QI (const_int 32) (match_dup 2)))))
13310 (clobber (reg:CC FLAGS_REG))])
13312 [(set (match_dup 5)
13313 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13314 (ashift:SI (match_dup 3)
13315 (minus:QI (const_int 32) (match_dup 2)))))
13316 (clobber (reg:CC FLAGS_REG))])]
13317 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13319 (define_insn "*rotrdi3_1_one_bit_rex64"
13320 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13321 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13322 (match_operand:QI 2 "const1_operand" "")))
13323 (clobber (reg:CC FLAGS_REG))]
13325 && (TARGET_SHIFT1 || optimize_size)
13326 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13328 [(set_attr "type" "rotate")
13329 (set (attr "length")
13330 (if_then_else (match_operand:DI 0 "register_operand" "")
13332 (const_string "*")))])
13334 (define_insn "*rotrdi3_1_rex64"
13335 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13336 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13337 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13338 (clobber (reg:CC FLAGS_REG))]
13339 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13341 ror{q}\t{%2, %0|%0, %2}
13342 ror{q}\t{%b2, %0|%0, %b2}"
13343 [(set_attr "type" "rotate")
13344 (set_attr "mode" "DI")])
13346 (define_expand "rotrsi3"
13347 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13348 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13349 (match_operand:QI 2 "nonmemory_operand" "")))]
13351 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13353 (define_insn "*rotrsi3_1_one_bit"
13354 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13355 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13356 (match_operand:QI 2 "const1_operand" "")))
13357 (clobber (reg:CC FLAGS_REG))]
13358 "(TARGET_SHIFT1 || optimize_size)
13359 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13361 [(set_attr "type" "rotate")
13362 (set (attr "length")
13363 (if_then_else (match_operand:SI 0 "register_operand" "")
13365 (const_string "*")))])
13367 (define_insn "*rotrsi3_1_one_bit_zext"
13368 [(set (match_operand:DI 0 "register_operand" "=r")
13370 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13371 (match_operand:QI 2 "const1_operand" ""))))
13372 (clobber (reg:CC FLAGS_REG))]
13374 && (TARGET_SHIFT1 || optimize_size)
13375 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13377 [(set_attr "type" "rotate")
13378 (set (attr "length")
13379 (if_then_else (match_operand:SI 0 "register_operand" "")
13381 (const_string "*")))])
13383 (define_insn "*rotrsi3_1"
13384 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13385 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13386 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13387 (clobber (reg:CC FLAGS_REG))]
13388 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13390 ror{l}\t{%2, %0|%0, %2}
13391 ror{l}\t{%b2, %0|%0, %b2}"
13392 [(set_attr "type" "rotate")
13393 (set_attr "mode" "SI")])
13395 (define_insn "*rotrsi3_1_zext"
13396 [(set (match_operand:DI 0 "register_operand" "=r,r")
13398 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13399 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13400 (clobber (reg:CC FLAGS_REG))]
13401 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13403 ror{l}\t{%2, %k0|%k0, %2}
13404 ror{l}\t{%b2, %k0|%k0, %b2}"
13405 [(set_attr "type" "rotate")
13406 (set_attr "mode" "SI")])
13408 (define_expand "rotrhi3"
13409 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13410 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13411 (match_operand:QI 2 "nonmemory_operand" "")))]
13412 "TARGET_HIMODE_MATH"
13413 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13415 (define_insn "*rotrhi3_one_bit"
13416 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13417 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13418 (match_operand:QI 2 "const1_operand" "")))
13419 (clobber (reg:CC FLAGS_REG))]
13420 "(TARGET_SHIFT1 || optimize_size)
13421 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13423 [(set_attr "type" "rotate")
13424 (set (attr "length")
13425 (if_then_else (match_operand 0 "register_operand" "")
13427 (const_string "*")))])
13429 (define_insn "*rotrhi3_1"
13430 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13431 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13432 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13433 (clobber (reg:CC FLAGS_REG))]
13434 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13436 ror{w}\t{%2, %0|%0, %2}
13437 ror{w}\t{%b2, %0|%0, %b2}"
13438 [(set_attr "type" "rotate")
13439 (set_attr "mode" "HI")])
13442 [(set (match_operand:HI 0 "register_operand" "")
13443 (rotatert:HI (match_dup 0) (const_int 8)))
13444 (clobber (reg:CC FLAGS_REG))]
13446 [(parallel [(set (strict_low_part (match_dup 0))
13447 (bswap:HI (match_dup 0)))
13448 (clobber (reg:CC FLAGS_REG))])]
13451 (define_expand "rotrqi3"
13452 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13453 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13454 (match_operand:QI 2 "nonmemory_operand" "")))]
13455 "TARGET_QIMODE_MATH"
13456 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13458 (define_insn "*rotrqi3_1_one_bit"
13459 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13460 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13461 (match_operand:QI 2 "const1_operand" "")))
13462 (clobber (reg:CC FLAGS_REG))]
13463 "(TARGET_SHIFT1 || optimize_size)
13464 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13466 [(set_attr "type" "rotate")
13467 (set (attr "length")
13468 (if_then_else (match_operand 0 "register_operand" "")
13470 (const_string "*")))])
13472 (define_insn "*rotrqi3_1_one_bit_slp"
13473 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13474 (rotatert:QI (match_dup 0)
13475 (match_operand:QI 1 "const1_operand" "")))
13476 (clobber (reg:CC FLAGS_REG))]
13477 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13478 && (TARGET_SHIFT1 || optimize_size)"
13480 [(set_attr "type" "rotate1")
13481 (set (attr "length")
13482 (if_then_else (match_operand 0 "register_operand" "")
13484 (const_string "*")))])
13486 (define_insn "*rotrqi3_1"
13487 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13488 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13489 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13490 (clobber (reg:CC FLAGS_REG))]
13491 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13493 ror{b}\t{%2, %0|%0, %2}
13494 ror{b}\t{%b2, %0|%0, %b2}"
13495 [(set_attr "type" "rotate")
13496 (set_attr "mode" "QI")])
13498 (define_insn "*rotrqi3_1_slp"
13499 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13500 (rotatert:QI (match_dup 0)
13501 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13502 (clobber (reg:CC FLAGS_REG))]
13503 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13504 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13506 ror{b}\t{%1, %0|%0, %1}
13507 ror{b}\t{%b1, %0|%0, %b1}"
13508 [(set_attr "type" "rotate1")
13509 (set_attr "mode" "QI")])
13511 ;; Bit set / bit test instructions
13513 (define_expand "extv"
13514 [(set (match_operand:SI 0 "register_operand" "")
13515 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13516 (match_operand:SI 2 "const8_operand" "")
13517 (match_operand:SI 3 "const8_operand" "")))]
13520 /* Handle extractions from %ah et al. */
13521 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13524 /* From mips.md: extract_bit_field doesn't verify that our source
13525 matches the predicate, so check it again here. */
13526 if (! ext_register_operand (operands[1], VOIDmode))
13530 (define_expand "extzv"
13531 [(set (match_operand:SI 0 "register_operand" "")
13532 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13533 (match_operand:SI 2 "const8_operand" "")
13534 (match_operand:SI 3 "const8_operand" "")))]
13537 /* Handle extractions from %ah et al. */
13538 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13541 /* From mips.md: extract_bit_field doesn't verify that our source
13542 matches the predicate, so check it again here. */
13543 if (! ext_register_operand (operands[1], VOIDmode))
13547 (define_expand "insv"
13548 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13549 (match_operand 1 "const8_operand" "")
13550 (match_operand 2 "const8_operand" ""))
13551 (match_operand 3 "register_operand" ""))]
13554 /* Handle insertions to %ah et al. */
13555 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13558 /* From mips.md: insert_bit_field doesn't verify that our source
13559 matches the predicate, so check it again here. */
13560 if (! ext_register_operand (operands[0], VOIDmode))
13564 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13566 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13571 ;; %%% bts, btr, btc, bt.
13572 ;; In general these instructions are *slow* when applied to memory,
13573 ;; since they enforce atomic operation. When applied to registers,
13574 ;; it depends on the cpu implementation. They're never faster than
13575 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13576 ;; no point. But in 64-bit, we can't hold the relevant immediates
13577 ;; within the instruction itself, so operating on bits in the high
13578 ;; 32-bits of a register becomes easier.
13580 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13581 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13582 ;; negdf respectively, so they can never be disabled entirely.
13584 (define_insn "*btsq"
13585 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13587 (match_operand:DI 1 "const_0_to_63_operand" ""))
13589 (clobber (reg:CC FLAGS_REG))]
13590 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13591 "bts{q}\t{%1, %0|%0, %1}"
13592 [(set_attr "type" "alu1")])
13594 (define_insn "*btrq"
13595 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13597 (match_operand:DI 1 "const_0_to_63_operand" ""))
13599 (clobber (reg:CC FLAGS_REG))]
13600 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13601 "btr{q}\t{%1, %0|%0, %1}"
13602 [(set_attr "type" "alu1")])
13604 (define_insn "*btcq"
13605 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13607 (match_operand:DI 1 "const_0_to_63_operand" ""))
13608 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13609 (clobber (reg:CC FLAGS_REG))]
13610 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13611 "btc{q}\t{%1, %0|%0, %1}"
13612 [(set_attr "type" "alu1")])
13614 ;; Allow Nocona to avoid these instructions if a register is available.
13617 [(match_scratch:DI 2 "r")
13618 (parallel [(set (zero_extract:DI
13619 (match_operand:DI 0 "register_operand" "")
13621 (match_operand:DI 1 "const_0_to_63_operand" ""))
13623 (clobber (reg:CC FLAGS_REG))])]
13624 "TARGET_64BIT && !TARGET_USE_BT"
13627 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13630 if (HOST_BITS_PER_WIDE_INT >= 64)
13631 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13632 else if (i < HOST_BITS_PER_WIDE_INT)
13633 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13635 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13637 op1 = immed_double_const (lo, hi, DImode);
13640 emit_move_insn (operands[2], op1);
13644 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13649 [(match_scratch:DI 2 "r")
13650 (parallel [(set (zero_extract:DI
13651 (match_operand:DI 0 "register_operand" "")
13653 (match_operand:DI 1 "const_0_to_63_operand" ""))
13655 (clobber (reg:CC FLAGS_REG))])]
13656 "TARGET_64BIT && !TARGET_USE_BT"
13659 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13662 if (HOST_BITS_PER_WIDE_INT >= 64)
13663 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13664 else if (i < HOST_BITS_PER_WIDE_INT)
13665 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13667 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13669 op1 = immed_double_const (~lo, ~hi, DImode);
13672 emit_move_insn (operands[2], op1);
13676 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13681 [(match_scratch:DI 2 "r")
13682 (parallel [(set (zero_extract:DI
13683 (match_operand:DI 0 "register_operand" "")
13685 (match_operand:DI 1 "const_0_to_63_operand" ""))
13686 (not:DI (zero_extract:DI
13687 (match_dup 0) (const_int 1) (match_dup 1))))
13688 (clobber (reg:CC FLAGS_REG))])]
13689 "TARGET_64BIT && !TARGET_USE_BT"
13692 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13695 if (HOST_BITS_PER_WIDE_INT >= 64)
13696 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13697 else if (i < HOST_BITS_PER_WIDE_INT)
13698 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13700 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13702 op1 = immed_double_const (lo, hi, DImode);
13705 emit_move_insn (operands[2], op1);
13709 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13713 (define_insn "*btdi_rex64"
13714 [(set (reg:CCC FLAGS_REG)
13717 (match_operand:DI 0 "register_operand" "r")
13719 (match_operand:DI 1 "nonmemory_operand" "rN"))
13721 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
13722 "bt{q}\t{%1, %0|%0, %1}"
13723 [(set_attr "type" "alu1")])
13725 (define_insn "*btsi"
13726 [(set (reg:CCC FLAGS_REG)
13729 (match_operand:SI 0 "register_operand" "r")
13731 (match_operand:SI 1 "nonmemory_operand" "rN"))
13733 "TARGET_USE_BT || optimize_size"
13734 "bt{l}\t{%1, %0|%0, %1}"
13735 [(set_attr "type" "alu1")])
13737 ;; Store-flag instructions.
13739 ;; For all sCOND expanders, also expand the compare or test insn that
13740 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13742 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13743 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13744 ;; way, which can later delete the movzx if only QImode is needed.
13746 (define_expand "s<code>"
13747 [(set (match_operand:QI 0 "register_operand" "")
13748 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13750 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13752 (define_expand "s<code>"
13753 [(set (match_operand:QI 0 "register_operand" "")
13754 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13755 "TARGET_80387 || TARGET_SSE"
13756 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13758 (define_insn "*setcc_1"
13759 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13760 (match_operator:QI 1 "ix86_comparison_operator"
13761 [(reg FLAGS_REG) (const_int 0)]))]
13764 [(set_attr "type" "setcc")
13765 (set_attr "mode" "QI")])
13767 (define_insn "*setcc_2"
13768 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13769 (match_operator:QI 1 "ix86_comparison_operator"
13770 [(reg FLAGS_REG) (const_int 0)]))]
13773 [(set_attr "type" "setcc")
13774 (set_attr "mode" "QI")])
13776 ;; In general it is not safe to assume too much about CCmode registers,
13777 ;; so simplify-rtx stops when it sees a second one. Under certain
13778 ;; conditions this is safe on x86, so help combine not create
13785 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13786 (ne:QI (match_operator 1 "ix86_comparison_operator"
13787 [(reg FLAGS_REG) (const_int 0)])
13790 [(set (match_dup 0) (match_dup 1))]
13792 PUT_MODE (operands[1], QImode);
13796 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13797 (ne:QI (match_operator 1 "ix86_comparison_operator"
13798 [(reg FLAGS_REG) (const_int 0)])
13801 [(set (match_dup 0) (match_dup 1))]
13803 PUT_MODE (operands[1], QImode);
13807 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13808 (eq:QI (match_operator 1 "ix86_comparison_operator"
13809 [(reg FLAGS_REG) (const_int 0)])
13812 [(set (match_dup 0) (match_dup 1))]
13814 rtx new_op1 = copy_rtx (operands[1]);
13815 operands[1] = new_op1;
13816 PUT_MODE (new_op1, QImode);
13817 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13818 GET_MODE (XEXP (new_op1, 0))));
13820 /* Make sure that (a) the CCmode we have for the flags is strong
13821 enough for the reversed compare or (b) we have a valid FP compare. */
13822 if (! ix86_comparison_operator (new_op1, VOIDmode))
13827 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13828 (eq:QI (match_operator 1 "ix86_comparison_operator"
13829 [(reg FLAGS_REG) (const_int 0)])
13832 [(set (match_dup 0) (match_dup 1))]
13834 rtx new_op1 = copy_rtx (operands[1]);
13835 operands[1] = new_op1;
13836 PUT_MODE (new_op1, QImode);
13837 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13838 GET_MODE (XEXP (new_op1, 0))));
13840 /* Make sure that (a) the CCmode we have for the flags is strong
13841 enough for the reversed compare or (b) we have a valid FP compare. */
13842 if (! ix86_comparison_operator (new_op1, VOIDmode))
13846 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13847 ;; subsequent logical operations are used to imitate conditional moves.
13848 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13851 (define_insn "*sse_setcc<mode>"
13852 [(set (match_operand:MODEF 0 "register_operand" "=x")
13853 (match_operator:MODEF 1 "sse_comparison_operator"
13854 [(match_operand:MODEF 2 "register_operand" "0")
13855 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13856 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13857 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13858 [(set_attr "type" "ssecmp")
13859 (set_attr "mode" "<MODE>")])
13861 (define_insn "*sse5_setcc<mode>"
13862 [(set (match_operand:MODEF 0 "register_operand" "=x")
13863 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13864 [(match_operand:MODEF 2 "register_operand" "x")
13865 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13867 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13868 [(set_attr "type" "sse4arg")
13869 (set_attr "mode" "<MODE>")])
13872 ;; Basic conditional jump instructions.
13873 ;; We ignore the overflow flag for signed branch instructions.
13875 ;; For all bCOND expanders, also expand the compare or test insn that
13876 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13878 (define_expand "b<code>"
13880 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13882 (label_ref (match_operand 0 ""))
13885 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13887 (define_expand "b<code>"
13889 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13891 (label_ref (match_operand 0 ""))
13893 "TARGET_80387 || TARGET_SSE_MATH"
13894 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13896 (define_insn "*jcc_1"
13898 (if_then_else (match_operator 1 "ix86_comparison_operator"
13899 [(reg FLAGS_REG) (const_int 0)])
13900 (label_ref (match_operand 0 "" ""))
13904 [(set_attr "type" "ibr")
13905 (set_attr "modrm" "0")
13906 (set (attr "length")
13907 (if_then_else (and (ge (minus (match_dup 0) (pc))
13909 (lt (minus (match_dup 0) (pc))
13914 (define_insn "*jcc_2"
13916 (if_then_else (match_operator 1 "ix86_comparison_operator"
13917 [(reg FLAGS_REG) (const_int 0)])
13919 (label_ref (match_operand 0 "" ""))))]
13922 [(set_attr "type" "ibr")
13923 (set_attr "modrm" "0")
13924 (set (attr "length")
13925 (if_then_else (and (ge (minus (match_dup 0) (pc))
13927 (lt (minus (match_dup 0) (pc))
13932 ;; ??? Handle alignment requirements for compare and branch fused macro-op;
13933 ;; the branch instruction does not start at a 16-byte boundary or cross
13934 ;; a 16-byte boundary.
13936 (define_insn "*jcc_fused_1"
13938 (if_then_else (match_operator 1 "comparison_operator"
13939 [(match_operand:SWI 2 "register_operand" "<r>")
13940 (match_operand:SWI 3 "const0_operand" "")])
13941 (label_ref (match_operand 0 "" ""))
13943 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
13945 return "test{<imodesuffix>}\t%2, %2\n\t"
13946 "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
13948 [(set_attr "type" "multi")
13949 (set_attr "mode" "<MODE>")])
13951 (define_insn "*jcc_fused_2"
13953 (if_then_else (match_operator 1 "comparison_operator"
13954 [(match_operand:SWI 2 "register_operand" "<r>")
13955 (match_operand:SWI 3 "const0_operand" "")])
13957 (label_ref (match_operand 0 "" ""))))]
13958 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
13960 return "test{<imodesuffix>}\t%2, %2\n\t"
13961 "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
13963 [(set_attr "type" "multi")
13964 (set_attr "mode" "<MODE>")])
13966 (define_insn "*jcc_fused_3"
13969 (match_operator 1 "ix86_comparison_uns_operator"
13970 [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
13971 (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
13972 (label_ref (match_operand 0 "" ""))
13974 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
13975 && !(MEM_P (operands[2])
13976 && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
13978 return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
13979 "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
13981 [(set_attr "type" "multi")
13982 (set_attr "mode" "<MODE>")])
13984 (define_insn "*jcc_fused_4"
13987 (match_operator 1 "ix86_comparison_uns_operator"
13988 [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
13989 (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
13991 (label_ref (match_operand 0 "" ""))))]
13992 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
13993 && !(MEM_P (operands[2])
13994 && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
13996 return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
13997 "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
13999 [(set_attr "type" "multi")
14000 (set_attr "mode" "<MODE>")])
14002 ;; In general it is not safe to assume too much about CCmode registers,
14003 ;; so simplify-rtx stops when it sees a second one. Under certain
14004 ;; conditions this is safe on x86, so help combine not create
14012 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14013 [(reg FLAGS_REG) (const_int 0)])
14015 (label_ref (match_operand 1 "" ""))
14019 (if_then_else (match_dup 0)
14020 (label_ref (match_dup 1))
14023 PUT_MODE (operands[0], VOIDmode);
14028 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14029 [(reg FLAGS_REG) (const_int 0)])
14031 (label_ref (match_operand 1 "" ""))
14035 (if_then_else (match_dup 0)
14036 (label_ref (match_dup 1))
14039 rtx new_op0 = copy_rtx (operands[0]);
14040 operands[0] = new_op0;
14041 PUT_MODE (new_op0, VOIDmode);
14042 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14043 GET_MODE (XEXP (new_op0, 0))));
14045 /* Make sure that (a) the CCmode we have for the flags is strong
14046 enough for the reversed compare or (b) we have a valid FP compare. */
14047 if (! ix86_comparison_operator (new_op0, VOIDmode))
14051 ;; zero_extend in SImode is correct, since this is what combine pass
14052 ;; generates from shift insn with QImode operand. Actually, the mode of
14053 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14054 ;; appropriate modulo of the bit offset value.
14056 (define_insn_and_split "*jcc_btdi_rex64"
14058 (if_then_else (match_operator 0 "bt_comparison_operator"
14060 (match_operand:DI 1 "register_operand" "r")
14063 (match_operand:QI 2 "register_operand" "r")))
14065 (label_ref (match_operand 3 "" ""))
14067 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
14070 [(set (reg:CCC FLAGS_REG)
14078 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14079 (label_ref (match_dup 3))
14082 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14084 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14087 ;; avoid useless masking of bit offset operand
14088 (define_insn_and_split "*jcc_btdi_mask_rex64"
14090 (if_then_else (match_operator 0 "bt_comparison_operator"
14092 (match_operand:DI 1 "register_operand" "r")
14095 (match_operand:SI 2 "register_operand" "r")
14096 (match_operand:SI 3 "const_int_operand" "n")))])
14097 (label_ref (match_operand 4 "" ""))
14099 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)
14100 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14103 [(set (reg:CCC FLAGS_REG)
14111 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14112 (label_ref (match_dup 4))
14115 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14117 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14120 (define_insn_and_split "*jcc_btsi"
14122 (if_then_else (match_operator 0 "bt_comparison_operator"
14124 (match_operand:SI 1 "register_operand" "r")
14127 (match_operand:QI 2 "register_operand" "r")))
14129 (label_ref (match_operand 3 "" ""))
14131 "TARGET_USE_BT || optimize_size"
14134 [(set (reg:CCC FLAGS_REG)
14142 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14143 (label_ref (match_dup 3))
14146 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14148 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14151 ;; avoid useless masking of bit offset operand
14152 (define_insn_and_split "*jcc_btsi_mask"
14154 (if_then_else (match_operator 0 "bt_comparison_operator"
14156 (match_operand:SI 1 "register_operand" "r")
14159 (match_operand:SI 2 "register_operand" "r")
14160 (match_operand:SI 3 "const_int_operand" "n")))])
14161 (label_ref (match_operand 4 "" ""))
14163 "(TARGET_USE_BT || optimize_size)
14164 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14167 [(set (reg:CCC FLAGS_REG)
14175 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14176 (label_ref (match_dup 4))
14178 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14180 (define_insn_and_split "*jcc_btsi_1"
14182 (if_then_else (match_operator 0 "bt_comparison_operator"
14185 (match_operand:SI 1 "register_operand" "r")
14186 (match_operand:QI 2 "register_operand" "r"))
14189 (label_ref (match_operand 3 "" ""))
14191 "TARGET_USE_BT || optimize_size"
14194 [(set (reg:CCC FLAGS_REG)
14202 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14203 (label_ref (match_dup 3))
14206 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14208 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14211 ;; avoid useless masking of bit offset operand
14212 (define_insn_and_split "*jcc_btsi_mask_1"
14215 (match_operator 0 "bt_comparison_operator"
14218 (match_operand:SI 1 "register_operand" "r")
14221 (match_operand:SI 2 "register_operand" "r")
14222 (match_operand:SI 3 "const_int_operand" "n")) 0))
14225 (label_ref (match_operand 4 "" ""))
14227 "(TARGET_USE_BT || optimize_size)
14228 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14231 [(set (reg:CCC FLAGS_REG)
14239 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14240 (label_ref (match_dup 4))
14242 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14244 ;; Define combination compare-and-branch fp compare instructions to use
14245 ;; during early optimization. Splitting the operation apart early makes
14246 ;; for bad code when we want to reverse the operation.
14248 (define_insn "*fp_jcc_1_mixed"
14250 (if_then_else (match_operator 0 "comparison_operator"
14251 [(match_operand 1 "register_operand" "f,x")
14252 (match_operand 2 "nonimmediate_operand" "f,xm")])
14253 (label_ref (match_operand 3 "" ""))
14255 (clobber (reg:CCFP FPSR_REG))
14256 (clobber (reg:CCFP FLAGS_REG))]
14257 "TARGET_MIX_SSE_I387
14258 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14259 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14260 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14263 (define_insn "*fp_jcc_1_sse"
14265 (if_then_else (match_operator 0 "comparison_operator"
14266 [(match_operand 1 "register_operand" "x")
14267 (match_operand 2 "nonimmediate_operand" "xm")])
14268 (label_ref (match_operand 3 "" ""))
14270 (clobber (reg:CCFP FPSR_REG))
14271 (clobber (reg:CCFP FLAGS_REG))]
14273 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14274 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14275 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14278 (define_insn "*fp_jcc_1_387"
14280 (if_then_else (match_operator 0 "comparison_operator"
14281 [(match_operand 1 "register_operand" "f")
14282 (match_operand 2 "register_operand" "f")])
14283 (label_ref (match_operand 3 "" ""))
14285 (clobber (reg:CCFP FPSR_REG))
14286 (clobber (reg:CCFP FLAGS_REG))]
14287 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14289 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14290 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14293 (define_insn "*fp_jcc_2_mixed"
14295 (if_then_else (match_operator 0 "comparison_operator"
14296 [(match_operand 1 "register_operand" "f,x")
14297 (match_operand 2 "nonimmediate_operand" "f,xm")])
14299 (label_ref (match_operand 3 "" ""))))
14300 (clobber (reg:CCFP FPSR_REG))
14301 (clobber (reg:CCFP FLAGS_REG))]
14302 "TARGET_MIX_SSE_I387
14303 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14304 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14305 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14308 (define_insn "*fp_jcc_2_sse"
14310 (if_then_else (match_operator 0 "comparison_operator"
14311 [(match_operand 1 "register_operand" "x")
14312 (match_operand 2 "nonimmediate_operand" "xm")])
14314 (label_ref (match_operand 3 "" ""))))
14315 (clobber (reg:CCFP FPSR_REG))
14316 (clobber (reg:CCFP FLAGS_REG))]
14318 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14319 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14320 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14323 (define_insn "*fp_jcc_2_387"
14325 (if_then_else (match_operator 0 "comparison_operator"
14326 [(match_operand 1 "register_operand" "f")
14327 (match_operand 2 "register_operand" "f")])
14329 (label_ref (match_operand 3 "" ""))))
14330 (clobber (reg:CCFP FPSR_REG))
14331 (clobber (reg:CCFP FLAGS_REG))]
14332 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14334 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14335 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14338 (define_insn "*fp_jcc_3_387"
14340 (if_then_else (match_operator 0 "comparison_operator"
14341 [(match_operand 1 "register_operand" "f")
14342 (match_operand 2 "nonimmediate_operand" "fm")])
14343 (label_ref (match_operand 3 "" ""))
14345 (clobber (reg:CCFP FPSR_REG))
14346 (clobber (reg:CCFP FLAGS_REG))
14347 (clobber (match_scratch:HI 4 "=a"))]
14349 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14350 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14351 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14352 && SELECT_CC_MODE (GET_CODE (operands[0]),
14353 operands[1], operands[2]) == CCFPmode
14354 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14357 (define_insn "*fp_jcc_4_387"
14359 (if_then_else (match_operator 0 "comparison_operator"
14360 [(match_operand 1 "register_operand" "f")
14361 (match_operand 2 "nonimmediate_operand" "fm")])
14363 (label_ref (match_operand 3 "" ""))))
14364 (clobber (reg:CCFP FPSR_REG))
14365 (clobber (reg:CCFP FLAGS_REG))
14366 (clobber (match_scratch:HI 4 "=a"))]
14368 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14369 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14370 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14371 && SELECT_CC_MODE (GET_CODE (operands[0]),
14372 operands[1], operands[2]) == CCFPmode
14373 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14376 (define_insn "*fp_jcc_5_387"
14378 (if_then_else (match_operator 0 "comparison_operator"
14379 [(match_operand 1 "register_operand" "f")
14380 (match_operand 2 "register_operand" "f")])
14381 (label_ref (match_operand 3 "" ""))
14383 (clobber (reg:CCFP FPSR_REG))
14384 (clobber (reg:CCFP FLAGS_REG))
14385 (clobber (match_scratch:HI 4 "=a"))]
14386 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14387 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14388 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14391 (define_insn "*fp_jcc_6_387"
14393 (if_then_else (match_operator 0 "comparison_operator"
14394 [(match_operand 1 "register_operand" "f")
14395 (match_operand 2 "register_operand" "f")])
14397 (label_ref (match_operand 3 "" ""))))
14398 (clobber (reg:CCFP FPSR_REG))
14399 (clobber (reg:CCFP FLAGS_REG))
14400 (clobber (match_scratch:HI 4 "=a"))]
14401 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14402 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14403 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14406 (define_insn "*fp_jcc_7_387"
14408 (if_then_else (match_operator 0 "comparison_operator"
14409 [(match_operand 1 "register_operand" "f")
14410 (match_operand 2 "const0_operand" "")])
14411 (label_ref (match_operand 3 "" ""))
14413 (clobber (reg:CCFP FPSR_REG))
14414 (clobber (reg:CCFP FLAGS_REG))
14415 (clobber (match_scratch:HI 4 "=a"))]
14416 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14417 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14418 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14419 && SELECT_CC_MODE (GET_CODE (operands[0]),
14420 operands[1], operands[2]) == CCFPmode
14421 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14424 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14425 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14426 ;; with a precedence over other operators and is always put in the first
14427 ;; place. Swap condition and operands to match ficom instruction.
14429 (define_insn "*fp_jcc_8<mode>_387"
14431 (if_then_else (match_operator 0 "comparison_operator"
14432 [(match_operator 1 "float_operator"
14433 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14434 (match_operand 3 "register_operand" "f,f")])
14435 (label_ref (match_operand 4 "" ""))
14437 (clobber (reg:CCFP FPSR_REG))
14438 (clobber (reg:CCFP FLAGS_REG))
14439 (clobber (match_scratch:HI 5 "=a,a"))]
14440 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14441 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
14442 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14443 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14444 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14445 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14450 (if_then_else (match_operator 0 "comparison_operator"
14451 [(match_operand 1 "register_operand" "")
14452 (match_operand 2 "nonimmediate_operand" "")])
14453 (match_operand 3 "" "")
14454 (match_operand 4 "" "")))
14455 (clobber (reg:CCFP FPSR_REG))
14456 (clobber (reg:CCFP FLAGS_REG))]
14460 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14461 operands[3], operands[4], NULL_RTX, NULL_RTX);
14467 (if_then_else (match_operator 0 "comparison_operator"
14468 [(match_operand 1 "register_operand" "")
14469 (match_operand 2 "general_operand" "")])
14470 (match_operand 3 "" "")
14471 (match_operand 4 "" "")))
14472 (clobber (reg:CCFP FPSR_REG))
14473 (clobber (reg:CCFP FLAGS_REG))
14474 (clobber (match_scratch:HI 5 "=a"))]
14478 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14479 operands[3], operands[4], operands[5], NULL_RTX);
14485 (if_then_else (match_operator 0 "comparison_operator"
14486 [(match_operator 1 "float_operator"
14487 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14488 (match_operand 3 "register_operand" "")])
14489 (match_operand 4 "" "")
14490 (match_operand 5 "" "")))
14491 (clobber (reg:CCFP FPSR_REG))
14492 (clobber (reg:CCFP FLAGS_REG))
14493 (clobber (match_scratch:HI 6 "=a"))]
14497 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14498 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14499 operands[3], operands[7],
14500 operands[4], operands[5], operands[6], NULL_RTX);
14504 ;; %%% Kill this when reload knows how to do it.
14507 (if_then_else (match_operator 0 "comparison_operator"
14508 [(match_operator 1 "float_operator"
14509 [(match_operand:X87MODEI12 2 "register_operand" "")])
14510 (match_operand 3 "register_operand" "")])
14511 (match_operand 4 "" "")
14512 (match_operand 5 "" "")))
14513 (clobber (reg:CCFP FPSR_REG))
14514 (clobber (reg:CCFP FLAGS_REG))
14515 (clobber (match_scratch:HI 6 "=a"))]
14519 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14520 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14521 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14522 operands[3], operands[7],
14523 operands[4], operands[5], operands[6], operands[2]);
14527 ;; Unconditional and other jump instructions
14529 (define_insn "jump"
14531 (label_ref (match_operand 0 "" "")))]
14534 [(set_attr "type" "ibr")
14535 (set (attr "length")
14536 (if_then_else (and (ge (minus (match_dup 0) (pc))
14538 (lt (minus (match_dup 0) (pc))
14542 (set_attr "modrm" "0")])
14544 (define_expand "indirect_jump"
14545 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14549 (define_insn "*indirect_jump"
14550 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14553 [(set_attr "type" "ibr")
14554 (set_attr "length_immediate" "0")])
14556 (define_expand "tablejump"
14557 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14558 (use (label_ref (match_operand 1 "" "")))])]
14561 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14562 relative. Convert the relative address to an absolute address. */
14566 enum rtx_code code;
14568 /* We can't use @GOTOFF for text labels on VxWorks;
14569 see gotoff_operand. */
14570 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14574 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14576 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14580 op1 = pic_offset_table_rtx;
14585 op0 = pic_offset_table_rtx;
14589 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14594 (define_insn "*tablejump_1"
14595 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14596 (use (label_ref (match_operand 1 "" "")))]
14599 [(set_attr "type" "ibr")
14600 (set_attr "length_immediate" "0")])
14602 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14605 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14606 (set (match_operand:QI 1 "register_operand" "")
14607 (match_operator:QI 2 "ix86_comparison_operator"
14608 [(reg FLAGS_REG) (const_int 0)]))
14609 (set (match_operand 3 "q_regs_operand" "")
14610 (zero_extend (match_dup 1)))]
14611 "(peep2_reg_dead_p (3, operands[1])
14612 || operands_match_p (operands[1], operands[3]))
14613 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14614 [(set (match_dup 4) (match_dup 0))
14615 (set (strict_low_part (match_dup 5))
14618 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14619 operands[5] = gen_lowpart (QImode, operands[3]);
14620 ix86_expand_clear (operands[3]);
14623 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14626 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14627 (set (match_operand:QI 1 "register_operand" "")
14628 (match_operator:QI 2 "ix86_comparison_operator"
14629 [(reg FLAGS_REG) (const_int 0)]))
14630 (parallel [(set (match_operand 3 "q_regs_operand" "")
14631 (zero_extend (match_dup 1)))
14632 (clobber (reg:CC FLAGS_REG))])]
14633 "(peep2_reg_dead_p (3, operands[1])
14634 || operands_match_p (operands[1], operands[3]))
14635 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14636 [(set (match_dup 4) (match_dup 0))
14637 (set (strict_low_part (match_dup 5))
14640 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14641 operands[5] = gen_lowpart (QImode, operands[3]);
14642 ix86_expand_clear (operands[3]);
14645 ;; Call instructions.
14647 ;; The predicates normally associated with named expanders are not properly
14648 ;; checked for calls. This is a bug in the generic code, but it isn't that
14649 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14651 ;; Call subroutine returning no value.
14653 (define_expand "call_pop"
14654 [(parallel [(call (match_operand:QI 0 "" "")
14655 (match_operand:SI 1 "" ""))
14656 (set (reg:SI SP_REG)
14657 (plus:SI (reg:SI SP_REG)
14658 (match_operand:SI 3 "" "")))])]
14661 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14665 (define_insn "*call_pop_0"
14666 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14667 (match_operand:SI 1 "" ""))
14668 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14669 (match_operand:SI 2 "immediate_operand" "")))]
14672 if (SIBLING_CALL_P (insn))
14675 return "call\t%P0";
14677 [(set_attr "type" "call")])
14679 (define_insn "*call_pop_1"
14680 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14681 (match_operand:SI 1 "" ""))
14682 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14683 (match_operand:SI 2 "immediate_operand" "i")))]
14686 if (constant_call_address_operand (operands[0], Pmode))
14688 if (SIBLING_CALL_P (insn))
14691 return "call\t%P0";
14693 if (SIBLING_CALL_P (insn))
14696 return "call\t%A0";
14698 [(set_attr "type" "call")])
14700 (define_expand "call"
14701 [(call (match_operand:QI 0 "" "")
14702 (match_operand 1 "" ""))
14703 (use (match_operand 2 "" ""))]
14706 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14710 (define_expand "sibcall"
14711 [(call (match_operand:QI 0 "" "")
14712 (match_operand 1 "" ""))
14713 (use (match_operand 2 "" ""))]
14716 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14720 (define_insn "*call_0"
14721 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14722 (match_operand 1 "" ""))]
14725 if (SIBLING_CALL_P (insn))
14728 return "call\t%P0";
14730 [(set_attr "type" "call")])
14732 (define_insn "*call_1"
14733 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14734 (match_operand 1 "" ""))]
14735 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14737 if (constant_call_address_operand (operands[0], Pmode))
14738 return "call\t%P0";
14739 return "call\t%A0";
14741 [(set_attr "type" "call")])
14743 (define_insn "*sibcall_1"
14744 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14745 (match_operand 1 "" ""))]
14746 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14748 if (constant_call_address_operand (operands[0], Pmode))
14752 [(set_attr "type" "call")])
14754 (define_insn "*call_1_rex64"
14755 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14756 (match_operand 1 "" ""))]
14757 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14758 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14760 if (constant_call_address_operand (operands[0], Pmode))
14761 return "call\t%P0";
14762 return "call\t%A0";
14764 [(set_attr "type" "call")])
14766 (define_insn "*call_1_rex64_large"
14767 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14768 (match_operand 1 "" ""))]
14769 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14771 [(set_attr "type" "call")])
14773 (define_insn "*sibcall_1_rex64"
14774 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14775 (match_operand 1 "" ""))]
14776 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14778 [(set_attr "type" "call")])
14780 (define_insn "*sibcall_1_rex64_v"
14781 [(call (mem:QI (reg:DI R11_REG))
14782 (match_operand 0 "" ""))]
14783 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14785 [(set_attr "type" "call")])
14788 ;; Call subroutine, returning value in operand 0
14790 (define_expand "call_value_pop"
14791 [(parallel [(set (match_operand 0 "" "")
14792 (call (match_operand:QI 1 "" "")
14793 (match_operand:SI 2 "" "")))
14794 (set (reg:SI SP_REG)
14795 (plus:SI (reg:SI SP_REG)
14796 (match_operand:SI 4 "" "")))])]
14799 ix86_expand_call (operands[0], operands[1], operands[2],
14800 operands[3], operands[4], 0);
14804 (define_expand "call_value"
14805 [(set (match_operand 0 "" "")
14806 (call (match_operand:QI 1 "" "")
14807 (match_operand:SI 2 "" "")))
14808 (use (match_operand:SI 3 "" ""))]
14809 ;; Operand 2 not used on the i386.
14812 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14816 (define_expand "sibcall_value"
14817 [(set (match_operand 0 "" "")
14818 (call (match_operand:QI 1 "" "")
14819 (match_operand:SI 2 "" "")))
14820 (use (match_operand:SI 3 "" ""))]
14821 ;; Operand 2 not used on the i386.
14824 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14828 ;; Call subroutine returning any type.
14830 (define_expand "untyped_call"
14831 [(parallel [(call (match_operand 0 "" "")
14833 (match_operand 1 "" "")
14834 (match_operand 2 "" "")])]
14839 /* In order to give reg-stack an easier job in validating two
14840 coprocessor registers as containing a possible return value,
14841 simply pretend the untyped call returns a complex long double
14844 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14845 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14846 operands[0], const0_rtx,
14847 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
14848 : X64_SSE_REGPARM_MAX)
14852 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14854 rtx set = XVECEXP (operands[2], 0, i);
14855 emit_move_insn (SET_DEST (set), SET_SRC (set));
14858 /* The optimizer does not know that the call sets the function value
14859 registers we stored in the result block. We avoid problems by
14860 claiming that all hard registers are used and clobbered at this
14862 emit_insn (gen_blockage ());
14867 ;; Prologue and epilogue instructions
14869 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14870 ;; all of memory. This blocks insns from being moved across this point.
14872 (define_insn "blockage"
14873 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14876 [(set_attr "length" "0")])
14878 ;; As USE insns aren't meaningful after reload, this is used instead
14879 ;; to prevent deleting instructions setting registers for PIC code
14880 (define_insn "prologue_use"
14881 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14884 [(set_attr "length" "0")])
14886 ;; Insn emitted into the body of a function to return from a function.
14887 ;; This is only done if the function's epilogue is known to be simple.
14888 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14890 (define_expand "return"
14892 "ix86_can_use_return_insn_p ()"
14894 if (crtl->args.pops_args)
14896 rtx popc = GEN_INT (crtl->args.pops_args);
14897 emit_jump_insn (gen_return_pop_internal (popc));
14902 (define_insn "return_internal"
14906 [(set_attr "length" "1")
14907 (set_attr "length_immediate" "0")
14908 (set_attr "modrm" "0")])
14910 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14911 ;; instruction Athlon and K8 have.
14913 (define_insn "return_internal_long"
14915 (unspec [(const_int 0)] UNSPEC_REP)]
14918 [(set_attr "length" "1")
14919 (set_attr "length_immediate" "0")
14920 (set_attr "prefix_rep" "1")
14921 (set_attr "modrm" "0")])
14923 (define_insn "return_pop_internal"
14925 (use (match_operand:SI 0 "const_int_operand" ""))]
14928 [(set_attr "length" "3")
14929 (set_attr "length_immediate" "2")
14930 (set_attr "modrm" "0")])
14932 (define_insn "return_indirect_internal"
14934 (use (match_operand:SI 0 "register_operand" "r"))]
14937 [(set_attr "type" "ibr")
14938 (set_attr "length_immediate" "0")])
14944 [(set_attr "length" "1")
14945 (set_attr "length_immediate" "0")
14946 (set_attr "modrm" "0")])
14948 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14949 ;; branch prediction penalty for the third jump in a 16-byte
14952 (define_insn "align"
14953 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14956 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14957 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14959 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14960 The align insn is used to avoid 3 jump instructions in the row to improve
14961 branch prediction and the benefits hardly outweigh the cost of extra 8
14962 nops on the average inserted by full alignment pseudo operation. */
14966 [(set_attr "length" "16")])
14968 (define_expand "prologue"
14971 "ix86_expand_prologue (); DONE;")
14973 (define_insn "set_got"
14974 [(set (match_operand:SI 0 "register_operand" "=r")
14975 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14976 (clobber (reg:CC FLAGS_REG))]
14978 { return output_set_got (operands[0], NULL_RTX); }
14979 [(set_attr "type" "multi")
14980 (set_attr "length" "12")])
14982 (define_insn "set_got_labelled"
14983 [(set (match_operand:SI 0 "register_operand" "=r")
14984 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14986 (clobber (reg:CC FLAGS_REG))]
14988 { return output_set_got (operands[0], operands[1]); }
14989 [(set_attr "type" "multi")
14990 (set_attr "length" "12")])
14992 (define_insn "set_got_rex64"
14993 [(set (match_operand:DI 0 "register_operand" "=r")
14994 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14996 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14997 [(set_attr "type" "lea")
14998 (set_attr "length" "6")])
15000 (define_insn "set_rip_rex64"
15001 [(set (match_operand:DI 0 "register_operand" "=r")
15002 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15004 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15005 [(set_attr "type" "lea")
15006 (set_attr "length" "6")])
15008 (define_insn "set_got_offset_rex64"
15009 [(set (match_operand:DI 0 "register_operand" "=r")
15010 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15012 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15013 [(set_attr "type" "imov")
15014 (set_attr "length" "11")])
15016 (define_expand "epilogue"
15019 "ix86_expand_epilogue (1); DONE;")
15021 (define_expand "sibcall_epilogue"
15024 "ix86_expand_epilogue (0); DONE;")
15026 (define_expand "eh_return"
15027 [(use (match_operand 0 "register_operand" ""))]
15030 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15032 /* Tricky bit: we write the address of the handler to which we will
15033 be returning into someone else's stack frame, one word below the
15034 stack address we wish to restore. */
15035 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15036 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15037 tmp = gen_rtx_MEM (Pmode, tmp);
15038 emit_move_insn (tmp, ra);
15040 if (Pmode == SImode)
15041 emit_jump_insn (gen_eh_return_si (sa));
15043 emit_jump_insn (gen_eh_return_di (sa));
15048 (define_insn_and_split "eh_return_<mode>"
15050 (unspec [(match_operand:P 0 "register_operand" "c")]
15051 UNSPEC_EH_RETURN))]
15056 "ix86_expand_epilogue (2); DONE;")
15058 (define_insn "leave"
15059 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15060 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15061 (clobber (mem:BLK (scratch)))]
15064 [(set_attr "type" "leave")])
15066 (define_insn "leave_rex64"
15067 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15068 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15069 (clobber (mem:BLK (scratch)))]
15072 [(set_attr "type" "leave")])
15074 (define_expand "ffssi2"
15076 [(set (match_operand:SI 0 "register_operand" "")
15077 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15078 (clobber (match_scratch:SI 2 ""))
15079 (clobber (reg:CC FLAGS_REG))])]
15084 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15089 (define_expand "ffs_cmove"
15090 [(set (match_dup 2) (const_int -1))
15091 (parallel [(set (reg:CCZ FLAGS_REG)
15092 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15094 (set (match_operand:SI 0 "nonimmediate_operand" "")
15095 (ctz:SI (match_dup 1)))])
15096 (set (match_dup 0) (if_then_else:SI
15097 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15100 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15101 (clobber (reg:CC FLAGS_REG))])]
15103 "operands[2] = gen_reg_rtx (SImode);")
15105 (define_insn_and_split "*ffs_no_cmove"
15106 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15107 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15108 (clobber (match_scratch:SI 2 "=&q"))
15109 (clobber (reg:CC FLAGS_REG))]
15112 "&& reload_completed"
15113 [(parallel [(set (reg:CCZ FLAGS_REG)
15114 (compare:CCZ (match_dup 1) (const_int 0)))
15115 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15116 (set (strict_low_part (match_dup 3))
15117 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15118 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15119 (clobber (reg:CC FLAGS_REG))])
15120 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15121 (clobber (reg:CC FLAGS_REG))])
15122 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15123 (clobber (reg:CC FLAGS_REG))])]
15125 operands[3] = gen_lowpart (QImode, operands[2]);
15126 ix86_expand_clear (operands[2]);
15129 (define_insn "*ffssi_1"
15130 [(set (reg:CCZ FLAGS_REG)
15131 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15133 (set (match_operand:SI 0 "register_operand" "=r")
15134 (ctz:SI (match_dup 1)))]
15136 "bsf{l}\t{%1, %0|%0, %1}"
15137 [(set_attr "prefix_0f" "1")])
15139 (define_expand "ffsdi2"
15140 [(set (match_dup 2) (const_int -1))
15141 (parallel [(set (reg:CCZ FLAGS_REG)
15142 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15144 (set (match_operand:DI 0 "nonimmediate_operand" "")
15145 (ctz:DI (match_dup 1)))])
15146 (set (match_dup 0) (if_then_else:DI
15147 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15150 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15151 (clobber (reg:CC FLAGS_REG))])]
15153 "operands[2] = gen_reg_rtx (DImode);")
15155 (define_insn "*ffsdi_1"
15156 [(set (reg:CCZ FLAGS_REG)
15157 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15159 (set (match_operand:DI 0 "register_operand" "=r")
15160 (ctz:DI (match_dup 1)))]
15162 "bsf{q}\t{%1, %0|%0, %1}"
15163 [(set_attr "prefix_0f" "1")])
15165 (define_insn "ctzsi2"
15166 [(set (match_operand:SI 0 "register_operand" "=r")
15167 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15168 (clobber (reg:CC FLAGS_REG))]
15170 "bsf{l}\t{%1, %0|%0, %1}"
15171 [(set_attr "prefix_0f" "1")])
15173 (define_insn "ctzdi2"
15174 [(set (match_operand:DI 0 "register_operand" "=r")
15175 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15176 (clobber (reg:CC FLAGS_REG))]
15178 "bsf{q}\t{%1, %0|%0, %1}"
15179 [(set_attr "prefix_0f" "1")])
15181 (define_expand "clzsi2"
15183 [(set (match_operand:SI 0 "register_operand" "")
15184 (minus:SI (const_int 31)
15185 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15186 (clobber (reg:CC FLAGS_REG))])
15188 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15189 (clobber (reg:CC FLAGS_REG))])]
15194 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15199 (define_insn "clzsi2_abm"
15200 [(set (match_operand:SI 0 "register_operand" "=r")
15201 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15202 (clobber (reg:CC FLAGS_REG))]
15204 "lzcnt{l}\t{%1, %0|%0, %1}"
15205 [(set_attr "prefix_rep" "1")
15206 (set_attr "type" "bitmanip")
15207 (set_attr "mode" "SI")])
15209 (define_insn "*bsr"
15210 [(set (match_operand:SI 0 "register_operand" "=r")
15211 (minus:SI (const_int 31)
15212 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15213 (clobber (reg:CC FLAGS_REG))]
15215 "bsr{l}\t{%1, %0|%0, %1}"
15216 [(set_attr "prefix_0f" "1")
15217 (set_attr "mode" "SI")])
15219 (define_insn "popcountsi2"
15220 [(set (match_operand:SI 0 "register_operand" "=r")
15221 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15222 (clobber (reg:CC FLAGS_REG))]
15224 "popcnt{l}\t{%1, %0|%0, %1}"
15225 [(set_attr "prefix_rep" "1")
15226 (set_attr "type" "bitmanip")
15227 (set_attr "mode" "SI")])
15229 (define_insn "*popcountsi2_cmp"
15230 [(set (reg FLAGS_REG)
15232 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15234 (set (match_operand:SI 0 "register_operand" "=r")
15235 (popcount:SI (match_dup 1)))]
15236 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15237 "popcnt{l}\t{%1, %0|%0, %1}"
15238 [(set_attr "prefix_rep" "1")
15239 (set_attr "type" "bitmanip")
15240 (set_attr "mode" "SI")])
15242 (define_insn "*popcountsi2_cmp_zext"
15243 [(set (reg FLAGS_REG)
15245 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15247 (set (match_operand:DI 0 "register_operand" "=r")
15248 (zero_extend:DI(popcount:SI (match_dup 1))))]
15249 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15250 "popcnt{l}\t{%1, %0|%0, %1}"
15251 [(set_attr "prefix_rep" "1")
15252 (set_attr "type" "bitmanip")
15253 (set_attr "mode" "SI")])
15255 (define_expand "bswapsi2"
15256 [(set (match_operand:SI 0 "register_operand" "")
15257 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15262 rtx x = operands[0];
15264 emit_move_insn (x, operands[1]);
15265 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15266 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15267 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15272 (define_insn "*bswapsi_1"
15273 [(set (match_operand:SI 0 "register_operand" "=r")
15274 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15277 [(set_attr "prefix_0f" "1")
15278 (set_attr "length" "2")])
15280 (define_insn "*bswaphi_lowpart_1"
15281 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15282 (bswap:HI (match_dup 0)))
15283 (clobber (reg:CC FLAGS_REG))]
15284 "TARGET_USE_XCHGB || optimize_size"
15286 xchg{b}\t{%h0, %b0|%b0, %h0}
15287 rol{w}\t{$8, %0|%0, 8}"
15288 [(set_attr "length" "2,4")
15289 (set_attr "mode" "QI,HI")])
15291 (define_insn "bswaphi_lowpart"
15292 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15293 (bswap:HI (match_dup 0)))
15294 (clobber (reg:CC FLAGS_REG))]
15296 "rol{w}\t{$8, %0|%0, 8}"
15297 [(set_attr "length" "4")
15298 (set_attr "mode" "HI")])
15300 (define_insn "bswapdi2"
15301 [(set (match_operand:DI 0 "register_operand" "=r")
15302 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15305 [(set_attr "prefix_0f" "1")
15306 (set_attr "length" "3")])
15308 (define_expand "clzdi2"
15310 [(set (match_operand:DI 0 "register_operand" "")
15311 (minus:DI (const_int 63)
15312 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15313 (clobber (reg:CC FLAGS_REG))])
15315 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15316 (clobber (reg:CC FLAGS_REG))])]
15321 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15326 (define_insn "clzdi2_abm"
15327 [(set (match_operand:DI 0 "register_operand" "=r")
15328 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15329 (clobber (reg:CC FLAGS_REG))]
15330 "TARGET_64BIT && TARGET_ABM"
15331 "lzcnt{q}\t{%1, %0|%0, %1}"
15332 [(set_attr "prefix_rep" "1")
15333 (set_attr "type" "bitmanip")
15334 (set_attr "mode" "DI")])
15336 (define_insn "*bsr_rex64"
15337 [(set (match_operand:DI 0 "register_operand" "=r")
15338 (minus:DI (const_int 63)
15339 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15340 (clobber (reg:CC FLAGS_REG))]
15342 "bsr{q}\t{%1, %0|%0, %1}"
15343 [(set_attr "prefix_0f" "1")
15344 (set_attr "mode" "DI")])
15346 (define_insn "popcountdi2"
15347 [(set (match_operand:DI 0 "register_operand" "=r")
15348 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15349 (clobber (reg:CC FLAGS_REG))]
15350 "TARGET_64BIT && TARGET_POPCNT"
15351 "popcnt{q}\t{%1, %0|%0, %1}"
15352 [(set_attr "prefix_rep" "1")
15353 (set_attr "type" "bitmanip")
15354 (set_attr "mode" "DI")])
15356 (define_insn "*popcountdi2_cmp"
15357 [(set (reg FLAGS_REG)
15359 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15361 (set (match_operand:DI 0 "register_operand" "=r")
15362 (popcount:DI (match_dup 1)))]
15363 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15364 "popcnt{q}\t{%1, %0|%0, %1}"
15365 [(set_attr "prefix_rep" "1")
15366 (set_attr "type" "bitmanip")
15367 (set_attr "mode" "DI")])
15369 (define_expand "clzhi2"
15371 [(set (match_operand:HI 0 "register_operand" "")
15372 (minus:HI (const_int 15)
15373 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15374 (clobber (reg:CC FLAGS_REG))])
15376 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15377 (clobber (reg:CC FLAGS_REG))])]
15382 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15387 (define_insn "clzhi2_abm"
15388 [(set (match_operand:HI 0 "register_operand" "=r")
15389 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15390 (clobber (reg:CC FLAGS_REG))]
15392 "lzcnt{w}\t{%1, %0|%0, %1}"
15393 [(set_attr "prefix_rep" "1")
15394 (set_attr "type" "bitmanip")
15395 (set_attr "mode" "HI")])
15397 (define_insn "*bsrhi"
15398 [(set (match_operand:HI 0 "register_operand" "=r")
15399 (minus:HI (const_int 15)
15400 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15401 (clobber (reg:CC FLAGS_REG))]
15403 "bsr{w}\t{%1, %0|%0, %1}"
15404 [(set_attr "prefix_0f" "1")
15405 (set_attr "mode" "HI")])
15407 (define_insn "popcounthi2"
15408 [(set (match_operand:HI 0 "register_operand" "=r")
15409 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15410 (clobber (reg:CC FLAGS_REG))]
15412 "popcnt{w}\t{%1, %0|%0, %1}"
15413 [(set_attr "prefix_rep" "1")
15414 (set_attr "type" "bitmanip")
15415 (set_attr "mode" "HI")])
15417 (define_insn "*popcounthi2_cmp"
15418 [(set (reg FLAGS_REG)
15420 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15422 (set (match_operand:HI 0 "register_operand" "=r")
15423 (popcount:HI (match_dup 1)))]
15424 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15425 "popcnt{w}\t{%1, %0|%0, %1}"
15426 [(set_attr "prefix_rep" "1")
15427 (set_attr "type" "bitmanip")
15428 (set_attr "mode" "HI")])
15430 (define_expand "paritydi2"
15431 [(set (match_operand:DI 0 "register_operand" "")
15432 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15435 rtx scratch = gen_reg_rtx (QImode);
15438 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15439 NULL_RTX, operands[1]));
15441 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15442 gen_rtx_REG (CCmode, FLAGS_REG),
15444 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15447 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15450 rtx tmp = gen_reg_rtx (SImode);
15452 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15453 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15458 (define_insn_and_split "paritydi2_cmp"
15459 [(set (reg:CC FLAGS_REG)
15460 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15461 (clobber (match_scratch:DI 0 "=r"))
15462 (clobber (match_scratch:SI 1 "=&r"))
15463 (clobber (match_scratch:HI 2 "=Q"))]
15466 "&& reload_completed"
15468 [(set (match_dup 1)
15469 (xor:SI (match_dup 1) (match_dup 4)))
15470 (clobber (reg:CC FLAGS_REG))])
15472 [(set (reg:CC FLAGS_REG)
15473 (parity:CC (match_dup 1)))
15474 (clobber (match_dup 1))
15475 (clobber (match_dup 2))])]
15477 operands[4] = gen_lowpart (SImode, operands[3]);
15481 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15482 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15485 operands[1] = gen_highpart (SImode, operands[3]);
15488 (define_expand "paritysi2"
15489 [(set (match_operand:SI 0 "register_operand" "")
15490 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15493 rtx scratch = gen_reg_rtx (QImode);
15496 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15498 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15499 gen_rtx_REG (CCmode, FLAGS_REG),
15501 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15503 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15507 (define_insn_and_split "paritysi2_cmp"
15508 [(set (reg:CC FLAGS_REG)
15509 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15510 (clobber (match_scratch:SI 0 "=r"))
15511 (clobber (match_scratch:HI 1 "=&Q"))]
15514 "&& reload_completed"
15516 [(set (match_dup 1)
15517 (xor:HI (match_dup 1) (match_dup 3)))
15518 (clobber (reg:CC FLAGS_REG))])
15520 [(set (reg:CC FLAGS_REG)
15521 (parity:CC (match_dup 1)))
15522 (clobber (match_dup 1))])]
15524 operands[3] = gen_lowpart (HImode, operands[2]);
15526 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15527 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15530 (define_insn "*parityhi2_cmp"
15531 [(set (reg:CC FLAGS_REG)
15532 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15533 (clobber (match_scratch:HI 0 "=Q"))]
15535 "xor{b}\t{%h0, %b0|%b0, %h0}"
15536 [(set_attr "length" "2")
15537 (set_attr "mode" "HI")])
15539 (define_insn "*parityqi2_cmp"
15540 [(set (reg:CC FLAGS_REG)
15541 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15544 [(set_attr "length" "2")
15545 (set_attr "mode" "QI")])
15547 ;; Thread-local storage patterns for ELF.
15549 ;; Note that these code sequences must appear exactly as shown
15550 ;; in order to allow linker relaxation.
15552 (define_insn "*tls_global_dynamic_32_gnu"
15553 [(set (match_operand:SI 0 "register_operand" "=a")
15554 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15555 (match_operand:SI 2 "tls_symbolic_operand" "")
15556 (match_operand:SI 3 "call_insn_operand" "")]
15558 (clobber (match_scratch:SI 4 "=d"))
15559 (clobber (match_scratch:SI 5 "=c"))
15560 (clobber (reg:CC FLAGS_REG))]
15561 "!TARGET_64BIT && TARGET_GNU_TLS"
15562 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15563 [(set_attr "type" "multi")
15564 (set_attr "length" "12")])
15566 (define_insn "*tls_global_dynamic_32_sun"
15567 [(set (match_operand:SI 0 "register_operand" "=a")
15568 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15569 (match_operand:SI 2 "tls_symbolic_operand" "")
15570 (match_operand:SI 3 "call_insn_operand" "")]
15572 (clobber (match_scratch:SI 4 "=d"))
15573 (clobber (match_scratch:SI 5 "=c"))
15574 (clobber (reg:CC FLAGS_REG))]
15575 "!TARGET_64BIT && TARGET_SUN_TLS"
15576 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15577 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15578 [(set_attr "type" "multi")
15579 (set_attr "length" "14")])
15581 (define_expand "tls_global_dynamic_32"
15582 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15585 (match_operand:SI 1 "tls_symbolic_operand" "")
15588 (clobber (match_scratch:SI 4 ""))
15589 (clobber (match_scratch:SI 5 ""))
15590 (clobber (reg:CC FLAGS_REG))])]
15594 operands[2] = pic_offset_table_rtx;
15597 operands[2] = gen_reg_rtx (Pmode);
15598 emit_insn (gen_set_got (operands[2]));
15600 if (TARGET_GNU2_TLS)
15602 emit_insn (gen_tls_dynamic_gnu2_32
15603 (operands[0], operands[1], operands[2]));
15606 operands[3] = ix86_tls_get_addr ();
15609 (define_insn "*tls_global_dynamic_64"
15610 [(set (match_operand:DI 0 "register_operand" "=a")
15611 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15612 (match_operand:DI 3 "" "")))
15613 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15616 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15617 [(set_attr "type" "multi")
15618 (set_attr "length" "16")])
15620 (define_expand "tls_global_dynamic_64"
15621 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15622 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15623 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15627 if (TARGET_GNU2_TLS)
15629 emit_insn (gen_tls_dynamic_gnu2_64
15630 (operands[0], operands[1]));
15633 operands[2] = ix86_tls_get_addr ();
15636 (define_insn "*tls_local_dynamic_base_32_gnu"
15637 [(set (match_operand:SI 0 "register_operand" "=a")
15638 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15639 (match_operand:SI 2 "call_insn_operand" "")]
15640 UNSPEC_TLS_LD_BASE))
15641 (clobber (match_scratch:SI 3 "=d"))
15642 (clobber (match_scratch:SI 4 "=c"))
15643 (clobber (reg:CC FLAGS_REG))]
15644 "!TARGET_64BIT && TARGET_GNU_TLS"
15645 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15646 [(set_attr "type" "multi")
15647 (set_attr "length" "11")])
15649 (define_insn "*tls_local_dynamic_base_32_sun"
15650 [(set (match_operand:SI 0 "register_operand" "=a")
15651 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15652 (match_operand:SI 2 "call_insn_operand" "")]
15653 UNSPEC_TLS_LD_BASE))
15654 (clobber (match_scratch:SI 3 "=d"))
15655 (clobber (match_scratch:SI 4 "=c"))
15656 (clobber (reg:CC FLAGS_REG))]
15657 "!TARGET_64BIT && TARGET_SUN_TLS"
15658 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15659 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15660 [(set_attr "type" "multi")
15661 (set_attr "length" "13")])
15663 (define_expand "tls_local_dynamic_base_32"
15664 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15665 (unspec:SI [(match_dup 1) (match_dup 2)]
15666 UNSPEC_TLS_LD_BASE))
15667 (clobber (match_scratch:SI 3 ""))
15668 (clobber (match_scratch:SI 4 ""))
15669 (clobber (reg:CC FLAGS_REG))])]
15673 operands[1] = pic_offset_table_rtx;
15676 operands[1] = gen_reg_rtx (Pmode);
15677 emit_insn (gen_set_got (operands[1]));
15679 if (TARGET_GNU2_TLS)
15681 emit_insn (gen_tls_dynamic_gnu2_32
15682 (operands[0], ix86_tls_module_base (), operands[1]));
15685 operands[2] = ix86_tls_get_addr ();
15688 (define_insn "*tls_local_dynamic_base_64"
15689 [(set (match_operand:DI 0 "register_operand" "=a")
15690 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15691 (match_operand:DI 2 "" "")))
15692 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15694 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15695 [(set_attr "type" "multi")
15696 (set_attr "length" "12")])
15698 (define_expand "tls_local_dynamic_base_64"
15699 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15700 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15701 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15704 if (TARGET_GNU2_TLS)
15706 emit_insn (gen_tls_dynamic_gnu2_64
15707 (operands[0], ix86_tls_module_base ()));
15710 operands[1] = ix86_tls_get_addr ();
15713 ;; Local dynamic of a single variable is a lose. Show combine how
15714 ;; to convert that back to global dynamic.
15716 (define_insn_and_split "*tls_local_dynamic_32_once"
15717 [(set (match_operand:SI 0 "register_operand" "=a")
15718 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15719 (match_operand:SI 2 "call_insn_operand" "")]
15720 UNSPEC_TLS_LD_BASE)
15721 (const:SI (unspec:SI
15722 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15724 (clobber (match_scratch:SI 4 "=d"))
15725 (clobber (match_scratch:SI 5 "=c"))
15726 (clobber (reg:CC FLAGS_REG))]
15730 [(parallel [(set (match_dup 0)
15731 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15733 (clobber (match_dup 4))
15734 (clobber (match_dup 5))
15735 (clobber (reg:CC FLAGS_REG))])]
15738 ;; Load and add the thread base pointer from %gs:0.
15740 (define_insn "*load_tp_si"
15741 [(set (match_operand:SI 0 "register_operand" "=r")
15742 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15744 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15745 [(set_attr "type" "imov")
15746 (set_attr "modrm" "0")
15747 (set_attr "length" "7")
15748 (set_attr "memory" "load")
15749 (set_attr "imm_disp" "false")])
15751 (define_insn "*add_tp_si"
15752 [(set (match_operand:SI 0 "register_operand" "=r")
15753 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15754 (match_operand:SI 1 "register_operand" "0")))
15755 (clobber (reg:CC FLAGS_REG))]
15757 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15758 [(set_attr "type" "alu")
15759 (set_attr "modrm" "0")
15760 (set_attr "length" "7")
15761 (set_attr "memory" "load")
15762 (set_attr "imm_disp" "false")])
15764 (define_insn "*load_tp_di"
15765 [(set (match_operand:DI 0 "register_operand" "=r")
15766 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15768 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15769 [(set_attr "type" "imov")
15770 (set_attr "modrm" "0")
15771 (set_attr "length" "7")
15772 (set_attr "memory" "load")
15773 (set_attr "imm_disp" "false")])
15775 (define_insn "*add_tp_di"
15776 [(set (match_operand:DI 0 "register_operand" "=r")
15777 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15778 (match_operand:DI 1 "register_operand" "0")))
15779 (clobber (reg:CC FLAGS_REG))]
15781 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15782 [(set_attr "type" "alu")
15783 (set_attr "modrm" "0")
15784 (set_attr "length" "7")
15785 (set_attr "memory" "load")
15786 (set_attr "imm_disp" "false")])
15788 ;; GNU2 TLS patterns can be split.
15790 (define_expand "tls_dynamic_gnu2_32"
15791 [(set (match_dup 3)
15792 (plus:SI (match_operand:SI 2 "register_operand" "")
15794 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15797 [(set (match_operand:SI 0 "register_operand" "")
15798 (unspec:SI [(match_dup 1) (match_dup 3)
15799 (match_dup 2) (reg:SI SP_REG)]
15801 (clobber (reg:CC FLAGS_REG))])]
15802 "!TARGET_64BIT && TARGET_GNU2_TLS"
15804 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15805 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15808 (define_insn "*tls_dynamic_lea_32"
15809 [(set (match_operand:SI 0 "register_operand" "=r")
15810 (plus:SI (match_operand:SI 1 "register_operand" "b")
15812 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15813 UNSPEC_TLSDESC))))]
15814 "!TARGET_64BIT && TARGET_GNU2_TLS"
15815 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15816 [(set_attr "type" "lea")
15817 (set_attr "mode" "SI")
15818 (set_attr "length" "6")
15819 (set_attr "length_address" "4")])
15821 (define_insn "*tls_dynamic_call_32"
15822 [(set (match_operand:SI 0 "register_operand" "=a")
15823 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15824 (match_operand:SI 2 "register_operand" "0")
15825 ;; we have to make sure %ebx still points to the GOT
15826 (match_operand:SI 3 "register_operand" "b")
15829 (clobber (reg:CC FLAGS_REG))]
15830 "!TARGET_64BIT && TARGET_GNU2_TLS"
15831 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15832 [(set_attr "type" "call")
15833 (set_attr "length" "2")
15834 (set_attr "length_address" "0")])
15836 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15837 [(set (match_operand:SI 0 "register_operand" "=&a")
15839 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15840 (match_operand:SI 4 "" "")
15841 (match_operand:SI 2 "register_operand" "b")
15844 (const:SI (unspec:SI
15845 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15847 (clobber (reg:CC FLAGS_REG))]
15848 "!TARGET_64BIT && TARGET_GNU2_TLS"
15851 [(set (match_dup 0) (match_dup 5))]
15853 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15854 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15857 (define_expand "tls_dynamic_gnu2_64"
15858 [(set (match_dup 2)
15859 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15862 [(set (match_operand:DI 0 "register_operand" "")
15863 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15865 (clobber (reg:CC FLAGS_REG))])]
15866 "TARGET_64BIT && TARGET_GNU2_TLS"
15868 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15869 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15872 (define_insn "*tls_dynamic_lea_64"
15873 [(set (match_operand:DI 0 "register_operand" "=r")
15874 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15876 "TARGET_64BIT && TARGET_GNU2_TLS"
15877 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15878 [(set_attr "type" "lea")
15879 (set_attr "mode" "DI")
15880 (set_attr "length" "7")
15881 (set_attr "length_address" "4")])
15883 (define_insn "*tls_dynamic_call_64"
15884 [(set (match_operand:DI 0 "register_operand" "=a")
15885 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15886 (match_operand:DI 2 "register_operand" "0")
15889 (clobber (reg:CC FLAGS_REG))]
15890 "TARGET_64BIT && TARGET_GNU2_TLS"
15891 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15892 [(set_attr "type" "call")
15893 (set_attr "length" "2")
15894 (set_attr "length_address" "0")])
15896 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15897 [(set (match_operand:DI 0 "register_operand" "=&a")
15899 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15900 (match_operand:DI 3 "" "")
15903 (const:DI (unspec:DI
15904 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15906 (clobber (reg:CC FLAGS_REG))]
15907 "TARGET_64BIT && TARGET_GNU2_TLS"
15910 [(set (match_dup 0) (match_dup 4))]
15912 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15913 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15918 ;; These patterns match the binary 387 instructions for addM3, subM3,
15919 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15920 ;; SFmode. The first is the normal insn, the second the same insn but
15921 ;; with one operand a conversion, and the third the same insn but with
15922 ;; the other operand a conversion. The conversion may be SFmode or
15923 ;; SImode if the target mode DFmode, but only SImode if the target mode
15926 ;; Gcc is slightly more smart about handling normal two address instructions
15927 ;; so use special patterns for add and mull.
15929 (define_insn "*fop_<mode>_comm_mixed"
15930 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15931 (match_operator:MODEF 3 "binary_fp_operator"
15932 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15933 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15934 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15935 && COMMUTATIVE_ARITH_P (operands[3])
15936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15937 "* return output_387_binary_op (insn, operands);"
15938 [(set (attr "type")
15939 (if_then_else (eq_attr "alternative" "1")
15940 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15941 (const_string "ssemul")
15942 (const_string "sseadd"))
15943 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15944 (const_string "fmul")
15945 (const_string "fop"))))
15946 (set_attr "mode" "<MODE>")])
15948 (define_insn "*fop_<mode>_comm_sse"
15949 [(set (match_operand:MODEF 0 "register_operand" "=x")
15950 (match_operator:MODEF 3 "binary_fp_operator"
15951 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15952 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15953 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15954 && COMMUTATIVE_ARITH_P (operands[3])
15955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15956 "* return output_387_binary_op (insn, operands);"
15957 [(set (attr "type")
15958 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15959 (const_string "ssemul")
15960 (const_string "sseadd")))
15961 (set_attr "mode" "<MODE>")])
15963 (define_insn "*fop_<mode>_comm_i387"
15964 [(set (match_operand:MODEF 0 "register_operand" "=f")
15965 (match_operator:MODEF 3 "binary_fp_operator"
15966 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15967 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15969 && COMMUTATIVE_ARITH_P (operands[3])
15970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15971 "* return output_387_binary_op (insn, operands);"
15972 [(set (attr "type")
15973 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15974 (const_string "fmul")
15975 (const_string "fop")))
15976 (set_attr "mode" "<MODE>")])
15978 (define_insn "*fop_<mode>_1_mixed"
15979 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15980 (match_operator:MODEF 3 "binary_fp_operator"
15981 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15982 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15983 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15984 && !COMMUTATIVE_ARITH_P (operands[3])
15985 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15986 "* return output_387_binary_op (insn, operands);"
15987 [(set (attr "type")
15988 (cond [(and (eq_attr "alternative" "2")
15989 (match_operand:MODEF 3 "mult_operator" ""))
15990 (const_string "ssemul")
15991 (and (eq_attr "alternative" "2")
15992 (match_operand:MODEF 3 "div_operator" ""))
15993 (const_string "ssediv")
15994 (eq_attr "alternative" "2")
15995 (const_string "sseadd")
15996 (match_operand:MODEF 3 "mult_operator" "")
15997 (const_string "fmul")
15998 (match_operand:MODEF 3 "div_operator" "")
15999 (const_string "fdiv")
16001 (const_string "fop")))
16002 (set_attr "mode" "<MODE>")])
16004 (define_insn "*rcpsf2_sse"
16005 [(set (match_operand:SF 0 "register_operand" "=x")
16006 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16009 "rcpss\t{%1, %0|%0, %1}"
16010 [(set_attr "type" "sse")
16011 (set_attr "mode" "SF")])
16013 (define_insn "*fop_<mode>_1_sse"
16014 [(set (match_operand:MODEF 0 "register_operand" "=x")
16015 (match_operator:MODEF 3 "binary_fp_operator"
16016 [(match_operand:MODEF 1 "register_operand" "0")
16017 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16018 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16019 && !COMMUTATIVE_ARITH_P (operands[3])"
16020 "* return output_387_binary_op (insn, operands);"
16021 [(set (attr "type")
16022 (cond [(match_operand:MODEF 3 "mult_operator" "")
16023 (const_string "ssemul")
16024 (match_operand:MODEF 3 "div_operator" "")
16025 (const_string "ssediv")
16027 (const_string "sseadd")))
16028 (set_attr "mode" "<MODE>")])
16030 ;; This pattern is not fully shadowed by the pattern above.
16031 (define_insn "*fop_<mode>_1_i387"
16032 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16033 (match_operator:MODEF 3 "binary_fp_operator"
16034 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16035 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16036 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16037 && !COMMUTATIVE_ARITH_P (operands[3])
16038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16039 "* return output_387_binary_op (insn, operands);"
16040 [(set (attr "type")
16041 (cond [(match_operand:MODEF 3 "mult_operator" "")
16042 (const_string "fmul")
16043 (match_operand:MODEF 3 "div_operator" "")
16044 (const_string "fdiv")
16046 (const_string "fop")))
16047 (set_attr "mode" "<MODE>")])
16049 ;; ??? Add SSE splitters for these!
16050 (define_insn "*fop_<MODEF:mode>_2_i387"
16051 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16052 (match_operator:MODEF 3 "binary_fp_operator"
16054 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16055 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16056 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16057 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16058 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16059 [(set (attr "type")
16060 (cond [(match_operand:MODEF 3 "mult_operator" "")
16061 (const_string "fmul")
16062 (match_operand:MODEF 3 "div_operator" "")
16063 (const_string "fdiv")
16065 (const_string "fop")))
16066 (set_attr "fp_int_src" "true")
16067 (set_attr "mode" "<X87MODEI12:MODE>")])
16069 (define_insn "*fop_<MODEF:mode>_3_i387"
16070 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16071 (match_operator:MODEF 3 "binary_fp_operator"
16072 [(match_operand:MODEF 1 "register_operand" "0,0")
16074 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16075 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16076 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16077 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16078 [(set (attr "type")
16079 (cond [(match_operand:MODEF 3 "mult_operator" "")
16080 (const_string "fmul")
16081 (match_operand:MODEF 3 "div_operator" "")
16082 (const_string "fdiv")
16084 (const_string "fop")))
16085 (set_attr "fp_int_src" "true")
16086 (set_attr "mode" "<MODE>")])
16088 (define_insn "*fop_df_4_i387"
16089 [(set (match_operand:DF 0 "register_operand" "=f,f")
16090 (match_operator:DF 3 "binary_fp_operator"
16092 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16093 (match_operand:DF 2 "register_operand" "0,f")]))]
16094 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16095 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16096 "* return output_387_binary_op (insn, operands);"
16097 [(set (attr "type")
16098 (cond [(match_operand:DF 3 "mult_operator" "")
16099 (const_string "fmul")
16100 (match_operand:DF 3 "div_operator" "")
16101 (const_string "fdiv")
16103 (const_string "fop")))
16104 (set_attr "mode" "SF")])
16106 (define_insn "*fop_df_5_i387"
16107 [(set (match_operand:DF 0 "register_operand" "=f,f")
16108 (match_operator:DF 3 "binary_fp_operator"
16109 [(match_operand:DF 1 "register_operand" "0,f")
16111 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16112 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16113 "* return output_387_binary_op (insn, operands);"
16114 [(set (attr "type")
16115 (cond [(match_operand:DF 3 "mult_operator" "")
16116 (const_string "fmul")
16117 (match_operand:DF 3 "div_operator" "")
16118 (const_string "fdiv")
16120 (const_string "fop")))
16121 (set_attr "mode" "SF")])
16123 (define_insn "*fop_df_6_i387"
16124 [(set (match_operand:DF 0 "register_operand" "=f,f")
16125 (match_operator:DF 3 "binary_fp_operator"
16127 (match_operand:SF 1 "register_operand" "0,f"))
16129 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16130 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16131 "* return output_387_binary_op (insn, operands);"
16132 [(set (attr "type")
16133 (cond [(match_operand:DF 3 "mult_operator" "")
16134 (const_string "fmul")
16135 (match_operand:DF 3 "div_operator" "")
16136 (const_string "fdiv")
16138 (const_string "fop")))
16139 (set_attr "mode" "SF")])
16141 (define_insn "*fop_xf_comm_i387"
16142 [(set (match_operand:XF 0 "register_operand" "=f")
16143 (match_operator:XF 3 "binary_fp_operator"
16144 [(match_operand:XF 1 "register_operand" "%0")
16145 (match_operand:XF 2 "register_operand" "f")]))]
16147 && COMMUTATIVE_ARITH_P (operands[3])"
16148 "* return output_387_binary_op (insn, operands);"
16149 [(set (attr "type")
16150 (if_then_else (match_operand:XF 3 "mult_operator" "")
16151 (const_string "fmul")
16152 (const_string "fop")))
16153 (set_attr "mode" "XF")])
16155 (define_insn "*fop_xf_1_i387"
16156 [(set (match_operand:XF 0 "register_operand" "=f,f")
16157 (match_operator:XF 3 "binary_fp_operator"
16158 [(match_operand:XF 1 "register_operand" "0,f")
16159 (match_operand:XF 2 "register_operand" "f,0")]))]
16161 && !COMMUTATIVE_ARITH_P (operands[3])"
16162 "* return output_387_binary_op (insn, operands);"
16163 [(set (attr "type")
16164 (cond [(match_operand:XF 3 "mult_operator" "")
16165 (const_string "fmul")
16166 (match_operand:XF 3 "div_operator" "")
16167 (const_string "fdiv")
16169 (const_string "fop")))
16170 (set_attr "mode" "XF")])
16172 (define_insn "*fop_xf_2_i387"
16173 [(set (match_operand:XF 0 "register_operand" "=f,f")
16174 (match_operator:XF 3 "binary_fp_operator"
16176 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16177 (match_operand:XF 2 "register_operand" "0,0")]))]
16178 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16179 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16180 [(set (attr "type")
16181 (cond [(match_operand:XF 3 "mult_operator" "")
16182 (const_string "fmul")
16183 (match_operand:XF 3 "div_operator" "")
16184 (const_string "fdiv")
16186 (const_string "fop")))
16187 (set_attr "fp_int_src" "true")
16188 (set_attr "mode" "<MODE>")])
16190 (define_insn "*fop_xf_3_i387"
16191 [(set (match_operand:XF 0 "register_operand" "=f,f")
16192 (match_operator:XF 3 "binary_fp_operator"
16193 [(match_operand:XF 1 "register_operand" "0,0")
16195 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16196 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16197 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16198 [(set (attr "type")
16199 (cond [(match_operand:XF 3 "mult_operator" "")
16200 (const_string "fmul")
16201 (match_operand:XF 3 "div_operator" "")
16202 (const_string "fdiv")
16204 (const_string "fop")))
16205 (set_attr "fp_int_src" "true")
16206 (set_attr "mode" "<MODE>")])
16208 (define_insn "*fop_xf_4_i387"
16209 [(set (match_operand:XF 0 "register_operand" "=f,f")
16210 (match_operator:XF 3 "binary_fp_operator"
16212 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16213 (match_operand:XF 2 "register_operand" "0,f")]))]
16215 "* return output_387_binary_op (insn, operands);"
16216 [(set (attr "type")
16217 (cond [(match_operand:XF 3 "mult_operator" "")
16218 (const_string "fmul")
16219 (match_operand:XF 3 "div_operator" "")
16220 (const_string "fdiv")
16222 (const_string "fop")))
16223 (set_attr "mode" "<MODE>")])
16225 (define_insn "*fop_xf_5_i387"
16226 [(set (match_operand:XF 0 "register_operand" "=f,f")
16227 (match_operator:XF 3 "binary_fp_operator"
16228 [(match_operand:XF 1 "register_operand" "0,f")
16230 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16232 "* return output_387_binary_op (insn, operands);"
16233 [(set (attr "type")
16234 (cond [(match_operand:XF 3 "mult_operator" "")
16235 (const_string "fmul")
16236 (match_operand:XF 3 "div_operator" "")
16237 (const_string "fdiv")
16239 (const_string "fop")))
16240 (set_attr "mode" "<MODE>")])
16242 (define_insn "*fop_xf_6_i387"
16243 [(set (match_operand:XF 0 "register_operand" "=f,f")
16244 (match_operator:XF 3 "binary_fp_operator"
16246 (match_operand:MODEF 1 "register_operand" "0,f"))
16248 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16250 "* return output_387_binary_op (insn, operands);"
16251 [(set (attr "type")
16252 (cond [(match_operand:XF 3 "mult_operator" "")
16253 (const_string "fmul")
16254 (match_operand:XF 3 "div_operator" "")
16255 (const_string "fdiv")
16257 (const_string "fop")))
16258 (set_attr "mode" "<MODE>")])
16261 [(set (match_operand 0 "register_operand" "")
16262 (match_operator 3 "binary_fp_operator"
16263 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16264 (match_operand 2 "register_operand" "")]))]
16266 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16269 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16270 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16271 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16272 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16273 GET_MODE (operands[3]),
16276 ix86_free_from_memory (GET_MODE (operands[1]));
16281 [(set (match_operand 0 "register_operand" "")
16282 (match_operator 3 "binary_fp_operator"
16283 [(match_operand 1 "register_operand" "")
16284 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16286 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16289 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16290 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16291 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16292 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16293 GET_MODE (operands[3]),
16296 ix86_free_from_memory (GET_MODE (operands[2]));
16300 ;; FPU special functions.
16302 ;; This pattern implements a no-op XFmode truncation for
16303 ;; all fancy i386 XFmode math functions.
16305 (define_insn "truncxf<mode>2_i387_noop_unspec"
16306 [(set (match_operand:MODEF 0 "register_operand" "=f")
16307 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16308 UNSPEC_TRUNC_NOOP))]
16309 "TARGET_USE_FANCY_MATH_387"
16310 "* return output_387_reg_move (insn, operands);"
16311 [(set_attr "type" "fmov")
16312 (set_attr "mode" "<MODE>")])
16314 (define_insn "sqrtxf2"
16315 [(set (match_operand:XF 0 "register_operand" "=f")
16316 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16317 "TARGET_USE_FANCY_MATH_387"
16319 [(set_attr "type" "fpspc")
16320 (set_attr "mode" "XF")
16321 (set_attr "athlon_decode" "direct")
16322 (set_attr "amdfam10_decode" "direct")])
16324 (define_insn "sqrt_extend<mode>xf2_i387"
16325 [(set (match_operand:XF 0 "register_operand" "=f")
16328 (match_operand:MODEF 1 "register_operand" "0"))))]
16329 "TARGET_USE_FANCY_MATH_387"
16331 [(set_attr "type" "fpspc")
16332 (set_attr "mode" "XF")
16333 (set_attr "athlon_decode" "direct")
16334 (set_attr "amdfam10_decode" "direct")])
16336 (define_insn "*rsqrtsf2_sse"
16337 [(set (match_operand:SF 0 "register_operand" "=x")
16338 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16341 "rsqrtss\t{%1, %0|%0, %1}"
16342 [(set_attr "type" "sse")
16343 (set_attr "mode" "SF")])
16345 (define_expand "rsqrtsf2"
16346 [(set (match_operand:SF 0 "register_operand" "")
16347 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16351 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16355 (define_insn "*sqrt<mode>2_sse"
16356 [(set (match_operand:MODEF 0 "register_operand" "=x")
16358 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16359 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16360 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16361 [(set_attr "type" "sse")
16362 (set_attr "mode" "<MODE>")
16363 (set_attr "athlon_decode" "*")
16364 (set_attr "amdfam10_decode" "*")])
16366 (define_expand "sqrt<mode>2"
16367 [(set (match_operand:MODEF 0 "register_operand" "")
16369 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16370 "TARGET_USE_FANCY_MATH_387
16371 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16373 if (<MODE>mode == SFmode
16374 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16375 && flag_finite_math_only && !flag_trapping_math
16376 && flag_unsafe_math_optimizations)
16378 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16382 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16384 rtx op0 = gen_reg_rtx (XFmode);
16385 rtx op1 = force_reg (<MODE>mode, operands[1]);
16387 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16388 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16393 (define_insn "fpremxf4_i387"
16394 [(set (match_operand:XF 0 "register_operand" "=f")
16395 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16396 (match_operand:XF 3 "register_operand" "1")]
16398 (set (match_operand:XF 1 "register_operand" "=u")
16399 (unspec:XF [(match_dup 2) (match_dup 3)]
16401 (set (reg:CCFP FPSR_REG)
16402 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16404 "TARGET_USE_FANCY_MATH_387"
16406 [(set_attr "type" "fpspc")
16407 (set_attr "mode" "XF")])
16409 (define_expand "fmodxf3"
16410 [(use (match_operand:XF 0 "register_operand" ""))
16411 (use (match_operand:XF 1 "general_operand" ""))
16412 (use (match_operand:XF 2 "general_operand" ""))]
16413 "TARGET_USE_FANCY_MATH_387"
16415 rtx label = gen_label_rtx ();
16417 rtx op1 = gen_reg_rtx (XFmode);
16418 rtx op2 = gen_reg_rtx (XFmode);
16420 emit_move_insn (op2, operands[2]);
16421 emit_move_insn (op1, operands[1]);
16423 emit_label (label);
16424 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16425 ix86_emit_fp_unordered_jump (label);
16426 LABEL_NUSES (label) = 1;
16428 emit_move_insn (operands[0], op1);
16432 (define_expand "fmod<mode>3"
16433 [(use (match_operand:MODEF 0 "register_operand" ""))
16434 (use (match_operand:MODEF 1 "general_operand" ""))
16435 (use (match_operand:MODEF 2 "general_operand" ""))]
16436 "TARGET_USE_FANCY_MATH_387"
16438 rtx label = gen_label_rtx ();
16440 rtx op1 = gen_reg_rtx (XFmode);
16441 rtx op2 = gen_reg_rtx (XFmode);
16443 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16444 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16446 emit_label (label);
16447 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16448 ix86_emit_fp_unordered_jump (label);
16449 LABEL_NUSES (label) = 1;
16451 /* Truncate the result properly for strict SSE math. */
16452 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16453 && !TARGET_MIX_SSE_I387)
16454 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16456 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16461 (define_insn "fprem1xf4_i387"
16462 [(set (match_operand:XF 0 "register_operand" "=f")
16463 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16464 (match_operand:XF 3 "register_operand" "1")]
16466 (set (match_operand:XF 1 "register_operand" "=u")
16467 (unspec:XF [(match_dup 2) (match_dup 3)]
16469 (set (reg:CCFP FPSR_REG)
16470 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16472 "TARGET_USE_FANCY_MATH_387"
16474 [(set_attr "type" "fpspc")
16475 (set_attr "mode" "XF")])
16477 (define_expand "remainderxf3"
16478 [(use (match_operand:XF 0 "register_operand" ""))
16479 (use (match_operand:XF 1 "general_operand" ""))
16480 (use (match_operand:XF 2 "general_operand" ""))]
16481 "TARGET_USE_FANCY_MATH_387"
16483 rtx label = gen_label_rtx ();
16485 rtx op1 = gen_reg_rtx (XFmode);
16486 rtx op2 = gen_reg_rtx (XFmode);
16488 emit_move_insn (op2, operands[2]);
16489 emit_move_insn (op1, operands[1]);
16491 emit_label (label);
16492 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16493 ix86_emit_fp_unordered_jump (label);
16494 LABEL_NUSES (label) = 1;
16496 emit_move_insn (operands[0], op1);
16500 (define_expand "remainder<mode>3"
16501 [(use (match_operand:MODEF 0 "register_operand" ""))
16502 (use (match_operand:MODEF 1 "general_operand" ""))
16503 (use (match_operand:MODEF 2 "general_operand" ""))]
16504 "TARGET_USE_FANCY_MATH_387"
16506 rtx label = gen_label_rtx ();
16508 rtx op1 = gen_reg_rtx (XFmode);
16509 rtx op2 = gen_reg_rtx (XFmode);
16511 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16512 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16514 emit_label (label);
16516 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16517 ix86_emit_fp_unordered_jump (label);
16518 LABEL_NUSES (label) = 1;
16520 /* Truncate the result properly for strict SSE math. */
16521 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16522 && !TARGET_MIX_SSE_I387)
16523 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16525 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16530 (define_insn "*sinxf2_i387"
16531 [(set (match_operand:XF 0 "register_operand" "=f")
16532 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16533 "TARGET_USE_FANCY_MATH_387
16534 && flag_unsafe_math_optimizations"
16536 [(set_attr "type" "fpspc")
16537 (set_attr "mode" "XF")])
16539 (define_insn "*sin_extend<mode>xf2_i387"
16540 [(set (match_operand:XF 0 "register_operand" "=f")
16541 (unspec:XF [(float_extend:XF
16542 (match_operand:MODEF 1 "register_operand" "0"))]
16544 "TARGET_USE_FANCY_MATH_387
16545 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16546 || TARGET_MIX_SSE_I387)
16547 && flag_unsafe_math_optimizations"
16549 [(set_attr "type" "fpspc")
16550 (set_attr "mode" "XF")])
16552 (define_insn "*cosxf2_i387"
16553 [(set (match_operand:XF 0 "register_operand" "=f")
16554 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16555 "TARGET_USE_FANCY_MATH_387
16556 && flag_unsafe_math_optimizations"
16558 [(set_attr "type" "fpspc")
16559 (set_attr "mode" "XF")])
16561 (define_insn "*cos_extend<mode>xf2_i387"
16562 [(set (match_operand:XF 0 "register_operand" "=f")
16563 (unspec:XF [(float_extend:XF
16564 (match_operand:MODEF 1 "register_operand" "0"))]
16566 "TARGET_USE_FANCY_MATH_387
16567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16568 || TARGET_MIX_SSE_I387)
16569 && flag_unsafe_math_optimizations"
16571 [(set_attr "type" "fpspc")
16572 (set_attr "mode" "XF")])
16574 ;; When sincos pattern is defined, sin and cos builtin functions will be
16575 ;; expanded to sincos pattern with one of its outputs left unused.
16576 ;; CSE pass will figure out if two sincos patterns can be combined,
16577 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16578 ;; depending on the unused output.
16580 (define_insn "sincosxf3"
16581 [(set (match_operand:XF 0 "register_operand" "=f")
16582 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16583 UNSPEC_SINCOS_COS))
16584 (set (match_operand:XF 1 "register_operand" "=u")
16585 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16586 "TARGET_USE_FANCY_MATH_387
16587 && flag_unsafe_math_optimizations"
16589 [(set_attr "type" "fpspc")
16590 (set_attr "mode" "XF")])
16593 [(set (match_operand:XF 0 "register_operand" "")
16594 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16595 UNSPEC_SINCOS_COS))
16596 (set (match_operand:XF 1 "register_operand" "")
16597 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16598 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16599 && !(reload_completed || reload_in_progress)"
16600 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16604 [(set (match_operand:XF 0 "register_operand" "")
16605 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16606 UNSPEC_SINCOS_COS))
16607 (set (match_operand:XF 1 "register_operand" "")
16608 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16609 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16610 && !(reload_completed || reload_in_progress)"
16611 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16614 (define_insn "sincos_extend<mode>xf3_i387"
16615 [(set (match_operand:XF 0 "register_operand" "=f")
16616 (unspec:XF [(float_extend:XF
16617 (match_operand:MODEF 2 "register_operand" "0"))]
16618 UNSPEC_SINCOS_COS))
16619 (set (match_operand:XF 1 "register_operand" "=u")
16620 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16621 "TARGET_USE_FANCY_MATH_387
16622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16623 || TARGET_MIX_SSE_I387)
16624 && flag_unsafe_math_optimizations"
16626 [(set_attr "type" "fpspc")
16627 (set_attr "mode" "XF")])
16630 [(set (match_operand:XF 0 "register_operand" "")
16631 (unspec:XF [(float_extend:XF
16632 (match_operand:MODEF 2 "register_operand" ""))]
16633 UNSPEC_SINCOS_COS))
16634 (set (match_operand:XF 1 "register_operand" "")
16635 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16636 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16637 && !(reload_completed || reload_in_progress)"
16638 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16642 [(set (match_operand:XF 0 "register_operand" "")
16643 (unspec:XF [(float_extend:XF
16644 (match_operand:MODEF 2 "register_operand" ""))]
16645 UNSPEC_SINCOS_COS))
16646 (set (match_operand:XF 1 "register_operand" "")
16647 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16648 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16649 && !(reload_completed || reload_in_progress)"
16650 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16653 (define_expand "sincos<mode>3"
16654 [(use (match_operand:MODEF 0 "register_operand" ""))
16655 (use (match_operand:MODEF 1 "register_operand" ""))
16656 (use (match_operand:MODEF 2 "register_operand" ""))]
16657 "TARGET_USE_FANCY_MATH_387
16658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16659 || TARGET_MIX_SSE_I387)
16660 && flag_unsafe_math_optimizations"
16662 rtx op0 = gen_reg_rtx (XFmode);
16663 rtx op1 = gen_reg_rtx (XFmode);
16665 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16666 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16667 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16671 (define_insn "fptanxf4_i387"
16672 [(set (match_operand:XF 0 "register_operand" "=f")
16673 (match_operand:XF 3 "const_double_operand" "F"))
16674 (set (match_operand:XF 1 "register_operand" "=u")
16675 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16677 "TARGET_USE_FANCY_MATH_387
16678 && flag_unsafe_math_optimizations
16679 && standard_80387_constant_p (operands[3]) == 2"
16681 [(set_attr "type" "fpspc")
16682 (set_attr "mode" "XF")])
16684 (define_insn "fptan_extend<mode>xf4_i387"
16685 [(set (match_operand:MODEF 0 "register_operand" "=f")
16686 (match_operand:MODEF 3 "const_double_operand" "F"))
16687 (set (match_operand:XF 1 "register_operand" "=u")
16688 (unspec:XF [(float_extend:XF
16689 (match_operand:MODEF 2 "register_operand" "0"))]
16691 "TARGET_USE_FANCY_MATH_387
16692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16693 || TARGET_MIX_SSE_I387)
16694 && flag_unsafe_math_optimizations
16695 && standard_80387_constant_p (operands[3]) == 2"
16697 [(set_attr "type" "fpspc")
16698 (set_attr "mode" "XF")])
16700 (define_expand "tanxf2"
16701 [(use (match_operand:XF 0 "register_operand" ""))
16702 (use (match_operand:XF 1 "register_operand" ""))]
16703 "TARGET_USE_FANCY_MATH_387
16704 && flag_unsafe_math_optimizations"
16706 rtx one = gen_reg_rtx (XFmode);
16707 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16709 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16713 (define_expand "tan<mode>2"
16714 [(use (match_operand:MODEF 0 "register_operand" ""))
16715 (use (match_operand:MODEF 1 "register_operand" ""))]
16716 "TARGET_USE_FANCY_MATH_387
16717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16718 || TARGET_MIX_SSE_I387)
16719 && flag_unsafe_math_optimizations"
16721 rtx op0 = gen_reg_rtx (XFmode);
16723 rtx one = gen_reg_rtx (<MODE>mode);
16724 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16726 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16727 operands[1], op2));
16728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16732 (define_insn "*fpatanxf3_i387"
16733 [(set (match_operand:XF 0 "register_operand" "=f")
16734 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16735 (match_operand:XF 2 "register_operand" "u")]
16737 (clobber (match_scratch:XF 3 "=2"))]
16738 "TARGET_USE_FANCY_MATH_387
16739 && flag_unsafe_math_optimizations"
16741 [(set_attr "type" "fpspc")
16742 (set_attr "mode" "XF")])
16744 (define_insn "fpatan_extend<mode>xf3_i387"
16745 [(set (match_operand:XF 0 "register_operand" "=f")
16746 (unspec:XF [(float_extend:XF
16747 (match_operand:MODEF 1 "register_operand" "0"))
16749 (match_operand:MODEF 2 "register_operand" "u"))]
16751 (clobber (match_scratch:XF 3 "=2"))]
16752 "TARGET_USE_FANCY_MATH_387
16753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16754 || TARGET_MIX_SSE_I387)
16755 && flag_unsafe_math_optimizations"
16757 [(set_attr "type" "fpspc")
16758 (set_attr "mode" "XF")])
16760 (define_expand "atan2xf3"
16761 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16762 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16763 (match_operand:XF 1 "register_operand" "")]
16765 (clobber (match_scratch:XF 3 ""))])]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations"
16770 (define_expand "atan2<mode>3"
16771 [(use (match_operand:MODEF 0 "register_operand" ""))
16772 (use (match_operand:MODEF 1 "register_operand" ""))
16773 (use (match_operand:MODEF 2 "register_operand" ""))]
16774 "TARGET_USE_FANCY_MATH_387
16775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16776 || TARGET_MIX_SSE_I387)
16777 && flag_unsafe_math_optimizations"
16779 rtx op0 = gen_reg_rtx (XFmode);
16781 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16782 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16786 (define_expand "atanxf2"
16787 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16788 (unspec:XF [(match_dup 2)
16789 (match_operand:XF 1 "register_operand" "")]
16791 (clobber (match_scratch:XF 3 ""))])]
16792 "TARGET_USE_FANCY_MATH_387
16793 && flag_unsafe_math_optimizations"
16795 operands[2] = gen_reg_rtx (XFmode);
16796 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16799 (define_expand "atan<mode>2"
16800 [(use (match_operand:MODEF 0 "register_operand" ""))
16801 (use (match_operand:MODEF 1 "register_operand" ""))]
16802 "TARGET_USE_FANCY_MATH_387
16803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16804 || TARGET_MIX_SSE_I387)
16805 && flag_unsafe_math_optimizations"
16807 rtx op0 = gen_reg_rtx (XFmode);
16809 rtx op2 = gen_reg_rtx (<MODE>mode);
16810 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16812 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16813 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16817 (define_expand "asinxf2"
16818 [(set (match_dup 2)
16819 (mult:XF (match_operand:XF 1 "register_operand" "")
16821 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16822 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16823 (parallel [(set (match_operand:XF 0 "register_operand" "")
16824 (unspec:XF [(match_dup 5) (match_dup 1)]
16826 (clobber (match_scratch:XF 6 ""))])]
16827 "TARGET_USE_FANCY_MATH_387
16828 && flag_unsafe_math_optimizations && !optimize_size"
16832 for (i = 2; i < 6; i++)
16833 operands[i] = gen_reg_rtx (XFmode);
16835 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16838 (define_expand "asin<mode>2"
16839 [(use (match_operand:MODEF 0 "register_operand" ""))
16840 (use (match_operand:MODEF 1 "general_operand" ""))]
16841 "TARGET_USE_FANCY_MATH_387
16842 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16843 || TARGET_MIX_SSE_I387)
16844 && flag_unsafe_math_optimizations && !optimize_size"
16846 rtx op0 = gen_reg_rtx (XFmode);
16847 rtx op1 = gen_reg_rtx (XFmode);
16849 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16850 emit_insn (gen_asinxf2 (op0, op1));
16851 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16855 (define_expand "acosxf2"
16856 [(set (match_dup 2)
16857 (mult:XF (match_operand:XF 1 "register_operand" "")
16859 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16860 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16861 (parallel [(set (match_operand:XF 0 "register_operand" "")
16862 (unspec:XF [(match_dup 1) (match_dup 5)]
16864 (clobber (match_scratch:XF 6 ""))])]
16865 "TARGET_USE_FANCY_MATH_387
16866 && flag_unsafe_math_optimizations && !optimize_size"
16870 for (i = 2; i < 6; i++)
16871 operands[i] = gen_reg_rtx (XFmode);
16873 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16876 (define_expand "acos<mode>2"
16877 [(use (match_operand:MODEF 0 "register_operand" ""))
16878 (use (match_operand:MODEF 1 "general_operand" ""))]
16879 "TARGET_USE_FANCY_MATH_387
16880 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16881 || TARGET_MIX_SSE_I387)
16882 && flag_unsafe_math_optimizations && !optimize_size"
16884 rtx op0 = gen_reg_rtx (XFmode);
16885 rtx op1 = gen_reg_rtx (XFmode);
16887 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16888 emit_insn (gen_acosxf2 (op0, op1));
16889 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16893 (define_insn "fyl2xxf3_i387"
16894 [(set (match_operand:XF 0 "register_operand" "=f")
16895 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16896 (match_operand:XF 2 "register_operand" "u")]
16898 (clobber (match_scratch:XF 3 "=2"))]
16899 "TARGET_USE_FANCY_MATH_387
16900 && flag_unsafe_math_optimizations"
16902 [(set_attr "type" "fpspc")
16903 (set_attr "mode" "XF")])
16905 (define_insn "fyl2x_extend<mode>xf3_i387"
16906 [(set (match_operand:XF 0 "register_operand" "=f")
16907 (unspec:XF [(float_extend:XF
16908 (match_operand:MODEF 1 "register_operand" "0"))
16909 (match_operand:XF 2 "register_operand" "u")]
16911 (clobber (match_scratch:XF 3 "=2"))]
16912 "TARGET_USE_FANCY_MATH_387
16913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16914 || TARGET_MIX_SSE_I387)
16915 && flag_unsafe_math_optimizations"
16917 [(set_attr "type" "fpspc")
16918 (set_attr "mode" "XF")])
16920 (define_expand "logxf2"
16921 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16922 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16923 (match_dup 2)] UNSPEC_FYL2X))
16924 (clobber (match_scratch:XF 3 ""))])]
16925 "TARGET_USE_FANCY_MATH_387
16926 && flag_unsafe_math_optimizations"
16928 operands[2] = gen_reg_rtx (XFmode);
16929 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16932 (define_expand "log<mode>2"
16933 [(use (match_operand:MODEF 0 "register_operand" ""))
16934 (use (match_operand:MODEF 1 "register_operand" ""))]
16935 "TARGET_USE_FANCY_MATH_387
16936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16937 || TARGET_MIX_SSE_I387)
16938 && flag_unsafe_math_optimizations"
16940 rtx op0 = gen_reg_rtx (XFmode);
16942 rtx op2 = gen_reg_rtx (XFmode);
16943 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16945 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16946 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16950 (define_expand "log10xf2"
16951 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16952 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16953 (match_dup 2)] UNSPEC_FYL2X))
16954 (clobber (match_scratch:XF 3 ""))])]
16955 "TARGET_USE_FANCY_MATH_387
16956 && flag_unsafe_math_optimizations"
16958 operands[2] = gen_reg_rtx (XFmode);
16959 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16962 (define_expand "log10<mode>2"
16963 [(use (match_operand:MODEF 0 "register_operand" ""))
16964 (use (match_operand:MODEF 1 "register_operand" ""))]
16965 "TARGET_USE_FANCY_MATH_387
16966 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16967 || TARGET_MIX_SSE_I387)
16968 && flag_unsafe_math_optimizations"
16970 rtx op0 = gen_reg_rtx (XFmode);
16972 rtx op2 = gen_reg_rtx (XFmode);
16973 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16975 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16976 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16980 (define_expand "log2xf2"
16981 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16982 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16983 (match_dup 2)] UNSPEC_FYL2X))
16984 (clobber (match_scratch:XF 3 ""))])]
16985 "TARGET_USE_FANCY_MATH_387
16986 && flag_unsafe_math_optimizations"
16988 operands[2] = gen_reg_rtx (XFmode);
16989 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16992 (define_expand "log2<mode>2"
16993 [(use (match_operand:MODEF 0 "register_operand" ""))
16994 (use (match_operand:MODEF 1 "register_operand" ""))]
16995 "TARGET_USE_FANCY_MATH_387
16996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16997 || TARGET_MIX_SSE_I387)
16998 && flag_unsafe_math_optimizations"
17000 rtx op0 = gen_reg_rtx (XFmode);
17002 rtx op2 = gen_reg_rtx (XFmode);
17003 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17005 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17006 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17010 (define_insn "fyl2xp1xf3_i387"
17011 [(set (match_operand:XF 0 "register_operand" "=f")
17012 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17013 (match_operand:XF 2 "register_operand" "u")]
17015 (clobber (match_scratch:XF 3 "=2"))]
17016 "TARGET_USE_FANCY_MATH_387
17017 && flag_unsafe_math_optimizations"
17019 [(set_attr "type" "fpspc")
17020 (set_attr "mode" "XF")])
17022 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17023 [(set (match_operand:XF 0 "register_operand" "=f")
17024 (unspec:XF [(float_extend:XF
17025 (match_operand:MODEF 1 "register_operand" "0"))
17026 (match_operand:XF 2 "register_operand" "u")]
17028 (clobber (match_scratch:XF 3 "=2"))]
17029 "TARGET_USE_FANCY_MATH_387
17030 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17031 || TARGET_MIX_SSE_I387)
17032 && flag_unsafe_math_optimizations"
17034 [(set_attr "type" "fpspc")
17035 (set_attr "mode" "XF")])
17037 (define_expand "log1pxf2"
17038 [(use (match_operand:XF 0 "register_operand" ""))
17039 (use (match_operand:XF 1 "register_operand" ""))]
17040 "TARGET_USE_FANCY_MATH_387
17041 && flag_unsafe_math_optimizations && !optimize_size"
17043 ix86_emit_i387_log1p (operands[0], operands[1]);
17047 (define_expand "log1p<mode>2"
17048 [(use (match_operand:MODEF 0 "register_operand" ""))
17049 (use (match_operand:MODEF 1 "register_operand" ""))]
17050 "TARGET_USE_FANCY_MATH_387
17051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17052 || TARGET_MIX_SSE_I387)
17053 && flag_unsafe_math_optimizations && !optimize_size"
17055 rtx op0 = gen_reg_rtx (XFmode);
17057 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17059 ix86_emit_i387_log1p (op0, operands[1]);
17060 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17064 (define_insn "fxtractxf3_i387"
17065 [(set (match_operand:XF 0 "register_operand" "=f")
17066 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17067 UNSPEC_XTRACT_FRACT))
17068 (set (match_operand:XF 1 "register_operand" "=u")
17069 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17070 "TARGET_USE_FANCY_MATH_387
17071 && flag_unsafe_math_optimizations"
17073 [(set_attr "type" "fpspc")
17074 (set_attr "mode" "XF")])
17076 (define_insn "fxtract_extend<mode>xf3_i387"
17077 [(set (match_operand:XF 0 "register_operand" "=f")
17078 (unspec:XF [(float_extend:XF
17079 (match_operand:MODEF 2 "register_operand" "0"))]
17080 UNSPEC_XTRACT_FRACT))
17081 (set (match_operand:XF 1 "register_operand" "=u")
17082 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17083 "TARGET_USE_FANCY_MATH_387
17084 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17085 || TARGET_MIX_SSE_I387)
17086 && flag_unsafe_math_optimizations"
17088 [(set_attr "type" "fpspc")
17089 (set_attr "mode" "XF")])
17091 (define_expand "logbxf2"
17092 [(parallel [(set (match_dup 2)
17093 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17094 UNSPEC_XTRACT_FRACT))
17095 (set (match_operand:XF 0 "register_operand" "")
17096 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17097 "TARGET_USE_FANCY_MATH_387
17098 && flag_unsafe_math_optimizations"
17100 operands[2] = gen_reg_rtx (XFmode);
17103 (define_expand "logb<mode>2"
17104 [(use (match_operand:MODEF 0 "register_operand" ""))
17105 (use (match_operand:MODEF 1 "register_operand" ""))]
17106 "TARGET_USE_FANCY_MATH_387
17107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17108 || TARGET_MIX_SSE_I387)
17109 && flag_unsafe_math_optimizations"
17111 rtx op0 = gen_reg_rtx (XFmode);
17112 rtx op1 = gen_reg_rtx (XFmode);
17114 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17115 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17119 (define_expand "ilogbxf2"
17120 [(use (match_operand:SI 0 "register_operand" ""))
17121 (use (match_operand:XF 1 "register_operand" ""))]
17122 "TARGET_USE_FANCY_MATH_387
17123 && flag_unsafe_math_optimizations && !optimize_size"
17125 rtx op0 = gen_reg_rtx (XFmode);
17126 rtx op1 = gen_reg_rtx (XFmode);
17128 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17129 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17133 (define_expand "ilogb<mode>2"
17134 [(use (match_operand:SI 0 "register_operand" ""))
17135 (use (match_operand:MODEF 1 "register_operand" ""))]
17136 "TARGET_USE_FANCY_MATH_387
17137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17138 || TARGET_MIX_SSE_I387)
17139 && flag_unsafe_math_optimizations && !optimize_size"
17141 rtx op0 = gen_reg_rtx (XFmode);
17142 rtx op1 = gen_reg_rtx (XFmode);
17144 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17145 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17149 (define_insn "*f2xm1xf2_i387"
17150 [(set (match_operand:XF 0 "register_operand" "=f")
17151 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17153 "TARGET_USE_FANCY_MATH_387
17154 && flag_unsafe_math_optimizations"
17156 [(set_attr "type" "fpspc")
17157 (set_attr "mode" "XF")])
17159 (define_insn "*fscalexf4_i387"
17160 [(set (match_operand:XF 0 "register_operand" "=f")
17161 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17162 (match_operand:XF 3 "register_operand" "1")]
17163 UNSPEC_FSCALE_FRACT))
17164 (set (match_operand:XF 1 "register_operand" "=u")
17165 (unspec:XF [(match_dup 2) (match_dup 3)]
17166 UNSPEC_FSCALE_EXP))]
17167 "TARGET_USE_FANCY_MATH_387
17168 && flag_unsafe_math_optimizations"
17170 [(set_attr "type" "fpspc")
17171 (set_attr "mode" "XF")])
17173 (define_expand "expNcorexf3"
17174 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17175 (match_operand:XF 2 "register_operand" "")))
17176 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17177 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17178 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17179 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17180 (parallel [(set (match_operand:XF 0 "register_operand" "")
17181 (unspec:XF [(match_dup 8) (match_dup 4)]
17182 UNSPEC_FSCALE_FRACT))
17184 (unspec:XF [(match_dup 8) (match_dup 4)]
17185 UNSPEC_FSCALE_EXP))])]
17186 "TARGET_USE_FANCY_MATH_387
17187 && flag_unsafe_math_optimizations && !optimize_size"
17191 for (i = 3; i < 10; i++)
17192 operands[i] = gen_reg_rtx (XFmode);
17194 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17197 (define_expand "expxf2"
17198 [(use (match_operand:XF 0 "register_operand" ""))
17199 (use (match_operand:XF 1 "register_operand" ""))]
17200 "TARGET_USE_FANCY_MATH_387
17201 && flag_unsafe_math_optimizations && !optimize_size"
17203 rtx op2 = gen_reg_rtx (XFmode);
17204 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17206 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17210 (define_expand "exp<mode>2"
17211 [(use (match_operand:MODEF 0 "register_operand" ""))
17212 (use (match_operand:MODEF 1 "general_operand" ""))]
17213 "TARGET_USE_FANCY_MATH_387
17214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17215 || TARGET_MIX_SSE_I387)
17216 && flag_unsafe_math_optimizations && !optimize_size"
17218 rtx op0 = gen_reg_rtx (XFmode);
17219 rtx op1 = gen_reg_rtx (XFmode);
17221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17222 emit_insn (gen_expxf2 (op0, op1));
17223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17227 (define_expand "exp10xf2"
17228 [(use (match_operand:XF 0 "register_operand" ""))
17229 (use (match_operand:XF 1 "register_operand" ""))]
17230 "TARGET_USE_FANCY_MATH_387
17231 && flag_unsafe_math_optimizations && !optimize_size"
17233 rtx op2 = gen_reg_rtx (XFmode);
17234 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17236 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17240 (define_expand "exp10<mode>2"
17241 [(use (match_operand:MODEF 0 "register_operand" ""))
17242 (use (match_operand:MODEF 1 "general_operand" ""))]
17243 "TARGET_USE_FANCY_MATH_387
17244 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17245 || TARGET_MIX_SSE_I387)
17246 && flag_unsafe_math_optimizations && !optimize_size"
17248 rtx op0 = gen_reg_rtx (XFmode);
17249 rtx op1 = gen_reg_rtx (XFmode);
17251 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17252 emit_insn (gen_exp10xf2 (op0, op1));
17253 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17257 (define_expand "exp2xf2"
17258 [(use (match_operand:XF 0 "register_operand" ""))
17259 (use (match_operand:XF 1 "register_operand" ""))]
17260 "TARGET_USE_FANCY_MATH_387
17261 && flag_unsafe_math_optimizations && !optimize_size"
17263 rtx op2 = gen_reg_rtx (XFmode);
17264 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17266 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17270 (define_expand "exp2<mode>2"
17271 [(use (match_operand:MODEF 0 "register_operand" ""))
17272 (use (match_operand:MODEF 1 "general_operand" ""))]
17273 "TARGET_USE_FANCY_MATH_387
17274 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17275 || TARGET_MIX_SSE_I387)
17276 && flag_unsafe_math_optimizations && !optimize_size"
17278 rtx op0 = gen_reg_rtx (XFmode);
17279 rtx op1 = gen_reg_rtx (XFmode);
17281 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17282 emit_insn (gen_exp2xf2 (op0, op1));
17283 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17287 (define_expand "expm1xf2"
17288 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17290 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17291 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17292 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17293 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17294 (parallel [(set (match_dup 7)
17295 (unspec:XF [(match_dup 6) (match_dup 4)]
17296 UNSPEC_FSCALE_FRACT))
17298 (unspec:XF [(match_dup 6) (match_dup 4)]
17299 UNSPEC_FSCALE_EXP))])
17300 (parallel [(set (match_dup 10)
17301 (unspec:XF [(match_dup 9) (match_dup 8)]
17302 UNSPEC_FSCALE_FRACT))
17303 (set (match_dup 11)
17304 (unspec:XF [(match_dup 9) (match_dup 8)]
17305 UNSPEC_FSCALE_EXP))])
17306 (set (match_dup 12) (minus:XF (match_dup 10)
17307 (float_extend:XF (match_dup 13))))
17308 (set (match_operand:XF 0 "register_operand" "")
17309 (plus:XF (match_dup 12) (match_dup 7)))]
17310 "TARGET_USE_FANCY_MATH_387
17311 && flag_unsafe_math_optimizations && !optimize_size"
17315 for (i = 2; i < 13; i++)
17316 operands[i] = gen_reg_rtx (XFmode);
17319 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17321 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17324 (define_expand "expm1<mode>2"
17325 [(use (match_operand:MODEF 0 "register_operand" ""))
17326 (use (match_operand:MODEF 1 "general_operand" ""))]
17327 "TARGET_USE_FANCY_MATH_387
17328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17329 || TARGET_MIX_SSE_I387)
17330 && flag_unsafe_math_optimizations && !optimize_size"
17332 rtx op0 = gen_reg_rtx (XFmode);
17333 rtx op1 = gen_reg_rtx (XFmode);
17335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17336 emit_insn (gen_expm1xf2 (op0, op1));
17337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17341 (define_expand "ldexpxf3"
17342 [(set (match_dup 3)
17343 (float:XF (match_operand:SI 2 "register_operand" "")))
17344 (parallel [(set (match_operand:XF 0 " register_operand" "")
17345 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17347 UNSPEC_FSCALE_FRACT))
17349 (unspec:XF [(match_dup 1) (match_dup 3)]
17350 UNSPEC_FSCALE_EXP))])]
17351 "TARGET_USE_FANCY_MATH_387
17352 && flag_unsafe_math_optimizations && !optimize_size"
17354 operands[3] = gen_reg_rtx (XFmode);
17355 operands[4] = gen_reg_rtx (XFmode);
17358 (define_expand "ldexp<mode>3"
17359 [(use (match_operand:MODEF 0 "register_operand" ""))
17360 (use (match_operand:MODEF 1 "general_operand" ""))
17361 (use (match_operand:SI 2 "register_operand" ""))]
17362 "TARGET_USE_FANCY_MATH_387
17363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17364 || TARGET_MIX_SSE_I387)
17365 && flag_unsafe_math_optimizations && !optimize_size"
17367 rtx op0 = gen_reg_rtx (XFmode);
17368 rtx op1 = gen_reg_rtx (XFmode);
17370 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17371 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17372 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17376 (define_expand "scalbxf3"
17377 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17378 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17379 (match_operand:XF 2 "register_operand" "")]
17380 UNSPEC_FSCALE_FRACT))
17382 (unspec:XF [(match_dup 1) (match_dup 2)]
17383 UNSPEC_FSCALE_EXP))])]
17384 "TARGET_USE_FANCY_MATH_387
17385 && flag_unsafe_math_optimizations && !optimize_size"
17387 operands[3] = gen_reg_rtx (XFmode);
17390 (define_expand "scalb<mode>3"
17391 [(use (match_operand:MODEF 0 "register_operand" ""))
17392 (use (match_operand:MODEF 1 "general_operand" ""))
17393 (use (match_operand:MODEF 2 "register_operand" ""))]
17394 "TARGET_USE_FANCY_MATH_387
17395 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17396 || TARGET_MIX_SSE_I387)
17397 && flag_unsafe_math_optimizations && !optimize_size"
17399 rtx op0 = gen_reg_rtx (XFmode);
17400 rtx op1 = gen_reg_rtx (XFmode);
17401 rtx op2 = gen_reg_rtx (XFmode);
17403 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17404 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17405 emit_insn (gen_scalbxf3 (op0, op1, op2));
17406 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17411 (define_insn "sse4_1_round<mode>2"
17412 [(set (match_operand:MODEF 0 "register_operand" "=x")
17413 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17414 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17417 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17418 [(set_attr "type" "ssecvt")
17419 (set_attr "prefix_extra" "1")
17420 (set_attr "mode" "<MODE>")])
17422 (define_insn "rintxf2"
17423 [(set (match_operand:XF 0 "register_operand" "=f")
17424 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17426 "TARGET_USE_FANCY_MATH_387
17427 && flag_unsafe_math_optimizations"
17429 [(set_attr "type" "fpspc")
17430 (set_attr "mode" "XF")])
17432 (define_expand "rint<mode>2"
17433 [(use (match_operand:MODEF 0 "register_operand" ""))
17434 (use (match_operand:MODEF 1 "register_operand" ""))]
17435 "(TARGET_USE_FANCY_MATH_387
17436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17437 || TARGET_MIX_SSE_I387)
17438 && flag_unsafe_math_optimizations)
17439 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17440 && !flag_trapping_math
17441 && (TARGET_ROUND || !optimize_size))"
17443 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17444 && !flag_trapping_math
17445 && (TARGET_ROUND || !optimize_size))
17448 emit_insn (gen_sse4_1_round<mode>2
17449 (operands[0], operands[1], GEN_INT (0x04)));
17451 ix86_expand_rint (operand0, operand1);
17455 rtx op0 = gen_reg_rtx (XFmode);
17456 rtx op1 = gen_reg_rtx (XFmode);
17458 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17459 emit_insn (gen_rintxf2 (op0, op1));
17461 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17466 (define_expand "round<mode>2"
17467 [(match_operand:MODEF 0 "register_operand" "")
17468 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17469 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17470 && !flag_trapping_math && !flag_rounding_math
17473 if (TARGET_64BIT || (<MODE>mode != DFmode))
17474 ix86_expand_round (operand0, operand1);
17476 ix86_expand_rounddf_32 (operand0, operand1);
17480 (define_insn_and_split "*fistdi2_1"
17481 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17482 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17484 "TARGET_USE_FANCY_MATH_387
17485 && !(reload_completed || reload_in_progress)"
17490 if (memory_operand (operands[0], VOIDmode))
17491 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17494 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17495 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17500 [(set_attr "type" "fpspc")
17501 (set_attr "mode" "DI")])
17503 (define_insn "fistdi2"
17504 [(set (match_operand:DI 0 "memory_operand" "=m")
17505 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17507 (clobber (match_scratch:XF 2 "=&1f"))]
17508 "TARGET_USE_FANCY_MATH_387"
17509 "* return output_fix_trunc (insn, operands, 0);"
17510 [(set_attr "type" "fpspc")
17511 (set_attr "mode" "DI")])
17513 (define_insn "fistdi2_with_temp"
17514 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17515 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17517 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17518 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17519 "TARGET_USE_FANCY_MATH_387"
17521 [(set_attr "type" "fpspc")
17522 (set_attr "mode" "DI")])
17525 [(set (match_operand:DI 0 "register_operand" "")
17526 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17528 (clobber (match_operand:DI 2 "memory_operand" ""))
17529 (clobber (match_scratch 3 ""))]
17531 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17532 (clobber (match_dup 3))])
17533 (set (match_dup 0) (match_dup 2))]
17537 [(set (match_operand:DI 0 "memory_operand" "")
17538 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17540 (clobber (match_operand:DI 2 "memory_operand" ""))
17541 (clobber (match_scratch 3 ""))]
17543 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17544 (clobber (match_dup 3))])]
17547 (define_insn_and_split "*fist<mode>2_1"
17548 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17549 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17551 "TARGET_USE_FANCY_MATH_387
17552 && !(reload_completed || reload_in_progress)"
17557 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17558 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17562 [(set_attr "type" "fpspc")
17563 (set_attr "mode" "<MODE>")])
17565 (define_insn "fist<mode>2"
17566 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17567 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17569 "TARGET_USE_FANCY_MATH_387"
17570 "* return output_fix_trunc (insn, operands, 0);"
17571 [(set_attr "type" "fpspc")
17572 (set_attr "mode" "<MODE>")])
17574 (define_insn "fist<mode>2_with_temp"
17575 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17576 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17578 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17579 "TARGET_USE_FANCY_MATH_387"
17581 [(set_attr "type" "fpspc")
17582 (set_attr "mode" "<MODE>")])
17585 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17586 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17588 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17590 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17591 (set (match_dup 0) (match_dup 2))]
17595 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17596 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17598 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17600 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17603 (define_expand "lrintxf<mode>2"
17604 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17605 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17607 "TARGET_USE_FANCY_MATH_387"
17610 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17611 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17612 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17613 UNSPEC_FIX_NOTRUNC))]
17614 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17615 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17618 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17619 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17620 (match_operand:MODEF 1 "register_operand" "")]
17621 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17622 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17623 && !flag_trapping_math && !flag_rounding_math
17626 ix86_expand_lround (operand0, operand1);
17630 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17631 (define_insn_and_split "frndintxf2_floor"
17632 [(set (match_operand:XF 0 "register_operand" "")
17633 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17634 UNSPEC_FRNDINT_FLOOR))
17635 (clobber (reg:CC FLAGS_REG))]
17636 "TARGET_USE_FANCY_MATH_387
17637 && flag_unsafe_math_optimizations
17638 && !(reload_completed || reload_in_progress)"
17643 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17645 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17646 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17648 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17649 operands[2], operands[3]));
17652 [(set_attr "type" "frndint")
17653 (set_attr "i387_cw" "floor")
17654 (set_attr "mode" "XF")])
17656 (define_insn "frndintxf2_floor_i387"
17657 [(set (match_operand:XF 0 "register_operand" "=f")
17658 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17659 UNSPEC_FRNDINT_FLOOR))
17660 (use (match_operand:HI 2 "memory_operand" "m"))
17661 (use (match_operand:HI 3 "memory_operand" "m"))]
17662 "TARGET_USE_FANCY_MATH_387
17663 && flag_unsafe_math_optimizations"
17664 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17665 [(set_attr "type" "frndint")
17666 (set_attr "i387_cw" "floor")
17667 (set_attr "mode" "XF")])
17669 (define_expand "floorxf2"
17670 [(use (match_operand:XF 0 "register_operand" ""))
17671 (use (match_operand:XF 1 "register_operand" ""))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && flag_unsafe_math_optimizations && !optimize_size"
17675 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17679 (define_expand "floor<mode>2"
17680 [(use (match_operand:MODEF 0 "register_operand" ""))
17681 (use (match_operand:MODEF 1 "register_operand" ""))]
17682 "(TARGET_USE_FANCY_MATH_387
17683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17684 || TARGET_MIX_SSE_I387)
17685 && flag_unsafe_math_optimizations && !optimize_size)
17686 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17687 && !flag_trapping_math
17688 && (TARGET_ROUND || !optimize_size))"
17690 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17691 && !flag_trapping_math
17692 && (TARGET_ROUND || !optimize_size))
17695 emit_insn (gen_sse4_1_round<mode>2
17696 (operands[0], operands[1], GEN_INT (0x01)));
17697 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17698 ix86_expand_floorceil (operand0, operand1, true);
17700 ix86_expand_floorceildf_32 (operand0, operand1, true);
17704 rtx op0 = gen_reg_rtx (XFmode);
17705 rtx op1 = gen_reg_rtx (XFmode);
17707 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17708 emit_insn (gen_frndintxf2_floor (op0, op1));
17710 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17715 (define_insn_and_split "*fist<mode>2_floor_1"
17716 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17717 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17718 UNSPEC_FIST_FLOOR))
17719 (clobber (reg:CC FLAGS_REG))]
17720 "TARGET_USE_FANCY_MATH_387
17721 && flag_unsafe_math_optimizations
17722 && !(reload_completed || reload_in_progress)"
17727 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17729 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17730 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17731 if (memory_operand (operands[0], VOIDmode))
17732 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17733 operands[2], operands[3]));
17736 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17737 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17738 operands[2], operands[3],
17743 [(set_attr "type" "fistp")
17744 (set_attr "i387_cw" "floor")
17745 (set_attr "mode" "<MODE>")])
17747 (define_insn "fistdi2_floor"
17748 [(set (match_operand:DI 0 "memory_operand" "=m")
17749 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17750 UNSPEC_FIST_FLOOR))
17751 (use (match_operand:HI 2 "memory_operand" "m"))
17752 (use (match_operand:HI 3 "memory_operand" "m"))
17753 (clobber (match_scratch:XF 4 "=&1f"))]
17754 "TARGET_USE_FANCY_MATH_387
17755 && flag_unsafe_math_optimizations"
17756 "* return output_fix_trunc (insn, operands, 0);"
17757 [(set_attr "type" "fistp")
17758 (set_attr "i387_cw" "floor")
17759 (set_attr "mode" "DI")])
17761 (define_insn "fistdi2_floor_with_temp"
17762 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17763 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17764 UNSPEC_FIST_FLOOR))
17765 (use (match_operand:HI 2 "memory_operand" "m,m"))
17766 (use (match_operand:HI 3 "memory_operand" "m,m"))
17767 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17768 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17769 "TARGET_USE_FANCY_MATH_387
17770 && flag_unsafe_math_optimizations"
17772 [(set_attr "type" "fistp")
17773 (set_attr "i387_cw" "floor")
17774 (set_attr "mode" "DI")])
17777 [(set (match_operand:DI 0 "register_operand" "")
17778 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17779 UNSPEC_FIST_FLOOR))
17780 (use (match_operand:HI 2 "memory_operand" ""))
17781 (use (match_operand:HI 3 "memory_operand" ""))
17782 (clobber (match_operand:DI 4 "memory_operand" ""))
17783 (clobber (match_scratch 5 ""))]
17785 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17786 (use (match_dup 2))
17787 (use (match_dup 3))
17788 (clobber (match_dup 5))])
17789 (set (match_dup 0) (match_dup 4))]
17793 [(set (match_operand:DI 0 "memory_operand" "")
17794 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17795 UNSPEC_FIST_FLOOR))
17796 (use (match_operand:HI 2 "memory_operand" ""))
17797 (use (match_operand:HI 3 "memory_operand" ""))
17798 (clobber (match_operand:DI 4 "memory_operand" ""))
17799 (clobber (match_scratch 5 ""))]
17801 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17802 (use (match_dup 2))
17803 (use (match_dup 3))
17804 (clobber (match_dup 5))])]
17807 (define_insn "fist<mode>2_floor"
17808 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17809 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17810 UNSPEC_FIST_FLOOR))
17811 (use (match_operand:HI 2 "memory_operand" "m"))
17812 (use (match_operand:HI 3 "memory_operand" "m"))]
17813 "TARGET_USE_FANCY_MATH_387
17814 && flag_unsafe_math_optimizations"
17815 "* return output_fix_trunc (insn, operands, 0);"
17816 [(set_attr "type" "fistp")
17817 (set_attr "i387_cw" "floor")
17818 (set_attr "mode" "<MODE>")])
17820 (define_insn "fist<mode>2_floor_with_temp"
17821 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17822 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17823 UNSPEC_FIST_FLOOR))
17824 (use (match_operand:HI 2 "memory_operand" "m,m"))
17825 (use (match_operand:HI 3 "memory_operand" "m,m"))
17826 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17827 "TARGET_USE_FANCY_MATH_387
17828 && flag_unsafe_math_optimizations"
17830 [(set_attr "type" "fistp")
17831 (set_attr "i387_cw" "floor")
17832 (set_attr "mode" "<MODE>")])
17835 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17836 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17837 UNSPEC_FIST_FLOOR))
17838 (use (match_operand:HI 2 "memory_operand" ""))
17839 (use (match_operand:HI 3 "memory_operand" ""))
17840 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17842 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17843 UNSPEC_FIST_FLOOR))
17844 (use (match_dup 2))
17845 (use (match_dup 3))])
17846 (set (match_dup 0) (match_dup 4))]
17850 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17851 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17852 UNSPEC_FIST_FLOOR))
17853 (use (match_operand:HI 2 "memory_operand" ""))
17854 (use (match_operand:HI 3 "memory_operand" ""))
17855 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17857 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17858 UNSPEC_FIST_FLOOR))
17859 (use (match_dup 2))
17860 (use (match_dup 3))])]
17863 (define_expand "lfloorxf<mode>2"
17864 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17865 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17866 UNSPEC_FIST_FLOOR))
17867 (clobber (reg:CC FLAGS_REG))])]
17868 "TARGET_USE_FANCY_MATH_387
17869 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17870 && flag_unsafe_math_optimizations"
17873 (define_expand "lfloor<mode>di2"
17874 [(match_operand:DI 0 "nonimmediate_operand" "")
17875 (match_operand:MODEF 1 "register_operand" "")]
17876 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17877 && !flag_trapping_math
17880 ix86_expand_lfloorceil (operand0, operand1, true);
17884 (define_expand "lfloor<mode>si2"
17885 [(match_operand:SI 0 "nonimmediate_operand" "")
17886 (match_operand:MODEF 1 "register_operand" "")]
17887 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17888 && !flag_trapping_math
17889 && (!optimize_size || !TARGET_64BIT)"
17891 ix86_expand_lfloorceil (operand0, operand1, true);
17895 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17896 (define_insn_and_split "frndintxf2_ceil"
17897 [(set (match_operand:XF 0 "register_operand" "")
17898 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17899 UNSPEC_FRNDINT_CEIL))
17900 (clobber (reg:CC FLAGS_REG))]
17901 "TARGET_USE_FANCY_MATH_387
17902 && flag_unsafe_math_optimizations
17903 && !(reload_completed || reload_in_progress)"
17908 ix86_optimize_mode_switching[I387_CEIL] = 1;
17910 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17911 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17913 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17914 operands[2], operands[3]));
17917 [(set_attr "type" "frndint")
17918 (set_attr "i387_cw" "ceil")
17919 (set_attr "mode" "XF")])
17921 (define_insn "frndintxf2_ceil_i387"
17922 [(set (match_operand:XF 0 "register_operand" "=f")
17923 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17924 UNSPEC_FRNDINT_CEIL))
17925 (use (match_operand:HI 2 "memory_operand" "m"))
17926 (use (match_operand:HI 3 "memory_operand" "m"))]
17927 "TARGET_USE_FANCY_MATH_387
17928 && flag_unsafe_math_optimizations"
17929 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17930 [(set_attr "type" "frndint")
17931 (set_attr "i387_cw" "ceil")
17932 (set_attr "mode" "XF")])
17934 (define_expand "ceilxf2"
17935 [(use (match_operand:XF 0 "register_operand" ""))
17936 (use (match_operand:XF 1 "register_operand" ""))]
17937 "TARGET_USE_FANCY_MATH_387
17938 && flag_unsafe_math_optimizations && !optimize_size"
17940 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17944 (define_expand "ceil<mode>2"
17945 [(use (match_operand:MODEF 0 "register_operand" ""))
17946 (use (match_operand:MODEF 1 "register_operand" ""))]
17947 "(TARGET_USE_FANCY_MATH_387
17948 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17949 || TARGET_MIX_SSE_I387)
17950 && flag_unsafe_math_optimizations && !optimize_size)
17951 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17952 && !flag_trapping_math
17953 && (TARGET_ROUND || !optimize_size))"
17955 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17956 && !flag_trapping_math
17957 && (TARGET_ROUND || !optimize_size))
17960 emit_insn (gen_sse4_1_round<mode>2
17961 (operands[0], operands[1], GEN_INT (0x02)));
17962 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17963 ix86_expand_floorceil (operand0, operand1, false);
17965 ix86_expand_floorceildf_32 (operand0, operand1, false);
17969 rtx op0 = gen_reg_rtx (XFmode);
17970 rtx op1 = gen_reg_rtx (XFmode);
17972 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17973 emit_insn (gen_frndintxf2_ceil (op0, op1));
17975 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17980 (define_insn_and_split "*fist<mode>2_ceil_1"
17981 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17982 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17984 (clobber (reg:CC FLAGS_REG))]
17985 "TARGET_USE_FANCY_MATH_387
17986 && flag_unsafe_math_optimizations
17987 && !(reload_completed || reload_in_progress)"
17992 ix86_optimize_mode_switching[I387_CEIL] = 1;
17994 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17995 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17996 if (memory_operand (operands[0], VOIDmode))
17997 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17998 operands[2], operands[3]));
18001 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18002 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18003 operands[2], operands[3],
18008 [(set_attr "type" "fistp")
18009 (set_attr "i387_cw" "ceil")
18010 (set_attr "mode" "<MODE>")])
18012 (define_insn "fistdi2_ceil"
18013 [(set (match_operand:DI 0 "memory_operand" "=m")
18014 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18016 (use (match_operand:HI 2 "memory_operand" "m"))
18017 (use (match_operand:HI 3 "memory_operand" "m"))
18018 (clobber (match_scratch:XF 4 "=&1f"))]
18019 "TARGET_USE_FANCY_MATH_387
18020 && flag_unsafe_math_optimizations"
18021 "* return output_fix_trunc (insn, operands, 0);"
18022 [(set_attr "type" "fistp")
18023 (set_attr "i387_cw" "ceil")
18024 (set_attr "mode" "DI")])
18026 (define_insn "fistdi2_ceil_with_temp"
18027 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18028 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18030 (use (match_operand:HI 2 "memory_operand" "m,m"))
18031 (use (match_operand:HI 3 "memory_operand" "m,m"))
18032 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18033 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18034 "TARGET_USE_FANCY_MATH_387
18035 && flag_unsafe_math_optimizations"
18037 [(set_attr "type" "fistp")
18038 (set_attr "i387_cw" "ceil")
18039 (set_attr "mode" "DI")])
18042 [(set (match_operand:DI 0 "register_operand" "")
18043 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18045 (use (match_operand:HI 2 "memory_operand" ""))
18046 (use (match_operand:HI 3 "memory_operand" ""))
18047 (clobber (match_operand:DI 4 "memory_operand" ""))
18048 (clobber (match_scratch 5 ""))]
18050 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18051 (use (match_dup 2))
18052 (use (match_dup 3))
18053 (clobber (match_dup 5))])
18054 (set (match_dup 0) (match_dup 4))]
18058 [(set (match_operand:DI 0 "memory_operand" "")
18059 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18061 (use (match_operand:HI 2 "memory_operand" ""))
18062 (use (match_operand:HI 3 "memory_operand" ""))
18063 (clobber (match_operand:DI 4 "memory_operand" ""))
18064 (clobber (match_scratch 5 ""))]
18066 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18067 (use (match_dup 2))
18068 (use (match_dup 3))
18069 (clobber (match_dup 5))])]
18072 (define_insn "fist<mode>2_ceil"
18073 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18074 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18076 (use (match_operand:HI 2 "memory_operand" "m"))
18077 (use (match_operand:HI 3 "memory_operand" "m"))]
18078 "TARGET_USE_FANCY_MATH_387
18079 && flag_unsafe_math_optimizations"
18080 "* return output_fix_trunc (insn, operands, 0);"
18081 [(set_attr "type" "fistp")
18082 (set_attr "i387_cw" "ceil")
18083 (set_attr "mode" "<MODE>")])
18085 (define_insn "fist<mode>2_ceil_with_temp"
18086 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18087 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18089 (use (match_operand:HI 2 "memory_operand" "m,m"))
18090 (use (match_operand:HI 3 "memory_operand" "m,m"))
18091 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18092 "TARGET_USE_FANCY_MATH_387
18093 && flag_unsafe_math_optimizations"
18095 [(set_attr "type" "fistp")
18096 (set_attr "i387_cw" "ceil")
18097 (set_attr "mode" "<MODE>")])
18100 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18101 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18103 (use (match_operand:HI 2 "memory_operand" ""))
18104 (use (match_operand:HI 3 "memory_operand" ""))
18105 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18107 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18109 (use (match_dup 2))
18110 (use (match_dup 3))])
18111 (set (match_dup 0) (match_dup 4))]
18115 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18116 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18118 (use (match_operand:HI 2 "memory_operand" ""))
18119 (use (match_operand:HI 3 "memory_operand" ""))
18120 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18122 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18124 (use (match_dup 2))
18125 (use (match_dup 3))])]
18128 (define_expand "lceilxf<mode>2"
18129 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18130 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18132 (clobber (reg:CC FLAGS_REG))])]
18133 "TARGET_USE_FANCY_MATH_387
18134 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18135 && flag_unsafe_math_optimizations"
18138 (define_expand "lceil<mode>di2"
18139 [(match_operand:DI 0 "nonimmediate_operand" "")
18140 (match_operand:MODEF 1 "register_operand" "")]
18141 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18142 && !flag_trapping_math"
18144 ix86_expand_lfloorceil (operand0, operand1, false);
18148 (define_expand "lceil<mode>si2"
18149 [(match_operand:SI 0 "nonimmediate_operand" "")
18150 (match_operand:MODEF 1 "register_operand" "")]
18151 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18152 && !flag_trapping_math"
18154 ix86_expand_lfloorceil (operand0, operand1, false);
18158 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18159 (define_insn_and_split "frndintxf2_trunc"
18160 [(set (match_operand:XF 0 "register_operand" "")
18161 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18162 UNSPEC_FRNDINT_TRUNC))
18163 (clobber (reg:CC FLAGS_REG))]
18164 "TARGET_USE_FANCY_MATH_387
18165 && flag_unsafe_math_optimizations
18166 && !(reload_completed || reload_in_progress)"
18171 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18173 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18174 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18176 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18177 operands[2], operands[3]));
18180 [(set_attr "type" "frndint")
18181 (set_attr "i387_cw" "trunc")
18182 (set_attr "mode" "XF")])
18184 (define_insn "frndintxf2_trunc_i387"
18185 [(set (match_operand:XF 0 "register_operand" "=f")
18186 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18187 UNSPEC_FRNDINT_TRUNC))
18188 (use (match_operand:HI 2 "memory_operand" "m"))
18189 (use (match_operand:HI 3 "memory_operand" "m"))]
18190 "TARGET_USE_FANCY_MATH_387
18191 && flag_unsafe_math_optimizations"
18192 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18193 [(set_attr "type" "frndint")
18194 (set_attr "i387_cw" "trunc")
18195 (set_attr "mode" "XF")])
18197 (define_expand "btruncxf2"
18198 [(use (match_operand:XF 0 "register_operand" ""))
18199 (use (match_operand:XF 1 "register_operand" ""))]
18200 "TARGET_USE_FANCY_MATH_387
18201 && flag_unsafe_math_optimizations && !optimize_size"
18203 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18207 (define_expand "btrunc<mode>2"
18208 [(use (match_operand:MODEF 0 "register_operand" ""))
18209 (use (match_operand:MODEF 1 "register_operand" ""))]
18210 "(TARGET_USE_FANCY_MATH_387
18211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18212 || TARGET_MIX_SSE_I387)
18213 && flag_unsafe_math_optimizations && !optimize_size)
18214 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18215 && !flag_trapping_math
18216 && (TARGET_ROUND || !optimize_size))"
18218 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18219 && !flag_trapping_math
18220 && (TARGET_ROUND || !optimize_size))
18223 emit_insn (gen_sse4_1_round<mode>2
18224 (operands[0], operands[1], GEN_INT (0x03)));
18225 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18226 ix86_expand_trunc (operand0, operand1);
18228 ix86_expand_truncdf_32 (operand0, operand1);
18232 rtx op0 = gen_reg_rtx (XFmode);
18233 rtx op1 = gen_reg_rtx (XFmode);
18235 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18236 emit_insn (gen_frndintxf2_trunc (op0, op1));
18238 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18243 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18244 (define_insn_and_split "frndintxf2_mask_pm"
18245 [(set (match_operand:XF 0 "register_operand" "")
18246 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18247 UNSPEC_FRNDINT_MASK_PM))
18248 (clobber (reg:CC FLAGS_REG))]
18249 "TARGET_USE_FANCY_MATH_387
18250 && flag_unsafe_math_optimizations
18251 && !(reload_completed || reload_in_progress)"
18256 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18258 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18259 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18261 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18262 operands[2], operands[3]));
18265 [(set_attr "type" "frndint")
18266 (set_attr "i387_cw" "mask_pm")
18267 (set_attr "mode" "XF")])
18269 (define_insn "frndintxf2_mask_pm_i387"
18270 [(set (match_operand:XF 0 "register_operand" "=f")
18271 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18272 UNSPEC_FRNDINT_MASK_PM))
18273 (use (match_operand:HI 2 "memory_operand" "m"))
18274 (use (match_operand:HI 3 "memory_operand" "m"))]
18275 "TARGET_USE_FANCY_MATH_387
18276 && flag_unsafe_math_optimizations"
18277 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18278 [(set_attr "type" "frndint")
18279 (set_attr "i387_cw" "mask_pm")
18280 (set_attr "mode" "XF")])
18282 (define_expand "nearbyintxf2"
18283 [(use (match_operand:XF 0 "register_operand" ""))
18284 (use (match_operand:XF 1 "register_operand" ""))]
18285 "TARGET_USE_FANCY_MATH_387
18286 && flag_unsafe_math_optimizations"
18288 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18293 (define_expand "nearbyint<mode>2"
18294 [(use (match_operand:MODEF 0 "register_operand" ""))
18295 (use (match_operand:MODEF 1 "register_operand" ""))]
18296 "TARGET_USE_FANCY_MATH_387
18297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18298 || TARGET_MIX_SSE_I387)
18299 && flag_unsafe_math_optimizations"
18301 rtx op0 = gen_reg_rtx (XFmode);
18302 rtx op1 = gen_reg_rtx (XFmode);
18304 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18305 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18307 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18311 (define_insn "fxam<mode>2_i387"
18312 [(set (match_operand:HI 0 "register_operand" "=a")
18314 [(match_operand:X87MODEF 1 "register_operand" "f")]
18316 "TARGET_USE_FANCY_MATH_387"
18317 "fxam\n\tfnstsw\t%0"
18318 [(set_attr "type" "multi")
18319 (set_attr "unit" "i387")
18320 (set_attr "mode" "<MODE>")])
18322 (define_expand "isinf<mode>2"
18323 [(use (match_operand:SI 0 "register_operand" ""))
18324 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18325 "TARGET_USE_FANCY_MATH_387
18326 && TARGET_C99_FUNCTIONS
18327 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18329 rtx mask = GEN_INT (0x45);
18330 rtx val = GEN_INT (0x05);
18334 rtx scratch = gen_reg_rtx (HImode);
18335 rtx res = gen_reg_rtx (QImode);
18337 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18338 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18339 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18340 cond = gen_rtx_fmt_ee (EQ, QImode,
18341 gen_rtx_REG (CCmode, FLAGS_REG),
18343 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18344 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18348 (define_expand "signbit<mode>2"
18349 [(use (match_operand:SI 0 "register_operand" ""))
18350 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18351 "TARGET_USE_FANCY_MATH_387
18352 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18354 rtx mask = GEN_INT (0x0200);
18356 rtx scratch = gen_reg_rtx (HImode);
18358 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18359 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18363 ;; Block operation instructions
18366 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18369 [(set_attr "length" "1")
18370 (set_attr "length_immediate" "0")
18371 (set_attr "modrm" "0")])
18373 (define_expand "movmemsi"
18374 [(use (match_operand:BLK 0 "memory_operand" ""))
18375 (use (match_operand:BLK 1 "memory_operand" ""))
18376 (use (match_operand:SI 2 "nonmemory_operand" ""))
18377 (use (match_operand:SI 3 "const_int_operand" ""))
18378 (use (match_operand:SI 4 "const_int_operand" ""))
18379 (use (match_operand:SI 5 "const_int_operand" ""))]
18382 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18383 operands[4], operands[5]))
18389 (define_expand "movmemdi"
18390 [(use (match_operand:BLK 0 "memory_operand" ""))
18391 (use (match_operand:BLK 1 "memory_operand" ""))
18392 (use (match_operand:DI 2 "nonmemory_operand" ""))
18393 (use (match_operand:DI 3 "const_int_operand" ""))
18394 (use (match_operand:SI 4 "const_int_operand" ""))
18395 (use (match_operand:SI 5 "const_int_operand" ""))]
18398 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18399 operands[4], operands[5]))
18405 ;; Most CPUs don't like single string operations
18406 ;; Handle this case here to simplify previous expander.
18408 (define_expand "strmov"
18409 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18410 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18411 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18412 (clobber (reg:CC FLAGS_REG))])
18413 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18414 (clobber (reg:CC FLAGS_REG))])]
18417 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18419 /* If .md ever supports :P for Pmode, these can be directly
18420 in the pattern above. */
18421 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18422 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18424 /* Can't use this if the user has appropriated esi or edi. */
18425 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18426 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18428 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18429 operands[2], operands[3],
18430 operands[5], operands[6]));
18434 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18437 (define_expand "strmov_singleop"
18438 [(parallel [(set (match_operand 1 "memory_operand" "")
18439 (match_operand 3 "memory_operand" ""))
18440 (set (match_operand 0 "register_operand" "")
18441 (match_operand 4 "" ""))
18442 (set (match_operand 2 "register_operand" "")
18443 (match_operand 5 "" ""))])]
18444 "TARGET_SINGLE_STRINGOP || optimize_size"
18445 "ix86_current_function_needs_cld = 1;")
18447 (define_insn "*strmovdi_rex_1"
18448 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18449 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18450 (set (match_operand:DI 0 "register_operand" "=D")
18451 (plus:DI (match_dup 2)
18453 (set (match_operand:DI 1 "register_operand" "=S")
18454 (plus:DI (match_dup 3)
18456 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18458 [(set_attr "type" "str")
18459 (set_attr "mode" "DI")
18460 (set_attr "memory" "both")])
18462 (define_insn "*strmovsi_1"
18463 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18464 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18465 (set (match_operand:SI 0 "register_operand" "=D")
18466 (plus:SI (match_dup 2)
18468 (set (match_operand:SI 1 "register_operand" "=S")
18469 (plus:SI (match_dup 3)
18471 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18473 [(set_attr "type" "str")
18474 (set_attr "mode" "SI")
18475 (set_attr "memory" "both")])
18477 (define_insn "*strmovsi_rex_1"
18478 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18479 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18480 (set (match_operand:DI 0 "register_operand" "=D")
18481 (plus:DI (match_dup 2)
18483 (set (match_operand:DI 1 "register_operand" "=S")
18484 (plus:DI (match_dup 3)
18486 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18488 [(set_attr "type" "str")
18489 (set_attr "mode" "SI")
18490 (set_attr "memory" "both")])
18492 (define_insn "*strmovhi_1"
18493 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18494 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18495 (set (match_operand:SI 0 "register_operand" "=D")
18496 (plus:SI (match_dup 2)
18498 (set (match_operand:SI 1 "register_operand" "=S")
18499 (plus:SI (match_dup 3)
18501 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18503 [(set_attr "type" "str")
18504 (set_attr "memory" "both")
18505 (set_attr "mode" "HI")])
18507 (define_insn "*strmovhi_rex_1"
18508 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18509 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18510 (set (match_operand:DI 0 "register_operand" "=D")
18511 (plus:DI (match_dup 2)
18513 (set (match_operand:DI 1 "register_operand" "=S")
18514 (plus:DI (match_dup 3)
18516 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18518 [(set_attr "type" "str")
18519 (set_attr "memory" "both")
18520 (set_attr "mode" "HI")])
18522 (define_insn "*strmovqi_1"
18523 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18524 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18525 (set (match_operand:SI 0 "register_operand" "=D")
18526 (plus:SI (match_dup 2)
18528 (set (match_operand:SI 1 "register_operand" "=S")
18529 (plus:SI (match_dup 3)
18531 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18533 [(set_attr "type" "str")
18534 (set_attr "memory" "both")
18535 (set_attr "mode" "QI")])
18537 (define_insn "*strmovqi_rex_1"
18538 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18539 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18540 (set (match_operand:DI 0 "register_operand" "=D")
18541 (plus:DI (match_dup 2)
18543 (set (match_operand:DI 1 "register_operand" "=S")
18544 (plus:DI (match_dup 3)
18546 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18548 [(set_attr "type" "str")
18549 (set_attr "memory" "both")
18550 (set_attr "mode" "QI")])
18552 (define_expand "rep_mov"
18553 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18554 (set (match_operand 0 "register_operand" "")
18555 (match_operand 5 "" ""))
18556 (set (match_operand 2 "register_operand" "")
18557 (match_operand 6 "" ""))
18558 (set (match_operand 1 "memory_operand" "")
18559 (match_operand 3 "memory_operand" ""))
18560 (use (match_dup 4))])]
18562 "ix86_current_function_needs_cld = 1;")
18564 (define_insn "*rep_movdi_rex64"
18565 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18566 (set (match_operand:DI 0 "register_operand" "=D")
18567 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18569 (match_operand:DI 3 "register_operand" "0")))
18570 (set (match_operand:DI 1 "register_operand" "=S")
18571 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18572 (match_operand:DI 4 "register_operand" "1")))
18573 (set (mem:BLK (match_dup 3))
18574 (mem:BLK (match_dup 4)))
18575 (use (match_dup 5))]
18578 [(set_attr "type" "str")
18579 (set_attr "prefix_rep" "1")
18580 (set_attr "memory" "both")
18581 (set_attr "mode" "DI")])
18583 (define_insn "*rep_movsi"
18584 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18585 (set (match_operand:SI 0 "register_operand" "=D")
18586 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18588 (match_operand:SI 3 "register_operand" "0")))
18589 (set (match_operand:SI 1 "register_operand" "=S")
18590 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18591 (match_operand:SI 4 "register_operand" "1")))
18592 (set (mem:BLK (match_dup 3))
18593 (mem:BLK (match_dup 4)))
18594 (use (match_dup 5))]
18597 [(set_attr "type" "str")
18598 (set_attr "prefix_rep" "1")
18599 (set_attr "memory" "both")
18600 (set_attr "mode" "SI")])
18602 (define_insn "*rep_movsi_rex64"
18603 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18604 (set (match_operand:DI 0 "register_operand" "=D")
18605 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18607 (match_operand:DI 3 "register_operand" "0")))
18608 (set (match_operand:DI 1 "register_operand" "=S")
18609 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18610 (match_operand:DI 4 "register_operand" "1")))
18611 (set (mem:BLK (match_dup 3))
18612 (mem:BLK (match_dup 4)))
18613 (use (match_dup 5))]
18616 [(set_attr "type" "str")
18617 (set_attr "prefix_rep" "1")
18618 (set_attr "memory" "both")
18619 (set_attr "mode" "SI")])
18621 (define_insn "*rep_movqi"
18622 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18623 (set (match_operand:SI 0 "register_operand" "=D")
18624 (plus:SI (match_operand:SI 3 "register_operand" "0")
18625 (match_operand:SI 5 "register_operand" "2")))
18626 (set (match_operand:SI 1 "register_operand" "=S")
18627 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18628 (set (mem:BLK (match_dup 3))
18629 (mem:BLK (match_dup 4)))
18630 (use (match_dup 5))]
18633 [(set_attr "type" "str")
18634 (set_attr "prefix_rep" "1")
18635 (set_attr "memory" "both")
18636 (set_attr "mode" "SI")])
18638 (define_insn "*rep_movqi_rex64"
18639 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18640 (set (match_operand:DI 0 "register_operand" "=D")
18641 (plus:DI (match_operand:DI 3 "register_operand" "0")
18642 (match_operand:DI 5 "register_operand" "2")))
18643 (set (match_operand:DI 1 "register_operand" "=S")
18644 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18645 (set (mem:BLK (match_dup 3))
18646 (mem:BLK (match_dup 4)))
18647 (use (match_dup 5))]
18650 [(set_attr "type" "str")
18651 (set_attr "prefix_rep" "1")
18652 (set_attr "memory" "both")
18653 (set_attr "mode" "SI")])
18655 (define_expand "setmemsi"
18656 [(use (match_operand:BLK 0 "memory_operand" ""))
18657 (use (match_operand:SI 1 "nonmemory_operand" ""))
18658 (use (match_operand 2 "const_int_operand" ""))
18659 (use (match_operand 3 "const_int_operand" ""))
18660 (use (match_operand:SI 4 "const_int_operand" ""))
18661 (use (match_operand:SI 5 "const_int_operand" ""))]
18664 if (ix86_expand_setmem (operands[0], operands[1],
18665 operands[2], operands[3],
18666 operands[4], operands[5]))
18672 (define_expand "setmemdi"
18673 [(use (match_operand:BLK 0 "memory_operand" ""))
18674 (use (match_operand:DI 1 "nonmemory_operand" ""))
18675 (use (match_operand 2 "const_int_operand" ""))
18676 (use (match_operand 3 "const_int_operand" ""))
18677 (use (match_operand 4 "const_int_operand" ""))
18678 (use (match_operand 5 "const_int_operand" ""))]
18681 if (ix86_expand_setmem (operands[0], operands[1],
18682 operands[2], operands[3],
18683 operands[4], operands[5]))
18689 ;; Most CPUs don't like single string operations
18690 ;; Handle this case here to simplify previous expander.
18692 (define_expand "strset"
18693 [(set (match_operand 1 "memory_operand" "")
18694 (match_operand 2 "register_operand" ""))
18695 (parallel [(set (match_operand 0 "register_operand" "")
18697 (clobber (reg:CC FLAGS_REG))])]
18700 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18701 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18703 /* If .md ever supports :P for Pmode, this can be directly
18704 in the pattern above. */
18705 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18706 GEN_INT (GET_MODE_SIZE (GET_MODE
18708 if (TARGET_SINGLE_STRINGOP || optimize_size)
18710 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18716 (define_expand "strset_singleop"
18717 [(parallel [(set (match_operand 1 "memory_operand" "")
18718 (match_operand 2 "register_operand" ""))
18719 (set (match_operand 0 "register_operand" "")
18720 (match_operand 3 "" ""))])]
18721 "TARGET_SINGLE_STRINGOP || optimize_size"
18722 "ix86_current_function_needs_cld = 1;")
18724 (define_insn "*strsetdi_rex_1"
18725 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18726 (match_operand:DI 2 "register_operand" "a"))
18727 (set (match_operand:DI 0 "register_operand" "=D")
18728 (plus:DI (match_dup 1)
18730 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18732 [(set_attr "type" "str")
18733 (set_attr "memory" "store")
18734 (set_attr "mode" "DI")])
18736 (define_insn "*strsetsi_1"
18737 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18738 (match_operand:SI 2 "register_operand" "a"))
18739 (set (match_operand:SI 0 "register_operand" "=D")
18740 (plus:SI (match_dup 1)
18742 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18744 [(set_attr "type" "str")
18745 (set_attr "memory" "store")
18746 (set_attr "mode" "SI")])
18748 (define_insn "*strsetsi_rex_1"
18749 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18750 (match_operand:SI 2 "register_operand" "a"))
18751 (set (match_operand:DI 0 "register_operand" "=D")
18752 (plus:DI (match_dup 1)
18754 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18756 [(set_attr "type" "str")
18757 (set_attr "memory" "store")
18758 (set_attr "mode" "SI")])
18760 (define_insn "*strsethi_1"
18761 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18762 (match_operand:HI 2 "register_operand" "a"))
18763 (set (match_operand:SI 0 "register_operand" "=D")
18764 (plus:SI (match_dup 1)
18766 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18768 [(set_attr "type" "str")
18769 (set_attr "memory" "store")
18770 (set_attr "mode" "HI")])
18772 (define_insn "*strsethi_rex_1"
18773 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18774 (match_operand:HI 2 "register_operand" "a"))
18775 (set (match_operand:DI 0 "register_operand" "=D")
18776 (plus:DI (match_dup 1)
18778 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18780 [(set_attr "type" "str")
18781 (set_attr "memory" "store")
18782 (set_attr "mode" "HI")])
18784 (define_insn "*strsetqi_1"
18785 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18786 (match_operand:QI 2 "register_operand" "a"))
18787 (set (match_operand:SI 0 "register_operand" "=D")
18788 (plus:SI (match_dup 1)
18790 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18792 [(set_attr "type" "str")
18793 (set_attr "memory" "store")
18794 (set_attr "mode" "QI")])
18796 (define_insn "*strsetqi_rex_1"
18797 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18798 (match_operand:QI 2 "register_operand" "a"))
18799 (set (match_operand:DI 0 "register_operand" "=D")
18800 (plus:DI (match_dup 1)
18802 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18804 [(set_attr "type" "str")
18805 (set_attr "memory" "store")
18806 (set_attr "mode" "QI")])
18808 (define_expand "rep_stos"
18809 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18810 (set (match_operand 0 "register_operand" "")
18811 (match_operand 4 "" ""))
18812 (set (match_operand 2 "memory_operand" "") (const_int 0))
18813 (use (match_operand 3 "register_operand" ""))
18814 (use (match_dup 1))])]
18816 "ix86_current_function_needs_cld = 1;")
18818 (define_insn "*rep_stosdi_rex64"
18819 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18820 (set (match_operand:DI 0 "register_operand" "=D")
18821 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18823 (match_operand:DI 3 "register_operand" "0")))
18824 (set (mem:BLK (match_dup 3))
18826 (use (match_operand:DI 2 "register_operand" "a"))
18827 (use (match_dup 4))]
18830 [(set_attr "type" "str")
18831 (set_attr "prefix_rep" "1")
18832 (set_attr "memory" "store")
18833 (set_attr "mode" "DI")])
18835 (define_insn "*rep_stossi"
18836 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18837 (set (match_operand:SI 0 "register_operand" "=D")
18838 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18840 (match_operand:SI 3 "register_operand" "0")))
18841 (set (mem:BLK (match_dup 3))
18843 (use (match_operand:SI 2 "register_operand" "a"))
18844 (use (match_dup 4))]
18847 [(set_attr "type" "str")
18848 (set_attr "prefix_rep" "1")
18849 (set_attr "memory" "store")
18850 (set_attr "mode" "SI")])
18852 (define_insn "*rep_stossi_rex64"
18853 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18854 (set (match_operand:DI 0 "register_operand" "=D")
18855 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18857 (match_operand:DI 3 "register_operand" "0")))
18858 (set (mem:BLK (match_dup 3))
18860 (use (match_operand:SI 2 "register_operand" "a"))
18861 (use (match_dup 4))]
18864 [(set_attr "type" "str")
18865 (set_attr "prefix_rep" "1")
18866 (set_attr "memory" "store")
18867 (set_attr "mode" "SI")])
18869 (define_insn "*rep_stosqi"
18870 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18871 (set (match_operand:SI 0 "register_operand" "=D")
18872 (plus:SI (match_operand:SI 3 "register_operand" "0")
18873 (match_operand:SI 4 "register_operand" "1")))
18874 (set (mem:BLK (match_dup 3))
18876 (use (match_operand:QI 2 "register_operand" "a"))
18877 (use (match_dup 4))]
18880 [(set_attr "type" "str")
18881 (set_attr "prefix_rep" "1")
18882 (set_attr "memory" "store")
18883 (set_attr "mode" "QI")])
18885 (define_insn "*rep_stosqi_rex64"
18886 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18887 (set (match_operand:DI 0 "register_operand" "=D")
18888 (plus:DI (match_operand:DI 3 "register_operand" "0")
18889 (match_operand:DI 4 "register_operand" "1")))
18890 (set (mem:BLK (match_dup 3))
18892 (use (match_operand:QI 2 "register_operand" "a"))
18893 (use (match_dup 4))]
18896 [(set_attr "type" "str")
18897 (set_attr "prefix_rep" "1")
18898 (set_attr "memory" "store")
18899 (set_attr "mode" "QI")])
18901 (define_expand "cmpstrnsi"
18902 [(set (match_operand:SI 0 "register_operand" "")
18903 (compare:SI (match_operand:BLK 1 "general_operand" "")
18904 (match_operand:BLK 2 "general_operand" "")))
18905 (use (match_operand 3 "general_operand" ""))
18906 (use (match_operand 4 "immediate_operand" ""))]
18907 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18909 rtx addr1, addr2, out, outlow, count, countreg, align;
18911 /* Can't use this if the user has appropriated esi or edi. */
18912 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18917 out = gen_reg_rtx (SImode);
18919 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18920 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18921 if (addr1 != XEXP (operands[1], 0))
18922 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18923 if (addr2 != XEXP (operands[2], 0))
18924 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18926 count = operands[3];
18927 countreg = ix86_zero_extend_to_Pmode (count);
18929 /* %%% Iff we are testing strict equality, we can use known alignment
18930 to good advantage. This may be possible with combine, particularly
18931 once cc0 is dead. */
18932 align = operands[4];
18934 if (CONST_INT_P (count))
18936 if (INTVAL (count) == 0)
18938 emit_move_insn (operands[0], const0_rtx);
18941 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18942 operands[1], operands[2]));
18947 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18949 emit_insn (gen_cmpsi_1 (countreg, countreg));
18950 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18951 operands[1], operands[2]));
18954 outlow = gen_lowpart (QImode, out);
18955 emit_insn (gen_cmpintqi (outlow));
18956 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18958 if (operands[0] != out)
18959 emit_move_insn (operands[0], out);
18964 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18966 (define_expand "cmpintqi"
18967 [(set (match_dup 1)
18968 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18970 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18971 (parallel [(set (match_operand:QI 0 "register_operand" "")
18972 (minus:QI (match_dup 1)
18974 (clobber (reg:CC FLAGS_REG))])]
18976 "operands[1] = gen_reg_rtx (QImode);
18977 operands[2] = gen_reg_rtx (QImode);")
18979 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18980 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18982 (define_expand "cmpstrnqi_nz_1"
18983 [(parallel [(set (reg:CC FLAGS_REG)
18984 (compare:CC (match_operand 4 "memory_operand" "")
18985 (match_operand 5 "memory_operand" "")))
18986 (use (match_operand 2 "register_operand" ""))
18987 (use (match_operand:SI 3 "immediate_operand" ""))
18988 (clobber (match_operand 0 "register_operand" ""))
18989 (clobber (match_operand 1 "register_operand" ""))
18990 (clobber (match_dup 2))])]
18992 "ix86_current_function_needs_cld = 1;")
18994 (define_insn "*cmpstrnqi_nz_1"
18995 [(set (reg:CC FLAGS_REG)
18996 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18997 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18998 (use (match_operand:SI 6 "register_operand" "2"))
18999 (use (match_operand:SI 3 "immediate_operand" "i"))
19000 (clobber (match_operand:SI 0 "register_operand" "=S"))
19001 (clobber (match_operand:SI 1 "register_operand" "=D"))
19002 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19005 [(set_attr "type" "str")
19006 (set_attr "mode" "QI")
19007 (set_attr "prefix_rep" "1")])
19009 (define_insn "*cmpstrnqi_nz_rex_1"
19010 [(set (reg:CC FLAGS_REG)
19011 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19012 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19013 (use (match_operand:DI 6 "register_operand" "2"))
19014 (use (match_operand:SI 3 "immediate_operand" "i"))
19015 (clobber (match_operand:DI 0 "register_operand" "=S"))
19016 (clobber (match_operand:DI 1 "register_operand" "=D"))
19017 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19020 [(set_attr "type" "str")
19021 (set_attr "mode" "QI")
19022 (set_attr "prefix_rep" "1")])
19024 ;; The same, but the count is not known to not be zero.
19026 (define_expand "cmpstrnqi_1"
19027 [(parallel [(set (reg:CC FLAGS_REG)
19028 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19030 (compare:CC (match_operand 4 "memory_operand" "")
19031 (match_operand 5 "memory_operand" ""))
19033 (use (match_operand:SI 3 "immediate_operand" ""))
19034 (use (reg:CC FLAGS_REG))
19035 (clobber (match_operand 0 "register_operand" ""))
19036 (clobber (match_operand 1 "register_operand" ""))
19037 (clobber (match_dup 2))])]
19039 "ix86_current_function_needs_cld = 1;")
19041 (define_insn "*cmpstrnqi_1"
19042 [(set (reg:CC FLAGS_REG)
19043 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19045 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19046 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19048 (use (match_operand:SI 3 "immediate_operand" "i"))
19049 (use (reg:CC FLAGS_REG))
19050 (clobber (match_operand:SI 0 "register_operand" "=S"))
19051 (clobber (match_operand:SI 1 "register_operand" "=D"))
19052 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19055 [(set_attr "type" "str")
19056 (set_attr "mode" "QI")
19057 (set_attr "prefix_rep" "1")])
19059 (define_insn "*cmpstrnqi_rex_1"
19060 [(set (reg:CC FLAGS_REG)
19061 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19063 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19064 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19066 (use (match_operand:SI 3 "immediate_operand" "i"))
19067 (use (reg:CC FLAGS_REG))
19068 (clobber (match_operand:DI 0 "register_operand" "=S"))
19069 (clobber (match_operand:DI 1 "register_operand" "=D"))
19070 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19073 [(set_attr "type" "str")
19074 (set_attr "mode" "QI")
19075 (set_attr "prefix_rep" "1")])
19077 (define_expand "strlensi"
19078 [(set (match_operand:SI 0 "register_operand" "")
19079 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19080 (match_operand:QI 2 "immediate_operand" "")
19081 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19084 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19090 (define_expand "strlendi"
19091 [(set (match_operand:DI 0 "register_operand" "")
19092 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19093 (match_operand:QI 2 "immediate_operand" "")
19094 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19097 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19103 (define_expand "strlenqi_1"
19104 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19105 (clobber (match_operand 1 "register_operand" ""))
19106 (clobber (reg:CC FLAGS_REG))])]
19108 "ix86_current_function_needs_cld = 1;")
19110 (define_insn "*strlenqi_1"
19111 [(set (match_operand:SI 0 "register_operand" "=&c")
19112 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19113 (match_operand:QI 2 "register_operand" "a")
19114 (match_operand:SI 3 "immediate_operand" "i")
19115 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19116 (clobber (match_operand:SI 1 "register_operand" "=D"))
19117 (clobber (reg:CC FLAGS_REG))]
19120 [(set_attr "type" "str")
19121 (set_attr "mode" "QI")
19122 (set_attr "prefix_rep" "1")])
19124 (define_insn "*strlenqi_rex_1"
19125 [(set (match_operand:DI 0 "register_operand" "=&c")
19126 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19127 (match_operand:QI 2 "register_operand" "a")
19128 (match_operand:DI 3 "immediate_operand" "i")
19129 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19130 (clobber (match_operand:DI 1 "register_operand" "=D"))
19131 (clobber (reg:CC FLAGS_REG))]
19134 [(set_attr "type" "str")
19135 (set_attr "mode" "QI")
19136 (set_attr "prefix_rep" "1")])
19138 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19139 ;; handled in combine, but it is not currently up to the task.
19140 ;; When used for their truth value, the cmpstrn* expanders generate
19149 ;; The intermediate three instructions are unnecessary.
19151 ;; This one handles cmpstrn*_nz_1...
19154 (set (reg:CC FLAGS_REG)
19155 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19156 (mem:BLK (match_operand 5 "register_operand" ""))))
19157 (use (match_operand 6 "register_operand" ""))
19158 (use (match_operand:SI 3 "immediate_operand" ""))
19159 (clobber (match_operand 0 "register_operand" ""))
19160 (clobber (match_operand 1 "register_operand" ""))
19161 (clobber (match_operand 2 "register_operand" ""))])
19162 (set (match_operand:QI 7 "register_operand" "")
19163 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19164 (set (match_operand:QI 8 "register_operand" "")
19165 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19166 (set (reg FLAGS_REG)
19167 (compare (match_dup 7) (match_dup 8)))
19169 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19171 (set (reg:CC FLAGS_REG)
19172 (compare:CC (mem:BLK (match_dup 4))
19173 (mem:BLK (match_dup 5))))
19174 (use (match_dup 6))
19175 (use (match_dup 3))
19176 (clobber (match_dup 0))
19177 (clobber (match_dup 1))
19178 (clobber (match_dup 2))])]
19181 ;; ...and this one handles cmpstrn*_1.
19184 (set (reg:CC FLAGS_REG)
19185 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19187 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19188 (mem:BLK (match_operand 5 "register_operand" "")))
19190 (use (match_operand:SI 3 "immediate_operand" ""))
19191 (use (reg:CC FLAGS_REG))
19192 (clobber (match_operand 0 "register_operand" ""))
19193 (clobber (match_operand 1 "register_operand" ""))
19194 (clobber (match_operand 2 "register_operand" ""))])
19195 (set (match_operand:QI 7 "register_operand" "")
19196 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19197 (set (match_operand:QI 8 "register_operand" "")
19198 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19199 (set (reg FLAGS_REG)
19200 (compare (match_dup 7) (match_dup 8)))
19202 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19204 (set (reg:CC FLAGS_REG)
19205 (if_then_else:CC (ne (match_dup 6)
19207 (compare:CC (mem:BLK (match_dup 4))
19208 (mem:BLK (match_dup 5)))
19210 (use (match_dup 3))
19211 (use (reg:CC FLAGS_REG))
19212 (clobber (match_dup 0))
19213 (clobber (match_dup 1))
19214 (clobber (match_dup 2))])]
19219 ;; Conditional move instructions.
19221 (define_expand "movdicc"
19222 [(set (match_operand:DI 0 "register_operand" "")
19223 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19224 (match_operand:DI 2 "general_operand" "")
19225 (match_operand:DI 3 "general_operand" "")))]
19227 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19229 (define_insn "x86_movdicc_0_m1_rex64"
19230 [(set (match_operand:DI 0 "register_operand" "=r")
19231 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19234 (clobber (reg:CC FLAGS_REG))]
19237 ; Since we don't have the proper number of operands for an alu insn,
19238 ; fill in all the blanks.
19239 [(set_attr "type" "alu")
19240 (set_attr "pent_pair" "pu")
19241 (set_attr "memory" "none")
19242 (set_attr "imm_disp" "false")
19243 (set_attr "mode" "DI")
19244 (set_attr "length_immediate" "0")])
19246 (define_insn "*x86_movdicc_0_m1_se"
19247 [(set (match_operand:DI 0 "register_operand" "=r")
19248 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19251 (clobber (reg:CC FLAGS_REG))]
19254 [(set_attr "type" "alu")
19255 (set_attr "pent_pair" "pu")
19256 (set_attr "memory" "none")
19257 (set_attr "imm_disp" "false")
19258 (set_attr "mode" "DI")
19259 (set_attr "length_immediate" "0")])
19261 (define_insn "*movdicc_c_rex64"
19262 [(set (match_operand:DI 0 "register_operand" "=r,r")
19263 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19264 [(reg FLAGS_REG) (const_int 0)])
19265 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19266 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19267 "TARGET_64BIT && TARGET_CMOVE
19268 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19270 cmov%O2%C1\t{%2, %0|%0, %2}
19271 cmov%O2%c1\t{%3, %0|%0, %3}"
19272 [(set_attr "type" "icmov")
19273 (set_attr "mode" "DI")])
19275 (define_expand "movsicc"
19276 [(set (match_operand:SI 0 "register_operand" "")
19277 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19278 (match_operand:SI 2 "general_operand" "")
19279 (match_operand:SI 3 "general_operand" "")))]
19281 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19283 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19284 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19285 ;; So just document what we're doing explicitly.
19287 (define_insn "x86_movsicc_0_m1"
19288 [(set (match_operand:SI 0 "register_operand" "=r")
19289 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19292 (clobber (reg:CC FLAGS_REG))]
19295 ; Since we don't have the proper number of operands for an alu insn,
19296 ; fill in all the blanks.
19297 [(set_attr "type" "alu")
19298 (set_attr "pent_pair" "pu")
19299 (set_attr "memory" "none")
19300 (set_attr "imm_disp" "false")
19301 (set_attr "mode" "SI")
19302 (set_attr "length_immediate" "0")])
19304 (define_insn "*x86_movsicc_0_m1_se"
19305 [(set (match_operand:SI 0 "register_operand" "=r")
19306 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19309 (clobber (reg:CC FLAGS_REG))]
19312 [(set_attr "type" "alu")
19313 (set_attr "pent_pair" "pu")
19314 (set_attr "memory" "none")
19315 (set_attr "imm_disp" "false")
19316 (set_attr "mode" "SI")
19317 (set_attr "length_immediate" "0")])
19319 (define_insn "*movsicc_noc"
19320 [(set (match_operand:SI 0 "register_operand" "=r,r")
19321 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19322 [(reg FLAGS_REG) (const_int 0)])
19323 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19324 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19326 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19328 cmov%O2%C1\t{%2, %0|%0, %2}
19329 cmov%O2%c1\t{%3, %0|%0, %3}"
19330 [(set_attr "type" "icmov")
19331 (set_attr "mode" "SI")])
19333 (define_expand "movhicc"
19334 [(set (match_operand:HI 0 "register_operand" "")
19335 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19336 (match_operand:HI 2 "general_operand" "")
19337 (match_operand:HI 3 "general_operand" "")))]
19338 "TARGET_HIMODE_MATH"
19339 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19341 (define_insn "*movhicc_noc"
19342 [(set (match_operand:HI 0 "register_operand" "=r,r")
19343 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19344 [(reg FLAGS_REG) (const_int 0)])
19345 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19346 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19348 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19350 cmov%O2%C1\t{%2, %0|%0, %2}
19351 cmov%O2%c1\t{%3, %0|%0, %3}"
19352 [(set_attr "type" "icmov")
19353 (set_attr "mode" "HI")])
19355 (define_expand "movqicc"
19356 [(set (match_operand:QI 0 "register_operand" "")
19357 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19358 (match_operand:QI 2 "general_operand" "")
19359 (match_operand:QI 3 "general_operand" "")))]
19360 "TARGET_QIMODE_MATH"
19361 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19363 (define_insn_and_split "*movqicc_noc"
19364 [(set (match_operand:QI 0 "register_operand" "=r,r")
19365 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19366 [(match_operand 4 "flags_reg_operand" "")
19368 (match_operand:QI 2 "register_operand" "r,0")
19369 (match_operand:QI 3 "register_operand" "0,r")))]
19370 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19372 "&& reload_completed"
19373 [(set (match_dup 0)
19374 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19377 "operands[0] = gen_lowpart (SImode, operands[0]);
19378 operands[2] = gen_lowpart (SImode, operands[2]);
19379 operands[3] = gen_lowpart (SImode, operands[3]);"
19380 [(set_attr "type" "icmov")
19381 (set_attr "mode" "SI")])
19383 (define_expand "mov<mode>cc"
19384 [(set (match_operand:X87MODEF 0 "register_operand" "")
19385 (if_then_else:X87MODEF
19386 (match_operand 1 "comparison_operator" "")
19387 (match_operand:X87MODEF 2 "register_operand" "")
19388 (match_operand:X87MODEF 3 "register_operand" "")))]
19389 "(TARGET_80387 && TARGET_CMOVE)
19390 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19391 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19393 (define_insn "*movsfcc_1_387"
19394 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19395 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19396 [(reg FLAGS_REG) (const_int 0)])
19397 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19398 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19399 "TARGET_80387 && TARGET_CMOVE
19400 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19402 fcmov%F1\t{%2, %0|%0, %2}
19403 fcmov%f1\t{%3, %0|%0, %3}
19404 cmov%O2%C1\t{%2, %0|%0, %2}
19405 cmov%O2%c1\t{%3, %0|%0, %3}"
19406 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19407 (set_attr "mode" "SF,SF,SI,SI")])
19409 (define_insn "*movdfcc_1"
19410 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19411 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19412 [(reg FLAGS_REG) (const_int 0)])
19413 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19414 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19415 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19416 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19418 fcmov%F1\t{%2, %0|%0, %2}
19419 fcmov%f1\t{%3, %0|%0, %3}
19422 [(set_attr "type" "fcmov,fcmov,multi,multi")
19423 (set_attr "mode" "DF")])
19425 (define_insn "*movdfcc_1_rex64"
19426 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19427 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19428 [(reg FLAGS_REG) (const_int 0)])
19429 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19430 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19431 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19432 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19434 fcmov%F1\t{%2, %0|%0, %2}
19435 fcmov%f1\t{%3, %0|%0, %3}
19436 cmov%O2%C1\t{%2, %0|%0, %2}
19437 cmov%O2%c1\t{%3, %0|%0, %3}"
19438 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19439 (set_attr "mode" "DF")])
19442 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19443 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19444 [(match_operand 4 "flags_reg_operand" "")
19446 (match_operand:DF 2 "nonimmediate_operand" "")
19447 (match_operand:DF 3 "nonimmediate_operand" "")))]
19448 "!TARGET_64BIT && reload_completed"
19449 [(set (match_dup 2)
19450 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19454 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19457 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19458 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19460 (define_insn "*movxfcc_1"
19461 [(set (match_operand:XF 0 "register_operand" "=f,f")
19462 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19463 [(reg FLAGS_REG) (const_int 0)])
19464 (match_operand:XF 2 "register_operand" "f,0")
19465 (match_operand:XF 3 "register_operand" "0,f")))]
19466 "TARGET_80387 && TARGET_CMOVE"
19468 fcmov%F1\t{%2, %0|%0, %2}
19469 fcmov%f1\t{%3, %0|%0, %3}"
19470 [(set_attr "type" "fcmov")
19471 (set_attr "mode" "XF")])
19473 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19474 ;; the scalar versions to have only XMM registers as operands.
19476 ;; SSE5 conditional move
19477 (define_insn "*sse5_pcmov_<mode>"
19478 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19479 (if_then_else:MODEF
19480 (match_operand:MODEF 1 "register_operand" "x,0")
19481 (match_operand:MODEF 2 "register_operand" "0,x")
19482 (match_operand:MODEF 3 "register_operand" "x,x")))]
19483 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19484 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19485 [(set_attr "type" "sse4arg")])
19487 ;; These versions of the min/max patterns are intentionally ignorant of
19488 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19489 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19490 ;; are undefined in this condition, we're certain this is correct.
19492 (define_insn "<code><mode>3"
19493 [(set (match_operand:MODEF 0 "register_operand" "=x")
19495 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19496 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19497 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19498 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19499 [(set_attr "type" "sseadd")
19500 (set_attr "mode" "<MODE>")])
19502 ;; These versions of the min/max patterns implement exactly the operations
19503 ;; min = (op1 < op2 ? op1 : op2)
19504 ;; max = (!(op1 < op2) ? op1 : op2)
19505 ;; Their operands are not commutative, and thus they may be used in the
19506 ;; presence of -0.0 and NaN.
19508 (define_insn "*ieee_smin<mode>3"
19509 [(set (match_operand:MODEF 0 "register_operand" "=x")
19511 [(match_operand:MODEF 1 "register_operand" "0")
19512 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19514 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19515 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19516 [(set_attr "type" "sseadd")
19517 (set_attr "mode" "<MODE>")])
19519 (define_insn "*ieee_smax<mode>3"
19520 [(set (match_operand:MODEF 0 "register_operand" "=x")
19522 [(match_operand:MODEF 1 "register_operand" "0")
19523 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19525 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19526 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19527 [(set_attr "type" "sseadd")
19528 (set_attr "mode" "<MODE>")])
19530 ;; Make two stack loads independent:
19532 ;; fld %st(0) -> fld bb
19533 ;; fmul bb fmul %st(1), %st
19535 ;; Actually we only match the last two instructions for simplicity.
19537 [(set (match_operand 0 "fp_register_operand" "")
19538 (match_operand 1 "fp_register_operand" ""))
19540 (match_operator 2 "binary_fp_operator"
19542 (match_operand 3 "memory_operand" "")]))]
19543 "REGNO (operands[0]) != REGNO (operands[1])"
19544 [(set (match_dup 0) (match_dup 3))
19545 (set (match_dup 0) (match_dup 4))]
19547 ;; The % modifier is not operational anymore in peephole2's, so we have to
19548 ;; swap the operands manually in the case of addition and multiplication.
19549 "if (COMMUTATIVE_ARITH_P (operands[2]))
19550 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19551 operands[0], operands[1]);
19553 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19554 operands[1], operands[0]);")
19556 ;; Conditional addition patterns
19557 (define_expand "add<mode>cc"
19558 [(match_operand:SWI 0 "register_operand" "")
19559 (match_operand 1 "comparison_operator" "")
19560 (match_operand:SWI 2 "register_operand" "")
19561 (match_operand:SWI 3 "const_int_operand" "")]
19563 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19566 ;; Misc patterns (?)
19568 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19569 ;; Otherwise there will be nothing to keep
19571 ;; [(set (reg ebp) (reg esp))]
19572 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19573 ;; (clobber (eflags)]
19574 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19576 ;; in proper program order.
19577 (define_insn "pro_epilogue_adjust_stack_1"
19578 [(set (match_operand:SI 0 "register_operand" "=r,r")
19579 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19580 (match_operand:SI 2 "immediate_operand" "i,i")))
19581 (clobber (reg:CC FLAGS_REG))
19582 (clobber (mem:BLK (scratch)))]
19585 switch (get_attr_type (insn))
19588 return "mov{l}\t{%1, %0|%0, %1}";
19591 if (CONST_INT_P (operands[2])
19592 && (INTVAL (operands[2]) == 128
19593 || (INTVAL (operands[2]) < 0
19594 && INTVAL (operands[2]) != -128)))
19596 operands[2] = GEN_INT (-INTVAL (operands[2]));
19597 return "sub{l}\t{%2, %0|%0, %2}";
19599 return "add{l}\t{%2, %0|%0, %2}";
19602 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19603 return "lea{l}\t{%a2, %0|%0, %a2}";
19606 gcc_unreachable ();
19609 [(set (attr "type")
19610 (cond [(eq_attr "alternative" "0")
19611 (const_string "alu")
19612 (match_operand:SI 2 "const0_operand" "")
19613 (const_string "imov")
19615 (const_string "lea")))
19616 (set_attr "mode" "SI")])
19618 (define_insn "pro_epilogue_adjust_stack_rex64"
19619 [(set (match_operand:DI 0 "register_operand" "=r,r")
19620 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19621 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19622 (clobber (reg:CC FLAGS_REG))
19623 (clobber (mem:BLK (scratch)))]
19626 switch (get_attr_type (insn))
19629 return "mov{q}\t{%1, %0|%0, %1}";
19632 if (CONST_INT_P (operands[2])
19633 /* Avoid overflows. */
19634 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19635 && (INTVAL (operands[2]) == 128
19636 || (INTVAL (operands[2]) < 0
19637 && INTVAL (operands[2]) != -128)))
19639 operands[2] = GEN_INT (-INTVAL (operands[2]));
19640 return "sub{q}\t{%2, %0|%0, %2}";
19642 return "add{q}\t{%2, %0|%0, %2}";
19645 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19646 return "lea{q}\t{%a2, %0|%0, %a2}";
19649 gcc_unreachable ();
19652 [(set (attr "type")
19653 (cond [(eq_attr "alternative" "0")
19654 (const_string "alu")
19655 (match_operand:DI 2 "const0_operand" "")
19656 (const_string "imov")
19658 (const_string "lea")))
19659 (set_attr "mode" "DI")])
19661 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19662 [(set (match_operand:DI 0 "register_operand" "=r,r")
19663 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19664 (match_operand:DI 3 "immediate_operand" "i,i")))
19665 (use (match_operand:DI 2 "register_operand" "r,r"))
19666 (clobber (reg:CC FLAGS_REG))
19667 (clobber (mem:BLK (scratch)))]
19670 switch (get_attr_type (insn))
19673 return "add{q}\t{%2, %0|%0, %2}";
19676 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19677 return "lea{q}\t{%a2, %0|%0, %a2}";
19680 gcc_unreachable ();
19683 [(set_attr "type" "alu,lea")
19684 (set_attr "mode" "DI")])
19686 (define_insn "allocate_stack_worker_32"
19687 [(set (match_operand:SI 0 "register_operand" "+a")
19688 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19689 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19690 (clobber (reg:CC FLAGS_REG))]
19691 "!TARGET_64BIT && TARGET_STACK_PROBE"
19693 [(set_attr "type" "multi")
19694 (set_attr "length" "5")])
19696 (define_insn "allocate_stack_worker_64"
19697 [(set (match_operand:DI 0 "register_operand" "+a")
19698 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19699 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19700 (clobber (reg:DI R10_REG))
19701 (clobber (reg:DI R11_REG))
19702 (clobber (reg:CC FLAGS_REG))]
19703 "TARGET_64BIT && TARGET_STACK_PROBE"
19705 [(set_attr "type" "multi")
19706 (set_attr "length" "5")])
19708 (define_expand "allocate_stack"
19709 [(match_operand 0 "register_operand" "")
19710 (match_operand 1 "general_operand" "")]
19711 "TARGET_STACK_PROBE"
19715 #ifndef CHECK_STACK_LIMIT
19716 #define CHECK_STACK_LIMIT 0
19719 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19720 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19722 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19723 stack_pointer_rtx, 0, OPTAB_DIRECT);
19724 if (x != stack_pointer_rtx)
19725 emit_move_insn (stack_pointer_rtx, x);
19729 x = copy_to_mode_reg (Pmode, operands[1]);
19731 x = gen_allocate_stack_worker_64 (x);
19733 x = gen_allocate_stack_worker_32 (x);
19737 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19741 (define_expand "builtin_setjmp_receiver"
19742 [(label_ref (match_operand 0 "" ""))]
19743 "!TARGET_64BIT && flag_pic"
19748 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19749 rtx label_rtx = gen_label_rtx ();
19750 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19751 xops[0] = xops[1] = picreg;
19752 xops[2] = gen_rtx_CONST (SImode,
19753 gen_rtx_MINUS (SImode,
19754 gen_rtx_LABEL_REF (SImode, label_rtx),
19755 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19756 ix86_expand_binary_operator (MINUS, SImode, xops);
19759 emit_insn (gen_set_got (pic_offset_table_rtx));
19763 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19766 [(set (match_operand 0 "register_operand" "")
19767 (match_operator 3 "promotable_binary_operator"
19768 [(match_operand 1 "register_operand" "")
19769 (match_operand 2 "aligned_operand" "")]))
19770 (clobber (reg:CC FLAGS_REG))]
19771 "! TARGET_PARTIAL_REG_STALL && reload_completed
19772 && ((GET_MODE (operands[0]) == HImode
19773 && ((!optimize_size && !TARGET_FAST_PREFIX)
19774 /* ??? next two lines just !satisfies_constraint_K (...) */
19775 || !CONST_INT_P (operands[2])
19776 || satisfies_constraint_K (operands[2])))
19777 || (GET_MODE (operands[0]) == QImode
19778 && (TARGET_PROMOTE_QImode || optimize_size)))"
19779 [(parallel [(set (match_dup 0)
19780 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19781 (clobber (reg:CC FLAGS_REG))])]
19782 "operands[0] = gen_lowpart (SImode, operands[0]);
19783 operands[1] = gen_lowpart (SImode, operands[1]);
19784 if (GET_CODE (operands[3]) != ASHIFT)
19785 operands[2] = gen_lowpart (SImode, operands[2]);
19786 PUT_MODE (operands[3], SImode);")
19788 ; Promote the QImode tests, as i386 has encoding of the AND
19789 ; instruction with 32-bit sign-extended immediate and thus the
19790 ; instruction size is unchanged, except in the %eax case for
19791 ; which it is increased by one byte, hence the ! optimize_size.
19793 [(set (match_operand 0 "flags_reg_operand" "")
19794 (match_operator 2 "compare_operator"
19795 [(and (match_operand 3 "aligned_operand" "")
19796 (match_operand 4 "const_int_operand" ""))
19798 (set (match_operand 1 "register_operand" "")
19799 (and (match_dup 3) (match_dup 4)))]
19800 "! TARGET_PARTIAL_REG_STALL && reload_completed
19802 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19803 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19804 /* Ensure that the operand will remain sign-extended immediate. */
19805 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19806 [(parallel [(set (match_dup 0)
19807 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19810 (and:SI (match_dup 3) (match_dup 4)))])]
19813 = gen_int_mode (INTVAL (operands[4])
19814 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19815 operands[1] = gen_lowpart (SImode, operands[1]);
19816 operands[3] = gen_lowpart (SImode, operands[3]);
19819 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19820 ; the TEST instruction with 32-bit sign-extended immediate and thus
19821 ; the instruction size would at least double, which is not what we
19822 ; want even with ! optimize_size.
19824 [(set (match_operand 0 "flags_reg_operand" "")
19825 (match_operator 1 "compare_operator"
19826 [(and (match_operand:HI 2 "aligned_operand" "")
19827 (match_operand:HI 3 "const_int_operand" ""))
19829 "! TARGET_PARTIAL_REG_STALL && reload_completed
19830 && ! TARGET_FAST_PREFIX
19832 /* Ensure that the operand will remain sign-extended immediate. */
19833 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19834 [(set (match_dup 0)
19835 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19839 = gen_int_mode (INTVAL (operands[3])
19840 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19841 operands[2] = gen_lowpart (SImode, operands[2]);
19845 [(set (match_operand 0 "register_operand" "")
19846 (neg (match_operand 1 "register_operand" "")))
19847 (clobber (reg:CC FLAGS_REG))]
19848 "! TARGET_PARTIAL_REG_STALL && reload_completed
19849 && (GET_MODE (operands[0]) == HImode
19850 || (GET_MODE (operands[0]) == QImode
19851 && (TARGET_PROMOTE_QImode || optimize_size)))"
19852 [(parallel [(set (match_dup 0)
19853 (neg:SI (match_dup 1)))
19854 (clobber (reg:CC FLAGS_REG))])]
19855 "operands[0] = gen_lowpart (SImode, operands[0]);
19856 operands[1] = gen_lowpart (SImode, operands[1]);")
19859 [(set (match_operand 0 "register_operand" "")
19860 (not (match_operand 1 "register_operand" "")))]
19861 "! TARGET_PARTIAL_REG_STALL && reload_completed
19862 && (GET_MODE (operands[0]) == HImode
19863 || (GET_MODE (operands[0]) == QImode
19864 && (TARGET_PROMOTE_QImode || optimize_size)))"
19865 [(set (match_dup 0)
19866 (not:SI (match_dup 1)))]
19867 "operands[0] = gen_lowpart (SImode, operands[0]);
19868 operands[1] = gen_lowpart (SImode, operands[1]);")
19871 [(set (match_operand 0 "register_operand" "")
19872 (if_then_else (match_operator 1 "comparison_operator"
19873 [(reg FLAGS_REG) (const_int 0)])
19874 (match_operand 2 "register_operand" "")
19875 (match_operand 3 "register_operand" "")))]
19876 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19877 && (GET_MODE (operands[0]) == HImode
19878 || (GET_MODE (operands[0]) == QImode
19879 && (TARGET_PROMOTE_QImode || optimize_size)))"
19880 [(set (match_dup 0)
19881 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19882 "operands[0] = gen_lowpart (SImode, operands[0]);
19883 operands[2] = gen_lowpart (SImode, operands[2]);
19884 operands[3] = gen_lowpart (SImode, operands[3]);")
19887 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19888 ;; transform a complex memory operation into two memory to register operations.
19890 ;; Don't push memory operands
19892 [(set (match_operand:SI 0 "push_operand" "")
19893 (match_operand:SI 1 "memory_operand" ""))
19894 (match_scratch:SI 2 "r")]
19895 "!optimize_size && !TARGET_PUSH_MEMORY
19896 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19897 [(set (match_dup 2) (match_dup 1))
19898 (set (match_dup 0) (match_dup 2))]
19902 [(set (match_operand:DI 0 "push_operand" "")
19903 (match_operand:DI 1 "memory_operand" ""))
19904 (match_scratch:DI 2 "r")]
19905 "!optimize_size && !TARGET_PUSH_MEMORY
19906 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19907 [(set (match_dup 2) (match_dup 1))
19908 (set (match_dup 0) (match_dup 2))]
19911 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19914 [(set (match_operand:SF 0 "push_operand" "")
19915 (match_operand:SF 1 "memory_operand" ""))
19916 (match_scratch:SF 2 "r")]
19917 "!optimize_size && !TARGET_PUSH_MEMORY
19918 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19919 [(set (match_dup 2) (match_dup 1))
19920 (set (match_dup 0) (match_dup 2))]
19924 [(set (match_operand:HI 0 "push_operand" "")
19925 (match_operand:HI 1 "memory_operand" ""))
19926 (match_scratch:HI 2 "r")]
19927 "!optimize_size && !TARGET_PUSH_MEMORY
19928 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19929 [(set (match_dup 2) (match_dup 1))
19930 (set (match_dup 0) (match_dup 2))]
19934 [(set (match_operand:QI 0 "push_operand" "")
19935 (match_operand:QI 1 "memory_operand" ""))
19936 (match_scratch:QI 2 "q")]
19937 "!optimize_size && !TARGET_PUSH_MEMORY
19938 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19939 [(set (match_dup 2) (match_dup 1))
19940 (set (match_dup 0) (match_dup 2))]
19943 ;; Don't move an immediate directly to memory when the instruction
19946 [(match_scratch:SI 1 "r")
19947 (set (match_operand:SI 0 "memory_operand" "")
19950 && ! TARGET_USE_MOV0
19951 && TARGET_SPLIT_LONG_MOVES
19952 && get_attr_length (insn) >= ix86_cost->large_insn
19953 && peep2_regno_dead_p (0, FLAGS_REG)"
19954 [(parallel [(set (match_dup 1) (const_int 0))
19955 (clobber (reg:CC FLAGS_REG))])
19956 (set (match_dup 0) (match_dup 1))]
19960 [(match_scratch:HI 1 "r")
19961 (set (match_operand:HI 0 "memory_operand" "")
19964 && ! TARGET_USE_MOV0
19965 && TARGET_SPLIT_LONG_MOVES
19966 && get_attr_length (insn) >= ix86_cost->large_insn
19967 && peep2_regno_dead_p (0, FLAGS_REG)"
19968 [(parallel [(set (match_dup 2) (const_int 0))
19969 (clobber (reg:CC FLAGS_REG))])
19970 (set (match_dup 0) (match_dup 1))]
19971 "operands[2] = gen_lowpart (SImode, operands[1]);")
19974 [(match_scratch:QI 1 "q")
19975 (set (match_operand:QI 0 "memory_operand" "")
19978 && ! TARGET_USE_MOV0
19979 && TARGET_SPLIT_LONG_MOVES
19980 && get_attr_length (insn) >= ix86_cost->large_insn
19981 && peep2_regno_dead_p (0, FLAGS_REG)"
19982 [(parallel [(set (match_dup 2) (const_int 0))
19983 (clobber (reg:CC FLAGS_REG))])
19984 (set (match_dup 0) (match_dup 1))]
19985 "operands[2] = gen_lowpart (SImode, operands[1]);")
19988 [(match_scratch:SI 2 "r")
19989 (set (match_operand:SI 0 "memory_operand" "")
19990 (match_operand:SI 1 "immediate_operand" ""))]
19992 && TARGET_SPLIT_LONG_MOVES
19993 && get_attr_length (insn) >= ix86_cost->large_insn"
19994 [(set (match_dup 2) (match_dup 1))
19995 (set (match_dup 0) (match_dup 2))]
19999 [(match_scratch:HI 2 "r")
20000 (set (match_operand:HI 0 "memory_operand" "")
20001 (match_operand:HI 1 "immediate_operand" ""))]
20003 && TARGET_SPLIT_LONG_MOVES
20004 && get_attr_length (insn) >= ix86_cost->large_insn"
20005 [(set (match_dup 2) (match_dup 1))
20006 (set (match_dup 0) (match_dup 2))]
20010 [(match_scratch:QI 2 "q")
20011 (set (match_operand:QI 0 "memory_operand" "")
20012 (match_operand:QI 1 "immediate_operand" ""))]
20014 && TARGET_SPLIT_LONG_MOVES
20015 && get_attr_length (insn) >= ix86_cost->large_insn"
20016 [(set (match_dup 2) (match_dup 1))
20017 (set (match_dup 0) (match_dup 2))]
20020 ;; Don't compare memory with zero, load and use a test instead.
20022 [(set (match_operand 0 "flags_reg_operand" "")
20023 (match_operator 1 "compare_operator"
20024 [(match_operand:SI 2 "memory_operand" "")
20026 (match_scratch:SI 3 "r")]
20027 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20028 [(set (match_dup 3) (match_dup 2))
20029 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20032 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20033 ;; Don't split NOTs with a displacement operand, because resulting XOR
20034 ;; will not be pairable anyway.
20036 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20037 ;; represented using a modRM byte. The XOR replacement is long decoded,
20038 ;; so this split helps here as well.
20040 ;; Note: Can't do this as a regular split because we can't get proper
20041 ;; lifetime information then.
20044 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20045 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20047 && ((TARGET_NOT_UNPAIRABLE
20048 && (!MEM_P (operands[0])
20049 || !memory_displacement_operand (operands[0], SImode)))
20050 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20051 && peep2_regno_dead_p (0, FLAGS_REG)"
20052 [(parallel [(set (match_dup 0)
20053 (xor:SI (match_dup 1) (const_int -1)))
20054 (clobber (reg:CC FLAGS_REG))])]
20058 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20059 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20061 && ((TARGET_NOT_UNPAIRABLE
20062 && (!MEM_P (operands[0])
20063 || !memory_displacement_operand (operands[0], HImode)))
20064 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20065 && peep2_regno_dead_p (0, FLAGS_REG)"
20066 [(parallel [(set (match_dup 0)
20067 (xor:HI (match_dup 1) (const_int -1)))
20068 (clobber (reg:CC FLAGS_REG))])]
20072 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20073 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20075 && ((TARGET_NOT_UNPAIRABLE
20076 && (!MEM_P (operands[0])
20077 || !memory_displacement_operand (operands[0], QImode)))
20078 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20079 && peep2_regno_dead_p (0, FLAGS_REG)"
20080 [(parallel [(set (match_dup 0)
20081 (xor:QI (match_dup 1) (const_int -1)))
20082 (clobber (reg:CC FLAGS_REG))])]
20085 ;; Non pairable "test imm, reg" instructions can be translated to
20086 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20087 ;; byte opcode instead of two, have a short form for byte operands),
20088 ;; so do it for other CPUs as well. Given that the value was dead,
20089 ;; this should not create any new dependencies. Pass on the sub-word
20090 ;; versions if we're concerned about partial register stalls.
20093 [(set (match_operand 0 "flags_reg_operand" "")
20094 (match_operator 1 "compare_operator"
20095 [(and:SI (match_operand:SI 2 "register_operand" "")
20096 (match_operand:SI 3 "immediate_operand" ""))
20098 "ix86_match_ccmode (insn, CCNOmode)
20099 && (true_regnum (operands[2]) != AX_REG
20100 || satisfies_constraint_K (operands[3]))
20101 && peep2_reg_dead_p (1, operands[2])"
20103 [(set (match_dup 0)
20104 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20107 (and:SI (match_dup 2) (match_dup 3)))])]
20110 ;; We don't need to handle HImode case, because it will be promoted to SImode
20111 ;; on ! TARGET_PARTIAL_REG_STALL
20114 [(set (match_operand 0 "flags_reg_operand" "")
20115 (match_operator 1 "compare_operator"
20116 [(and:QI (match_operand:QI 2 "register_operand" "")
20117 (match_operand:QI 3 "immediate_operand" ""))
20119 "! TARGET_PARTIAL_REG_STALL
20120 && ix86_match_ccmode (insn, CCNOmode)
20121 && true_regnum (operands[2]) != AX_REG
20122 && peep2_reg_dead_p (1, operands[2])"
20124 [(set (match_dup 0)
20125 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20128 (and:QI (match_dup 2) (match_dup 3)))])]
20132 [(set (match_operand 0 "flags_reg_operand" "")
20133 (match_operator 1 "compare_operator"
20136 (match_operand 2 "ext_register_operand" "")
20139 (match_operand 3 "const_int_operand" ""))
20141 "! TARGET_PARTIAL_REG_STALL
20142 && ix86_match_ccmode (insn, CCNOmode)
20143 && true_regnum (operands[2]) != AX_REG
20144 && peep2_reg_dead_p (1, operands[2])"
20145 [(parallel [(set (match_dup 0)
20154 (set (zero_extract:SI (match_dup 2)
20165 ;; Don't do logical operations with memory inputs.
20167 [(match_scratch:SI 2 "r")
20168 (parallel [(set (match_operand:SI 0 "register_operand" "")
20169 (match_operator:SI 3 "arith_or_logical_operator"
20171 (match_operand:SI 1 "memory_operand" "")]))
20172 (clobber (reg:CC FLAGS_REG))])]
20173 "! optimize_size && ! TARGET_READ_MODIFY"
20174 [(set (match_dup 2) (match_dup 1))
20175 (parallel [(set (match_dup 0)
20176 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20177 (clobber (reg:CC FLAGS_REG))])]
20181 [(match_scratch:SI 2 "r")
20182 (parallel [(set (match_operand:SI 0 "register_operand" "")
20183 (match_operator:SI 3 "arith_or_logical_operator"
20184 [(match_operand:SI 1 "memory_operand" "")
20186 (clobber (reg:CC FLAGS_REG))])]
20187 "! optimize_size && ! TARGET_READ_MODIFY"
20188 [(set (match_dup 2) (match_dup 1))
20189 (parallel [(set (match_dup 0)
20190 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20191 (clobber (reg:CC FLAGS_REG))])]
20194 ; Don't do logical operations with memory outputs
20196 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20197 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20198 ; the same decoder scheduling characteristics as the original.
20201 [(match_scratch:SI 2 "r")
20202 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20203 (match_operator:SI 3 "arith_or_logical_operator"
20205 (match_operand:SI 1 "nonmemory_operand" "")]))
20206 (clobber (reg:CC FLAGS_REG))])]
20207 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20208 [(set (match_dup 2) (match_dup 0))
20209 (parallel [(set (match_dup 2)
20210 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20211 (clobber (reg:CC FLAGS_REG))])
20212 (set (match_dup 0) (match_dup 2))]
20216 [(match_scratch:SI 2 "r")
20217 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20218 (match_operator:SI 3 "arith_or_logical_operator"
20219 [(match_operand:SI 1 "nonmemory_operand" "")
20221 (clobber (reg:CC FLAGS_REG))])]
20222 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20223 [(set (match_dup 2) (match_dup 0))
20224 (parallel [(set (match_dup 2)
20225 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20226 (clobber (reg:CC FLAGS_REG))])
20227 (set (match_dup 0) (match_dup 2))]
20230 ;; Attempt to always use XOR for zeroing registers.
20232 [(set (match_operand 0 "register_operand" "")
20233 (match_operand 1 "const0_operand" ""))]
20234 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20235 && (! TARGET_USE_MOV0 || optimize_size)
20236 && GENERAL_REG_P (operands[0])
20237 && peep2_regno_dead_p (0, FLAGS_REG)"
20238 [(parallel [(set (match_dup 0) (const_int 0))
20239 (clobber (reg:CC FLAGS_REG))])]
20241 operands[0] = gen_lowpart (word_mode, operands[0]);
20245 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20247 "(GET_MODE (operands[0]) == QImode
20248 || GET_MODE (operands[0]) == HImode)
20249 && (! TARGET_USE_MOV0 || optimize_size)
20250 && peep2_regno_dead_p (0, FLAGS_REG)"
20251 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20252 (clobber (reg:CC FLAGS_REG))])])
20254 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20256 [(set (match_operand 0 "register_operand" "")
20258 "(GET_MODE (operands[0]) == HImode
20259 || GET_MODE (operands[0]) == SImode
20260 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20261 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20262 && peep2_regno_dead_p (0, FLAGS_REG)"
20263 [(parallel [(set (match_dup 0) (const_int -1))
20264 (clobber (reg:CC FLAGS_REG))])]
20265 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20268 ;; Attempt to convert simple leas to adds. These can be created by
20271 [(set (match_operand:SI 0 "register_operand" "")
20272 (plus:SI (match_dup 0)
20273 (match_operand:SI 1 "nonmemory_operand" "")))]
20274 "peep2_regno_dead_p (0, FLAGS_REG)"
20275 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20276 (clobber (reg:CC FLAGS_REG))])]
20280 [(set (match_operand:SI 0 "register_operand" "")
20281 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20282 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20283 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20284 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20285 (clobber (reg:CC FLAGS_REG))])]
20286 "operands[2] = gen_lowpart (SImode, operands[2]);")
20289 [(set (match_operand:DI 0 "register_operand" "")
20290 (plus:DI (match_dup 0)
20291 (match_operand:DI 1 "x86_64_general_operand" "")))]
20292 "peep2_regno_dead_p (0, FLAGS_REG)"
20293 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20294 (clobber (reg:CC FLAGS_REG))])]
20298 [(set (match_operand:SI 0 "register_operand" "")
20299 (mult:SI (match_dup 0)
20300 (match_operand:SI 1 "const_int_operand" "")))]
20301 "exact_log2 (INTVAL (operands[1])) >= 0
20302 && peep2_regno_dead_p (0, FLAGS_REG)"
20303 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20304 (clobber (reg:CC FLAGS_REG))])]
20305 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20308 [(set (match_operand:DI 0 "register_operand" "")
20309 (mult:DI (match_dup 0)
20310 (match_operand:DI 1 "const_int_operand" "")))]
20311 "exact_log2 (INTVAL (operands[1])) >= 0
20312 && peep2_regno_dead_p (0, FLAGS_REG)"
20313 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20314 (clobber (reg:CC FLAGS_REG))])]
20315 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20318 [(set (match_operand:SI 0 "register_operand" "")
20319 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20320 (match_operand:DI 2 "const_int_operand" "")) 0))]
20321 "exact_log2 (INTVAL (operands[2])) >= 0
20322 && REGNO (operands[0]) == REGNO (operands[1])
20323 && peep2_regno_dead_p (0, FLAGS_REG)"
20324 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20325 (clobber (reg:CC FLAGS_REG))])]
20326 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20328 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20329 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20330 ;; many CPUs it is also faster, since special hardware to avoid esp
20331 ;; dependencies is present.
20333 ;; While some of these conversions may be done using splitters, we use peepholes
20334 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20336 ;; Convert prologue esp subtractions to push.
20337 ;; We need register to push. In order to keep verify_flow_info happy we have
20339 ;; - use scratch and clobber it in order to avoid dependencies
20340 ;; - use already live register
20341 ;; We can't use the second way right now, since there is no reliable way how to
20342 ;; verify that given register is live. First choice will also most likely in
20343 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20344 ;; call clobbered registers are dead. We may want to use base pointer as an
20345 ;; alternative when no register is available later.
20348 [(match_scratch:SI 0 "r")
20349 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20350 (clobber (reg:CC FLAGS_REG))
20351 (clobber (mem:BLK (scratch)))])]
20352 "optimize_size || !TARGET_SUB_ESP_4"
20353 [(clobber (match_dup 0))
20354 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20355 (clobber (mem:BLK (scratch)))])])
20358 [(match_scratch:SI 0 "r")
20359 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20360 (clobber (reg:CC FLAGS_REG))
20361 (clobber (mem:BLK (scratch)))])]
20362 "optimize_size || !TARGET_SUB_ESP_8"
20363 [(clobber (match_dup 0))
20364 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20365 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20366 (clobber (mem:BLK (scratch)))])])
20368 ;; Convert esp subtractions to push.
20370 [(match_scratch:SI 0 "r")
20371 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20372 (clobber (reg:CC FLAGS_REG))])]
20373 "optimize_size || !TARGET_SUB_ESP_4"
20374 [(clobber (match_dup 0))
20375 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20378 [(match_scratch:SI 0 "r")
20379 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20380 (clobber (reg:CC FLAGS_REG))])]
20381 "optimize_size || !TARGET_SUB_ESP_8"
20382 [(clobber (match_dup 0))
20383 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20384 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20386 ;; Convert epilogue deallocator to pop.
20388 [(match_scratch:SI 0 "r")
20389 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20390 (clobber (reg:CC FLAGS_REG))
20391 (clobber (mem:BLK (scratch)))])]
20392 "optimize_size || !TARGET_ADD_ESP_4"
20393 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20394 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20395 (clobber (mem:BLK (scratch)))])]
20398 ;; Two pops case is tricky, since pop causes dependency on destination register.
20399 ;; We use two registers if available.
20401 [(match_scratch:SI 0 "r")
20402 (match_scratch:SI 1 "r")
20403 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20404 (clobber (reg:CC FLAGS_REG))
20405 (clobber (mem:BLK (scratch)))])]
20406 "optimize_size || !TARGET_ADD_ESP_8"
20407 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20408 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20409 (clobber (mem:BLK (scratch)))])
20410 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20411 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20415 [(match_scratch:SI 0 "r")
20416 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20417 (clobber (reg:CC FLAGS_REG))
20418 (clobber (mem:BLK (scratch)))])]
20420 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20421 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20422 (clobber (mem:BLK (scratch)))])
20423 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20424 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20427 ;; Convert esp additions to pop.
20429 [(match_scratch:SI 0 "r")
20430 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20431 (clobber (reg:CC FLAGS_REG))])]
20433 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20434 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20437 ;; Two pops case is tricky, since pop causes dependency on destination register.
20438 ;; We use two registers if available.
20440 [(match_scratch:SI 0 "r")
20441 (match_scratch:SI 1 "r")
20442 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20443 (clobber (reg:CC FLAGS_REG))])]
20445 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20446 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20447 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20448 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20452 [(match_scratch:SI 0 "r")
20453 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20454 (clobber (reg:CC FLAGS_REG))])]
20456 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20457 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20458 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20459 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20462 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20463 ;; required and register dies. Similarly for 128 to plus -128.
20465 [(set (match_operand 0 "flags_reg_operand" "")
20466 (match_operator 1 "compare_operator"
20467 [(match_operand 2 "register_operand" "")
20468 (match_operand 3 "const_int_operand" "")]))]
20469 "(INTVAL (operands[3]) == -1
20470 || INTVAL (operands[3]) == 1
20471 || INTVAL (operands[3]) == 128)
20472 && ix86_match_ccmode (insn, CCGCmode)
20473 && peep2_reg_dead_p (1, operands[2])"
20474 [(parallel [(set (match_dup 0)
20475 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20476 (clobber (match_dup 2))])]
20480 [(match_scratch:DI 0 "r")
20481 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20482 (clobber (reg:CC FLAGS_REG))
20483 (clobber (mem:BLK (scratch)))])]
20484 "optimize_size || !TARGET_SUB_ESP_4"
20485 [(clobber (match_dup 0))
20486 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20487 (clobber (mem:BLK (scratch)))])])
20490 [(match_scratch:DI 0 "r")
20491 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20492 (clobber (reg:CC FLAGS_REG))
20493 (clobber (mem:BLK (scratch)))])]
20494 "optimize_size || !TARGET_SUB_ESP_8"
20495 [(clobber (match_dup 0))
20496 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20497 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20498 (clobber (mem:BLK (scratch)))])])
20500 ;; Convert esp subtractions to push.
20502 [(match_scratch:DI 0 "r")
20503 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20504 (clobber (reg:CC FLAGS_REG))])]
20505 "optimize_size || !TARGET_SUB_ESP_4"
20506 [(clobber (match_dup 0))
20507 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20510 [(match_scratch:DI 0 "r")
20511 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20512 (clobber (reg:CC FLAGS_REG))])]
20513 "optimize_size || !TARGET_SUB_ESP_8"
20514 [(clobber (match_dup 0))
20515 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20516 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20518 ;; Convert epilogue deallocator to pop.
20520 [(match_scratch:DI 0 "r")
20521 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20522 (clobber (reg:CC FLAGS_REG))
20523 (clobber (mem:BLK (scratch)))])]
20524 "optimize_size || !TARGET_ADD_ESP_4"
20525 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20526 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20527 (clobber (mem:BLK (scratch)))])]
20530 ;; Two pops case is tricky, since pop causes dependency on destination register.
20531 ;; We use two registers if available.
20533 [(match_scratch:DI 0 "r")
20534 (match_scratch:DI 1 "r")
20535 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20536 (clobber (reg:CC FLAGS_REG))
20537 (clobber (mem:BLK (scratch)))])]
20538 "optimize_size || !TARGET_ADD_ESP_8"
20539 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20540 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20541 (clobber (mem:BLK (scratch)))])
20542 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20543 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20547 [(match_scratch:DI 0 "r")
20548 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20549 (clobber (reg:CC FLAGS_REG))
20550 (clobber (mem:BLK (scratch)))])]
20552 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20553 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20554 (clobber (mem:BLK (scratch)))])
20555 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20556 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20559 ;; Convert esp additions to pop.
20561 [(match_scratch:DI 0 "r")
20562 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20563 (clobber (reg:CC FLAGS_REG))])]
20565 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20566 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20569 ;; Two pops case is tricky, since pop causes dependency on destination register.
20570 ;; We use two registers if available.
20572 [(match_scratch:DI 0 "r")
20573 (match_scratch:DI 1 "r")
20574 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20575 (clobber (reg:CC FLAGS_REG))])]
20577 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20578 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20579 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20580 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20584 [(match_scratch:DI 0 "r")
20585 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20586 (clobber (reg:CC FLAGS_REG))])]
20588 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20589 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20590 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20591 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20594 ;; Convert imul by three, five and nine into lea
20597 [(set (match_operand:SI 0 "register_operand" "")
20598 (mult:SI (match_operand:SI 1 "register_operand" "")
20599 (match_operand:SI 2 "const_int_operand" "")))
20600 (clobber (reg:CC FLAGS_REG))])]
20601 "INTVAL (operands[2]) == 3
20602 || INTVAL (operands[2]) == 5
20603 || INTVAL (operands[2]) == 9"
20604 [(set (match_dup 0)
20605 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20607 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20611 [(set (match_operand:SI 0 "register_operand" "")
20612 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20613 (match_operand:SI 2 "const_int_operand" "")))
20614 (clobber (reg:CC FLAGS_REG))])]
20616 && (INTVAL (operands[2]) == 3
20617 || INTVAL (operands[2]) == 5
20618 || INTVAL (operands[2]) == 9)"
20619 [(set (match_dup 0) (match_dup 1))
20621 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20623 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20627 [(set (match_operand:DI 0 "register_operand" "")
20628 (mult:DI (match_operand:DI 1 "register_operand" "")
20629 (match_operand:DI 2 "const_int_operand" "")))
20630 (clobber (reg:CC FLAGS_REG))])]
20632 && (INTVAL (operands[2]) == 3
20633 || INTVAL (operands[2]) == 5
20634 || INTVAL (operands[2]) == 9)"
20635 [(set (match_dup 0)
20636 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20638 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20642 [(set (match_operand:DI 0 "register_operand" "")
20643 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20644 (match_operand:DI 2 "const_int_operand" "")))
20645 (clobber (reg:CC FLAGS_REG))])]
20648 && (INTVAL (operands[2]) == 3
20649 || INTVAL (operands[2]) == 5
20650 || INTVAL (operands[2]) == 9)"
20651 [(set (match_dup 0) (match_dup 1))
20653 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20655 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20657 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20658 ;; imul $32bit_imm, reg, reg is direct decoded.
20660 [(match_scratch:DI 3 "r")
20661 (parallel [(set (match_operand:DI 0 "register_operand" "")
20662 (mult:DI (match_operand:DI 1 "memory_operand" "")
20663 (match_operand:DI 2 "immediate_operand" "")))
20664 (clobber (reg:CC FLAGS_REG))])]
20665 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20666 && !satisfies_constraint_K (operands[2])"
20667 [(set (match_dup 3) (match_dup 1))
20668 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20669 (clobber (reg:CC FLAGS_REG))])]
20673 [(match_scratch:SI 3 "r")
20674 (parallel [(set (match_operand:SI 0 "register_operand" "")
20675 (mult:SI (match_operand:SI 1 "memory_operand" "")
20676 (match_operand:SI 2 "immediate_operand" "")))
20677 (clobber (reg:CC FLAGS_REG))])]
20678 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20679 && !satisfies_constraint_K (operands[2])"
20680 [(set (match_dup 3) (match_dup 1))
20681 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20682 (clobber (reg:CC FLAGS_REG))])]
20686 [(match_scratch:SI 3 "r")
20687 (parallel [(set (match_operand:DI 0 "register_operand" "")
20689 (mult:SI (match_operand:SI 1 "memory_operand" "")
20690 (match_operand:SI 2 "immediate_operand" ""))))
20691 (clobber (reg:CC FLAGS_REG))])]
20692 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20693 && !satisfies_constraint_K (operands[2])"
20694 [(set (match_dup 3) (match_dup 1))
20695 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20696 (clobber (reg:CC FLAGS_REG))])]
20699 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20700 ;; Convert it into imul reg, reg
20701 ;; It would be better to force assembler to encode instruction using long
20702 ;; immediate, but there is apparently no way to do so.
20704 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20705 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20706 (match_operand:DI 2 "const_int_operand" "")))
20707 (clobber (reg:CC FLAGS_REG))])
20708 (match_scratch:DI 3 "r")]
20709 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20710 && satisfies_constraint_K (operands[2])"
20711 [(set (match_dup 3) (match_dup 2))
20712 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20713 (clobber (reg:CC FLAGS_REG))])]
20715 if (!rtx_equal_p (operands[0], operands[1]))
20716 emit_move_insn (operands[0], operands[1]);
20720 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20721 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20722 (match_operand:SI 2 "const_int_operand" "")))
20723 (clobber (reg:CC FLAGS_REG))])
20724 (match_scratch:SI 3 "r")]
20725 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20726 && satisfies_constraint_K (operands[2])"
20727 [(set (match_dup 3) (match_dup 2))
20728 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20729 (clobber (reg:CC FLAGS_REG))])]
20731 if (!rtx_equal_p (operands[0], operands[1]))
20732 emit_move_insn (operands[0], operands[1]);
20736 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20737 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20738 (match_operand:HI 2 "immediate_operand" "")))
20739 (clobber (reg:CC FLAGS_REG))])
20740 (match_scratch:HI 3 "r")]
20741 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20742 [(set (match_dup 3) (match_dup 2))
20743 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20744 (clobber (reg:CC FLAGS_REG))])]
20746 if (!rtx_equal_p (operands[0], operands[1]))
20747 emit_move_insn (operands[0], operands[1]);
20750 ;; After splitting up read-modify operations, array accesses with memory
20751 ;; operands might end up in form:
20753 ;; movl 4(%esp), %edx
20755 ;; instead of pre-splitting:
20757 ;; addl 4(%esp), %eax
20759 ;; movl 4(%esp), %edx
20760 ;; leal (%edx,%eax,4), %eax
20763 [(parallel [(set (match_operand 0 "register_operand" "")
20764 (ashift (match_operand 1 "register_operand" "")
20765 (match_operand 2 "const_int_operand" "")))
20766 (clobber (reg:CC FLAGS_REG))])
20767 (set (match_operand 3 "register_operand")
20768 (match_operand 4 "x86_64_general_operand" ""))
20769 (parallel [(set (match_operand 5 "register_operand" "")
20770 (plus (match_operand 6 "register_operand" "")
20771 (match_operand 7 "register_operand" "")))
20772 (clobber (reg:CC FLAGS_REG))])]
20773 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20774 /* Validate MODE for lea. */
20775 && ((!TARGET_PARTIAL_REG_STALL
20776 && (GET_MODE (operands[0]) == QImode
20777 || GET_MODE (operands[0]) == HImode))
20778 || GET_MODE (operands[0]) == SImode
20779 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20780 /* We reorder load and the shift. */
20781 && !rtx_equal_p (operands[1], operands[3])
20782 && !reg_overlap_mentioned_p (operands[0], operands[4])
20783 /* Last PLUS must consist of operand 0 and 3. */
20784 && !rtx_equal_p (operands[0], operands[3])
20785 && (rtx_equal_p (operands[3], operands[6])
20786 || rtx_equal_p (operands[3], operands[7]))
20787 && (rtx_equal_p (operands[0], operands[6])
20788 || rtx_equal_p (operands[0], operands[7]))
20789 /* The intermediate operand 0 must die or be same as output. */
20790 && (rtx_equal_p (operands[0], operands[5])
20791 || peep2_reg_dead_p (3, operands[0]))"
20792 [(set (match_dup 3) (match_dup 4))
20793 (set (match_dup 0) (match_dup 1))]
20795 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20796 int scale = 1 << INTVAL (operands[2]);
20797 rtx index = gen_lowpart (Pmode, operands[1]);
20798 rtx base = gen_lowpart (Pmode, operands[3]);
20799 rtx dest = gen_lowpart (mode, operands[5]);
20801 operands[1] = gen_rtx_PLUS (Pmode, base,
20802 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20804 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20805 operands[0] = dest;
20808 ;; Call-value patterns last so that the wildcard operand does not
20809 ;; disrupt insn-recog's switch tables.
20811 (define_insn "*call_value_pop_0"
20812 [(set (match_operand 0 "" "")
20813 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20814 (match_operand:SI 2 "" "")))
20815 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20816 (match_operand:SI 3 "immediate_operand" "")))]
20819 if (SIBLING_CALL_P (insn))
20822 return "call\t%P1";
20824 [(set_attr "type" "callv")])
20826 (define_insn "*call_value_pop_1"
20827 [(set (match_operand 0 "" "")
20828 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20829 (match_operand:SI 2 "" "")))
20830 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20831 (match_operand:SI 3 "immediate_operand" "i")))]
20834 if (constant_call_address_operand (operands[1], Pmode))
20836 if (SIBLING_CALL_P (insn))
20839 return "call\t%P1";
20841 if (SIBLING_CALL_P (insn))
20844 return "call\t%A1";
20846 [(set_attr "type" "callv")])
20848 (define_insn "*call_value_0"
20849 [(set (match_operand 0 "" "")
20850 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20851 (match_operand:SI 2 "" "")))]
20854 if (SIBLING_CALL_P (insn))
20857 return "call\t%P1";
20859 [(set_attr "type" "callv")])
20861 (define_insn "*call_value_0_rex64"
20862 [(set (match_operand 0 "" "")
20863 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20864 (match_operand:DI 2 "const_int_operand" "")))]
20867 if (SIBLING_CALL_P (insn))
20870 return "call\t%P1";
20872 [(set_attr "type" "callv")])
20874 (define_insn "*call_value_1"
20875 [(set (match_operand 0 "" "")
20876 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20877 (match_operand:SI 2 "" "")))]
20878 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20880 if (constant_call_address_operand (operands[1], Pmode))
20881 return "call\t%P1";
20882 return "call\t%A1";
20884 [(set_attr "type" "callv")])
20886 (define_insn "*sibcall_value_1"
20887 [(set (match_operand 0 "" "")
20888 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20889 (match_operand:SI 2 "" "")))]
20890 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20892 if (constant_call_address_operand (operands[1], Pmode))
20896 [(set_attr "type" "callv")])
20898 (define_insn "*call_value_1_rex64"
20899 [(set (match_operand 0 "" "")
20900 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20901 (match_operand:DI 2 "" "")))]
20902 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20903 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20905 if (constant_call_address_operand (operands[1], Pmode))
20906 return "call\t%P1";
20907 return "call\t%A1";
20909 [(set_attr "type" "callv")])
20911 (define_insn "*call_value_1_rex64_large"
20912 [(set (match_operand 0 "" "")
20913 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20914 (match_operand:DI 2 "" "")))]
20915 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20917 [(set_attr "type" "callv")])
20919 (define_insn "*sibcall_value_1_rex64"
20920 [(set (match_operand 0 "" "")
20921 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20922 (match_operand:DI 2 "" "")))]
20923 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20925 [(set_attr "type" "callv")])
20927 (define_insn "*sibcall_value_1_rex64_v"
20928 [(set (match_operand 0 "" "")
20929 (call (mem:QI (reg:DI R11_REG))
20930 (match_operand:DI 1 "" "")))]
20931 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20933 [(set_attr "type" "callv")])
20935 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20936 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20937 ;; caught for use by garbage collectors and the like. Using an insn that
20938 ;; maps to SIGILL makes it more likely the program will rightfully die.
20939 ;; Keeping with tradition, "6" is in honor of #UD.
20940 (define_insn "trap"
20941 [(trap_if (const_int 1) (const_int 6))]
20943 { return ASM_SHORT "0x0b0f"; }
20944 [(set_attr "length" "2")])
20946 (define_expand "sse_prologue_save"
20947 [(parallel [(set (match_operand:BLK 0 "" "")
20948 (unspec:BLK [(reg:DI 21)
20955 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20956 (use (match_operand:DI 1 "register_operand" ""))
20957 (use (match_operand:DI 2 "immediate_operand" ""))
20958 (use (label_ref:DI (match_operand 3 "" "")))])]
20962 (define_insn "*sse_prologue_save_insn"
20963 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20964 (match_operand:DI 4 "const_int_operand" "n")))
20965 (unspec:BLK [(reg:DI 21)
20972 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20973 (use (match_operand:DI 1 "register_operand" "r"))
20974 (use (match_operand:DI 2 "const_int_operand" "i"))
20975 (use (label_ref:DI (match_operand 3 "" "X")))]
20977 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20978 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20981 operands[0] = gen_rtx_MEM (Pmode,
20982 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20983 output_asm_insn ("jmp\t%A1", operands);
20984 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20986 operands[4] = adjust_address (operands[0], DImode, i*16);
20987 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20988 PUT_MODE (operands[4], TImode);
20989 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20990 output_asm_insn ("rex", operands);
20991 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
20993 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20994 CODE_LABEL_NUMBER (operands[3]));
20997 [(set_attr "type" "other")
20998 (set_attr "length_immediate" "0")
20999 (set_attr "length_address" "0")
21000 (set_attr "length" "34")
21001 (set_attr "memory" "store")
21002 (set_attr "modrm" "0")
21003 (set_attr "mode" "DI")])
21005 (define_expand "prefetch"
21006 [(prefetch (match_operand 0 "address_operand" "")
21007 (match_operand:SI 1 "const_int_operand" "")
21008 (match_operand:SI 2 "const_int_operand" ""))]
21009 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21011 int rw = INTVAL (operands[1]);
21012 int locality = INTVAL (operands[2]);
21014 gcc_assert (rw == 0 || rw == 1);
21015 gcc_assert (locality >= 0 && locality <= 3);
21016 gcc_assert (GET_MODE (operands[0]) == Pmode
21017 || GET_MODE (operands[0]) == VOIDmode);
21019 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21020 supported by SSE counterpart or the SSE prefetch is not available
21021 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21023 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21024 operands[2] = GEN_INT (3);
21026 operands[1] = const0_rtx;
21029 (define_insn "*prefetch_sse"
21030 [(prefetch (match_operand:SI 0 "address_operand" "p")
21032 (match_operand:SI 1 "const_int_operand" ""))]
21033 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21035 static const char * const patterns[4] = {
21036 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21039 int locality = INTVAL (operands[1]);
21040 gcc_assert (locality >= 0 && locality <= 3);
21042 return patterns[locality];
21044 [(set_attr "type" "sse")
21045 (set_attr "memory" "none")])
21047 (define_insn "*prefetch_sse_rex"
21048 [(prefetch (match_operand:DI 0 "address_operand" "p")
21050 (match_operand:SI 1 "const_int_operand" ""))]
21051 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21053 static const char * const patterns[4] = {
21054 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21057 int locality = INTVAL (operands[1]);
21058 gcc_assert (locality >= 0 && locality <= 3);
21060 return patterns[locality];
21062 [(set_attr "type" "sse")
21063 (set_attr "memory" "none")])
21065 (define_insn "*prefetch_3dnow"
21066 [(prefetch (match_operand:SI 0 "address_operand" "p")
21067 (match_operand:SI 1 "const_int_operand" "n")
21069 "TARGET_3DNOW && !TARGET_64BIT"
21071 if (INTVAL (operands[1]) == 0)
21072 return "prefetch\t%a0";
21074 return "prefetchw\t%a0";
21076 [(set_attr "type" "mmx")
21077 (set_attr "memory" "none")])
21079 (define_insn "*prefetch_3dnow_rex"
21080 [(prefetch (match_operand:DI 0 "address_operand" "p")
21081 (match_operand:SI 1 "const_int_operand" "n")
21083 "TARGET_3DNOW && TARGET_64BIT"
21085 if (INTVAL (operands[1]) == 0)
21086 return "prefetch\t%a0";
21088 return "prefetchw\t%a0";
21090 [(set_attr "type" "mmx")
21091 (set_attr "memory" "none")])
21093 (define_expand "stack_protect_set"
21094 [(match_operand 0 "memory_operand" "")
21095 (match_operand 1 "memory_operand" "")]
21098 #ifdef TARGET_THREAD_SSP_OFFSET
21100 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21101 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21103 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21104 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21107 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21109 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21114 (define_insn "stack_protect_set_si"
21115 [(set (match_operand:SI 0 "memory_operand" "=m")
21116 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21117 (set (match_scratch:SI 2 "=&r") (const_int 0))
21118 (clobber (reg:CC FLAGS_REG))]
21120 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121 [(set_attr "type" "multi")])
21123 (define_insn "stack_protect_set_di"
21124 [(set (match_operand:DI 0 "memory_operand" "=m")
21125 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21126 (set (match_scratch:DI 2 "=&r") (const_int 0))
21127 (clobber (reg:CC FLAGS_REG))]
21129 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21130 [(set_attr "type" "multi")])
21132 (define_insn "stack_tls_protect_set_si"
21133 [(set (match_operand:SI 0 "memory_operand" "=m")
21134 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21135 (set (match_scratch:SI 2 "=&r") (const_int 0))
21136 (clobber (reg:CC FLAGS_REG))]
21138 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21139 [(set_attr "type" "multi")])
21141 (define_insn "stack_tls_protect_set_di"
21142 [(set (match_operand:DI 0 "memory_operand" "=m")
21143 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21144 (set (match_scratch:DI 2 "=&r") (const_int 0))
21145 (clobber (reg:CC FLAGS_REG))]
21148 /* The kernel uses a different segment register for performance reasons; a
21149 system call would not have to trash the userspace segment register,
21150 which would be expensive */
21151 if (ix86_cmodel != CM_KERNEL)
21152 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21154 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21156 [(set_attr "type" "multi")])
21158 (define_expand "stack_protect_test"
21159 [(match_operand 0 "memory_operand" "")
21160 (match_operand 1 "memory_operand" "")
21161 (match_operand 2 "" "")]
21164 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21165 ix86_compare_op0 = operands[0];
21166 ix86_compare_op1 = operands[1];
21167 ix86_compare_emitted = flags;
21169 #ifdef TARGET_THREAD_SSP_OFFSET
21171 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21172 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21174 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21175 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21178 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21180 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21182 emit_jump_insn (gen_beq (operands[2]));
21186 (define_insn "stack_protect_test_si"
21187 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21188 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21189 (match_operand:SI 2 "memory_operand" "m")]
21191 (clobber (match_scratch:SI 3 "=&r"))]
21193 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21194 [(set_attr "type" "multi")])
21196 (define_insn "stack_protect_test_di"
21197 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21198 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21199 (match_operand:DI 2 "memory_operand" "m")]
21201 (clobber (match_scratch:DI 3 "=&r"))]
21203 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21204 [(set_attr "type" "multi")])
21206 (define_insn "stack_tls_protect_test_si"
21207 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21208 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21209 (match_operand:SI 2 "const_int_operand" "i")]
21210 UNSPEC_SP_TLS_TEST))
21211 (clobber (match_scratch:SI 3 "=r"))]
21213 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21214 [(set_attr "type" "multi")])
21216 (define_insn "stack_tls_protect_test_di"
21217 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21218 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21219 (match_operand:DI 2 "const_int_operand" "i")]
21220 UNSPEC_SP_TLS_TEST))
21221 (clobber (match_scratch:DI 3 "=r"))]
21224 /* The kernel uses a different segment register for performance reasons; a
21225 system call would not have to trash the userspace segment register,
21226 which would be expensive */
21227 if (ix86_cmodel != CM_KERNEL)
21228 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21230 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21232 [(set_attr "type" "multi")])
21234 (define_mode_iterator CRC32MODE [QI HI SI])
21235 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21236 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21238 (define_insn "sse4_2_crc32<mode>"
21239 [(set (match_operand:SI 0 "register_operand" "=r")
21241 [(match_operand:SI 1 "register_operand" "0")
21242 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21245 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21246 [(set_attr "type" "sselog1")
21247 (set_attr "prefix_rep" "1")
21248 (set_attr "prefix_extra" "1")
21249 (set_attr "mode" "SI")])
21251 (define_insn "sse4_2_crc32di"
21252 [(set (match_operand:DI 0 "register_operand" "=r")
21254 [(match_operand:DI 1 "register_operand" "0")
21255 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21257 "TARGET_SSE4_2 && TARGET_64BIT"
21258 "crc32q\t{%2, %0|%0, %2}"
21259 [(set_attr "type" "sselog1")
21260 (set_attr "prefix_rep" "1")
21261 (set_attr "prefix_extra" "1")
21262 (set_attr "mode" "DI")])
21266 (include "sync.md")