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 "i") (HI "i") (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" "n,n")))]
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" "n,n")))]
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" "n,n")))]
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" "ri,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" "ri,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" "n,n")))]
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" "qi,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" "qi,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" "n")))]
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" "X"))]
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" "X")))
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" "i"))
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 "rinm,rin,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" "ri"))]
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" "i"))
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" "qi"))]
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" "i"))
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" "i"))
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" "")))
5466 (clobber (reg:CC FLAGS_REG))]
5468 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5470 (define_insn "*addti3_1"
5471 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5472 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5473 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5474 (clobber (reg:CC FLAGS_REG))]
5475 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5479 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5480 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5481 (match_operand:TI 2 "x86_64_general_operand" "")))
5482 (clobber (reg:CC FLAGS_REG))]
5483 "TARGET_64BIT && reload_completed"
5484 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5486 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5487 (parallel [(set (match_dup 3)
5488 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5491 (clobber (reg:CC FLAGS_REG))])]
5492 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5494 ;; %%% splits for addsidi3
5495 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5496 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5497 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5499 (define_expand "adddi3"
5500 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5501 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5502 (match_operand:DI 2 "x86_64_general_operand" "")))
5503 (clobber (reg:CC FLAGS_REG))]
5505 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5507 (define_insn "*adddi3_1"
5508 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5509 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5510 (match_operand:DI 2 "general_operand" "roiF,riF")))
5511 (clobber (reg:CC FLAGS_REG))]
5512 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5516 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5517 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5518 (match_operand:DI 2 "general_operand" "")))
5519 (clobber (reg:CC FLAGS_REG))]
5520 "!TARGET_64BIT && reload_completed"
5521 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5523 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5524 (parallel [(set (match_dup 3)
5525 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5528 (clobber (reg:CC FLAGS_REG))])]
5529 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5531 (define_insn "adddi3_carry_rex64"
5532 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5533 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5534 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5535 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5536 (clobber (reg:CC FLAGS_REG))]
5537 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5538 "adc{q}\t{%2, %0|%0, %2}"
5539 [(set_attr "type" "alu")
5540 (set_attr "pent_pair" "pu")
5541 (set_attr "mode" "DI")])
5543 (define_insn "*adddi3_cc_rex64"
5544 [(set (reg:CC FLAGS_REG)
5545 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5546 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5548 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5549 (plus:DI (match_dup 1) (match_dup 2)))]
5550 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5551 "add{q}\t{%2, %0|%0, %2}"
5552 [(set_attr "type" "alu")
5553 (set_attr "mode" "DI")])
5555 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5556 [(set (reg:CCC FLAGS_REG)
5559 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5560 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5562 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5563 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5564 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5565 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5566 [(set_attr "type" "alu")
5567 (set_attr "mode" "<MODE>")])
5569 (define_insn "*add<mode>3_cconly_overflow"
5570 [(set (reg:CCC FLAGS_REG)
5572 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5573 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5575 (clobber (match_scratch:SWI 0 "=<r>"))]
5576 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5577 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5578 [(set_attr "type" "alu")
5579 (set_attr "mode" "<MODE>")])
5581 (define_insn "*sub<mode>3_cconly_overflow"
5582 [(set (reg:CCC FLAGS_REG)
5584 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5585 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5588 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5589 [(set_attr "type" "icmp")
5590 (set_attr "mode" "<MODE>")])
5592 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5593 [(set (reg:CCC FLAGS_REG)
5595 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5596 (match_operand:SI 2 "general_operand" "g"))
5598 (set (match_operand:DI 0 "register_operand" "=r")
5599 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5600 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5601 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5602 [(set_attr "type" "alu")
5603 (set_attr "mode" "SI")])
5605 (define_insn "addqi3_carry"
5606 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5607 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5608 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5609 (match_operand:QI 2 "general_operand" "qi,qm")))
5610 (clobber (reg:CC FLAGS_REG))]
5611 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5612 "adc{b}\t{%2, %0|%0, %2}"
5613 [(set_attr "type" "alu")
5614 (set_attr "pent_pair" "pu")
5615 (set_attr "mode" "QI")])
5617 (define_insn "addhi3_carry"
5618 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5619 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5620 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5621 (match_operand:HI 2 "general_operand" "ri,rm")))
5622 (clobber (reg:CC FLAGS_REG))]
5623 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5624 "adc{w}\t{%2, %0|%0, %2}"
5625 [(set_attr "type" "alu")
5626 (set_attr "pent_pair" "pu")
5627 (set_attr "mode" "HI")])
5629 (define_insn "addsi3_carry"
5630 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5631 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5632 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5633 (match_operand:SI 2 "general_operand" "ri,rm")))
5634 (clobber (reg:CC FLAGS_REG))]
5635 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5636 "adc{l}\t{%2, %0|%0, %2}"
5637 [(set_attr "type" "alu")
5638 (set_attr "pent_pair" "pu")
5639 (set_attr "mode" "SI")])
5641 (define_insn "*addsi3_carry_zext"
5642 [(set (match_operand:DI 0 "register_operand" "=r")
5644 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5645 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5646 (match_operand:SI 2 "general_operand" "g"))))
5647 (clobber (reg:CC FLAGS_REG))]
5648 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5649 "adc{l}\t{%2, %k0|%k0, %2}"
5650 [(set_attr "type" "alu")
5651 (set_attr "pent_pair" "pu")
5652 (set_attr "mode" "SI")])
5654 (define_insn "*addsi3_cc"
5655 [(set (reg:CC FLAGS_REG)
5656 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5657 (match_operand:SI 2 "general_operand" "ri,rm")]
5659 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5660 (plus:SI (match_dup 1) (match_dup 2)))]
5661 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5662 "add{l}\t{%2, %0|%0, %2}"
5663 [(set_attr "type" "alu")
5664 (set_attr "mode" "SI")])
5666 (define_insn "addqi3_cc"
5667 [(set (reg:CC FLAGS_REG)
5668 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5669 (match_operand:QI 2 "general_operand" "qi,qm")]
5671 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5672 (plus:QI (match_dup 1) (match_dup 2)))]
5673 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5674 "add{b}\t{%2, %0|%0, %2}"
5675 [(set_attr "type" "alu")
5676 (set_attr "mode" "QI")])
5678 (define_expand "addsi3"
5679 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5680 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5681 (match_operand:SI 2 "general_operand" "")))
5682 (clobber (reg:CC FLAGS_REG))])]
5684 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5686 (define_insn "*lea_1"
5687 [(set (match_operand:SI 0 "register_operand" "=r")
5688 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5690 "lea{l}\t{%a1, %0|%0, %a1}"
5691 [(set_attr "type" "lea")
5692 (set_attr "mode" "SI")])
5694 (define_insn "*lea_1_rex64"
5695 [(set (match_operand:SI 0 "register_operand" "=r")
5696 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5698 "lea{l}\t{%a1, %0|%0, %a1}"
5699 [(set_attr "type" "lea")
5700 (set_attr "mode" "SI")])
5702 (define_insn "*lea_1_zext"
5703 [(set (match_operand:DI 0 "register_operand" "=r")
5705 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5707 "lea{l}\t{%a1, %k0|%k0, %a1}"
5708 [(set_attr "type" "lea")
5709 (set_attr "mode" "SI")])
5711 (define_insn "*lea_2_rex64"
5712 [(set (match_operand:DI 0 "register_operand" "=r")
5713 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5715 "lea{q}\t{%a1, %0|%0, %a1}"
5716 [(set_attr "type" "lea")
5717 (set_attr "mode" "DI")])
5719 ;; The lea patterns for non-Pmodes needs to be matched by several
5720 ;; insns converted to real lea by splitters.
5722 (define_insn_and_split "*lea_general_1"
5723 [(set (match_operand 0 "register_operand" "=r")
5724 (plus (plus (match_operand 1 "index_register_operand" "l")
5725 (match_operand 2 "register_operand" "r"))
5726 (match_operand 3 "immediate_operand" "i")))]
5727 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5728 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5729 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5730 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5731 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5732 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5733 || GET_MODE (operands[3]) == VOIDmode)"
5735 "&& reload_completed"
5739 operands[0] = gen_lowpart (SImode, operands[0]);
5740 operands[1] = gen_lowpart (Pmode, operands[1]);
5741 operands[2] = gen_lowpart (Pmode, operands[2]);
5742 operands[3] = gen_lowpart (Pmode, operands[3]);
5743 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5745 if (Pmode != SImode)
5746 pat = gen_rtx_SUBREG (SImode, pat, 0);
5747 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5750 [(set_attr "type" "lea")
5751 (set_attr "mode" "SI")])
5753 (define_insn_and_split "*lea_general_1_zext"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5756 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5757 (match_operand:SI 2 "register_operand" "r"))
5758 (match_operand:SI 3 "immediate_operand" "i"))))]
5761 "&& reload_completed"
5763 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5765 (match_dup 3)) 0)))]
5767 operands[1] = gen_lowpart (Pmode, operands[1]);
5768 operands[2] = gen_lowpart (Pmode, operands[2]);
5769 operands[3] = gen_lowpart (Pmode, operands[3]);
5771 [(set_attr "type" "lea")
5772 (set_attr "mode" "SI")])
5774 (define_insn_and_split "*lea_general_2"
5775 [(set (match_operand 0 "register_operand" "=r")
5776 (plus (mult (match_operand 1 "index_register_operand" "l")
5777 (match_operand 2 "const248_operand" "i"))
5778 (match_operand 3 "nonmemory_operand" "ri")))]
5779 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5780 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5781 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5782 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5783 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5784 || GET_MODE (operands[3]) == VOIDmode)"
5786 "&& reload_completed"
5790 operands[0] = gen_lowpart (SImode, operands[0]);
5791 operands[1] = gen_lowpart (Pmode, operands[1]);
5792 operands[3] = gen_lowpart (Pmode, operands[3]);
5793 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5795 if (Pmode != SImode)
5796 pat = gen_rtx_SUBREG (SImode, pat, 0);
5797 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5800 [(set_attr "type" "lea")
5801 (set_attr "mode" "SI")])
5803 (define_insn_and_split "*lea_general_2_zext"
5804 [(set (match_operand:DI 0 "register_operand" "=r")
5806 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5807 (match_operand:SI 2 "const248_operand" "n"))
5808 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5811 "&& reload_completed"
5813 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5815 (match_dup 3)) 0)))]
5817 operands[1] = gen_lowpart (Pmode, operands[1]);
5818 operands[3] = gen_lowpart (Pmode, operands[3]);
5820 [(set_attr "type" "lea")
5821 (set_attr "mode" "SI")])
5823 (define_insn_and_split "*lea_general_3"
5824 [(set (match_operand 0 "register_operand" "=r")
5825 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5826 (match_operand 2 "const248_operand" "i"))
5827 (match_operand 3 "register_operand" "r"))
5828 (match_operand 4 "immediate_operand" "i")))]
5829 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5830 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5831 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5832 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5833 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5835 "&& reload_completed"
5839 operands[0] = gen_lowpart (SImode, operands[0]);
5840 operands[1] = gen_lowpart (Pmode, operands[1]);
5841 operands[3] = gen_lowpart (Pmode, operands[3]);
5842 operands[4] = gen_lowpart (Pmode, operands[4]);
5843 pat = gen_rtx_PLUS (Pmode,
5844 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5848 if (Pmode != SImode)
5849 pat = gen_rtx_SUBREG (SImode, pat, 0);
5850 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5853 [(set_attr "type" "lea")
5854 (set_attr "mode" "SI")])
5856 (define_insn_and_split "*lea_general_3_zext"
5857 [(set (match_operand:DI 0 "register_operand" "=r")
5859 (plus:SI (plus:SI (mult:SI
5860 (match_operand:SI 1 "index_register_operand" "l")
5861 (match_operand:SI 2 "const248_operand" "n"))
5862 (match_operand:SI 3 "register_operand" "r"))
5863 (match_operand:SI 4 "immediate_operand" "i"))))]
5866 "&& reload_completed"
5868 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5871 (match_dup 4)) 0)))]
5873 operands[1] = gen_lowpart (Pmode, operands[1]);
5874 operands[3] = gen_lowpart (Pmode, operands[3]);
5875 operands[4] = gen_lowpart (Pmode, operands[4]);
5877 [(set_attr "type" "lea")
5878 (set_attr "mode" "SI")])
5880 (define_insn "*adddi_1_rex64"
5881 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5882 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5883 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5884 (clobber (reg:CC FLAGS_REG))]
5885 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5887 switch (get_attr_type (insn))
5890 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5891 return "lea{q}\t{%a2, %0|%0, %a2}";
5894 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5895 if (operands[2] == const1_rtx)
5896 return "inc{q}\t%0";
5899 gcc_assert (operands[2] == constm1_rtx);
5900 return "dec{q}\t%0";
5904 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5906 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5907 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5908 if (CONST_INT_P (operands[2])
5909 /* Avoid overflows. */
5910 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5911 && (INTVAL (operands[2]) == 128
5912 || (INTVAL (operands[2]) < 0
5913 && INTVAL (operands[2]) != -128)))
5915 operands[2] = GEN_INT (-INTVAL (operands[2]));
5916 return "sub{q}\t{%2, %0|%0, %2}";
5918 return "add{q}\t{%2, %0|%0, %2}";
5922 (cond [(eq_attr "alternative" "2")
5923 (const_string "lea")
5924 ; Current assemblers are broken and do not allow @GOTOFF in
5925 ; ought but a memory context.
5926 (match_operand:DI 2 "pic_symbolic_operand" "")
5927 (const_string "lea")
5928 (match_operand:DI 2 "incdec_operand" "")
5929 (const_string "incdec")
5931 (const_string "alu")))
5932 (set_attr "mode" "DI")])
5934 ;; Convert lea to the lea pattern to avoid flags dependency.
5936 [(set (match_operand:DI 0 "register_operand" "")
5937 (plus:DI (match_operand:DI 1 "register_operand" "")
5938 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5939 (clobber (reg:CC FLAGS_REG))]
5940 "TARGET_64BIT && reload_completed
5941 && true_regnum (operands[0]) != true_regnum (operands[1])"
5943 (plus:DI (match_dup 1)
5947 (define_insn "*adddi_2_rex64"
5948 [(set (reg FLAGS_REG)
5950 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5951 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5953 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5954 (plus:DI (match_dup 1) (match_dup 2)))]
5955 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5956 && ix86_binary_operator_ok (PLUS, DImode, operands)
5957 /* Current assemblers are broken and do not allow @GOTOFF in
5958 ought but a memory context. */
5959 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5961 switch (get_attr_type (insn))
5964 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965 if (operands[2] == const1_rtx)
5966 return "inc{q}\t%0";
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return "dec{q}\t%0";
5974 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5975 /* ???? We ought to handle there the 32bit case too
5976 - do we need new constraint? */
5977 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5978 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5979 if (CONST_INT_P (operands[2])
5980 /* Avoid overflows. */
5981 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5982 && (INTVAL (operands[2]) == 128
5983 || (INTVAL (operands[2]) < 0
5984 && INTVAL (operands[2]) != -128)))
5986 operands[2] = GEN_INT (-INTVAL (operands[2]));
5987 return "sub{q}\t{%2, %0|%0, %2}";
5989 return "add{q}\t{%2, %0|%0, %2}";
5993 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5994 (const_string "incdec")
5995 (const_string "alu")))
5996 (set_attr "mode" "DI")])
5998 (define_insn "*adddi_3_rex64"
5999 [(set (reg FLAGS_REG)
6000 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6001 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6002 (clobber (match_scratch:DI 0 "=r"))]
6004 && ix86_match_ccmode (insn, CCZmode)
6005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6006 /* Current assemblers are broken and do not allow @GOTOFF in
6007 ought but a memory context. */
6008 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6010 switch (get_attr_type (insn))
6013 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6014 if (operands[2] == const1_rtx)
6015 return "inc{q}\t%0";
6018 gcc_assert (operands[2] == constm1_rtx);
6019 return "dec{q}\t%0";
6023 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6024 /* ???? We ought to handle there the 32bit case too
6025 - do we need new constraint? */
6026 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6027 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6028 if (CONST_INT_P (operands[2])
6029 /* Avoid overflows. */
6030 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6031 && (INTVAL (operands[2]) == 128
6032 || (INTVAL (operands[2]) < 0
6033 && INTVAL (operands[2]) != -128)))
6035 operands[2] = GEN_INT (-INTVAL (operands[2]));
6036 return "sub{q}\t{%2, %0|%0, %2}";
6038 return "add{q}\t{%2, %0|%0, %2}";
6042 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6043 (const_string "incdec")
6044 (const_string "alu")))
6045 (set_attr "mode" "DI")])
6047 ; For comparisons against 1, -1 and 128, we may generate better code
6048 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6049 ; is matched then. We can't accept general immediate, because for
6050 ; case of overflows, the result is messed up.
6051 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6053 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6054 ; only for comparisons not depending on it.
6055 (define_insn "*adddi_4_rex64"
6056 [(set (reg FLAGS_REG)
6057 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6058 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6059 (clobber (match_scratch:DI 0 "=rm"))]
6061 && ix86_match_ccmode (insn, CCGCmode)"
6063 switch (get_attr_type (insn))
6066 if (operands[2] == constm1_rtx)
6067 return "inc{q}\t%0";
6070 gcc_assert (operands[2] == const1_rtx);
6071 return "dec{q}\t%0";
6075 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6076 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6077 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6078 if ((INTVAL (operands[2]) == -128
6079 || (INTVAL (operands[2]) > 0
6080 && INTVAL (operands[2]) != 128))
6081 /* Avoid overflows. */
6082 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6083 return "sub{q}\t{%2, %0|%0, %2}";
6084 operands[2] = GEN_INT (-INTVAL (operands[2]));
6085 return "add{q}\t{%2, %0|%0, %2}";
6089 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6090 (const_string "incdec")
6091 (const_string "alu")))
6092 (set_attr "mode" "DI")])
6094 (define_insn "*adddi_5_rex64"
6095 [(set (reg FLAGS_REG)
6097 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6098 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6100 (clobber (match_scratch:DI 0 "=r"))]
6102 && ix86_match_ccmode (insn, CCGOCmode)
6103 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6104 /* Current assemblers are broken and do not allow @GOTOFF in
6105 ought but a memory context. */
6106 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6108 switch (get_attr_type (insn))
6111 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6112 if (operands[2] == const1_rtx)
6113 return "inc{q}\t%0";
6116 gcc_assert (operands[2] == constm1_rtx);
6117 return "dec{q}\t%0";
6121 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6122 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6123 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6124 if (CONST_INT_P (operands[2])
6125 /* Avoid overflows. */
6126 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6127 && (INTVAL (operands[2]) == 128
6128 || (INTVAL (operands[2]) < 0
6129 && INTVAL (operands[2]) != -128)))
6131 operands[2] = GEN_INT (-INTVAL (operands[2]));
6132 return "sub{q}\t{%2, %0|%0, %2}";
6134 return "add{q}\t{%2, %0|%0, %2}";
6138 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set_attr "mode" "DI")])
6144 (define_insn "*addsi_1"
6145 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6146 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6147 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6148 (clobber (reg:CC FLAGS_REG))]
6149 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6151 switch (get_attr_type (insn))
6154 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6155 return "lea{l}\t{%a2, %0|%0, %a2}";
6158 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6159 if (operands[2] == const1_rtx)
6160 return "inc{l}\t%0";
6163 gcc_assert (operands[2] == constm1_rtx);
6164 return "dec{l}\t%0";
6168 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6170 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6171 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6172 if (CONST_INT_P (operands[2])
6173 && (INTVAL (operands[2]) == 128
6174 || (INTVAL (operands[2]) < 0
6175 && INTVAL (operands[2]) != -128)))
6177 operands[2] = GEN_INT (-INTVAL (operands[2]));
6178 return "sub{l}\t{%2, %0|%0, %2}";
6180 return "add{l}\t{%2, %0|%0, %2}";
6184 (cond [(eq_attr "alternative" "2")
6185 (const_string "lea")
6186 ; Current assemblers are broken and do not allow @GOTOFF in
6187 ; ought but a memory context.
6188 (match_operand:SI 2 "pic_symbolic_operand" "")
6189 (const_string "lea")
6190 (match_operand:SI 2 "incdec_operand" "")
6191 (const_string "incdec")
6193 (const_string "alu")))
6194 (set_attr "mode" "SI")])
6196 ;; Convert lea to the lea pattern to avoid flags dependency.
6198 [(set (match_operand 0 "register_operand" "")
6199 (plus (match_operand 1 "register_operand" "")
6200 (match_operand 2 "nonmemory_operand" "")))
6201 (clobber (reg:CC FLAGS_REG))]
6203 && true_regnum (operands[0]) != true_regnum (operands[1])"
6207 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6208 may confuse gen_lowpart. */
6209 if (GET_MODE (operands[0]) != Pmode)
6211 operands[1] = gen_lowpart (Pmode, operands[1]);
6212 operands[2] = gen_lowpart (Pmode, operands[2]);
6214 operands[0] = gen_lowpart (SImode, operands[0]);
6215 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6216 if (Pmode != SImode)
6217 pat = gen_rtx_SUBREG (SImode, pat, 0);
6218 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6222 ;; It may seem that nonimmediate operand is proper one for operand 1.
6223 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6224 ;; we take care in ix86_binary_operator_ok to not allow two memory
6225 ;; operands so proper swapping will be done in reload. This allow
6226 ;; patterns constructed from addsi_1 to match.
6227 (define_insn "addsi_1_zext"
6228 [(set (match_operand:DI 0 "register_operand" "=r,r")
6230 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6231 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6232 (clobber (reg:CC FLAGS_REG))]
6233 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6235 switch (get_attr_type (insn))
6238 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6239 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6242 if (operands[2] == const1_rtx)
6243 return "inc{l}\t%k0";
6246 gcc_assert (operands[2] == constm1_rtx);
6247 return "dec{l}\t%k0";
6251 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6252 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6253 if (CONST_INT_P (operands[2])
6254 && (INTVAL (operands[2]) == 128
6255 || (INTVAL (operands[2]) < 0
6256 && INTVAL (operands[2]) != -128)))
6258 operands[2] = GEN_INT (-INTVAL (operands[2]));
6259 return "sub{l}\t{%2, %k0|%k0, %2}";
6261 return "add{l}\t{%2, %k0|%k0, %2}";
6265 (cond [(eq_attr "alternative" "1")
6266 (const_string "lea")
6267 ; Current assemblers are broken and do not allow @GOTOFF in
6268 ; ought but a memory context.
6269 (match_operand:SI 2 "pic_symbolic_operand" "")
6270 (const_string "lea")
6271 (match_operand:SI 2 "incdec_operand" "")
6272 (const_string "incdec")
6274 (const_string "alu")))
6275 (set_attr "mode" "SI")])
6277 ;; Convert lea to the lea pattern to avoid flags dependency.
6279 [(set (match_operand:DI 0 "register_operand" "")
6281 (plus:SI (match_operand:SI 1 "register_operand" "")
6282 (match_operand:SI 2 "nonmemory_operand" ""))))
6283 (clobber (reg:CC FLAGS_REG))]
6284 "TARGET_64BIT && reload_completed
6285 && true_regnum (operands[0]) != true_regnum (operands[1])"
6287 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6289 operands[1] = gen_lowpart (Pmode, operands[1]);
6290 operands[2] = gen_lowpart (Pmode, operands[2]);
6293 (define_insn "*addsi_2"
6294 [(set (reg FLAGS_REG)
6296 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6297 (match_operand:SI 2 "general_operand" "rmni,rni"))
6299 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6300 (plus:SI (match_dup 1) (match_dup 2)))]
6301 "ix86_match_ccmode (insn, CCGOCmode)
6302 && ix86_binary_operator_ok (PLUS, SImode, operands)
6303 /* Current assemblers are broken and do not allow @GOTOFF in
6304 ought but a memory context. */
6305 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6307 switch (get_attr_type (insn))
6310 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6311 if (operands[2] == const1_rtx)
6312 return "inc{l}\t%0";
6315 gcc_assert (operands[2] == constm1_rtx);
6316 return "dec{l}\t%0";
6320 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6321 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6322 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6323 if (CONST_INT_P (operands[2])
6324 && (INTVAL (operands[2]) == 128
6325 || (INTVAL (operands[2]) < 0
6326 && INTVAL (operands[2]) != -128)))
6328 operands[2] = GEN_INT (-INTVAL (operands[2]));
6329 return "sub{l}\t{%2, %0|%0, %2}";
6331 return "add{l}\t{%2, %0|%0, %2}";
6335 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6336 (const_string "incdec")
6337 (const_string "alu")))
6338 (set_attr "mode" "SI")])
6340 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6341 (define_insn "*addsi_2_zext"
6342 [(set (reg FLAGS_REG)
6344 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6345 (match_operand:SI 2 "general_operand" "rmni"))
6347 (set (match_operand:DI 0 "register_operand" "=r")
6348 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6349 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6350 && ix86_binary_operator_ok (PLUS, SImode, operands)
6351 /* Current assemblers are broken and do not allow @GOTOFF in
6352 ought but a memory context. */
6353 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6355 switch (get_attr_type (insn))
6358 if (operands[2] == const1_rtx)
6359 return "inc{l}\t%k0";
6362 gcc_assert (operands[2] == constm1_rtx);
6363 return "dec{l}\t%k0";
6367 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6368 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6369 if (CONST_INT_P (operands[2])
6370 && (INTVAL (operands[2]) == 128
6371 || (INTVAL (operands[2]) < 0
6372 && INTVAL (operands[2]) != -128)))
6374 operands[2] = GEN_INT (-INTVAL (operands[2]));
6375 return "sub{l}\t{%2, %k0|%k0, %2}";
6377 return "add{l}\t{%2, %k0|%k0, %2}";
6381 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6382 (const_string "incdec")
6383 (const_string "alu")))
6384 (set_attr "mode" "SI")])
6386 (define_insn "*addsi_3"
6387 [(set (reg FLAGS_REG)
6388 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6389 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6390 (clobber (match_scratch:SI 0 "=r"))]
6391 "ix86_match_ccmode (insn, CCZmode)
6392 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6393 /* Current assemblers are broken and do not allow @GOTOFF in
6394 ought but a memory context. */
6395 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6397 switch (get_attr_type (insn))
6400 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6401 if (operands[2] == const1_rtx)
6402 return "inc{l}\t%0";
6405 gcc_assert (operands[2] == constm1_rtx);
6406 return "dec{l}\t%0";
6410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6412 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6413 if (CONST_INT_P (operands[2])
6414 && (INTVAL (operands[2]) == 128
6415 || (INTVAL (operands[2]) < 0
6416 && INTVAL (operands[2]) != -128)))
6418 operands[2] = GEN_INT (-INTVAL (operands[2]));
6419 return "sub{l}\t{%2, %0|%0, %2}";
6421 return "add{l}\t{%2, %0|%0, %2}";
6425 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6426 (const_string "incdec")
6427 (const_string "alu")))
6428 (set_attr "mode" "SI")])
6430 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6431 (define_insn "*addsi_3_zext"
6432 [(set (reg FLAGS_REG)
6433 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6434 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6435 (set (match_operand:DI 0 "register_operand" "=r")
6436 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6437 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6438 && ix86_binary_operator_ok (PLUS, SImode, operands)
6439 /* Current assemblers are broken and do not allow @GOTOFF in
6440 ought but a memory context. */
6441 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6443 switch (get_attr_type (insn))
6446 if (operands[2] == const1_rtx)
6447 return "inc{l}\t%k0";
6450 gcc_assert (operands[2] == constm1_rtx);
6451 return "dec{l}\t%k0";
6455 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6456 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6457 if (CONST_INT_P (operands[2])
6458 && (INTVAL (operands[2]) == 128
6459 || (INTVAL (operands[2]) < 0
6460 && INTVAL (operands[2]) != -128)))
6462 operands[2] = GEN_INT (-INTVAL (operands[2]));
6463 return "sub{l}\t{%2, %k0|%k0, %2}";
6465 return "add{l}\t{%2, %k0|%k0, %2}";
6469 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6470 (const_string "incdec")
6471 (const_string "alu")))
6472 (set_attr "mode" "SI")])
6474 ; For comparisons against 1, -1 and 128, we may generate better code
6475 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6476 ; is matched then. We can't accept general immediate, because for
6477 ; case of overflows, the result is messed up.
6478 ; This pattern also don't hold of 0x80000000, since the value overflows
6480 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6481 ; only for comparisons not depending on it.
6482 (define_insn "*addsi_4"
6483 [(set (reg FLAGS_REG)
6484 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6485 (match_operand:SI 2 "const_int_operand" "n")))
6486 (clobber (match_scratch:SI 0 "=rm"))]
6487 "ix86_match_ccmode (insn, CCGCmode)
6488 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6490 switch (get_attr_type (insn))
6493 if (operands[2] == constm1_rtx)
6494 return "inc{l}\t%0";
6497 gcc_assert (operands[2] == const1_rtx);
6498 return "dec{l}\t%0";
6502 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6503 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6504 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6505 if ((INTVAL (operands[2]) == -128
6506 || (INTVAL (operands[2]) > 0
6507 && INTVAL (operands[2]) != 128)))
6508 return "sub{l}\t{%2, %0|%0, %2}";
6509 operands[2] = GEN_INT (-INTVAL (operands[2]));
6510 return "add{l}\t{%2, %0|%0, %2}";
6514 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6515 (const_string "incdec")
6516 (const_string "alu")))
6517 (set_attr "mode" "SI")])
6519 (define_insn "*addsi_5"
6520 [(set (reg FLAGS_REG)
6522 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6523 (match_operand:SI 2 "general_operand" "rmni"))
6525 (clobber (match_scratch:SI 0 "=r"))]
6526 "ix86_match_ccmode (insn, CCGOCmode)
6527 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6528 /* Current assemblers are broken and do not allow @GOTOFF in
6529 ought but a memory context. */
6530 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6532 switch (get_attr_type (insn))
6535 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6536 if (operands[2] == const1_rtx)
6537 return "inc{l}\t%0";
6540 gcc_assert (operands[2] == constm1_rtx);
6541 return "dec{l}\t%0";
6545 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6546 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6547 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6548 if (CONST_INT_P (operands[2])
6549 && (INTVAL (operands[2]) == 128
6550 || (INTVAL (operands[2]) < 0
6551 && INTVAL (operands[2]) != -128)))
6553 operands[2] = GEN_INT (-INTVAL (operands[2]));
6554 return "sub{l}\t{%2, %0|%0, %2}";
6556 return "add{l}\t{%2, %0|%0, %2}";
6560 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6561 (const_string "incdec")
6562 (const_string "alu")))
6563 (set_attr "mode" "SI")])
6565 (define_expand "addhi3"
6566 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6567 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6568 (match_operand:HI 2 "general_operand" "")))
6569 (clobber (reg:CC FLAGS_REG))])]
6570 "TARGET_HIMODE_MATH"
6571 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6573 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6574 ;; type optimizations enabled by define-splits. This is not important
6575 ;; for PII, and in fact harmful because of partial register stalls.
6577 (define_insn "*addhi_1_lea"
6578 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6579 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6580 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6581 (clobber (reg:CC FLAGS_REG))]
6582 "!TARGET_PARTIAL_REG_STALL
6583 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6585 switch (get_attr_type (insn))
6590 if (operands[2] == const1_rtx)
6591 return "inc{w}\t%0";
6594 gcc_assert (operands[2] == constm1_rtx);
6595 return "dec{w}\t%0";
6599 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6600 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6601 if (CONST_INT_P (operands[2])
6602 && (INTVAL (operands[2]) == 128
6603 || (INTVAL (operands[2]) < 0
6604 && INTVAL (operands[2]) != -128)))
6606 operands[2] = GEN_INT (-INTVAL (operands[2]));
6607 return "sub{w}\t{%2, %0|%0, %2}";
6609 return "add{w}\t{%2, %0|%0, %2}";
6613 (if_then_else (eq_attr "alternative" "2")
6614 (const_string "lea")
6615 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6616 (const_string "incdec")
6617 (const_string "alu"))))
6618 (set_attr "mode" "HI,HI,SI")])
6620 (define_insn "*addhi_1"
6621 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6622 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6623 (match_operand:HI 2 "general_operand" "ri,rm")))
6624 (clobber (reg:CC FLAGS_REG))]
6625 "TARGET_PARTIAL_REG_STALL
6626 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6628 switch (get_attr_type (insn))
6631 if (operands[2] == const1_rtx)
6632 return "inc{w}\t%0";
6635 gcc_assert (operands[2] == constm1_rtx);
6636 return "dec{w}\t%0";
6640 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6641 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6642 if (CONST_INT_P (operands[2])
6643 && (INTVAL (operands[2]) == 128
6644 || (INTVAL (operands[2]) < 0
6645 && INTVAL (operands[2]) != -128)))
6647 operands[2] = GEN_INT (-INTVAL (operands[2]));
6648 return "sub{w}\t{%2, %0|%0, %2}";
6650 return "add{w}\t{%2, %0|%0, %2}";
6654 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6655 (const_string "incdec")
6656 (const_string "alu")))
6657 (set_attr "mode" "HI")])
6659 (define_insn "*addhi_2"
6660 [(set (reg FLAGS_REG)
6662 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6663 (match_operand:HI 2 "general_operand" "rmni,rni"))
6665 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6666 (plus:HI (match_dup 1) (match_dup 2)))]
6667 "ix86_match_ccmode (insn, CCGOCmode)
6668 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6670 switch (get_attr_type (insn))
6673 if (operands[2] == const1_rtx)
6674 return "inc{w}\t%0";
6677 gcc_assert (operands[2] == constm1_rtx);
6678 return "dec{w}\t%0";
6682 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6683 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6684 if (CONST_INT_P (operands[2])
6685 && (INTVAL (operands[2]) == 128
6686 || (INTVAL (operands[2]) < 0
6687 && INTVAL (operands[2]) != -128)))
6689 operands[2] = GEN_INT (-INTVAL (operands[2]));
6690 return "sub{w}\t{%2, %0|%0, %2}";
6692 return "add{w}\t{%2, %0|%0, %2}";
6696 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6697 (const_string "incdec")
6698 (const_string "alu")))
6699 (set_attr "mode" "HI")])
6701 (define_insn "*addhi_3"
6702 [(set (reg FLAGS_REG)
6703 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6704 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6705 (clobber (match_scratch:HI 0 "=r"))]
6706 "ix86_match_ccmode (insn, CCZmode)
6707 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6709 switch (get_attr_type (insn))
6712 if (operands[2] == const1_rtx)
6713 return "inc{w}\t%0";
6716 gcc_assert (operands[2] == constm1_rtx);
6717 return "dec{w}\t%0";
6721 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6722 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6723 if (CONST_INT_P (operands[2])
6724 && (INTVAL (operands[2]) == 128
6725 || (INTVAL (operands[2]) < 0
6726 && INTVAL (operands[2]) != -128)))
6728 operands[2] = GEN_INT (-INTVAL (operands[2]));
6729 return "sub{w}\t{%2, %0|%0, %2}";
6731 return "add{w}\t{%2, %0|%0, %2}";
6735 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6736 (const_string "incdec")
6737 (const_string "alu")))
6738 (set_attr "mode" "HI")])
6740 ; See comments above addsi_4 for details.
6741 (define_insn "*addhi_4"
6742 [(set (reg FLAGS_REG)
6743 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6744 (match_operand:HI 2 "const_int_operand" "n")))
6745 (clobber (match_scratch:HI 0 "=rm"))]
6746 "ix86_match_ccmode (insn, CCGCmode)
6747 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6749 switch (get_attr_type (insn))
6752 if (operands[2] == constm1_rtx)
6753 return "inc{w}\t%0";
6756 gcc_assert (operands[2] == const1_rtx);
6757 return "dec{w}\t%0";
6761 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6762 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6763 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6764 if ((INTVAL (operands[2]) == -128
6765 || (INTVAL (operands[2]) > 0
6766 && INTVAL (operands[2]) != 128)))
6767 return "sub{w}\t{%2, %0|%0, %2}";
6768 operands[2] = GEN_INT (-INTVAL (operands[2]));
6769 return "add{w}\t{%2, %0|%0, %2}";
6773 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6774 (const_string "incdec")
6775 (const_string "alu")))
6776 (set_attr "mode" "SI")])
6779 (define_insn "*addhi_5"
6780 [(set (reg FLAGS_REG)
6782 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6783 (match_operand:HI 2 "general_operand" "rmni"))
6785 (clobber (match_scratch:HI 0 "=r"))]
6786 "ix86_match_ccmode (insn, CCGOCmode)
6787 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6789 switch (get_attr_type (insn))
6792 if (operands[2] == const1_rtx)
6793 return "inc{w}\t%0";
6796 gcc_assert (operands[2] == constm1_rtx);
6797 return "dec{w}\t%0";
6801 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6802 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6803 if (CONST_INT_P (operands[2])
6804 && (INTVAL (operands[2]) == 128
6805 || (INTVAL (operands[2]) < 0
6806 && INTVAL (operands[2]) != -128)))
6808 operands[2] = GEN_INT (-INTVAL (operands[2]));
6809 return "sub{w}\t{%2, %0|%0, %2}";
6811 return "add{w}\t{%2, %0|%0, %2}";
6815 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6816 (const_string "incdec")
6817 (const_string "alu")))
6818 (set_attr "mode" "HI")])
6820 (define_expand "addqi3"
6821 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6822 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6823 (match_operand:QI 2 "general_operand" "")))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 "TARGET_QIMODE_MATH"
6826 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6828 ;; %%% Potential partial reg stall on alternative 2. What to do?
6829 (define_insn "*addqi_1_lea"
6830 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6831 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6832 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6833 (clobber (reg:CC FLAGS_REG))]
6834 "!TARGET_PARTIAL_REG_STALL
6835 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6837 int widen = (which_alternative == 2);
6838 switch (get_attr_type (insn))
6843 if (operands[2] == const1_rtx)
6844 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6847 gcc_assert (operands[2] == constm1_rtx);
6848 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6852 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6853 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6854 if (CONST_INT_P (operands[2])
6855 && (INTVAL (operands[2]) == 128
6856 || (INTVAL (operands[2]) < 0
6857 && INTVAL (operands[2]) != -128)))
6859 operands[2] = GEN_INT (-INTVAL (operands[2]));
6861 return "sub{l}\t{%2, %k0|%k0, %2}";
6863 return "sub{b}\t{%2, %0|%0, %2}";
6866 return "add{l}\t{%k2, %k0|%k0, %k2}";
6868 return "add{b}\t{%2, %0|%0, %2}";
6872 (if_then_else (eq_attr "alternative" "3")
6873 (const_string "lea")
6874 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6875 (const_string "incdec")
6876 (const_string "alu"))))
6877 (set_attr "mode" "QI,QI,SI,SI")])
6879 (define_insn "*addqi_1"
6880 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6881 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6882 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6883 (clobber (reg:CC FLAGS_REG))]
6884 "TARGET_PARTIAL_REG_STALL
6885 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6887 int widen = (which_alternative == 2);
6888 switch (get_attr_type (insn))
6891 if (operands[2] == const1_rtx)
6892 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6895 gcc_assert (operands[2] == constm1_rtx);
6896 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6900 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6901 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6902 if (CONST_INT_P (operands[2])
6903 && (INTVAL (operands[2]) == 128
6904 || (INTVAL (operands[2]) < 0
6905 && INTVAL (operands[2]) != -128)))
6907 operands[2] = GEN_INT (-INTVAL (operands[2]));
6909 return "sub{l}\t{%2, %k0|%k0, %2}";
6911 return "sub{b}\t{%2, %0|%0, %2}";
6914 return "add{l}\t{%k2, %k0|%k0, %k2}";
6916 return "add{b}\t{%2, %0|%0, %2}";
6920 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6921 (const_string "incdec")
6922 (const_string "alu")))
6923 (set_attr "mode" "QI,QI,SI")])
6925 (define_insn "*addqi_1_slp"
6926 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6927 (plus:QI (match_dup 0)
6928 (match_operand:QI 1 "general_operand" "qn,qnm")))
6929 (clobber (reg:CC FLAGS_REG))]
6930 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6931 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6933 switch (get_attr_type (insn))
6936 if (operands[1] == const1_rtx)
6937 return "inc{b}\t%0";
6940 gcc_assert (operands[1] == constm1_rtx);
6941 return "dec{b}\t%0";
6945 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6946 if (CONST_INT_P (operands[1])
6947 && INTVAL (operands[1]) < 0)
6949 operands[1] = GEN_INT (-INTVAL (operands[1]));
6950 return "sub{b}\t{%1, %0|%0, %1}";
6952 return "add{b}\t{%1, %0|%0, %1}";
6956 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6957 (const_string "incdec")
6958 (const_string "alu1")))
6959 (set (attr "memory")
6960 (if_then_else (match_operand 1 "memory_operand" "")
6961 (const_string "load")
6962 (const_string "none")))
6963 (set_attr "mode" "QI")])
6965 (define_insn "*addqi_2"
6966 [(set (reg FLAGS_REG)
6968 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6969 (match_operand:QI 2 "general_operand" "qmni,qni"))
6971 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6972 (plus:QI (match_dup 1) (match_dup 2)))]
6973 "ix86_match_ccmode (insn, CCGOCmode)
6974 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6976 switch (get_attr_type (insn))
6979 if (operands[2] == const1_rtx)
6980 return "inc{b}\t%0";
6983 gcc_assert (operands[2] == constm1_rtx
6984 || (CONST_INT_P (operands[2])
6985 && INTVAL (operands[2]) == 255));
6986 return "dec{b}\t%0";
6990 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6991 if (CONST_INT_P (operands[2])
6992 && INTVAL (operands[2]) < 0)
6994 operands[2] = GEN_INT (-INTVAL (operands[2]));
6995 return "sub{b}\t{%2, %0|%0, %2}";
6997 return "add{b}\t{%2, %0|%0, %2}";
7001 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7002 (const_string "incdec")
7003 (const_string "alu")))
7004 (set_attr "mode" "QI")])
7006 (define_insn "*addqi_3"
7007 [(set (reg FLAGS_REG)
7008 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7009 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7010 (clobber (match_scratch:QI 0 "=q"))]
7011 "ix86_match_ccmode (insn, CCZmode)
7012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7014 switch (get_attr_type (insn))
7017 if (operands[2] == const1_rtx)
7018 return "inc{b}\t%0";
7021 gcc_assert (operands[2] == constm1_rtx
7022 || (CONST_INT_P (operands[2])
7023 && INTVAL (operands[2]) == 255));
7024 return "dec{b}\t%0";
7028 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7029 if (CONST_INT_P (operands[2])
7030 && INTVAL (operands[2]) < 0)
7032 operands[2] = GEN_INT (-INTVAL (operands[2]));
7033 return "sub{b}\t{%2, %0|%0, %2}";
7035 return "add{b}\t{%2, %0|%0, %2}";
7039 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7040 (const_string "incdec")
7041 (const_string "alu")))
7042 (set_attr "mode" "QI")])
7044 ; See comments above addsi_4 for details.
7045 (define_insn "*addqi_4"
7046 [(set (reg FLAGS_REG)
7047 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7048 (match_operand:QI 2 "const_int_operand" "n")))
7049 (clobber (match_scratch:QI 0 "=qm"))]
7050 "ix86_match_ccmode (insn, CCGCmode)
7051 && (INTVAL (operands[2]) & 0xff) != 0x80"
7053 switch (get_attr_type (insn))
7056 if (operands[2] == constm1_rtx
7057 || (CONST_INT_P (operands[2])
7058 && INTVAL (operands[2]) == 255))
7059 return "inc{b}\t%0";
7062 gcc_assert (operands[2] == const1_rtx);
7063 return "dec{b}\t%0";
7067 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7068 if (INTVAL (operands[2]) < 0)
7070 operands[2] = GEN_INT (-INTVAL (operands[2]));
7071 return "add{b}\t{%2, %0|%0, %2}";
7073 return "sub{b}\t{%2, %0|%0, %2}";
7077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7078 (const_string "incdec")
7079 (const_string "alu")))
7080 (set_attr "mode" "QI")])
7083 (define_insn "*addqi_5"
7084 [(set (reg FLAGS_REG)
7086 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7087 (match_operand:QI 2 "general_operand" "qmni"))
7089 (clobber (match_scratch:QI 0 "=q"))]
7090 "ix86_match_ccmode (insn, CCGOCmode)
7091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7093 switch (get_attr_type (insn))
7096 if (operands[2] == const1_rtx)
7097 return "inc{b}\t%0";
7100 gcc_assert (operands[2] == constm1_rtx
7101 || (CONST_INT_P (operands[2])
7102 && INTVAL (operands[2]) == 255));
7103 return "dec{b}\t%0";
7107 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7108 if (CONST_INT_P (operands[2])
7109 && INTVAL (operands[2]) < 0)
7111 operands[2] = GEN_INT (-INTVAL (operands[2]));
7112 return "sub{b}\t{%2, %0|%0, %2}";
7114 return "add{b}\t{%2, %0|%0, %2}";
7118 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7119 (const_string "incdec")
7120 (const_string "alu")))
7121 (set_attr "mode" "QI")])
7124 (define_insn "addqi_ext_1"
7125 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7130 (match_operand 1 "ext_register_operand" "0")
7133 (match_operand:QI 2 "general_operand" "Qmn")))
7134 (clobber (reg:CC FLAGS_REG))]
7137 switch (get_attr_type (insn))
7140 if (operands[2] == const1_rtx)
7141 return "inc{b}\t%h0";
7144 gcc_assert (operands[2] == constm1_rtx
7145 || (CONST_INT_P (operands[2])
7146 && INTVAL (operands[2]) == 255));
7147 return "dec{b}\t%h0";
7151 return "add{b}\t{%2, %h0|%h0, %2}";
7155 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7156 (const_string "incdec")
7157 (const_string "alu")))
7158 (set_attr "mode" "QI")])
7160 (define_insn "*addqi_ext_1_rex64"
7161 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7166 (match_operand 1 "ext_register_operand" "0")
7169 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7170 (clobber (reg:CC FLAGS_REG))]
7173 switch (get_attr_type (insn))
7176 if (operands[2] == const1_rtx)
7177 return "inc{b}\t%h0";
7180 gcc_assert (operands[2] == constm1_rtx
7181 || (CONST_INT_P (operands[2])
7182 && INTVAL (operands[2]) == 255));
7183 return "dec{b}\t%h0";
7187 return "add{b}\t{%2, %h0|%h0, %2}";
7191 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7192 (const_string "incdec")
7193 (const_string "alu")))
7194 (set_attr "mode" "QI")])
7196 (define_insn "*addqi_ext_2"
7197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7202 (match_operand 1 "ext_register_operand" "%0")
7206 (match_operand 2 "ext_register_operand" "Q")
7209 (clobber (reg:CC FLAGS_REG))]
7211 "add{b}\t{%h2, %h0|%h0, %h2}"
7212 [(set_attr "type" "alu")
7213 (set_attr "mode" "QI")])
7215 ;; The patterns that match these are at the end of this file.
7217 (define_expand "addxf3"
7218 [(set (match_operand:XF 0 "register_operand" "")
7219 (plus:XF (match_operand:XF 1 "register_operand" "")
7220 (match_operand:XF 2 "register_operand" "")))]
7224 (define_expand "add<mode>3"
7225 [(set (match_operand:MODEF 0 "register_operand" "")
7226 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7227 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7228 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7231 ;; Subtract instructions
7233 ;; %%% splits for subditi3
7235 (define_expand "subti3"
7236 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7237 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7238 (match_operand:TI 2 "x86_64_general_operand" "")))
7239 (clobber (reg:CC FLAGS_REG))])]
7241 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7243 (define_insn "*subti3_1"
7244 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7245 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7246 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7247 (clobber (reg:CC FLAGS_REG))]
7248 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7252 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7253 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7254 (match_operand:TI 2 "x86_64_general_operand" "")))
7255 (clobber (reg:CC FLAGS_REG))]
7256 "TARGET_64BIT && reload_completed"
7257 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7258 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7259 (parallel [(set (match_dup 3)
7260 (minus:DI (match_dup 4)
7261 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7263 (clobber (reg:CC FLAGS_REG))])]
7264 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7266 ;; %%% splits for subsidi3
7268 (define_expand "subdi3"
7269 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7270 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7271 (match_operand:DI 2 "x86_64_general_operand" "")))
7272 (clobber (reg:CC FLAGS_REG))])]
7274 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7276 (define_insn "*subdi3_1"
7277 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7278 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7279 (match_operand:DI 2 "general_operand" "roiF,riF")))
7280 (clobber (reg:CC FLAGS_REG))]
7281 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7285 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7286 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7287 (match_operand:DI 2 "general_operand" "")))
7288 (clobber (reg:CC FLAGS_REG))]
7289 "!TARGET_64BIT && reload_completed"
7290 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7291 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7292 (parallel [(set (match_dup 3)
7293 (minus:SI (match_dup 4)
7294 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7296 (clobber (reg:CC FLAGS_REG))])]
7297 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7299 (define_insn "subdi3_carry_rex64"
7300 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7301 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7302 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7303 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7304 (clobber (reg:CC FLAGS_REG))]
7305 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7306 "sbb{q}\t{%2, %0|%0, %2}"
7307 [(set_attr "type" "alu")
7308 (set_attr "pent_pair" "pu")
7309 (set_attr "mode" "DI")])
7311 (define_insn "*subdi_1_rex64"
7312 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7313 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7314 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7315 (clobber (reg:CC FLAGS_REG))]
7316 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7317 "sub{q}\t{%2, %0|%0, %2}"
7318 [(set_attr "type" "alu")
7319 (set_attr "mode" "DI")])
7321 (define_insn "*subdi_2_rex64"
7322 [(set (reg FLAGS_REG)
7324 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7325 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7327 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7328 (minus:DI (match_dup 1) (match_dup 2)))]
7329 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7330 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7331 "sub{q}\t{%2, %0|%0, %2}"
7332 [(set_attr "type" "alu")
7333 (set_attr "mode" "DI")])
7335 (define_insn "*subdi_3_rex63"
7336 [(set (reg FLAGS_REG)
7337 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7338 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7339 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7340 (minus:DI (match_dup 1) (match_dup 2)))]
7341 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7342 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7343 "sub{q}\t{%2, %0|%0, %2}"
7344 [(set_attr "type" "alu")
7345 (set_attr "mode" "DI")])
7347 (define_insn "subqi3_carry"
7348 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7349 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7350 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7351 (match_operand:QI 2 "general_operand" "qi,qm"))))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7354 "sbb{b}\t{%2, %0|%0, %2}"
7355 [(set_attr "type" "alu")
7356 (set_attr "pent_pair" "pu")
7357 (set_attr "mode" "QI")])
7359 (define_insn "subhi3_carry"
7360 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7361 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7362 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7363 (match_operand:HI 2 "general_operand" "ri,rm"))))
7364 (clobber (reg:CC FLAGS_REG))]
7365 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7366 "sbb{w}\t{%2, %0|%0, %2}"
7367 [(set_attr "type" "alu")
7368 (set_attr "pent_pair" "pu")
7369 (set_attr "mode" "HI")])
7371 (define_insn "subsi3_carry"
7372 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7373 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7374 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7375 (match_operand:SI 2 "general_operand" "ri,rm"))))
7376 (clobber (reg:CC FLAGS_REG))]
7377 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7378 "sbb{l}\t{%2, %0|%0, %2}"
7379 [(set_attr "type" "alu")
7380 (set_attr "pent_pair" "pu")
7381 (set_attr "mode" "SI")])
7383 (define_insn "subsi3_carry_zext"
7384 [(set (match_operand:DI 0 "register_operand" "=r")
7386 (minus:SI (match_operand:SI 1 "register_operand" "0")
7387 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7388 (match_operand:SI 2 "general_operand" "g")))))
7389 (clobber (reg:CC FLAGS_REG))]
7390 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7391 "sbb{l}\t{%2, %k0|%k0, %2}"
7392 [(set_attr "type" "alu")
7393 (set_attr "pent_pair" "pu")
7394 (set_attr "mode" "SI")])
7396 (define_expand "subsi3"
7397 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7398 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7399 (match_operand:SI 2 "general_operand" "")))
7400 (clobber (reg:CC FLAGS_REG))])]
7402 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7404 (define_insn "*subsi_1"
7405 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7406 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7407 (match_operand:SI 2 "general_operand" "ri,rm")))
7408 (clobber (reg:CC FLAGS_REG))]
7409 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7410 "sub{l}\t{%2, %0|%0, %2}"
7411 [(set_attr "type" "alu")
7412 (set_attr "mode" "SI")])
7414 (define_insn "*subsi_1_zext"
7415 [(set (match_operand:DI 0 "register_operand" "=r")
7417 (minus:SI (match_operand:SI 1 "register_operand" "0")
7418 (match_operand:SI 2 "general_operand" "g"))))
7419 (clobber (reg:CC FLAGS_REG))]
7420 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7421 "sub{l}\t{%2, %k0|%k0, %2}"
7422 [(set_attr "type" "alu")
7423 (set_attr "mode" "SI")])
7425 (define_insn "*subsi_2"
7426 [(set (reg FLAGS_REG)
7428 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7429 (match_operand:SI 2 "general_operand" "ri,rm"))
7431 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7432 (minus:SI (match_dup 1) (match_dup 2)))]
7433 "ix86_match_ccmode (insn, CCGOCmode)
7434 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7435 "sub{l}\t{%2, %0|%0, %2}"
7436 [(set_attr "type" "alu")
7437 (set_attr "mode" "SI")])
7439 (define_insn "*subsi_2_zext"
7440 [(set (reg FLAGS_REG)
7442 (minus:SI (match_operand:SI 1 "register_operand" "0")
7443 (match_operand:SI 2 "general_operand" "g"))
7445 (set (match_operand:DI 0 "register_operand" "=r")
7447 (minus:SI (match_dup 1)
7449 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7450 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7451 "sub{l}\t{%2, %k0|%k0, %2}"
7452 [(set_attr "type" "alu")
7453 (set_attr "mode" "SI")])
7455 (define_insn "*subsi_3"
7456 [(set (reg FLAGS_REG)
7457 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7458 (match_operand:SI 2 "general_operand" "ri,rm")))
7459 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7460 (minus:SI (match_dup 1) (match_dup 2)))]
7461 "ix86_match_ccmode (insn, CCmode)
7462 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7463 "sub{l}\t{%2, %0|%0, %2}"
7464 [(set_attr "type" "alu")
7465 (set_attr "mode" "SI")])
7467 (define_insn "*subsi_3_zext"
7468 [(set (reg FLAGS_REG)
7469 (compare (match_operand:SI 1 "register_operand" "0")
7470 (match_operand:SI 2 "general_operand" "g")))
7471 (set (match_operand:DI 0 "register_operand" "=r")
7473 (minus:SI (match_dup 1)
7475 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7476 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7477 "sub{l}\t{%2, %1|%1, %2}"
7478 [(set_attr "type" "alu")
7479 (set_attr "mode" "DI")])
7481 (define_expand "subhi3"
7482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7483 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7484 (match_operand:HI 2 "general_operand" "")))
7485 (clobber (reg:CC FLAGS_REG))])]
7486 "TARGET_HIMODE_MATH"
7487 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7489 (define_insn "*subhi_1"
7490 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7491 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7492 (match_operand:HI 2 "general_operand" "ri,rm")))
7493 (clobber (reg:CC FLAGS_REG))]
7494 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7495 "sub{w}\t{%2, %0|%0, %2}"
7496 [(set_attr "type" "alu")
7497 (set_attr "mode" "HI")])
7499 (define_insn "*subhi_2"
7500 [(set (reg FLAGS_REG)
7502 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7503 (match_operand:HI 2 "general_operand" "ri,rm"))
7505 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7506 (minus:HI (match_dup 1) (match_dup 2)))]
7507 "ix86_match_ccmode (insn, CCGOCmode)
7508 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7509 "sub{w}\t{%2, %0|%0, %2}"
7510 [(set_attr "type" "alu")
7511 (set_attr "mode" "HI")])
7513 (define_insn "*subhi_3"
7514 [(set (reg FLAGS_REG)
7515 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7516 (match_operand:HI 2 "general_operand" "ri,rm")))
7517 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7518 (minus:HI (match_dup 1) (match_dup 2)))]
7519 "ix86_match_ccmode (insn, CCmode)
7520 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7521 "sub{w}\t{%2, %0|%0, %2}"
7522 [(set_attr "type" "alu")
7523 (set_attr "mode" "HI")])
7525 (define_expand "subqi3"
7526 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7527 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7528 (match_operand:QI 2 "general_operand" "")))
7529 (clobber (reg:CC FLAGS_REG))])]
7530 "TARGET_QIMODE_MATH"
7531 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7533 (define_insn "*subqi_1"
7534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7535 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7536 (match_operand:QI 2 "general_operand" "qn,qmn")))
7537 (clobber (reg:CC FLAGS_REG))]
7538 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7539 "sub{b}\t{%2, %0|%0, %2}"
7540 [(set_attr "type" "alu")
7541 (set_attr "mode" "QI")])
7543 (define_insn "*subqi_1_slp"
7544 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7545 (minus:QI (match_dup 0)
7546 (match_operand:QI 1 "general_operand" "qn,qmn")))
7547 (clobber (reg:CC FLAGS_REG))]
7548 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7550 "sub{b}\t{%1, %0|%0, %1}"
7551 [(set_attr "type" "alu1")
7552 (set_attr "mode" "QI")])
7554 (define_insn "*subqi_2"
7555 [(set (reg FLAGS_REG)
7557 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7558 (match_operand:QI 2 "general_operand" "qi,qm"))
7560 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7561 (minus:HI (match_dup 1) (match_dup 2)))]
7562 "ix86_match_ccmode (insn, CCGOCmode)
7563 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7564 "sub{b}\t{%2, %0|%0, %2}"
7565 [(set_attr "type" "alu")
7566 (set_attr "mode" "QI")])
7568 (define_insn "*subqi_3"
7569 [(set (reg FLAGS_REG)
7570 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7571 (match_operand:QI 2 "general_operand" "qi,qm")))
7572 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7573 (minus:HI (match_dup 1) (match_dup 2)))]
7574 "ix86_match_ccmode (insn, CCmode)
7575 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7576 "sub{b}\t{%2, %0|%0, %2}"
7577 [(set_attr "type" "alu")
7578 (set_attr "mode" "QI")])
7580 ;; The patterns that match these are at the end of this file.
7582 (define_expand "subxf3"
7583 [(set (match_operand:XF 0 "register_operand" "")
7584 (minus:XF (match_operand:XF 1 "register_operand" "")
7585 (match_operand:XF 2 "register_operand" "")))]
7589 (define_expand "sub<mode>3"
7590 [(set (match_operand:MODEF 0 "register_operand" "")
7591 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7592 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7593 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7596 ;; Multiply instructions
7598 (define_expand "muldi3"
7599 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7600 (mult:DI (match_operand:DI 1 "register_operand" "")
7601 (match_operand:DI 2 "x86_64_general_operand" "")))
7602 (clobber (reg:CC FLAGS_REG))])]
7607 ;; IMUL reg64, reg64, imm8 Direct
7608 ;; IMUL reg64, mem64, imm8 VectorPath
7609 ;; IMUL reg64, reg64, imm32 Direct
7610 ;; IMUL reg64, mem64, imm32 VectorPath
7611 ;; IMUL reg64, reg64 Direct
7612 ;; IMUL reg64, mem64 Direct
7614 (define_insn "*muldi3_1_rex64"
7615 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7616 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7617 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7618 (clobber (reg:CC FLAGS_REG))]
7620 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7622 imul{q}\t{%2, %1, %0|%0, %1, %2}
7623 imul{q}\t{%2, %1, %0|%0, %1, %2}
7624 imul{q}\t{%2, %0|%0, %2}"
7625 [(set_attr "type" "imul")
7626 (set_attr "prefix_0f" "0,0,1")
7627 (set (attr "athlon_decode")
7628 (cond [(eq_attr "cpu" "athlon")
7629 (const_string "vector")
7630 (eq_attr "alternative" "1")
7631 (const_string "vector")
7632 (and (eq_attr "alternative" "2")
7633 (match_operand 1 "memory_operand" ""))
7634 (const_string "vector")]
7635 (const_string "direct")))
7636 (set (attr "amdfam10_decode")
7637 (cond [(and (eq_attr "alternative" "0,1")
7638 (match_operand 1 "memory_operand" ""))
7639 (const_string "vector")]
7640 (const_string "direct")))
7641 (set_attr "mode" "DI")])
7643 (define_expand "mulsi3"
7644 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7645 (mult:SI (match_operand:SI 1 "register_operand" "")
7646 (match_operand:SI 2 "general_operand" "")))
7647 (clobber (reg:CC FLAGS_REG))])]
7652 ;; IMUL reg32, reg32, imm8 Direct
7653 ;; IMUL reg32, mem32, imm8 VectorPath
7654 ;; IMUL reg32, reg32, imm32 Direct
7655 ;; IMUL reg32, mem32, imm32 VectorPath
7656 ;; IMUL reg32, reg32 Direct
7657 ;; IMUL reg32, mem32 Direct
7659 (define_insn "*mulsi3_1"
7660 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7661 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7662 (match_operand:SI 2 "general_operand" "K,i,mr")))
7663 (clobber (reg:CC FLAGS_REG))]
7664 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7666 imul{l}\t{%2, %1, %0|%0, %1, %2}
7667 imul{l}\t{%2, %1, %0|%0, %1, %2}
7668 imul{l}\t{%2, %0|%0, %2}"
7669 [(set_attr "type" "imul")
7670 (set_attr "prefix_0f" "0,0,1")
7671 (set (attr "athlon_decode")
7672 (cond [(eq_attr "cpu" "athlon")
7673 (const_string "vector")
7674 (eq_attr "alternative" "1")
7675 (const_string "vector")
7676 (and (eq_attr "alternative" "2")
7677 (match_operand 1 "memory_operand" ""))
7678 (const_string "vector")]
7679 (const_string "direct")))
7680 (set (attr "amdfam10_decode")
7681 (cond [(and (eq_attr "alternative" "0,1")
7682 (match_operand 1 "memory_operand" ""))
7683 (const_string "vector")]
7684 (const_string "direct")))
7685 (set_attr "mode" "SI")])
7687 (define_insn "*mulsi3_1_zext"
7688 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7690 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7691 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7692 (clobber (reg:CC FLAGS_REG))]
7694 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7696 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7697 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7698 imul{l}\t{%2, %k0|%k0, %2}"
7699 [(set_attr "type" "imul")
7700 (set_attr "prefix_0f" "0,0,1")
7701 (set (attr "athlon_decode")
7702 (cond [(eq_attr "cpu" "athlon")
7703 (const_string "vector")
7704 (eq_attr "alternative" "1")
7705 (const_string "vector")
7706 (and (eq_attr "alternative" "2")
7707 (match_operand 1 "memory_operand" ""))
7708 (const_string "vector")]
7709 (const_string "direct")))
7710 (set (attr "amdfam10_decode")
7711 (cond [(and (eq_attr "alternative" "0,1")
7712 (match_operand 1 "memory_operand" ""))
7713 (const_string "vector")]
7714 (const_string "direct")))
7715 (set_attr "mode" "SI")])
7717 (define_expand "mulhi3"
7718 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7719 (mult:HI (match_operand:HI 1 "register_operand" "")
7720 (match_operand:HI 2 "general_operand" "")))
7721 (clobber (reg:CC FLAGS_REG))])]
7722 "TARGET_HIMODE_MATH"
7726 ;; IMUL reg16, reg16, imm8 VectorPath
7727 ;; IMUL reg16, mem16, imm8 VectorPath
7728 ;; IMUL reg16, reg16, imm16 VectorPath
7729 ;; IMUL reg16, mem16, imm16 VectorPath
7730 ;; IMUL reg16, reg16 Direct
7731 ;; IMUL reg16, mem16 Direct
7732 (define_insn "*mulhi3_1"
7733 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7734 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7735 (match_operand:HI 2 "general_operand" "K,i,mr")))
7736 (clobber (reg:CC FLAGS_REG))]
7737 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7739 imul{w}\t{%2, %1, %0|%0, %1, %2}
7740 imul{w}\t{%2, %1, %0|%0, %1, %2}
7741 imul{w}\t{%2, %0|%0, %2}"
7742 [(set_attr "type" "imul")
7743 (set_attr "prefix_0f" "0,0,1")
7744 (set (attr "athlon_decode")
7745 (cond [(eq_attr "cpu" "athlon")
7746 (const_string "vector")
7747 (eq_attr "alternative" "1,2")
7748 (const_string "vector")]
7749 (const_string "direct")))
7750 (set (attr "amdfam10_decode")
7751 (cond [(eq_attr "alternative" "0,1")
7752 (const_string "vector")]
7753 (const_string "direct")))
7754 (set_attr "mode" "HI")])
7756 (define_expand "mulqi3"
7757 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7758 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7759 (match_operand:QI 2 "register_operand" "")))
7760 (clobber (reg:CC FLAGS_REG))])]
7761 "TARGET_QIMODE_MATH"
7768 (define_insn "*mulqi3_1"
7769 [(set (match_operand:QI 0 "register_operand" "=a")
7770 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7771 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7772 (clobber (reg:CC FLAGS_REG))]
7774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776 [(set_attr "type" "imul")
7777 (set_attr "length_immediate" "0")
7778 (set (attr "athlon_decode")
7779 (if_then_else (eq_attr "cpu" "athlon")
7780 (const_string "vector")
7781 (const_string "direct")))
7782 (set_attr "amdfam10_decode" "direct")
7783 (set_attr "mode" "QI")])
7785 (define_expand "umulqihi3"
7786 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7787 (mult:HI (zero_extend:HI
7788 (match_operand:QI 1 "nonimmediate_operand" ""))
7790 (match_operand:QI 2 "register_operand" ""))))
7791 (clobber (reg:CC FLAGS_REG))])]
7792 "TARGET_QIMODE_MATH"
7795 (define_insn "*umulqihi3_1"
7796 [(set (match_operand:HI 0 "register_operand" "=a")
7797 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7798 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7799 (clobber (reg:CC FLAGS_REG))]
7801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7803 [(set_attr "type" "imul")
7804 (set_attr "length_immediate" "0")
7805 (set (attr "athlon_decode")
7806 (if_then_else (eq_attr "cpu" "athlon")
7807 (const_string "vector")
7808 (const_string "direct")))
7809 (set_attr "amdfam10_decode" "direct")
7810 (set_attr "mode" "QI")])
7812 (define_expand "mulqihi3"
7813 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7814 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7815 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7816 (clobber (reg:CC FLAGS_REG))])]
7817 "TARGET_QIMODE_MATH"
7820 (define_insn "*mulqihi3_insn"
7821 [(set (match_operand:HI 0 "register_operand" "=a")
7822 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7823 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7824 (clobber (reg:CC FLAGS_REG))]
7826 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7828 [(set_attr "type" "imul")
7829 (set_attr "length_immediate" "0")
7830 (set (attr "athlon_decode")
7831 (if_then_else (eq_attr "cpu" "athlon")
7832 (const_string "vector")
7833 (const_string "direct")))
7834 (set_attr "amdfam10_decode" "direct")
7835 (set_attr "mode" "QI")])
7837 (define_expand "umulditi3"
7838 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7839 (mult:TI (zero_extend:TI
7840 (match_operand:DI 1 "nonimmediate_operand" ""))
7842 (match_operand:DI 2 "register_operand" ""))))
7843 (clobber (reg:CC FLAGS_REG))])]
7847 (define_insn "*umulditi3_insn"
7848 [(set (match_operand:TI 0 "register_operand" "=A")
7849 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7850 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7851 (clobber (reg:CC FLAGS_REG))]
7853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7855 [(set_attr "type" "imul")
7856 (set_attr "length_immediate" "0")
7857 (set (attr "athlon_decode")
7858 (if_then_else (eq_attr "cpu" "athlon")
7859 (const_string "vector")
7860 (const_string "double")))
7861 (set_attr "amdfam10_decode" "double")
7862 (set_attr "mode" "DI")])
7864 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7865 (define_expand "umulsidi3"
7866 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7867 (mult:DI (zero_extend:DI
7868 (match_operand:SI 1 "nonimmediate_operand" ""))
7870 (match_operand:SI 2 "register_operand" ""))))
7871 (clobber (reg:CC FLAGS_REG))])]
7875 (define_insn "*umulsidi3_insn"
7876 [(set (match_operand:DI 0 "register_operand" "=A")
7877 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7878 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7879 (clobber (reg:CC FLAGS_REG))]
7881 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7883 [(set_attr "type" "imul")
7884 (set_attr "length_immediate" "0")
7885 (set (attr "athlon_decode")
7886 (if_then_else (eq_attr "cpu" "athlon")
7887 (const_string "vector")
7888 (const_string "double")))
7889 (set_attr "amdfam10_decode" "double")
7890 (set_attr "mode" "SI")])
7892 (define_expand "mulditi3"
7893 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7894 (mult:TI (sign_extend:TI
7895 (match_operand:DI 1 "nonimmediate_operand" ""))
7897 (match_operand:DI 2 "register_operand" ""))))
7898 (clobber (reg:CC FLAGS_REG))])]
7902 (define_insn "*mulditi3_insn"
7903 [(set (match_operand:TI 0 "register_operand" "=A")
7904 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7905 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7906 (clobber (reg:CC FLAGS_REG))]
7908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7910 [(set_attr "type" "imul")
7911 (set_attr "length_immediate" "0")
7912 (set (attr "athlon_decode")
7913 (if_then_else (eq_attr "cpu" "athlon")
7914 (const_string "vector")
7915 (const_string "double")))
7916 (set_attr "amdfam10_decode" "double")
7917 (set_attr "mode" "DI")])
7919 (define_expand "mulsidi3"
7920 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7921 (mult:DI (sign_extend:DI
7922 (match_operand:SI 1 "nonimmediate_operand" ""))
7924 (match_operand:SI 2 "register_operand" ""))))
7925 (clobber (reg:CC FLAGS_REG))])]
7929 (define_insn "*mulsidi3_insn"
7930 [(set (match_operand:DI 0 "register_operand" "=A")
7931 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7932 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7933 (clobber (reg:CC FLAGS_REG))]
7935 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7937 [(set_attr "type" "imul")
7938 (set_attr "length_immediate" "0")
7939 (set (attr "athlon_decode")
7940 (if_then_else (eq_attr "cpu" "athlon")
7941 (const_string "vector")
7942 (const_string "double")))
7943 (set_attr "amdfam10_decode" "double")
7944 (set_attr "mode" "SI")])
7946 (define_expand "umuldi3_highpart"
7947 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7950 (mult:TI (zero_extend:TI
7951 (match_operand:DI 1 "nonimmediate_operand" ""))
7953 (match_operand:DI 2 "register_operand" "")))
7955 (clobber (match_scratch:DI 3 ""))
7956 (clobber (reg:CC FLAGS_REG))])]
7960 (define_insn "*umuldi3_highpart_rex64"
7961 [(set (match_operand:DI 0 "register_operand" "=d")
7964 (mult:TI (zero_extend:TI
7965 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7967 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7969 (clobber (match_scratch:DI 3 "=1"))
7970 (clobber (reg:CC FLAGS_REG))]
7972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7974 [(set_attr "type" "imul")
7975 (set_attr "length_immediate" "0")
7976 (set (attr "athlon_decode")
7977 (if_then_else (eq_attr "cpu" "athlon")
7978 (const_string "vector")
7979 (const_string "double")))
7980 (set_attr "amdfam10_decode" "double")
7981 (set_attr "mode" "DI")])
7983 (define_expand "umulsi3_highpart"
7984 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7987 (mult:DI (zero_extend:DI
7988 (match_operand:SI 1 "nonimmediate_operand" ""))
7990 (match_operand:SI 2 "register_operand" "")))
7992 (clobber (match_scratch:SI 3 ""))
7993 (clobber (reg:CC FLAGS_REG))])]
7997 (define_insn "*umulsi3_highpart_insn"
7998 [(set (match_operand:SI 0 "register_operand" "=d")
8001 (mult:DI (zero_extend:DI
8002 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8004 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8006 (clobber (match_scratch:SI 3 "=1"))
8007 (clobber (reg:CC FLAGS_REG))]
8008 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8010 [(set_attr "type" "imul")
8011 (set_attr "length_immediate" "0")
8012 (set (attr "athlon_decode")
8013 (if_then_else (eq_attr "cpu" "athlon")
8014 (const_string "vector")
8015 (const_string "double")))
8016 (set_attr "amdfam10_decode" "double")
8017 (set_attr "mode" "SI")])
8019 (define_insn "*umulsi3_highpart_zext"
8020 [(set (match_operand:DI 0 "register_operand" "=d")
8021 (zero_extend:DI (truncate:SI
8023 (mult:DI (zero_extend:DI
8024 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8026 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8028 (clobber (match_scratch:SI 3 "=1"))
8029 (clobber (reg:CC FLAGS_REG))]
8031 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8033 [(set_attr "type" "imul")
8034 (set_attr "length_immediate" "0")
8035 (set (attr "athlon_decode")
8036 (if_then_else (eq_attr "cpu" "athlon")
8037 (const_string "vector")
8038 (const_string "double")))
8039 (set_attr "amdfam10_decode" "double")
8040 (set_attr "mode" "SI")])
8042 (define_expand "smuldi3_highpart"
8043 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8046 (mult:TI (sign_extend:TI
8047 (match_operand:DI 1 "nonimmediate_operand" ""))
8049 (match_operand:DI 2 "register_operand" "")))
8051 (clobber (match_scratch:DI 3 ""))
8052 (clobber (reg:CC FLAGS_REG))])]
8056 (define_insn "*smuldi3_highpart_rex64"
8057 [(set (match_operand:DI 0 "register_operand" "=d")
8060 (mult:TI (sign_extend:TI
8061 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8063 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8065 (clobber (match_scratch:DI 3 "=1"))
8066 (clobber (reg:CC FLAGS_REG))]
8068 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8070 [(set_attr "type" "imul")
8071 (set (attr "athlon_decode")
8072 (if_then_else (eq_attr "cpu" "athlon")
8073 (const_string "vector")
8074 (const_string "double")))
8075 (set_attr "amdfam10_decode" "double")
8076 (set_attr "mode" "DI")])
8078 (define_expand "smulsi3_highpart"
8079 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8082 (mult:DI (sign_extend:DI
8083 (match_operand:SI 1 "nonimmediate_operand" ""))
8085 (match_operand:SI 2 "register_operand" "")))
8087 (clobber (match_scratch:SI 3 ""))
8088 (clobber (reg:CC FLAGS_REG))])]
8092 (define_insn "*smulsi3_highpart_insn"
8093 [(set (match_operand:SI 0 "register_operand" "=d")
8096 (mult:DI (sign_extend:DI
8097 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8099 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8101 (clobber (match_scratch:SI 3 "=1"))
8102 (clobber (reg:CC FLAGS_REG))]
8103 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8105 [(set_attr "type" "imul")
8106 (set (attr "athlon_decode")
8107 (if_then_else (eq_attr "cpu" "athlon")
8108 (const_string "vector")
8109 (const_string "double")))
8110 (set_attr "amdfam10_decode" "double")
8111 (set_attr "mode" "SI")])
8113 (define_insn "*smulsi3_highpart_zext"
8114 [(set (match_operand:DI 0 "register_operand" "=d")
8115 (zero_extend:DI (truncate:SI
8117 (mult:DI (sign_extend:DI
8118 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8120 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8122 (clobber (match_scratch:SI 3 "=1"))
8123 (clobber (reg:CC FLAGS_REG))]
8125 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8127 [(set_attr "type" "imul")
8128 (set (attr "athlon_decode")
8129 (if_then_else (eq_attr "cpu" "athlon")
8130 (const_string "vector")
8131 (const_string "double")))
8132 (set_attr "amdfam10_decode" "double")
8133 (set_attr "mode" "SI")])
8135 ;; The patterns that match these are at the end of this file.
8137 (define_expand "mulxf3"
8138 [(set (match_operand:XF 0 "register_operand" "")
8139 (mult:XF (match_operand:XF 1 "register_operand" "")
8140 (match_operand:XF 2 "register_operand" "")))]
8144 (define_expand "mul<mode>3"
8145 [(set (match_operand:MODEF 0 "register_operand" "")
8146 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8147 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8148 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8151 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8154 ;; Divide instructions
8156 (define_insn "divqi3"
8157 [(set (match_operand:QI 0 "register_operand" "=a")
8158 (div: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 (define_insn "udivqi3"
8167 [(set (match_operand:QI 0 "register_operand" "=a")
8168 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8169 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8170 (clobber (reg:CC FLAGS_REG))]
8171 "TARGET_QIMODE_MATH"
8173 [(set_attr "type" "idiv")
8174 (set_attr "mode" "QI")])
8176 ;; The patterns that match these are at the end of this file.
8178 (define_expand "divxf3"
8179 [(set (match_operand:XF 0 "register_operand" "")
8180 (div:XF (match_operand:XF 1 "register_operand" "")
8181 (match_operand:XF 2 "register_operand" "")))]
8185 (define_expand "divdf3"
8186 [(set (match_operand:DF 0 "register_operand" "")
8187 (div:DF (match_operand:DF 1 "register_operand" "")
8188 (match_operand:DF 2 "nonimmediate_operand" "")))]
8189 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8192 (define_expand "divsf3"
8193 [(set (match_operand:SF 0 "register_operand" "")
8194 (div:SF (match_operand:SF 1 "register_operand" "")
8195 (match_operand:SF 2 "nonimmediate_operand" "")))]
8196 "TARGET_80387 || TARGET_SSE_MATH"
8198 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8199 && flag_finite_math_only && !flag_trapping_math
8200 && flag_unsafe_math_optimizations)
8202 ix86_emit_swdivsf (operands[0], operands[1],
8203 operands[2], SFmode);
8208 ;; Remainder instructions.
8210 (define_expand "divmoddi4"
8211 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8212 (div:DI (match_operand:DI 1 "register_operand" "")
8213 (match_operand:DI 2 "nonimmediate_operand" "")))
8214 (set (match_operand:DI 3 "register_operand" "")
8215 (mod:DI (match_dup 1) (match_dup 2)))
8216 (clobber (reg:CC FLAGS_REG))])]
8220 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8221 ;; Penalize eax case slightly because it results in worse scheduling
8223 (define_insn "*divmoddi4_nocltd_rex64"
8224 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8225 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8226 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8227 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8228 (mod:DI (match_dup 2) (match_dup 3)))
8229 (clobber (reg:CC FLAGS_REG))]
8230 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8232 [(set_attr "type" "multi")])
8234 (define_insn "*divmoddi4_cltd_rex64"
8235 [(set (match_operand:DI 0 "register_operand" "=a")
8236 (div:DI (match_operand:DI 2 "register_operand" "a")
8237 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8238 (set (match_operand:DI 1 "register_operand" "=&d")
8239 (mod:DI (match_dup 2) (match_dup 3)))
8240 (clobber (reg:CC FLAGS_REG))]
8241 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8243 [(set_attr "type" "multi")])
8245 (define_insn "*divmoddi_noext_rex64"
8246 [(set (match_operand:DI 0 "register_operand" "=a")
8247 (div:DI (match_operand:DI 1 "register_operand" "0")
8248 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8249 (set (match_operand:DI 3 "register_operand" "=d")
8250 (mod:DI (match_dup 1) (match_dup 2)))
8251 (use (match_operand:DI 4 "register_operand" "3"))
8252 (clobber (reg:CC FLAGS_REG))]
8255 [(set_attr "type" "idiv")
8256 (set_attr "mode" "DI")])
8259 [(set (match_operand:DI 0 "register_operand" "")
8260 (div:DI (match_operand:DI 1 "register_operand" "")
8261 (match_operand:DI 2 "nonimmediate_operand" "")))
8262 (set (match_operand:DI 3 "register_operand" "")
8263 (mod:DI (match_dup 1) (match_dup 2)))
8264 (clobber (reg:CC FLAGS_REG))]
8265 "TARGET_64BIT && reload_completed"
8266 [(parallel [(set (match_dup 3)
8267 (ashiftrt:DI (match_dup 4) (const_int 63)))
8268 (clobber (reg:CC FLAGS_REG))])
8269 (parallel [(set (match_dup 0)
8270 (div:DI (reg:DI 0) (match_dup 2)))
8272 (mod:DI (reg:DI 0) (match_dup 2)))
8274 (clobber (reg:CC FLAGS_REG))])]
8276 /* Avoid use of cltd in favor of a mov+shift. */
8277 if (!TARGET_USE_CLTD && !optimize_size)
8279 if (true_regnum (operands[1]))
8280 emit_move_insn (operands[0], operands[1]);
8282 emit_move_insn (operands[3], operands[1]);
8283 operands[4] = operands[3];
8287 gcc_assert (!true_regnum (operands[1]));
8288 operands[4] = operands[1];
8293 (define_expand "divmodsi4"
8294 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8295 (div:SI (match_operand:SI 1 "register_operand" "")
8296 (match_operand:SI 2 "nonimmediate_operand" "")))
8297 (set (match_operand:SI 3 "register_operand" "")
8298 (mod:SI (match_dup 1) (match_dup 2)))
8299 (clobber (reg:CC FLAGS_REG))])]
8303 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8304 ;; Penalize eax case slightly because it results in worse scheduling
8306 (define_insn "*divmodsi4_nocltd"
8307 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8308 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8309 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8310 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8311 (mod:SI (match_dup 2) (match_dup 3)))
8312 (clobber (reg:CC FLAGS_REG))]
8313 "!optimize_size && !TARGET_USE_CLTD"
8315 [(set_attr "type" "multi")])
8317 (define_insn "*divmodsi4_cltd"
8318 [(set (match_operand:SI 0 "register_operand" "=a")
8319 (div:SI (match_operand:SI 2 "register_operand" "a")
8320 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8321 (set (match_operand:SI 1 "register_operand" "=&d")
8322 (mod:SI (match_dup 2) (match_dup 3)))
8323 (clobber (reg:CC FLAGS_REG))]
8324 "optimize_size || TARGET_USE_CLTD"
8326 [(set_attr "type" "multi")])
8328 (define_insn "*divmodsi_noext"
8329 [(set (match_operand:SI 0 "register_operand" "=a")
8330 (div:SI (match_operand:SI 1 "register_operand" "0")
8331 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8332 (set (match_operand:SI 3 "register_operand" "=d")
8333 (mod:SI (match_dup 1) (match_dup 2)))
8334 (use (match_operand:SI 4 "register_operand" "3"))
8335 (clobber (reg:CC FLAGS_REG))]
8338 [(set_attr "type" "idiv")
8339 (set_attr "mode" "SI")])
8342 [(set (match_operand:SI 0 "register_operand" "")
8343 (div:SI (match_operand:SI 1 "register_operand" "")
8344 (match_operand:SI 2 "nonimmediate_operand" "")))
8345 (set (match_operand:SI 3 "register_operand" "")
8346 (mod:SI (match_dup 1) (match_dup 2)))
8347 (clobber (reg:CC FLAGS_REG))]
8349 [(parallel [(set (match_dup 3)
8350 (ashiftrt:SI (match_dup 4) (const_int 31)))
8351 (clobber (reg:CC FLAGS_REG))])
8352 (parallel [(set (match_dup 0)
8353 (div:SI (reg:SI 0) (match_dup 2)))
8355 (mod:SI (reg:SI 0) (match_dup 2)))
8357 (clobber (reg:CC FLAGS_REG))])]
8359 /* Avoid use of cltd in favor of a mov+shift. */
8360 if (!TARGET_USE_CLTD && !optimize_size)
8362 if (true_regnum (operands[1]))
8363 emit_move_insn (operands[0], operands[1]);
8365 emit_move_insn (operands[3], operands[1]);
8366 operands[4] = operands[3];
8370 gcc_assert (!true_regnum (operands[1]));
8371 operands[4] = operands[1];
8375 (define_insn "divmodhi4"
8376 [(set (match_operand:HI 0 "register_operand" "=a")
8377 (div:HI (match_operand:HI 1 "register_operand" "0")
8378 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8379 (set (match_operand:HI 3 "register_operand" "=&d")
8380 (mod:HI (match_dup 1) (match_dup 2)))
8381 (clobber (reg:CC FLAGS_REG))]
8382 "TARGET_HIMODE_MATH"
8384 [(set_attr "type" "multi")
8385 (set_attr "length_immediate" "0")
8386 (set_attr "mode" "SI")])
8388 (define_insn "udivmoddi4"
8389 [(set (match_operand:DI 0 "register_operand" "=a")
8390 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8391 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8392 (set (match_operand:DI 3 "register_operand" "=&d")
8393 (umod:DI (match_dup 1) (match_dup 2)))
8394 (clobber (reg:CC FLAGS_REG))]
8396 "xor{q}\t%3, %3\;div{q}\t%2"
8397 [(set_attr "type" "multi")
8398 (set_attr "length_immediate" "0")
8399 (set_attr "mode" "DI")])
8401 (define_insn "*udivmoddi4_noext"
8402 [(set (match_operand:DI 0 "register_operand" "=a")
8403 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8404 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8405 (set (match_operand:DI 3 "register_operand" "=d")
8406 (umod:DI (match_dup 1) (match_dup 2)))
8408 (clobber (reg:CC FLAGS_REG))]
8411 [(set_attr "type" "idiv")
8412 (set_attr "mode" "DI")])
8415 [(set (match_operand:DI 0 "register_operand" "")
8416 (udiv:DI (match_operand:DI 1 "register_operand" "")
8417 (match_operand:DI 2 "nonimmediate_operand" "")))
8418 (set (match_operand:DI 3 "register_operand" "")
8419 (umod:DI (match_dup 1) (match_dup 2)))
8420 (clobber (reg:CC FLAGS_REG))]
8421 "TARGET_64BIT && reload_completed"
8422 [(set (match_dup 3) (const_int 0))
8423 (parallel [(set (match_dup 0)
8424 (udiv:DI (match_dup 1) (match_dup 2)))
8426 (umod:DI (match_dup 1) (match_dup 2)))
8428 (clobber (reg:CC FLAGS_REG))])]
8431 (define_insn "udivmodsi4"
8432 [(set (match_operand:SI 0 "register_operand" "=a")
8433 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8434 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8435 (set (match_operand:SI 3 "register_operand" "=&d")
8436 (umod:SI (match_dup 1) (match_dup 2)))
8437 (clobber (reg:CC FLAGS_REG))]
8439 "xor{l}\t%3, %3\;div{l}\t%2"
8440 [(set_attr "type" "multi")
8441 (set_attr "length_immediate" "0")
8442 (set_attr "mode" "SI")])
8444 (define_insn "*udivmodsi4_noext"
8445 [(set (match_operand:SI 0 "register_operand" "=a")
8446 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8447 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8448 (set (match_operand:SI 3 "register_operand" "=d")
8449 (umod:SI (match_dup 1) (match_dup 2)))
8451 (clobber (reg:CC FLAGS_REG))]
8454 [(set_attr "type" "idiv")
8455 (set_attr "mode" "SI")])
8458 [(set (match_operand:SI 0 "register_operand" "")
8459 (udiv:SI (match_operand:SI 1 "register_operand" "")
8460 (match_operand:SI 2 "nonimmediate_operand" "")))
8461 (set (match_operand:SI 3 "register_operand" "")
8462 (umod:SI (match_dup 1) (match_dup 2)))
8463 (clobber (reg:CC FLAGS_REG))]
8465 [(set (match_dup 3) (const_int 0))
8466 (parallel [(set (match_dup 0)
8467 (udiv:SI (match_dup 1) (match_dup 2)))
8469 (umod:SI (match_dup 1) (match_dup 2)))
8471 (clobber (reg:CC FLAGS_REG))])]
8474 (define_expand "udivmodhi4"
8475 [(set (match_dup 4) (const_int 0))
8476 (parallel [(set (match_operand:HI 0 "register_operand" "")
8477 (udiv:HI (match_operand:HI 1 "register_operand" "")
8478 (match_operand:HI 2 "nonimmediate_operand" "")))
8479 (set (match_operand:HI 3 "register_operand" "")
8480 (umod:HI (match_dup 1) (match_dup 2)))
8482 (clobber (reg:CC FLAGS_REG))])]
8483 "TARGET_HIMODE_MATH"
8484 "operands[4] = gen_reg_rtx (HImode);")
8486 (define_insn "*udivmodhi_noext"
8487 [(set (match_operand:HI 0 "register_operand" "=a")
8488 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8489 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8490 (set (match_operand:HI 3 "register_operand" "=d")
8491 (umod:HI (match_dup 1) (match_dup 2)))
8492 (use (match_operand:HI 4 "register_operand" "3"))
8493 (clobber (reg:CC FLAGS_REG))]
8496 [(set_attr "type" "idiv")
8497 (set_attr "mode" "HI")])
8499 ;; We cannot use div/idiv for double division, because it causes
8500 ;; "division by zero" on the overflow and that's not what we expect
8501 ;; from truncate. Because true (non truncating) double division is
8502 ;; never generated, we can't create this insn anyway.
8505 ; [(set (match_operand:SI 0 "register_operand" "=a")
8507 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8509 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8510 ; (set (match_operand:SI 3 "register_operand" "=d")
8512 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8513 ; (clobber (reg:CC FLAGS_REG))]
8515 ; "div{l}\t{%2, %0|%0, %2}"
8516 ; [(set_attr "type" "idiv")])
8518 ;;- Logical AND instructions
8520 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8521 ;; Note that this excludes ah.
8523 (define_insn "*testdi_1_rex64"
8524 [(set (reg FLAGS_REG)
8526 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8527 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8529 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8530 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8532 test{l}\t{%k1, %k0|%k0, %k1}
8533 test{l}\t{%k1, %k0|%k0, %k1}
8534 test{q}\t{%1, %0|%0, %1}
8535 test{q}\t{%1, %0|%0, %1}
8536 test{q}\t{%1, %0|%0, %1}"
8537 [(set_attr "type" "test")
8538 (set_attr "modrm" "0,1,0,1,1")
8539 (set_attr "mode" "SI,SI,DI,DI,DI")
8540 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8542 (define_insn "testsi_1"
8543 [(set (reg FLAGS_REG)
8545 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8546 (match_operand:SI 1 "general_operand" "in,in,rin"))
8548 "ix86_match_ccmode (insn, CCNOmode)
8549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8550 "test{l}\t{%1, %0|%0, %1}"
8551 [(set_attr "type" "test")
8552 (set_attr "modrm" "0,1,1")
8553 (set_attr "mode" "SI")
8554 (set_attr "pent_pair" "uv,np,uv")])
8556 (define_expand "testsi_ccno_1"
8557 [(set (reg:CCNO FLAGS_REG)
8559 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8560 (match_operand:SI 1 "nonmemory_operand" ""))
8565 (define_insn "*testhi_1"
8566 [(set (reg FLAGS_REG)
8567 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8568 (match_operand:HI 1 "general_operand" "n,n,rn"))
8570 "ix86_match_ccmode (insn, CCNOmode)
8571 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8572 "test{w}\t{%1, %0|%0, %1}"
8573 [(set_attr "type" "test")
8574 (set_attr "modrm" "0,1,1")
8575 (set_attr "mode" "HI")
8576 (set_attr "pent_pair" "uv,np,uv")])
8578 (define_expand "testqi_ccz_1"
8579 [(set (reg:CCZ FLAGS_REG)
8580 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8581 (match_operand:QI 1 "nonmemory_operand" ""))
8586 (define_insn "*testqi_1_maybe_si"
8587 [(set (reg FLAGS_REG)
8590 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8591 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8593 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8594 && ix86_match_ccmode (insn,
8595 CONST_INT_P (operands[1])
8596 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8598 if (which_alternative == 3)
8600 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8601 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8602 return "test{l}\t{%1, %k0|%k0, %1}";
8604 return "test{b}\t{%1, %0|%0, %1}";
8606 [(set_attr "type" "test")
8607 (set_attr "modrm" "0,1,1,1")
8608 (set_attr "mode" "QI,QI,QI,SI")
8609 (set_attr "pent_pair" "uv,np,uv,np")])
8611 (define_insn "*testqi_1"
8612 [(set (reg FLAGS_REG)
8615 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8616 (match_operand:QI 1 "general_operand" "n,n,qn"))
8618 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8619 && ix86_match_ccmode (insn, CCNOmode)"
8620 "test{b}\t{%1, %0|%0, %1}"
8621 [(set_attr "type" "test")
8622 (set_attr "modrm" "0,1,1")
8623 (set_attr "mode" "QI")
8624 (set_attr "pent_pair" "uv,np,uv")])
8626 (define_expand "testqi_ext_ccno_0"
8627 [(set (reg:CCNO FLAGS_REG)
8631 (match_operand 0 "ext_register_operand" "")
8634 (match_operand 1 "const_int_operand" ""))
8639 (define_insn "*testqi_ext_0"
8640 [(set (reg FLAGS_REG)
8644 (match_operand 0 "ext_register_operand" "Q")
8647 (match_operand 1 "const_int_operand" "n"))
8649 "ix86_match_ccmode (insn, CCNOmode)"
8650 "test{b}\t{%1, %h0|%h0, %1}"
8651 [(set_attr "type" "test")
8652 (set_attr "mode" "QI")
8653 (set_attr "length_immediate" "1")
8654 (set_attr "pent_pair" "np")])
8656 (define_insn "*testqi_ext_1"
8657 [(set (reg FLAGS_REG)
8661 (match_operand 0 "ext_register_operand" "Q")
8665 (match_operand:QI 1 "general_operand" "Qm")))
8667 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8668 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8669 "test{b}\t{%1, %h0|%h0, %1}"
8670 [(set_attr "type" "test")
8671 (set_attr "mode" "QI")])
8673 (define_insn "*testqi_ext_1_rex64"
8674 [(set (reg FLAGS_REG)
8678 (match_operand 0 "ext_register_operand" "Q")
8682 (match_operand:QI 1 "register_operand" "Q")))
8684 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8685 "test{b}\t{%1, %h0|%h0, %1}"
8686 [(set_attr "type" "test")
8687 (set_attr "mode" "QI")])
8689 (define_insn "*testqi_ext_2"
8690 [(set (reg FLAGS_REG)
8694 (match_operand 0 "ext_register_operand" "Q")
8698 (match_operand 1 "ext_register_operand" "Q")
8702 "ix86_match_ccmode (insn, CCNOmode)"
8703 "test{b}\t{%h1, %h0|%h0, %h1}"
8704 [(set_attr "type" "test")
8705 (set_attr "mode" "QI")])
8707 ;; Combine likes to form bit extractions for some tests. Humor it.
8708 (define_insn "*testqi_ext_3"
8709 [(set (reg FLAGS_REG)
8710 (compare (zero_extract:SI
8711 (match_operand 0 "nonimmediate_operand" "rm")
8712 (match_operand:SI 1 "const_int_operand" "")
8713 (match_operand:SI 2 "const_int_operand" ""))
8715 "ix86_match_ccmode (insn, CCNOmode)
8716 && INTVAL (operands[1]) > 0
8717 && INTVAL (operands[2]) >= 0
8718 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8719 && (GET_MODE (operands[0]) == SImode
8720 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8721 || GET_MODE (operands[0]) == HImode
8722 || GET_MODE (operands[0]) == QImode)"
8725 (define_insn "*testqi_ext_3_rex64"
8726 [(set (reg FLAGS_REG)
8727 (compare (zero_extract:DI
8728 (match_operand 0 "nonimmediate_operand" "rm")
8729 (match_operand:DI 1 "const_int_operand" "")
8730 (match_operand:DI 2 "const_int_operand" ""))
8733 && ix86_match_ccmode (insn, CCNOmode)
8734 && INTVAL (operands[1]) > 0
8735 && INTVAL (operands[2]) >= 0
8736 /* Ensure that resulting mask is zero or sign extended operand. */
8737 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8738 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8739 && INTVAL (operands[1]) > 32))
8740 && (GET_MODE (operands[0]) == SImode
8741 || GET_MODE (operands[0]) == DImode
8742 || GET_MODE (operands[0]) == HImode
8743 || GET_MODE (operands[0]) == QImode)"
8747 [(set (match_operand 0 "flags_reg_operand" "")
8748 (match_operator 1 "compare_operator"
8750 (match_operand 2 "nonimmediate_operand" "")
8751 (match_operand 3 "const_int_operand" "")
8752 (match_operand 4 "const_int_operand" ""))
8754 "ix86_match_ccmode (insn, CCNOmode)"
8755 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8757 rtx val = operands[2];
8758 HOST_WIDE_INT len = INTVAL (operands[3]);
8759 HOST_WIDE_INT pos = INTVAL (operands[4]);
8761 enum machine_mode mode, submode;
8763 mode = GET_MODE (val);
8766 /* ??? Combine likes to put non-volatile mem extractions in QImode
8767 no matter the size of the test. So find a mode that works. */
8768 if (! MEM_VOLATILE_P (val))
8770 mode = smallest_mode_for_size (pos + len, MODE_INT);
8771 val = adjust_address (val, mode, 0);
8774 else if (GET_CODE (val) == SUBREG
8775 && (submode = GET_MODE (SUBREG_REG (val)),
8776 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8777 && pos + len <= GET_MODE_BITSIZE (submode))
8779 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8781 val = SUBREG_REG (val);
8783 else if (mode == HImode && pos + len <= 8)
8785 /* Small HImode tests can be converted to QImode. */
8787 val = gen_lowpart (QImode, val);
8790 if (len == HOST_BITS_PER_WIDE_INT)
8793 mask = ((HOST_WIDE_INT)1 << len) - 1;
8796 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8799 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8800 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8801 ;; this is relatively important trick.
8802 ;; Do the conversion only post-reload to avoid limiting of the register class
8805 [(set (match_operand 0 "flags_reg_operand" "")
8806 (match_operator 1 "compare_operator"
8807 [(and (match_operand 2 "register_operand" "")
8808 (match_operand 3 "const_int_operand" ""))
8811 && QI_REG_P (operands[2])
8812 && GET_MODE (operands[2]) != QImode
8813 && ((ix86_match_ccmode (insn, CCZmode)
8814 && !(INTVAL (operands[3]) & ~(255 << 8)))
8815 || (ix86_match_ccmode (insn, CCNOmode)
8816 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8819 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8822 "operands[2] = gen_lowpart (SImode, operands[2]);
8823 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8826 [(set (match_operand 0 "flags_reg_operand" "")
8827 (match_operator 1 "compare_operator"
8828 [(and (match_operand 2 "nonimmediate_operand" "")
8829 (match_operand 3 "const_int_operand" ""))
8832 && GET_MODE (operands[2]) != QImode
8833 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8834 && ((ix86_match_ccmode (insn, CCZmode)
8835 && !(INTVAL (operands[3]) & ~255))
8836 || (ix86_match_ccmode (insn, CCNOmode)
8837 && !(INTVAL (operands[3]) & ~127)))"
8839 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8841 "operands[2] = gen_lowpart (QImode, operands[2]);
8842 operands[3] = gen_lowpart (QImode, operands[3]);")
8845 ;; %%% This used to optimize known byte-wide and operations to memory,
8846 ;; and sometimes to QImode registers. If this is considered useful,
8847 ;; it should be done with splitters.
8849 (define_expand "anddi3"
8850 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8851 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8852 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8853 (clobber (reg:CC FLAGS_REG))]
8855 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8857 (define_insn "*anddi_1_rex64"
8858 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8859 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8860 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8861 (clobber (reg:CC FLAGS_REG))]
8862 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8864 switch (get_attr_type (insn))
8868 enum machine_mode mode;
8870 gcc_assert (CONST_INT_P (operands[2]));
8871 if (INTVAL (operands[2]) == 0xff)
8875 gcc_assert (INTVAL (operands[2]) == 0xffff);
8879 operands[1] = gen_lowpart (mode, operands[1]);
8881 return "movz{bq|x}\t{%1,%0|%0, %1}";
8883 return "movz{wq|x}\t{%1,%0|%0, %1}";
8887 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8888 if (get_attr_mode (insn) == MODE_SI)
8889 return "and{l}\t{%k2, %k0|%k0, %k2}";
8891 return "and{q}\t{%2, %0|%0, %2}";
8894 [(set_attr "type" "alu,alu,alu,imovx")
8895 (set_attr "length_immediate" "*,*,*,0")
8896 (set_attr "mode" "SI,DI,DI,DI")])
8898 (define_insn "*anddi_2"
8899 [(set (reg FLAGS_REG)
8900 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8901 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8903 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8904 (and:DI (match_dup 1) (match_dup 2)))]
8905 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8906 && ix86_binary_operator_ok (AND, DImode, operands)"
8908 and{l}\t{%k2, %k0|%k0, %k2}
8909 and{q}\t{%2, %0|%0, %2}
8910 and{q}\t{%2, %0|%0, %2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "mode" "SI,DI,DI")])
8914 (define_expand "andsi3"
8915 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8916 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8917 (match_operand:SI 2 "general_operand" "")))
8918 (clobber (reg:CC FLAGS_REG))]
8920 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8922 (define_insn "*andsi_1"
8923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8924 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8925 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8926 (clobber (reg:CC FLAGS_REG))]
8927 "ix86_binary_operator_ok (AND, SImode, operands)"
8929 switch (get_attr_type (insn))
8933 enum machine_mode mode;
8935 gcc_assert (CONST_INT_P (operands[2]));
8936 if (INTVAL (operands[2]) == 0xff)
8940 gcc_assert (INTVAL (operands[2]) == 0xffff);
8944 operands[1] = gen_lowpart (mode, operands[1]);
8946 return "movz{bl|x}\t{%1,%0|%0, %1}";
8948 return "movz{wl|x}\t{%1,%0|%0, %1}";
8952 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8953 return "and{l}\t{%2, %0|%0, %2}";
8956 [(set_attr "type" "alu,alu,imovx")
8957 (set_attr "length_immediate" "*,*,0")
8958 (set_attr "mode" "SI")])
8961 [(set (match_operand 0 "register_operand" "")
8963 (const_int -65536)))
8964 (clobber (reg:CC FLAGS_REG))]
8965 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8966 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8967 "operands[1] = gen_lowpart (HImode, operands[0]);")
8970 [(set (match_operand 0 "ext_register_operand" "")
8973 (clobber (reg:CC FLAGS_REG))]
8974 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8975 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8976 "operands[1] = gen_lowpart (QImode, operands[0]);")
8979 [(set (match_operand 0 "ext_register_operand" "")
8981 (const_int -65281)))
8982 (clobber (reg:CC FLAGS_REG))]
8983 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8984 [(parallel [(set (zero_extract:SI (match_dup 0)
8988 (zero_extract:SI (match_dup 0)
8991 (zero_extract:SI (match_dup 0)
8994 (clobber (reg:CC FLAGS_REG))])]
8995 "operands[0] = gen_lowpart (SImode, operands[0]);")
8997 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8998 (define_insn "*andsi_1_zext"
8999 [(set (match_operand:DI 0 "register_operand" "=r")
9001 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002 (match_operand:SI 2 "general_operand" "g"))))
9003 (clobber (reg:CC FLAGS_REG))]
9004 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9005 "and{l}\t{%2, %k0|%k0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "SI")])
9009 (define_insn "*andsi_2"
9010 [(set (reg FLAGS_REG)
9011 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9012 (match_operand:SI 2 "general_operand" "g,ri"))
9014 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9015 (and:SI (match_dup 1) (match_dup 2)))]
9016 "ix86_match_ccmode (insn, CCNOmode)
9017 && ix86_binary_operator_ok (AND, SImode, operands)"
9018 "and{l}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "SI")])
9022 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9023 (define_insn "*andsi_2_zext"
9024 [(set (reg FLAGS_REG)
9025 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9026 (match_operand:SI 2 "general_operand" "g"))
9028 (set (match_operand:DI 0 "register_operand" "=r")
9029 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9030 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9031 && ix86_binary_operator_ok (AND, SImode, operands)"
9032 "and{l}\t{%2, %k0|%k0, %2}"
9033 [(set_attr "type" "alu")
9034 (set_attr "mode" "SI")])
9036 (define_expand "andhi3"
9037 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9038 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9039 (match_operand:HI 2 "general_operand" "")))
9040 (clobber (reg:CC FLAGS_REG))]
9041 "TARGET_HIMODE_MATH"
9042 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9044 (define_insn "*andhi_1"
9045 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9046 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9047 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9048 (clobber (reg:CC FLAGS_REG))]
9049 "ix86_binary_operator_ok (AND, HImode, operands)"
9051 switch (get_attr_type (insn))
9054 gcc_assert (CONST_INT_P (operands[2]));
9055 gcc_assert (INTVAL (operands[2]) == 0xff);
9056 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9059 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9061 return "and{w}\t{%2, %0|%0, %2}";
9064 [(set_attr "type" "alu,alu,imovx")
9065 (set_attr "length_immediate" "*,*,0")
9066 (set_attr "mode" "HI,HI,SI")])
9068 (define_insn "*andhi_2"
9069 [(set (reg FLAGS_REG)
9070 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9071 (match_operand:HI 2 "general_operand" "g,ri"))
9073 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9074 (and:HI (match_dup 1) (match_dup 2)))]
9075 "ix86_match_ccmode (insn, CCNOmode)
9076 && ix86_binary_operator_ok (AND, HImode, operands)"
9077 "and{w}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "HI")])
9081 (define_expand "andqi3"
9082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9083 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9084 (match_operand:QI 2 "general_operand" "")))
9085 (clobber (reg:CC FLAGS_REG))]
9086 "TARGET_QIMODE_MATH"
9087 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9089 ;; %%% Potential partial reg stall on alternative 2. What to do?
9090 (define_insn "*andqi_1"
9091 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9092 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9093 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9094 (clobber (reg:CC FLAGS_REG))]
9095 "ix86_binary_operator_ok (AND, QImode, operands)"
9097 and{b}\t{%2, %0|%0, %2}
9098 and{b}\t{%2, %0|%0, %2}
9099 and{l}\t{%k2, %k0|%k0, %k2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "mode" "QI,QI,SI")])
9103 (define_insn "*andqi_1_slp"
9104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9105 (and:QI (match_dup 0)
9106 (match_operand:QI 1 "general_operand" "qi,qmi")))
9107 (clobber (reg:CC FLAGS_REG))]
9108 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9109 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9110 "and{b}\t{%1, %0|%0, %1}"
9111 [(set_attr "type" "alu1")
9112 (set_attr "mode" "QI")])
9114 (define_insn "*andqi_2_maybe_si"
9115 [(set (reg FLAGS_REG)
9117 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9118 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9120 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9121 (and:QI (match_dup 1) (match_dup 2)))]
9122 "ix86_binary_operator_ok (AND, QImode, operands)
9123 && ix86_match_ccmode (insn,
9124 CONST_INT_P (operands[2])
9125 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9127 if (which_alternative == 2)
9129 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9130 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9131 return "and{l}\t{%2, %k0|%k0, %2}";
9133 return "and{b}\t{%2, %0|%0, %2}";
9135 [(set_attr "type" "alu")
9136 (set_attr "mode" "QI,QI,SI")])
9138 (define_insn "*andqi_2"
9139 [(set (reg FLAGS_REG)
9141 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9142 (match_operand:QI 2 "general_operand" "qim,qi"))
9144 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9145 (and:QI (match_dup 1) (match_dup 2)))]
9146 "ix86_match_ccmode (insn, CCNOmode)
9147 && ix86_binary_operator_ok (AND, QImode, operands)"
9148 "and{b}\t{%2, %0|%0, %2}"
9149 [(set_attr "type" "alu")
9150 (set_attr "mode" "QI")])
9152 (define_insn "*andqi_2_slp"
9153 [(set (reg FLAGS_REG)
9155 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9156 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9158 (set (strict_low_part (match_dup 0))
9159 (and:QI (match_dup 0) (match_dup 1)))]
9160 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9161 && ix86_match_ccmode (insn, CCNOmode)
9162 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9163 "and{b}\t{%1, %0|%0, %1}"
9164 [(set_attr "type" "alu1")
9165 (set_attr "mode" "QI")])
9167 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9168 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9169 ;; for a QImode operand, which of course failed.
9171 (define_insn "andqi_ext_0"
9172 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177 (match_operand 1 "ext_register_operand" "0")
9180 (match_operand 2 "const_int_operand" "n")))
9181 (clobber (reg:CC FLAGS_REG))]
9183 "and{b}\t{%2, %h0|%h0, %2}"
9184 [(set_attr "type" "alu")
9185 (set_attr "length_immediate" "1")
9186 (set_attr "mode" "QI")])
9188 ;; Generated by peephole translating test to and. This shows up
9189 ;; often in fp comparisons.
9191 (define_insn "*andqi_ext_0_cc"
9192 [(set (reg FLAGS_REG)
9196 (match_operand 1 "ext_register_operand" "0")
9199 (match_operand 2 "const_int_operand" "n"))
9201 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9210 "ix86_match_ccmode (insn, CCNOmode)"
9211 "and{b}\t{%2, %h0|%h0, %2}"
9212 [(set_attr "type" "alu")
9213 (set_attr "length_immediate" "1")
9214 (set_attr "mode" "QI")])
9216 (define_insn "*andqi_ext_1"
9217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222 (match_operand 1 "ext_register_operand" "0")
9226 (match_operand:QI 2 "general_operand" "Qm"))))
9227 (clobber (reg:CC FLAGS_REG))]
9229 "and{b}\t{%2, %h0|%h0, %2}"
9230 [(set_attr "type" "alu")
9231 (set_attr "length_immediate" "0")
9232 (set_attr "mode" "QI")])
9234 (define_insn "*andqi_ext_1_rex64"
9235 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9240 (match_operand 1 "ext_register_operand" "0")
9244 (match_operand 2 "ext_register_operand" "Q"))))
9245 (clobber (reg:CC FLAGS_REG))]
9247 "and{b}\t{%2, %h0|%h0, %2}"
9248 [(set_attr "type" "alu")
9249 (set_attr "length_immediate" "0")
9250 (set_attr "mode" "QI")])
9252 (define_insn "*andqi_ext_2"
9253 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9258 (match_operand 1 "ext_register_operand" "%0")
9262 (match_operand 2 "ext_register_operand" "Q")
9265 (clobber (reg:CC FLAGS_REG))]
9267 "and{b}\t{%h2, %h0|%h0, %h2}"
9268 [(set_attr "type" "alu")
9269 (set_attr "length_immediate" "0")
9270 (set_attr "mode" "QI")])
9272 ;; Convert wide AND instructions with immediate operand to shorter QImode
9273 ;; equivalents when possible.
9274 ;; Don't do the splitting with memory operands, since it introduces risk
9275 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9276 ;; for size, but that can (should?) be handled by generic code instead.
9278 [(set (match_operand 0 "register_operand" "")
9279 (and (match_operand 1 "register_operand" "")
9280 (match_operand 2 "const_int_operand" "")))
9281 (clobber (reg:CC FLAGS_REG))]
9283 && QI_REG_P (operands[0])
9284 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9285 && !(~INTVAL (operands[2]) & ~(255 << 8))
9286 && GET_MODE (operands[0]) != QImode"
9287 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9288 (and:SI (zero_extract:SI (match_dup 1)
9289 (const_int 8) (const_int 8))
9291 (clobber (reg:CC FLAGS_REG))])]
9292 "operands[0] = gen_lowpart (SImode, operands[0]);
9293 operands[1] = gen_lowpart (SImode, operands[1]);
9294 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9296 ;; Since AND can be encoded with sign extended immediate, this is only
9297 ;; profitable when 7th bit is not set.
9299 [(set (match_operand 0 "register_operand" "")
9300 (and (match_operand 1 "general_operand" "")
9301 (match_operand 2 "const_int_operand" "")))
9302 (clobber (reg:CC FLAGS_REG))]
9304 && ANY_QI_REG_P (operands[0])
9305 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9306 && !(~INTVAL (operands[2]) & ~255)
9307 && !(INTVAL (operands[2]) & 128)
9308 && GET_MODE (operands[0]) != QImode"
9309 [(parallel [(set (strict_low_part (match_dup 0))
9310 (and:QI (match_dup 1)
9312 (clobber (reg:CC FLAGS_REG))])]
9313 "operands[0] = gen_lowpart (QImode, operands[0]);
9314 operands[1] = gen_lowpart (QImode, operands[1]);
9315 operands[2] = gen_lowpart (QImode, operands[2]);")
9317 ;; Logical inclusive OR instructions
9319 ;; %%% This used to optimize known byte-wide and operations to memory.
9320 ;; If this is considered useful, it should be done with splitters.
9322 (define_expand "iordi3"
9323 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9325 (match_operand:DI 2 "x86_64_general_operand" "")))
9326 (clobber (reg:CC FLAGS_REG))]
9328 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9330 (define_insn "*iordi_1_rex64"
9331 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9332 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9333 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9334 (clobber (reg:CC FLAGS_REG))]
9336 && ix86_binary_operator_ok (IOR, DImode, operands)"
9337 "or{q}\t{%2, %0|%0, %2}"
9338 [(set_attr "type" "alu")
9339 (set_attr "mode" "DI")])
9341 (define_insn "*iordi_2_rex64"
9342 [(set (reg FLAGS_REG)
9343 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9344 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9346 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9347 (ior:DI (match_dup 1) (match_dup 2)))]
9349 && ix86_match_ccmode (insn, CCNOmode)
9350 && ix86_binary_operator_ok (IOR, DImode, operands)"
9351 "or{q}\t{%2, %0|%0, %2}"
9352 [(set_attr "type" "alu")
9353 (set_attr "mode" "DI")])
9355 (define_insn "*iordi_3_rex64"
9356 [(set (reg FLAGS_REG)
9357 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9358 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9360 (clobber (match_scratch:DI 0 "=r"))]
9362 && ix86_match_ccmode (insn, CCNOmode)
9363 && ix86_binary_operator_ok (IOR, DImode, operands)"
9364 "or{q}\t{%2, %0|%0, %2}"
9365 [(set_attr "type" "alu")
9366 (set_attr "mode" "DI")])
9369 (define_expand "iorsi3"
9370 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9371 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9372 (match_operand:SI 2 "general_operand" "")))
9373 (clobber (reg:CC FLAGS_REG))]
9375 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9377 (define_insn "*iorsi_1"
9378 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9379 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9380 (match_operand:SI 2 "general_operand" "ri,g")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "ix86_binary_operator_ok (IOR, SImode, operands)"
9383 "or{l}\t{%2, %0|%0, %2}"
9384 [(set_attr "type" "alu")
9385 (set_attr "mode" "SI")])
9387 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9388 (define_insn "*iorsi_1_zext"
9389 [(set (match_operand:DI 0 "register_operand" "=r")
9391 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9392 (match_operand:SI 2 "general_operand" "g"))))
9393 (clobber (reg:CC FLAGS_REG))]
9394 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9395 "or{l}\t{%2, %k0|%k0, %2}"
9396 [(set_attr "type" "alu")
9397 (set_attr "mode" "SI")])
9399 (define_insn "*iorsi_1_zext_imm"
9400 [(set (match_operand:DI 0 "register_operand" "=r")
9401 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9402 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9403 (clobber (reg:CC FLAGS_REG))]
9405 "or{l}\t{%2, %k0|%k0, %2}"
9406 [(set_attr "type" "alu")
9407 (set_attr "mode" "SI")])
9409 (define_insn "*iorsi_2"
9410 [(set (reg FLAGS_REG)
9411 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9412 (match_operand:SI 2 "general_operand" "g,ri"))
9414 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9415 (ior:SI (match_dup 1) (match_dup 2)))]
9416 "ix86_match_ccmode (insn, CCNOmode)
9417 && ix86_binary_operator_ok (IOR, SImode, operands)"
9418 "or{l}\t{%2, %0|%0, %2}"
9419 [(set_attr "type" "alu")
9420 (set_attr "mode" "SI")])
9422 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9423 ;; ??? Special case for immediate operand is missing - it is tricky.
9424 (define_insn "*iorsi_2_zext"
9425 [(set (reg FLAGS_REG)
9426 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9427 (match_operand:SI 2 "general_operand" "g"))
9429 (set (match_operand:DI 0 "register_operand" "=r")
9430 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9431 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9432 && ix86_binary_operator_ok (IOR, SImode, operands)"
9433 "or{l}\t{%2, %k0|%k0, %2}"
9434 [(set_attr "type" "alu")
9435 (set_attr "mode" "SI")])
9437 (define_insn "*iorsi_2_zext_imm"
9438 [(set (reg FLAGS_REG)
9439 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9440 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9442 (set (match_operand:DI 0 "register_operand" "=r")
9443 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9444 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9445 && ix86_binary_operator_ok (IOR, SImode, operands)"
9446 "or{l}\t{%2, %k0|%k0, %2}"
9447 [(set_attr "type" "alu")
9448 (set_attr "mode" "SI")])
9450 (define_insn "*iorsi_3"
9451 [(set (reg FLAGS_REG)
9452 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9453 (match_operand:SI 2 "general_operand" "g"))
9455 (clobber (match_scratch:SI 0 "=r"))]
9456 "ix86_match_ccmode (insn, CCNOmode)
9457 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9458 "or{l}\t{%2, %0|%0, %2}"
9459 [(set_attr "type" "alu")
9460 (set_attr "mode" "SI")])
9462 (define_expand "iorhi3"
9463 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9464 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9465 (match_operand:HI 2 "general_operand" "")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "TARGET_HIMODE_MATH"
9468 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9470 (define_insn "*iorhi_1"
9471 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9472 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9473 (match_operand:HI 2 "general_operand" "g,ri")))
9474 (clobber (reg:CC FLAGS_REG))]
9475 "ix86_binary_operator_ok (IOR, HImode, operands)"
9476 "or{w}\t{%2, %0|%0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "mode" "HI")])
9480 (define_insn "*iorhi_2"
9481 [(set (reg FLAGS_REG)
9482 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9483 (match_operand:HI 2 "general_operand" "g,ri"))
9485 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9486 (ior:HI (match_dup 1) (match_dup 2)))]
9487 "ix86_match_ccmode (insn, CCNOmode)
9488 && ix86_binary_operator_ok (IOR, HImode, operands)"
9489 "or{w}\t{%2, %0|%0, %2}"
9490 [(set_attr "type" "alu")
9491 (set_attr "mode" "HI")])
9493 (define_insn "*iorhi_3"
9494 [(set (reg FLAGS_REG)
9495 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9496 (match_operand:HI 2 "general_operand" "g"))
9498 (clobber (match_scratch:HI 0 "=r"))]
9499 "ix86_match_ccmode (insn, CCNOmode)
9500 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9501 "or{w}\t{%2, %0|%0, %2}"
9502 [(set_attr "type" "alu")
9503 (set_attr "mode" "HI")])
9505 (define_expand "iorqi3"
9506 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9507 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9508 (match_operand:QI 2 "general_operand" "")))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "TARGET_QIMODE_MATH"
9511 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9513 ;; %%% Potential partial reg stall on alternative 2. What to do?
9514 (define_insn "*iorqi_1"
9515 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9516 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9517 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9518 (clobber (reg:CC FLAGS_REG))]
9519 "ix86_binary_operator_ok (IOR, QImode, operands)"
9521 or{b}\t{%2, %0|%0, %2}
9522 or{b}\t{%2, %0|%0, %2}
9523 or{l}\t{%k2, %k0|%k0, %k2}"
9524 [(set_attr "type" "alu")
9525 (set_attr "mode" "QI,QI,SI")])
9527 (define_insn "*iorqi_1_slp"
9528 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9529 (ior:QI (match_dup 0)
9530 (match_operand:QI 1 "general_operand" "qmi,qi")))
9531 (clobber (reg:CC FLAGS_REG))]
9532 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9533 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9534 "or{b}\t{%1, %0|%0, %1}"
9535 [(set_attr "type" "alu1")
9536 (set_attr "mode" "QI")])
9538 (define_insn "*iorqi_2"
9539 [(set (reg FLAGS_REG)
9540 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9541 (match_operand:QI 2 "general_operand" "qim,qi"))
9543 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9544 (ior:QI (match_dup 1) (match_dup 2)))]
9545 "ix86_match_ccmode (insn, CCNOmode)
9546 && ix86_binary_operator_ok (IOR, QImode, operands)"
9547 "or{b}\t{%2, %0|%0, %2}"
9548 [(set_attr "type" "alu")
9549 (set_attr "mode" "QI")])
9551 (define_insn "*iorqi_2_slp"
9552 [(set (reg FLAGS_REG)
9553 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9554 (match_operand:QI 1 "general_operand" "qim,qi"))
9556 (set (strict_low_part (match_dup 0))
9557 (ior:QI (match_dup 0) (match_dup 1)))]
9558 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9559 && ix86_match_ccmode (insn, CCNOmode)
9560 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9561 "or{b}\t{%1, %0|%0, %1}"
9562 [(set_attr "type" "alu1")
9563 (set_attr "mode" "QI")])
9565 (define_insn "*iorqi_3"
9566 [(set (reg FLAGS_REG)
9567 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9568 (match_operand:QI 2 "general_operand" "qim"))
9570 (clobber (match_scratch:QI 0 "=q"))]
9571 "ix86_match_ccmode (insn, CCNOmode)
9572 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9573 "or{b}\t{%2, %0|%0, %2}"
9574 [(set_attr "type" "alu")
9575 (set_attr "mode" "QI")])
9577 (define_insn "iorqi_ext_0"
9578 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9583 (match_operand 1 "ext_register_operand" "0")
9586 (match_operand 2 "const_int_operand" "n")))
9587 (clobber (reg:CC FLAGS_REG))]
9588 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9589 "or{b}\t{%2, %h0|%h0, %2}"
9590 [(set_attr "type" "alu")
9591 (set_attr "length_immediate" "1")
9592 (set_attr "mode" "QI")])
9594 (define_insn "*iorqi_ext_1"
9595 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9600 (match_operand 1 "ext_register_operand" "0")
9604 (match_operand:QI 2 "general_operand" "Qm"))))
9605 (clobber (reg:CC FLAGS_REG))]
9607 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9608 "or{b}\t{%2, %h0|%h0, %2}"
9609 [(set_attr "type" "alu")
9610 (set_attr "length_immediate" "0")
9611 (set_attr "mode" "QI")])
9613 (define_insn "*iorqi_ext_1_rex64"
9614 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9619 (match_operand 1 "ext_register_operand" "0")
9623 (match_operand 2 "ext_register_operand" "Q"))))
9624 (clobber (reg:CC FLAGS_REG))]
9626 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9627 "or{b}\t{%2, %h0|%h0, %2}"
9628 [(set_attr "type" "alu")
9629 (set_attr "length_immediate" "0")
9630 (set_attr "mode" "QI")])
9632 (define_insn "*iorqi_ext_2"
9633 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9637 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9640 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9643 (clobber (reg:CC FLAGS_REG))]
9644 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9645 "ior{b}\t{%h2, %h0|%h0, %h2}"
9646 [(set_attr "type" "alu")
9647 (set_attr "length_immediate" "0")
9648 (set_attr "mode" "QI")])
9651 [(set (match_operand 0 "register_operand" "")
9652 (ior (match_operand 1 "register_operand" "")
9653 (match_operand 2 "const_int_operand" "")))
9654 (clobber (reg:CC FLAGS_REG))]
9656 && QI_REG_P (operands[0])
9657 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9658 && !(INTVAL (operands[2]) & ~(255 << 8))
9659 && GET_MODE (operands[0]) != QImode"
9660 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9661 (ior:SI (zero_extract:SI (match_dup 1)
9662 (const_int 8) (const_int 8))
9664 (clobber (reg:CC FLAGS_REG))])]
9665 "operands[0] = gen_lowpart (SImode, operands[0]);
9666 operands[1] = gen_lowpart (SImode, operands[1]);
9667 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9669 ;; Since OR can be encoded with sign extended immediate, this is only
9670 ;; profitable when 7th bit is set.
9672 [(set (match_operand 0 "register_operand" "")
9673 (ior (match_operand 1 "general_operand" "")
9674 (match_operand 2 "const_int_operand" "")))
9675 (clobber (reg:CC FLAGS_REG))]
9677 && ANY_QI_REG_P (operands[0])
9678 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9679 && !(INTVAL (operands[2]) & ~255)
9680 && (INTVAL (operands[2]) & 128)
9681 && GET_MODE (operands[0]) != QImode"
9682 [(parallel [(set (strict_low_part (match_dup 0))
9683 (ior:QI (match_dup 1)
9685 (clobber (reg:CC FLAGS_REG))])]
9686 "operands[0] = gen_lowpart (QImode, operands[0]);
9687 operands[1] = gen_lowpart (QImode, operands[1]);
9688 operands[2] = gen_lowpart (QImode, operands[2]);")
9690 ;; Logical XOR instructions
9692 ;; %%% This used to optimize known byte-wide and operations to memory.
9693 ;; If this is considered useful, it should be done with splitters.
9695 (define_expand "xordi3"
9696 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9697 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9698 (match_operand:DI 2 "x86_64_general_operand" "")))
9699 (clobber (reg:CC FLAGS_REG))]
9701 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9703 (define_insn "*xordi_1_rex64"
9704 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9705 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9706 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9707 (clobber (reg:CC FLAGS_REG))]
9709 && ix86_binary_operator_ok (XOR, DImode, operands)"
9710 "xor{q}\t{%2, %0|%0, %2}"
9711 [(set_attr "type" "alu")
9712 (set_attr "mode" "DI")])
9714 (define_insn "*xordi_2_rex64"
9715 [(set (reg FLAGS_REG)
9716 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9717 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9719 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9720 (xor:DI (match_dup 1) (match_dup 2)))]
9722 && ix86_match_ccmode (insn, CCNOmode)
9723 && ix86_binary_operator_ok (XOR, DImode, operands)"
9724 "xor{q}\t{%2, %0|%0, %2}"
9725 [(set_attr "type" "alu")
9726 (set_attr "mode" "DI")])
9728 (define_insn "*xordi_3_rex64"
9729 [(set (reg FLAGS_REG)
9730 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9731 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9733 (clobber (match_scratch:DI 0 "=r"))]
9735 && ix86_match_ccmode (insn, CCNOmode)
9736 && ix86_binary_operator_ok (XOR, DImode, operands)"
9737 "xor{q}\t{%2, %0|%0, %2}"
9738 [(set_attr "type" "alu")
9739 (set_attr "mode" "DI")])
9741 (define_expand "xorsi3"
9742 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9743 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9744 (match_operand:SI 2 "general_operand" "")))
9745 (clobber (reg:CC FLAGS_REG))]
9747 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9749 (define_insn "*xorsi_1"
9750 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9751 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9752 (match_operand:SI 2 "general_operand" "ri,rm")))
9753 (clobber (reg:CC FLAGS_REG))]
9754 "ix86_binary_operator_ok (XOR, SImode, operands)"
9755 "xor{l}\t{%2, %0|%0, %2}"
9756 [(set_attr "type" "alu")
9757 (set_attr "mode" "SI")])
9759 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9760 ;; Add speccase for immediates
9761 (define_insn "*xorsi_1_zext"
9762 [(set (match_operand:DI 0 "register_operand" "=r")
9764 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9765 (match_operand:SI 2 "general_operand" "g"))))
9766 (clobber (reg:CC FLAGS_REG))]
9767 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9768 "xor{l}\t{%2, %k0|%k0, %2}"
9769 [(set_attr "type" "alu")
9770 (set_attr "mode" "SI")])
9772 (define_insn "*xorsi_1_zext_imm"
9773 [(set (match_operand:DI 0 "register_operand" "=r")
9774 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9775 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9778 "xor{l}\t{%2, %k0|%k0, %2}"
9779 [(set_attr "type" "alu")
9780 (set_attr "mode" "SI")])
9782 (define_insn "*xorsi_2"
9783 [(set (reg FLAGS_REG)
9784 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9785 (match_operand:SI 2 "general_operand" "g,ri"))
9787 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9788 (xor:SI (match_dup 1) (match_dup 2)))]
9789 "ix86_match_ccmode (insn, CCNOmode)
9790 && ix86_binary_operator_ok (XOR, SImode, operands)"
9791 "xor{l}\t{%2, %0|%0, %2}"
9792 [(set_attr "type" "alu")
9793 (set_attr "mode" "SI")])
9795 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9796 ;; ??? Special case for immediate operand is missing - it is tricky.
9797 (define_insn "*xorsi_2_zext"
9798 [(set (reg FLAGS_REG)
9799 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9800 (match_operand:SI 2 "general_operand" "g"))
9802 (set (match_operand:DI 0 "register_operand" "=r")
9803 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9804 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9805 && ix86_binary_operator_ok (XOR, SImode, operands)"
9806 "xor{l}\t{%2, %k0|%k0, %2}"
9807 [(set_attr "type" "alu")
9808 (set_attr "mode" "SI")])
9810 (define_insn "*xorsi_2_zext_imm"
9811 [(set (reg FLAGS_REG)
9812 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9813 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9815 (set (match_operand:DI 0 "register_operand" "=r")
9816 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9817 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9818 && ix86_binary_operator_ok (XOR, SImode, operands)"
9819 "xor{l}\t{%2, %k0|%k0, %2}"
9820 [(set_attr "type" "alu")
9821 (set_attr "mode" "SI")])
9823 (define_insn "*xorsi_3"
9824 [(set (reg FLAGS_REG)
9825 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9826 (match_operand:SI 2 "general_operand" "g"))
9828 (clobber (match_scratch:SI 0 "=r"))]
9829 "ix86_match_ccmode (insn, CCNOmode)
9830 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9831 "xor{l}\t{%2, %0|%0, %2}"
9832 [(set_attr "type" "alu")
9833 (set_attr "mode" "SI")])
9835 (define_expand "xorhi3"
9836 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9837 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9838 (match_operand:HI 2 "general_operand" "")))
9839 (clobber (reg:CC FLAGS_REG))]
9840 "TARGET_HIMODE_MATH"
9841 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9843 (define_insn "*xorhi_1"
9844 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9845 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9846 (match_operand:HI 2 "general_operand" "g,ri")))
9847 (clobber (reg:CC FLAGS_REG))]
9848 "ix86_binary_operator_ok (XOR, HImode, operands)"
9849 "xor{w}\t{%2, %0|%0, %2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "mode" "HI")])
9853 (define_insn "*xorhi_2"
9854 [(set (reg FLAGS_REG)
9855 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9856 (match_operand:HI 2 "general_operand" "g,ri"))
9858 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9859 (xor:HI (match_dup 1) (match_dup 2)))]
9860 "ix86_match_ccmode (insn, CCNOmode)
9861 && ix86_binary_operator_ok (XOR, HImode, operands)"
9862 "xor{w}\t{%2, %0|%0, %2}"
9863 [(set_attr "type" "alu")
9864 (set_attr "mode" "HI")])
9866 (define_insn "*xorhi_3"
9867 [(set (reg FLAGS_REG)
9868 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9869 (match_operand:HI 2 "general_operand" "g"))
9871 (clobber (match_scratch:HI 0 "=r"))]
9872 "ix86_match_ccmode (insn, CCNOmode)
9873 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9874 "xor{w}\t{%2, %0|%0, %2}"
9875 [(set_attr "type" "alu")
9876 (set_attr "mode" "HI")])
9878 (define_expand "xorqi3"
9879 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9880 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9881 (match_operand:QI 2 "general_operand" "")))
9882 (clobber (reg:CC FLAGS_REG))]
9883 "TARGET_QIMODE_MATH"
9884 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9886 ;; %%% Potential partial reg stall on alternative 2. What to do?
9887 (define_insn "*xorqi_1"
9888 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9889 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9890 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "ix86_binary_operator_ok (XOR, QImode, operands)"
9894 xor{b}\t{%2, %0|%0, %2}
9895 xor{b}\t{%2, %0|%0, %2}
9896 xor{l}\t{%k2, %k0|%k0, %k2}"
9897 [(set_attr "type" "alu")
9898 (set_attr "mode" "QI,QI,SI")])
9900 (define_insn "*xorqi_1_slp"
9901 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9902 (xor:QI (match_dup 0)
9903 (match_operand:QI 1 "general_operand" "qi,qmi")))
9904 (clobber (reg:CC FLAGS_REG))]
9905 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9906 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9907 "xor{b}\t{%1, %0|%0, %1}"
9908 [(set_attr "type" "alu1")
9909 (set_attr "mode" "QI")])
9911 (define_insn "xorqi_ext_0"
9912 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9917 (match_operand 1 "ext_register_operand" "0")
9920 (match_operand 2 "const_int_operand" "n")))
9921 (clobber (reg:CC FLAGS_REG))]
9922 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9923 "xor{b}\t{%2, %h0|%h0, %2}"
9924 [(set_attr "type" "alu")
9925 (set_attr "length_immediate" "1")
9926 (set_attr "mode" "QI")])
9928 (define_insn "*xorqi_ext_1"
9929 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9934 (match_operand 1 "ext_register_operand" "0")
9938 (match_operand:QI 2 "general_operand" "Qm"))))
9939 (clobber (reg:CC FLAGS_REG))]
9941 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9942 "xor{b}\t{%2, %h0|%h0, %2}"
9943 [(set_attr "type" "alu")
9944 (set_attr "length_immediate" "0")
9945 (set_attr "mode" "QI")])
9947 (define_insn "*xorqi_ext_1_rex64"
9948 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9953 (match_operand 1 "ext_register_operand" "0")
9957 (match_operand 2 "ext_register_operand" "Q"))))
9958 (clobber (reg:CC FLAGS_REG))]
9960 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9961 "xor{b}\t{%2, %h0|%h0, %2}"
9962 [(set_attr "type" "alu")
9963 (set_attr "length_immediate" "0")
9964 (set_attr "mode" "QI")])
9966 (define_insn "*xorqi_ext_2"
9967 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9971 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9974 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9977 (clobber (reg:CC FLAGS_REG))]
9978 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9979 "xor{b}\t{%h2, %h0|%h0, %h2}"
9980 [(set_attr "type" "alu")
9981 (set_attr "length_immediate" "0")
9982 (set_attr "mode" "QI")])
9984 (define_insn "*xorqi_cc_1"
9985 [(set (reg FLAGS_REG)
9987 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9988 (match_operand:QI 2 "general_operand" "qim,qi"))
9990 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9991 (xor:QI (match_dup 1) (match_dup 2)))]
9992 "ix86_match_ccmode (insn, CCNOmode)
9993 && ix86_binary_operator_ok (XOR, QImode, operands)"
9994 "xor{b}\t{%2, %0|%0, %2}"
9995 [(set_attr "type" "alu")
9996 (set_attr "mode" "QI")])
9998 (define_insn "*xorqi_2_slp"
9999 [(set (reg FLAGS_REG)
10000 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10001 (match_operand:QI 1 "general_operand" "qim,qi"))
10003 (set (strict_low_part (match_dup 0))
10004 (xor:QI (match_dup 0) (match_dup 1)))]
10005 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10006 && ix86_match_ccmode (insn, CCNOmode)
10007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10008 "xor{b}\t{%1, %0|%0, %1}"
10009 [(set_attr "type" "alu1")
10010 (set_attr "mode" "QI")])
10012 (define_insn "*xorqi_cc_2"
10013 [(set (reg FLAGS_REG)
10015 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10016 (match_operand:QI 2 "general_operand" "qim"))
10018 (clobber (match_scratch:QI 0 "=q"))]
10019 "ix86_match_ccmode (insn, CCNOmode)
10020 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10021 "xor{b}\t{%2, %0|%0, %2}"
10022 [(set_attr "type" "alu")
10023 (set_attr "mode" "QI")])
10025 (define_insn "*xorqi_cc_ext_1"
10026 [(set (reg FLAGS_REG)
10030 (match_operand 1 "ext_register_operand" "0")
10033 (match_operand:QI 2 "general_operand" "qmn"))
10035 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10039 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10041 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10042 "xor{b}\t{%2, %h0|%h0, %2}"
10043 [(set_attr "type" "alu")
10044 (set_attr "mode" "QI")])
10046 (define_insn "*xorqi_cc_ext_1_rex64"
10047 [(set (reg FLAGS_REG)
10051 (match_operand 1 "ext_register_operand" "0")
10054 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10056 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10060 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10062 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10063 "xor{b}\t{%2, %h0|%h0, %2}"
10064 [(set_attr "type" "alu")
10065 (set_attr "mode" "QI")])
10067 (define_expand "xorqi_cc_ext_1"
10069 (set (reg:CCNO FLAGS_REG)
10073 (match_operand 1 "ext_register_operand" "")
10076 (match_operand:QI 2 "general_operand" ""))
10078 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10082 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10088 [(set (match_operand 0 "register_operand" "")
10089 (xor (match_operand 1 "register_operand" "")
10090 (match_operand 2 "const_int_operand" "")))
10091 (clobber (reg:CC FLAGS_REG))]
10093 && QI_REG_P (operands[0])
10094 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10095 && !(INTVAL (operands[2]) & ~(255 << 8))
10096 && GET_MODE (operands[0]) != QImode"
10097 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10098 (xor:SI (zero_extract:SI (match_dup 1)
10099 (const_int 8) (const_int 8))
10101 (clobber (reg:CC FLAGS_REG))])]
10102 "operands[0] = gen_lowpart (SImode, operands[0]);
10103 operands[1] = gen_lowpart (SImode, operands[1]);
10104 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10106 ;; Since XOR can be encoded with sign extended immediate, this is only
10107 ;; profitable when 7th bit is set.
10109 [(set (match_operand 0 "register_operand" "")
10110 (xor (match_operand 1 "general_operand" "")
10111 (match_operand 2 "const_int_operand" "")))
10112 (clobber (reg:CC FLAGS_REG))]
10114 && ANY_QI_REG_P (operands[0])
10115 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10116 && !(INTVAL (operands[2]) & ~255)
10117 && (INTVAL (operands[2]) & 128)
10118 && GET_MODE (operands[0]) != QImode"
10119 [(parallel [(set (strict_low_part (match_dup 0))
10120 (xor:QI (match_dup 1)
10122 (clobber (reg:CC FLAGS_REG))])]
10123 "operands[0] = gen_lowpart (QImode, operands[0]);
10124 operands[1] = gen_lowpart (QImode, operands[1]);
10125 operands[2] = gen_lowpart (QImode, operands[2]);")
10127 ;; Negation instructions
10129 (define_expand "negti2"
10130 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10131 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10132 (clobber (reg:CC FLAGS_REG))])]
10134 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10136 (define_insn "*negti2_1"
10137 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10138 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10139 (clobber (reg:CC FLAGS_REG))]
10141 && ix86_unary_operator_ok (NEG, TImode, operands)"
10145 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10146 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10147 (clobber (reg:CC FLAGS_REG))]
10148 "TARGET_64BIT && reload_completed"
10150 [(set (reg:CCZ FLAGS_REG)
10151 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10152 (set (match_dup 0) (neg:DI (match_dup 1)))])
10154 [(set (match_dup 2)
10155 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10158 (clobber (reg:CC FLAGS_REG))])
10160 [(set (match_dup 2)
10161 (neg:DI (match_dup 2)))
10162 (clobber (reg:CC FLAGS_REG))])]
10163 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10165 (define_expand "negdi2"
10166 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10167 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10168 (clobber (reg:CC FLAGS_REG))])]
10170 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10172 (define_insn "*negdi2_1"
10173 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10174 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10175 (clobber (reg:CC FLAGS_REG))]
10177 && ix86_unary_operator_ok (NEG, DImode, operands)"
10181 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10182 (neg:DI (match_operand:DI 1 "general_operand" "")))
10183 (clobber (reg:CC FLAGS_REG))]
10184 "!TARGET_64BIT && reload_completed"
10186 [(set (reg:CCZ FLAGS_REG)
10187 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10188 (set (match_dup 0) (neg:SI (match_dup 1)))])
10190 [(set (match_dup 2)
10191 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10194 (clobber (reg:CC FLAGS_REG))])
10196 [(set (match_dup 2)
10197 (neg:SI (match_dup 2)))
10198 (clobber (reg:CC FLAGS_REG))])]
10199 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10201 (define_insn "*negdi2_1_rex64"
10202 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10203 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10204 (clobber (reg:CC FLAGS_REG))]
10205 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10207 [(set_attr "type" "negnot")
10208 (set_attr "mode" "DI")])
10210 ;; The problem with neg is that it does not perform (compare x 0),
10211 ;; it really performs (compare 0 x), which leaves us with the zero
10212 ;; flag being the only useful item.
10214 (define_insn "*negdi2_cmpz_rex64"
10215 [(set (reg:CCZ FLAGS_REG)
10216 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10218 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10219 (neg:DI (match_dup 1)))]
10220 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10222 [(set_attr "type" "negnot")
10223 (set_attr "mode" "DI")])
10226 (define_expand "negsi2"
10227 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10228 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10229 (clobber (reg:CC FLAGS_REG))])]
10231 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10233 (define_insn "*negsi2_1"
10234 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10235 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10236 (clobber (reg:CC FLAGS_REG))]
10237 "ix86_unary_operator_ok (NEG, SImode, operands)"
10239 [(set_attr "type" "negnot")
10240 (set_attr "mode" "SI")])
10242 ;; Combine is quite creative about this pattern.
10243 (define_insn "*negsi2_1_zext"
10244 [(set (match_operand:DI 0 "register_operand" "=r")
10245 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10248 (clobber (reg:CC FLAGS_REG))]
10249 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10251 [(set_attr "type" "negnot")
10252 (set_attr "mode" "SI")])
10254 ;; The problem with neg is that it does not perform (compare x 0),
10255 ;; it really performs (compare 0 x), which leaves us with the zero
10256 ;; flag being the only useful item.
10258 (define_insn "*negsi2_cmpz"
10259 [(set (reg:CCZ FLAGS_REG)
10260 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10262 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10263 (neg:SI (match_dup 1)))]
10264 "ix86_unary_operator_ok (NEG, SImode, operands)"
10266 [(set_attr "type" "negnot")
10267 (set_attr "mode" "SI")])
10269 (define_insn "*negsi2_cmpz_zext"
10270 [(set (reg:CCZ FLAGS_REG)
10271 (compare:CCZ (lshiftrt:DI
10273 (match_operand:DI 1 "register_operand" "0")
10277 (set (match_operand:DI 0 "register_operand" "=r")
10278 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10281 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10283 [(set_attr "type" "negnot")
10284 (set_attr "mode" "SI")])
10286 (define_expand "neghi2"
10287 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10288 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10289 (clobber (reg:CC FLAGS_REG))])]
10290 "TARGET_HIMODE_MATH"
10291 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10293 (define_insn "*neghi2_1"
10294 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10295 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "ix86_unary_operator_ok (NEG, HImode, operands)"
10299 [(set_attr "type" "negnot")
10300 (set_attr "mode" "HI")])
10302 (define_insn "*neghi2_cmpz"
10303 [(set (reg:CCZ FLAGS_REG)
10304 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10306 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10307 (neg:HI (match_dup 1)))]
10308 "ix86_unary_operator_ok (NEG, HImode, operands)"
10310 [(set_attr "type" "negnot")
10311 (set_attr "mode" "HI")])
10313 (define_expand "negqi2"
10314 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10315 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10316 (clobber (reg:CC FLAGS_REG))])]
10317 "TARGET_QIMODE_MATH"
10318 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10320 (define_insn "*negqi2_1"
10321 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10322 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10323 (clobber (reg:CC FLAGS_REG))]
10324 "ix86_unary_operator_ok (NEG, QImode, operands)"
10326 [(set_attr "type" "negnot")
10327 (set_attr "mode" "QI")])
10329 (define_insn "*negqi2_cmpz"
10330 [(set (reg:CCZ FLAGS_REG)
10331 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10333 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10334 (neg:QI (match_dup 1)))]
10335 "ix86_unary_operator_ok (NEG, QImode, operands)"
10337 [(set_attr "type" "negnot")
10338 (set_attr "mode" "QI")])
10340 ;; Changing of sign for FP values is doable using integer unit too.
10342 (define_expand "<code><mode>2"
10343 [(set (match_operand:X87MODEF 0 "register_operand" "")
10344 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10345 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10346 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10348 (define_insn "*absneg<mode>2_mixed"
10349 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10350 (match_operator:MODEF 3 "absneg_operator"
10351 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10352 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10353 (clobber (reg:CC FLAGS_REG))]
10354 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10357 (define_insn "*absneg<mode>2_sse"
10358 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10359 (match_operator:MODEF 3 "absneg_operator"
10360 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10361 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10362 (clobber (reg:CC FLAGS_REG))]
10363 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10366 (define_insn "*absneg<mode>2_i387"
10367 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10368 (match_operator:X87MODEF 3 "absneg_operator"
10369 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10370 (use (match_operand 2 "" ""))
10371 (clobber (reg:CC FLAGS_REG))]
10372 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10375 (define_expand "<code>tf2"
10376 [(set (match_operand:TF 0 "register_operand" "")
10377 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10379 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10381 (define_insn "*absnegtf2_sse"
10382 [(set (match_operand:TF 0 "register_operand" "=x,x")
10383 (match_operator:TF 3 "absneg_operator"
10384 [(match_operand:TF 1 "register_operand" "0,x")]))
10385 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10386 (clobber (reg:CC FLAGS_REG))]
10390 ;; Splitters for fp abs and neg.
10393 [(set (match_operand 0 "fp_register_operand" "")
10394 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10395 (use (match_operand 2 "" ""))
10396 (clobber (reg:CC FLAGS_REG))]
10398 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10401 [(set (match_operand 0 "register_operand" "")
10402 (match_operator 3 "absneg_operator"
10403 [(match_operand 1 "register_operand" "")]))
10404 (use (match_operand 2 "nonimmediate_operand" ""))
10405 (clobber (reg:CC FLAGS_REG))]
10406 "reload_completed && SSE_REG_P (operands[0])"
10407 [(set (match_dup 0) (match_dup 3))]
10409 enum machine_mode mode = GET_MODE (operands[0]);
10410 enum machine_mode vmode = GET_MODE (operands[2]);
10413 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10414 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10415 if (operands_match_p (operands[0], operands[2]))
10418 operands[1] = operands[2];
10421 if (GET_CODE (operands[3]) == ABS)
10422 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10424 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10429 [(set (match_operand:SF 0 "register_operand" "")
10430 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10431 (use (match_operand:V4SF 2 "" ""))
10432 (clobber (reg:CC FLAGS_REG))]
10434 [(parallel [(set (match_dup 0) (match_dup 1))
10435 (clobber (reg:CC FLAGS_REG))])]
10438 operands[0] = gen_lowpart (SImode, operands[0]);
10439 if (GET_CODE (operands[1]) == ABS)
10441 tmp = gen_int_mode (0x7fffffff, SImode);
10442 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10446 tmp = gen_int_mode (0x80000000, SImode);
10447 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10453 [(set (match_operand:DF 0 "register_operand" "")
10454 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10455 (use (match_operand 2 "" ""))
10456 (clobber (reg:CC FLAGS_REG))]
10458 [(parallel [(set (match_dup 0) (match_dup 1))
10459 (clobber (reg:CC FLAGS_REG))])]
10464 tmp = gen_lowpart (DImode, operands[0]);
10465 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10468 if (GET_CODE (operands[1]) == ABS)
10471 tmp = gen_rtx_NOT (DImode, tmp);
10475 operands[0] = gen_highpart (SImode, operands[0]);
10476 if (GET_CODE (operands[1]) == ABS)
10478 tmp = gen_int_mode (0x7fffffff, SImode);
10479 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10483 tmp = gen_int_mode (0x80000000, SImode);
10484 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10491 [(set (match_operand:XF 0 "register_operand" "")
10492 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10493 (use (match_operand 2 "" ""))
10494 (clobber (reg:CC FLAGS_REG))]
10496 [(parallel [(set (match_dup 0) (match_dup 1))
10497 (clobber (reg:CC FLAGS_REG))])]
10500 operands[0] = gen_rtx_REG (SImode,
10501 true_regnum (operands[0])
10502 + (TARGET_64BIT ? 1 : 2));
10503 if (GET_CODE (operands[1]) == ABS)
10505 tmp = GEN_INT (0x7fff);
10506 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10510 tmp = GEN_INT (0x8000);
10511 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10516 ;; Conditionalize these after reload. If they match before reload, we
10517 ;; lose the clobber and ability to use integer instructions.
10519 (define_insn "*<code><mode>2_1"
10520 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10521 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10523 && (reload_completed
10524 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10526 [(set_attr "type" "fsgn")
10527 (set_attr "mode" "<MODE>")])
10529 (define_insn "*<code>extendsfdf2"
10530 [(set (match_operand:DF 0 "register_operand" "=f")
10531 (absneg:DF (float_extend:DF
10532 (match_operand:SF 1 "register_operand" "0"))))]
10533 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10535 [(set_attr "type" "fsgn")
10536 (set_attr "mode" "DF")])
10538 (define_insn "*<code>extendsfxf2"
10539 [(set (match_operand:XF 0 "register_operand" "=f")
10540 (absneg:XF (float_extend:XF
10541 (match_operand:SF 1 "register_operand" "0"))))]
10544 [(set_attr "type" "fsgn")
10545 (set_attr "mode" "XF")])
10547 (define_insn "*<code>extenddfxf2"
10548 [(set (match_operand:XF 0 "register_operand" "=f")
10549 (absneg:XF (float_extend:XF
10550 (match_operand:DF 1 "register_operand" "0"))))]
10553 [(set_attr "type" "fsgn")
10554 (set_attr "mode" "XF")])
10556 ;; Copysign instructions
10558 (define_mode_iterator CSGNMODE [SF DF TF])
10559 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10561 (define_expand "copysign<mode>3"
10562 [(match_operand:CSGNMODE 0 "register_operand" "")
10563 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10564 (match_operand:CSGNMODE 2 "register_operand" "")]
10565 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10566 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10568 ix86_expand_copysign (operands);
10572 (define_insn_and_split "copysign<mode>3_const"
10573 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10575 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10576 (match_operand:CSGNMODE 2 "register_operand" "0")
10577 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10579 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10580 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10582 "&& reload_completed"
10585 ix86_split_copysign_const (operands);
10589 (define_insn "copysign<mode>3_var"
10590 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10592 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10593 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10594 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10595 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10597 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10598 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10599 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10603 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10605 [(match_operand:CSGNMODE 2 "register_operand" "")
10606 (match_operand:CSGNMODE 3 "register_operand" "")
10607 (match_operand:<CSGNVMODE> 4 "" "")
10608 (match_operand:<CSGNVMODE> 5 "" "")]
10610 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10611 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10612 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10613 && reload_completed"
10616 ix86_split_copysign_var (operands);
10620 ;; One complement instructions
10622 (define_expand "one_cmpldi2"
10623 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10624 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10626 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10628 (define_insn "*one_cmpldi2_1_rex64"
10629 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10630 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10631 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10633 [(set_attr "type" "negnot")
10634 (set_attr "mode" "DI")])
10636 (define_insn "*one_cmpldi2_2_rex64"
10637 [(set (reg FLAGS_REG)
10638 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10640 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10641 (not:DI (match_dup 1)))]
10642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10643 && ix86_unary_operator_ok (NOT, DImode, operands)"
10645 [(set_attr "type" "alu1")
10646 (set_attr "mode" "DI")])
10649 [(set (match_operand 0 "flags_reg_operand" "")
10650 (match_operator 2 "compare_operator"
10651 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10653 (set (match_operand:DI 1 "nonimmediate_operand" "")
10654 (not:DI (match_dup 3)))]
10655 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10656 [(parallel [(set (match_dup 0)
10658 [(xor:DI (match_dup 3) (const_int -1))
10661 (xor:DI (match_dup 3) (const_int -1)))])]
10664 (define_expand "one_cmplsi2"
10665 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10666 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10668 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10670 (define_insn "*one_cmplsi2_1"
10671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10672 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10673 "ix86_unary_operator_ok (NOT, SImode, operands)"
10675 [(set_attr "type" "negnot")
10676 (set_attr "mode" "SI")])
10678 ;; ??? Currently never generated - xor is used instead.
10679 (define_insn "*one_cmplsi2_1_zext"
10680 [(set (match_operand:DI 0 "register_operand" "=r")
10681 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10682 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10684 [(set_attr "type" "negnot")
10685 (set_attr "mode" "SI")])
10687 (define_insn "*one_cmplsi2_2"
10688 [(set (reg FLAGS_REG)
10689 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10691 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10692 (not:SI (match_dup 1)))]
10693 "ix86_match_ccmode (insn, CCNOmode)
10694 && ix86_unary_operator_ok (NOT, SImode, operands)"
10696 [(set_attr "type" "alu1")
10697 (set_attr "mode" "SI")])
10700 [(set (match_operand 0 "flags_reg_operand" "")
10701 (match_operator 2 "compare_operator"
10702 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10704 (set (match_operand:SI 1 "nonimmediate_operand" "")
10705 (not:SI (match_dup 3)))]
10706 "ix86_match_ccmode (insn, CCNOmode)"
10707 [(parallel [(set (match_dup 0)
10708 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10711 (xor:SI (match_dup 3) (const_int -1)))])]
10714 ;; ??? Currently never generated - xor is used instead.
10715 (define_insn "*one_cmplsi2_2_zext"
10716 [(set (reg FLAGS_REG)
10717 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10719 (set (match_operand:DI 0 "register_operand" "=r")
10720 (zero_extend:DI (not:SI (match_dup 1))))]
10721 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10722 && ix86_unary_operator_ok (NOT, SImode, operands)"
10724 [(set_attr "type" "alu1")
10725 (set_attr "mode" "SI")])
10728 [(set (match_operand 0 "flags_reg_operand" "")
10729 (match_operator 2 "compare_operator"
10730 [(not:SI (match_operand:SI 3 "register_operand" ""))
10732 (set (match_operand:DI 1 "register_operand" "")
10733 (zero_extend:DI (not:SI (match_dup 3))))]
10734 "ix86_match_ccmode (insn, CCNOmode)"
10735 [(parallel [(set (match_dup 0)
10736 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10739 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10742 (define_expand "one_cmplhi2"
10743 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10744 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10745 "TARGET_HIMODE_MATH"
10746 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10748 (define_insn "*one_cmplhi2_1"
10749 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10750 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10751 "ix86_unary_operator_ok (NOT, HImode, operands)"
10753 [(set_attr "type" "negnot")
10754 (set_attr "mode" "HI")])
10756 (define_insn "*one_cmplhi2_2"
10757 [(set (reg FLAGS_REG)
10758 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10760 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10761 (not:HI (match_dup 1)))]
10762 "ix86_match_ccmode (insn, CCNOmode)
10763 && ix86_unary_operator_ok (NEG, HImode, operands)"
10765 [(set_attr "type" "alu1")
10766 (set_attr "mode" "HI")])
10769 [(set (match_operand 0 "flags_reg_operand" "")
10770 (match_operator 2 "compare_operator"
10771 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10773 (set (match_operand:HI 1 "nonimmediate_operand" "")
10774 (not:HI (match_dup 3)))]
10775 "ix86_match_ccmode (insn, CCNOmode)"
10776 [(parallel [(set (match_dup 0)
10777 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10780 (xor:HI (match_dup 3) (const_int -1)))])]
10783 ;; %%% Potential partial reg stall on alternative 1. What to do?
10784 (define_expand "one_cmplqi2"
10785 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10786 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10787 "TARGET_QIMODE_MATH"
10788 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10790 (define_insn "*one_cmplqi2_1"
10791 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10792 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10793 "ix86_unary_operator_ok (NOT, QImode, operands)"
10797 [(set_attr "type" "negnot")
10798 (set_attr "mode" "QI,SI")])
10800 (define_insn "*one_cmplqi2_2"
10801 [(set (reg FLAGS_REG)
10802 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10804 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10805 (not:QI (match_dup 1)))]
10806 "ix86_match_ccmode (insn, CCNOmode)
10807 && ix86_unary_operator_ok (NOT, QImode, operands)"
10809 [(set_attr "type" "alu1")
10810 (set_attr "mode" "QI")])
10813 [(set (match_operand 0 "flags_reg_operand" "")
10814 (match_operator 2 "compare_operator"
10815 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10817 (set (match_operand:QI 1 "nonimmediate_operand" "")
10818 (not:QI (match_dup 3)))]
10819 "ix86_match_ccmode (insn, CCNOmode)"
10820 [(parallel [(set (match_dup 0)
10821 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10824 (xor:QI (match_dup 3) (const_int -1)))])]
10827 ;; Arithmetic shift instructions
10829 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10830 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10831 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10832 ;; from the assembler input.
10834 ;; This instruction shifts the target reg/mem as usual, but instead of
10835 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10836 ;; is a left shift double, bits are taken from the high order bits of
10837 ;; reg, else if the insn is a shift right double, bits are taken from the
10838 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10839 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10841 ;; Since sh[lr]d does not change the `reg' operand, that is done
10842 ;; separately, making all shifts emit pairs of shift double and normal
10843 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10844 ;; support a 63 bit shift, each shift where the count is in a reg expands
10845 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10847 ;; If the shift count is a constant, we need never emit more than one
10848 ;; shift pair, instead using moves and sign extension for counts greater
10851 (define_expand "ashlti3"
10852 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10853 (ashift:TI (match_operand:TI 1 "register_operand" "")
10854 (match_operand:QI 2 "nonmemory_operand" "")))
10855 (clobber (reg:CC FLAGS_REG))])]
10858 if (! immediate_operand (operands[2], QImode))
10860 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10863 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10867 (define_insn "ashlti3_1"
10868 [(set (match_operand:TI 0 "register_operand" "=r")
10869 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10870 (match_operand:QI 2 "register_operand" "c")))
10871 (clobber (match_scratch:DI 3 "=&r"))
10872 (clobber (reg:CC FLAGS_REG))]
10875 [(set_attr "type" "multi")])
10877 ;; This pattern must be defined before *ashlti3_2 to prevent
10878 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10880 (define_insn "sse2_ashlti3"
10881 [(set (match_operand:TI 0 "register_operand" "=x")
10882 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10883 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10886 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10887 return "pslldq\t{%2, %0|%0, %2}";
10889 [(set_attr "type" "sseishft")
10890 (set_attr "prefix_data16" "1")
10891 (set_attr "mode" "TI")])
10893 (define_insn "*ashlti3_2"
10894 [(set (match_operand:TI 0 "register_operand" "=r")
10895 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10896 (match_operand:QI 2 "immediate_operand" "O")))
10897 (clobber (reg:CC FLAGS_REG))]
10900 [(set_attr "type" "multi")])
10903 [(set (match_operand:TI 0 "register_operand" "")
10904 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10905 (match_operand:QI 2 "register_operand" "")))
10906 (clobber (match_scratch:DI 3 ""))
10907 (clobber (reg:CC FLAGS_REG))]
10908 "TARGET_64BIT && reload_completed"
10910 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10913 [(set (match_operand:TI 0 "register_operand" "")
10914 (ashift:TI (match_operand:TI 1 "register_operand" "")
10915 (match_operand:QI 2 "immediate_operand" "")))
10916 (clobber (reg:CC FLAGS_REG))]
10917 "TARGET_64BIT && reload_completed"
10919 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10921 (define_insn "x86_64_shld"
10922 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10923 (ior:DI (ashift:DI (match_dup 0)
10924 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10925 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10926 (minus:QI (const_int 64) (match_dup 2)))))
10927 (clobber (reg:CC FLAGS_REG))]
10930 shld{q}\t{%2, %1, %0|%0, %1, %2}
10931 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10932 [(set_attr "type" "ishift")
10933 (set_attr "prefix_0f" "1")
10934 (set_attr "mode" "DI")
10935 (set_attr "athlon_decode" "vector")
10936 (set_attr "amdfam10_decode" "vector")])
10938 (define_expand "x86_64_shift_adj"
10939 [(set (reg:CCZ FLAGS_REG)
10940 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10943 (set (match_operand:DI 0 "register_operand" "")
10944 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10945 (match_operand:DI 1 "register_operand" "")
10948 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10949 (match_operand:DI 3 "register_operand" "r")
10954 (define_expand "ashldi3"
10955 [(set (match_operand:DI 0 "shiftdi_operand" "")
10956 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10957 (match_operand:QI 2 "nonmemory_operand" "")))]
10959 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10961 (define_insn "*ashldi3_1_rex64"
10962 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10963 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10964 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10965 (clobber (reg:CC FLAGS_REG))]
10966 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10968 switch (get_attr_type (insn))
10971 gcc_assert (operands[2] == const1_rtx);
10972 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10973 return "add{q}\t%0, %0";
10976 gcc_assert (CONST_INT_P (operands[2]));
10977 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10978 operands[1] = gen_rtx_MULT (DImode, operands[1],
10979 GEN_INT (1 << INTVAL (operands[2])));
10980 return "lea{q}\t{%a1, %0|%0, %a1}";
10983 if (REG_P (operands[2]))
10984 return "sal{q}\t{%b2, %0|%0, %b2}";
10985 else if (operands[2] == const1_rtx
10986 && (TARGET_SHIFT1 || optimize_size))
10987 return "sal{q}\t%0";
10989 return "sal{q}\t{%2, %0|%0, %2}";
10992 [(set (attr "type")
10993 (cond [(eq_attr "alternative" "1")
10994 (const_string "lea")
10995 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10997 (match_operand 0 "register_operand" ""))
10998 (match_operand 2 "const1_operand" ""))
10999 (const_string "alu")
11001 (const_string "ishift")))
11002 (set_attr "mode" "DI")])
11004 ;; Convert lea to the lea pattern to avoid flags dependency.
11006 [(set (match_operand:DI 0 "register_operand" "")
11007 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11008 (match_operand:QI 2 "immediate_operand" "")))
11009 (clobber (reg:CC FLAGS_REG))]
11010 "TARGET_64BIT && reload_completed
11011 && true_regnum (operands[0]) != true_regnum (operands[1])"
11012 [(set (match_dup 0)
11013 (mult:DI (match_dup 1)
11015 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11017 ;; This pattern can't accept a variable shift count, since shifts by
11018 ;; zero don't affect the flags. We assume that shifts by constant
11019 ;; zero are optimized away.
11020 (define_insn "*ashldi3_cmp_rex64"
11021 [(set (reg FLAGS_REG)
11023 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11024 (match_operand:QI 2 "immediate_operand" "e"))
11026 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11027 (ashift:DI (match_dup 1) (match_dup 2)))]
11030 || !TARGET_PARTIAL_FLAG_REG_STALL
11031 || (operands[2] == const1_rtx
11033 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11034 && ix86_match_ccmode (insn, CCGOCmode)
11035 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11037 switch (get_attr_type (insn))
11040 gcc_assert (operands[2] == const1_rtx);
11041 return "add{q}\t%0, %0";
11044 if (REG_P (operands[2]))
11045 return "sal{q}\t{%b2, %0|%0, %b2}";
11046 else if (operands[2] == const1_rtx
11047 && (TARGET_SHIFT1 || optimize_size))
11048 return "sal{q}\t%0";
11050 return "sal{q}\t{%2, %0|%0, %2}";
11053 [(set (attr "type")
11054 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11056 (match_operand 0 "register_operand" ""))
11057 (match_operand 2 "const1_operand" ""))
11058 (const_string "alu")
11060 (const_string "ishift")))
11061 (set_attr "mode" "DI")])
11063 (define_insn "*ashldi3_cconly_rex64"
11064 [(set (reg FLAGS_REG)
11066 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11067 (match_operand:QI 2 "immediate_operand" "e"))
11069 (clobber (match_scratch:DI 0 "=r"))]
11072 || !TARGET_PARTIAL_FLAG_REG_STALL
11073 || (operands[2] == const1_rtx
11075 || TARGET_DOUBLE_WITH_ADD)))
11076 && ix86_match_ccmode (insn, CCGOCmode)
11077 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11079 switch (get_attr_type (insn))
11082 gcc_assert (operands[2] == const1_rtx);
11083 return "add{q}\t%0, %0";
11086 if (REG_P (operands[2]))
11087 return "sal{q}\t{%b2, %0|%0, %b2}";
11088 else if (operands[2] == const1_rtx
11089 && (TARGET_SHIFT1 || optimize_size))
11090 return "sal{q}\t%0";
11092 return "sal{q}\t{%2, %0|%0, %2}";
11095 [(set (attr "type")
11096 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11098 (match_operand 0 "register_operand" ""))
11099 (match_operand 2 "const1_operand" ""))
11100 (const_string "alu")
11102 (const_string "ishift")))
11103 (set_attr "mode" "DI")])
11105 (define_insn "*ashldi3_1"
11106 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11107 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11108 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11109 (clobber (reg:CC FLAGS_REG))]
11112 [(set_attr "type" "multi")])
11114 ;; By default we don't ask for a scratch register, because when DImode
11115 ;; values are manipulated, registers are already at a premium. But if
11116 ;; we have one handy, we won't turn it away.
11118 [(match_scratch:SI 3 "r")
11119 (parallel [(set (match_operand:DI 0 "register_operand" "")
11120 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11121 (match_operand:QI 2 "nonmemory_operand" "")))
11122 (clobber (reg:CC FLAGS_REG))])
11124 "!TARGET_64BIT && TARGET_CMOVE"
11126 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11129 [(set (match_operand:DI 0 "register_operand" "")
11130 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11131 (match_operand:QI 2 "nonmemory_operand" "")))
11132 (clobber (reg:CC FLAGS_REG))]
11133 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11134 ? epilogue_completed : reload_completed)"
11136 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11138 (define_insn "x86_shld_1"
11139 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11140 (ior:SI (ashift:SI (match_dup 0)
11141 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11142 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11143 (minus:QI (const_int 32) (match_dup 2)))))
11144 (clobber (reg:CC FLAGS_REG))]
11147 shld{l}\t{%2, %1, %0|%0, %1, %2}
11148 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11149 [(set_attr "type" "ishift")
11150 (set_attr "prefix_0f" "1")
11151 (set_attr "mode" "SI")
11152 (set_attr "pent_pair" "np")
11153 (set_attr "athlon_decode" "vector")
11154 (set_attr "amdfam10_decode" "vector")])
11156 (define_expand "x86_shift_adj_1"
11157 [(set (reg:CCZ FLAGS_REG)
11158 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11161 (set (match_operand:SI 0 "register_operand" "")
11162 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11163 (match_operand:SI 1 "register_operand" "")
11166 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11167 (match_operand:SI 3 "register_operand" "r")
11172 (define_expand "x86_shift_adj_2"
11173 [(use (match_operand:SI 0 "register_operand" ""))
11174 (use (match_operand:SI 1 "register_operand" ""))
11175 (use (match_operand:QI 2 "register_operand" ""))]
11178 rtx label = gen_label_rtx ();
11181 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11183 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11184 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11185 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11186 gen_rtx_LABEL_REF (VOIDmode, label),
11188 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11189 JUMP_LABEL (tmp) = label;
11191 emit_move_insn (operands[0], operands[1]);
11192 ix86_expand_clear (operands[1]);
11194 emit_label (label);
11195 LABEL_NUSES (label) = 1;
11200 (define_expand "ashlsi3"
11201 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11202 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11203 (match_operand:QI 2 "nonmemory_operand" "")))
11204 (clobber (reg:CC FLAGS_REG))]
11206 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11208 (define_insn "*ashlsi3_1"
11209 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11210 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11211 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11212 (clobber (reg:CC FLAGS_REG))]
11213 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11215 switch (get_attr_type (insn))
11218 gcc_assert (operands[2] == const1_rtx);
11219 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11220 return "add{l}\t%0, %0";
11226 if (REG_P (operands[2]))
11227 return "sal{l}\t{%b2, %0|%0, %b2}";
11228 else if (operands[2] == const1_rtx
11229 && (TARGET_SHIFT1 || optimize_size))
11230 return "sal{l}\t%0";
11232 return "sal{l}\t{%2, %0|%0, %2}";
11235 [(set (attr "type")
11236 (cond [(eq_attr "alternative" "1")
11237 (const_string "lea")
11238 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11240 (match_operand 0 "register_operand" ""))
11241 (match_operand 2 "const1_operand" ""))
11242 (const_string "alu")
11244 (const_string "ishift")))
11245 (set_attr "mode" "SI")])
11247 ;; Convert lea to the lea pattern to avoid flags dependency.
11249 [(set (match_operand 0 "register_operand" "")
11250 (ashift (match_operand 1 "index_register_operand" "")
11251 (match_operand:QI 2 "const_int_operand" "")))
11252 (clobber (reg:CC FLAGS_REG))]
11254 && true_regnum (operands[0]) != true_regnum (operands[1])
11255 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11259 enum machine_mode mode = GET_MODE (operands[0]);
11261 if (GET_MODE_SIZE (mode) < 4)
11262 operands[0] = gen_lowpart (SImode, operands[0]);
11264 operands[1] = gen_lowpart (Pmode, operands[1]);
11265 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11267 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11268 if (Pmode != SImode)
11269 pat = gen_rtx_SUBREG (SImode, pat, 0);
11270 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11274 ;; Rare case of shifting RSP is handled by generating move and shift
11276 [(set (match_operand 0 "register_operand" "")
11277 (ashift (match_operand 1 "register_operand" "")
11278 (match_operand:QI 2 "const_int_operand" "")))
11279 (clobber (reg:CC FLAGS_REG))]
11281 && true_regnum (operands[0]) != true_regnum (operands[1])"
11285 emit_move_insn (operands[0], operands[1]);
11286 pat = gen_rtx_SET (VOIDmode, operands[0],
11287 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11288 operands[0], operands[2]));
11289 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11290 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11294 (define_insn "*ashlsi3_1_zext"
11295 [(set (match_operand:DI 0 "register_operand" "=r,r")
11296 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11297 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11298 (clobber (reg:CC FLAGS_REG))]
11299 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11301 switch (get_attr_type (insn))
11304 gcc_assert (operands[2] == const1_rtx);
11305 return "add{l}\t%k0, %k0";
11311 if (REG_P (operands[2]))
11312 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11313 else if (operands[2] == const1_rtx
11314 && (TARGET_SHIFT1 || optimize_size))
11315 return "sal{l}\t%k0";
11317 return "sal{l}\t{%2, %k0|%k0, %2}";
11320 [(set (attr "type")
11321 (cond [(eq_attr "alternative" "1")
11322 (const_string "lea")
11323 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11325 (match_operand 2 "const1_operand" ""))
11326 (const_string "alu")
11328 (const_string "ishift")))
11329 (set_attr "mode" "SI")])
11331 ;; Convert lea to the lea pattern to avoid flags dependency.
11333 [(set (match_operand:DI 0 "register_operand" "")
11334 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11335 (match_operand:QI 2 "const_int_operand" ""))))
11336 (clobber (reg:CC FLAGS_REG))]
11337 "TARGET_64BIT && reload_completed
11338 && true_regnum (operands[0]) != true_regnum (operands[1])"
11339 [(set (match_dup 0) (zero_extend:DI
11340 (subreg:SI (mult:SI (match_dup 1)
11341 (match_dup 2)) 0)))]
11343 operands[1] = gen_lowpart (Pmode, operands[1]);
11344 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags. We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashlsi3_cmp"
11351 [(set (reg FLAGS_REG)
11353 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11354 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11356 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11357 (ashift:SI (match_dup 1) (match_dup 2)))]
11359 || !TARGET_PARTIAL_FLAG_REG_STALL
11360 || (operands[2] == const1_rtx
11362 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11363 && ix86_match_ccmode (insn, CCGOCmode)
11364 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11366 switch (get_attr_type (insn))
11369 gcc_assert (operands[2] == const1_rtx);
11370 return "add{l}\t%0, %0";
11373 if (REG_P (operands[2]))
11374 return "sal{l}\t{%b2, %0|%0, %b2}";
11375 else if (operands[2] == const1_rtx
11376 && (TARGET_SHIFT1 || optimize_size))
11377 return "sal{l}\t%0";
11379 return "sal{l}\t{%2, %0|%0, %2}";
11382 [(set (attr "type")
11383 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11385 (match_operand 0 "register_operand" ""))
11386 (match_operand 2 "const1_operand" ""))
11387 (const_string "alu")
11389 (const_string "ishift")))
11390 (set_attr "mode" "SI")])
11392 (define_insn "*ashlsi3_cconly"
11393 [(set (reg FLAGS_REG)
11395 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11396 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11398 (clobber (match_scratch:SI 0 "=r"))]
11400 || !TARGET_PARTIAL_FLAG_REG_STALL
11401 || (operands[2] == const1_rtx
11403 || TARGET_DOUBLE_WITH_ADD)))
11404 && ix86_match_ccmode (insn, CCGOCmode)
11405 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11407 switch (get_attr_type (insn))
11410 gcc_assert (operands[2] == const1_rtx);
11411 return "add{l}\t%0, %0";
11414 if (REG_P (operands[2]))
11415 return "sal{l}\t{%b2, %0|%0, %b2}";
11416 else if (operands[2] == const1_rtx
11417 && (TARGET_SHIFT1 || optimize_size))
11418 return "sal{l}\t%0";
11420 return "sal{l}\t{%2, %0|%0, %2}";
11423 [(set (attr "type")
11424 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11426 (match_operand 0 "register_operand" ""))
11427 (match_operand 2 "const1_operand" ""))
11428 (const_string "alu")
11430 (const_string "ishift")))
11431 (set_attr "mode" "SI")])
11433 (define_insn "*ashlsi3_cmp_zext"
11434 [(set (reg FLAGS_REG)
11436 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11437 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11439 (set (match_operand:DI 0 "register_operand" "=r")
11440 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11443 || !TARGET_PARTIAL_FLAG_REG_STALL
11444 || (operands[2] == const1_rtx
11446 || TARGET_DOUBLE_WITH_ADD)))
11447 && ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11450 switch (get_attr_type (insn))
11453 gcc_assert (operands[2] == const1_rtx);
11454 return "add{l}\t%k0, %k0";
11457 if (REG_P (operands[2]))
11458 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11459 else if (operands[2] == const1_rtx
11460 && (TARGET_SHIFT1 || optimize_size))
11461 return "sal{l}\t%k0";
11463 return "sal{l}\t{%2, %k0|%k0, %2}";
11466 [(set (attr "type")
11467 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11469 (match_operand 2 "const1_operand" ""))
11470 (const_string "alu")
11472 (const_string "ishift")))
11473 (set_attr "mode" "SI")])
11475 (define_expand "ashlhi3"
11476 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11477 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11478 (match_operand:QI 2 "nonmemory_operand" "")))
11479 (clobber (reg:CC FLAGS_REG))]
11480 "TARGET_HIMODE_MATH"
11481 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11483 (define_insn "*ashlhi3_1_lea"
11484 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11485 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11486 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11487 (clobber (reg:CC FLAGS_REG))]
11488 "!TARGET_PARTIAL_REG_STALL
11489 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11491 switch (get_attr_type (insn))
11496 gcc_assert (operands[2] == const1_rtx);
11497 return "add{w}\t%0, %0";
11500 if (REG_P (operands[2]))
11501 return "sal{w}\t{%b2, %0|%0, %b2}";
11502 else if (operands[2] == const1_rtx
11503 && (TARGET_SHIFT1 || optimize_size))
11504 return "sal{w}\t%0";
11506 return "sal{w}\t{%2, %0|%0, %2}";
11509 [(set (attr "type")
11510 (cond [(eq_attr "alternative" "1")
11511 (const_string "lea")
11512 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11514 (match_operand 0 "register_operand" ""))
11515 (match_operand 2 "const1_operand" ""))
11516 (const_string "alu")
11518 (const_string "ishift")))
11519 (set_attr "mode" "HI,SI")])
11521 (define_insn "*ashlhi3_1"
11522 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11523 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11524 (match_operand:QI 2 "nonmemory_operand" "cI")))
11525 (clobber (reg:CC FLAGS_REG))]
11526 "TARGET_PARTIAL_REG_STALL
11527 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11529 switch (get_attr_type (insn))
11532 gcc_assert (operands[2] == const1_rtx);
11533 return "add{w}\t%0, %0";
11536 if (REG_P (operands[2]))
11537 return "sal{w}\t{%b2, %0|%0, %b2}";
11538 else if (operands[2] == const1_rtx
11539 && (TARGET_SHIFT1 || optimize_size))
11540 return "sal{w}\t%0";
11542 return "sal{w}\t{%2, %0|%0, %2}";
11545 [(set (attr "type")
11546 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11548 (match_operand 0 "register_operand" ""))
11549 (match_operand 2 "const1_operand" ""))
11550 (const_string "alu")
11552 (const_string "ishift")))
11553 (set_attr "mode" "HI")])
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags. We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*ashlhi3_cmp"
11559 [(set (reg FLAGS_REG)
11561 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11562 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11564 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11565 (ashift:HI (match_dup 1) (match_dup 2)))]
11567 || !TARGET_PARTIAL_FLAG_REG_STALL
11568 || (operands[2] == const1_rtx
11570 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11571 && ix86_match_ccmode (insn, CCGOCmode)
11572 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11574 switch (get_attr_type (insn))
11577 gcc_assert (operands[2] == const1_rtx);
11578 return "add{w}\t%0, %0";
11581 if (REG_P (operands[2]))
11582 return "sal{w}\t{%b2, %0|%0, %b2}";
11583 else if (operands[2] == const1_rtx
11584 && (TARGET_SHIFT1 || optimize_size))
11585 return "sal{w}\t%0";
11587 return "sal{w}\t{%2, %0|%0, %2}";
11590 [(set (attr "type")
11591 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11593 (match_operand 0 "register_operand" ""))
11594 (match_operand 2 "const1_operand" ""))
11595 (const_string "alu")
11597 (const_string "ishift")))
11598 (set_attr "mode" "HI")])
11600 (define_insn "*ashlhi3_cconly"
11601 [(set (reg FLAGS_REG)
11603 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11606 (clobber (match_scratch:HI 0 "=r"))]
11608 || !TARGET_PARTIAL_FLAG_REG_STALL
11609 || (operands[2] == const1_rtx
11611 || TARGET_DOUBLE_WITH_ADD)))
11612 && ix86_match_ccmode (insn, CCGOCmode)
11613 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11615 switch (get_attr_type (insn))
11618 gcc_assert (operands[2] == const1_rtx);
11619 return "add{w}\t%0, %0";
11622 if (REG_P (operands[2]))
11623 return "sal{w}\t{%b2, %0|%0, %b2}";
11624 else if (operands[2] == const1_rtx
11625 && (TARGET_SHIFT1 || optimize_size))
11626 return "sal{w}\t%0";
11628 return "sal{w}\t{%2, %0|%0, %2}";
11631 [(set (attr "type")
11632 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11634 (match_operand 0 "register_operand" ""))
11635 (match_operand 2 "const1_operand" ""))
11636 (const_string "alu")
11638 (const_string "ishift")))
11639 (set_attr "mode" "HI")])
11641 (define_expand "ashlqi3"
11642 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11643 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11644 (match_operand:QI 2 "nonmemory_operand" "")))
11645 (clobber (reg:CC FLAGS_REG))]
11646 "TARGET_QIMODE_MATH"
11647 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11649 ;; %%% Potential partial reg stall on alternative 2. What to do?
11651 (define_insn "*ashlqi3_1_lea"
11652 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11653 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11654 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11655 (clobber (reg:CC FLAGS_REG))]
11656 "!TARGET_PARTIAL_REG_STALL
11657 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11659 switch (get_attr_type (insn))
11664 gcc_assert (operands[2] == const1_rtx);
11665 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11666 return "add{l}\t%k0, %k0";
11668 return "add{b}\t%0, %0";
11671 if (REG_P (operands[2]))
11673 if (get_attr_mode (insn) == MODE_SI)
11674 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11676 return "sal{b}\t{%b2, %0|%0, %b2}";
11678 else if (operands[2] == const1_rtx
11679 && (TARGET_SHIFT1 || optimize_size))
11681 if (get_attr_mode (insn) == MODE_SI)
11682 return "sal{l}\t%0";
11684 return "sal{b}\t%0";
11688 if (get_attr_mode (insn) == MODE_SI)
11689 return "sal{l}\t{%2, %k0|%k0, %2}";
11691 return "sal{b}\t{%2, %0|%0, %2}";
11695 [(set (attr "type")
11696 (cond [(eq_attr "alternative" "2")
11697 (const_string "lea")
11698 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700 (match_operand 0 "register_operand" ""))
11701 (match_operand 2 "const1_operand" ""))
11702 (const_string "alu")
11704 (const_string "ishift")))
11705 (set_attr "mode" "QI,SI,SI")])
11707 (define_insn "*ashlqi3_1"
11708 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11709 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11710 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11711 (clobber (reg:CC FLAGS_REG))]
11712 "TARGET_PARTIAL_REG_STALL
11713 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11715 switch (get_attr_type (insn))
11718 gcc_assert (operands[2] == const1_rtx);
11719 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11720 return "add{l}\t%k0, %k0";
11722 return "add{b}\t%0, %0";
11725 if (REG_P (operands[2]))
11727 if (get_attr_mode (insn) == MODE_SI)
11728 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11730 return "sal{b}\t{%b2, %0|%0, %b2}";
11732 else if (operands[2] == const1_rtx
11733 && (TARGET_SHIFT1 || optimize_size))
11735 if (get_attr_mode (insn) == MODE_SI)
11736 return "sal{l}\t%0";
11738 return "sal{b}\t%0";
11742 if (get_attr_mode (insn) == MODE_SI)
11743 return "sal{l}\t{%2, %k0|%k0, %2}";
11745 return "sal{b}\t{%2, %0|%0, %2}";
11749 [(set (attr "type")
11750 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11752 (match_operand 0 "register_operand" ""))
11753 (match_operand 2 "const1_operand" ""))
11754 (const_string "alu")
11756 (const_string "ishift")))
11757 (set_attr "mode" "QI,SI")])
11759 ;; This pattern can't accept a variable shift count, since shifts by
11760 ;; zero don't affect the flags. We assume that shifts by constant
11761 ;; zero are optimized away.
11762 (define_insn "*ashlqi3_cmp"
11763 [(set (reg FLAGS_REG)
11765 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11768 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11769 (ashift:QI (match_dup 1) (match_dup 2)))]
11771 || !TARGET_PARTIAL_FLAG_REG_STALL
11772 || (operands[2] == const1_rtx
11774 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11775 && ix86_match_ccmode (insn, CCGOCmode)
11776 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11778 switch (get_attr_type (insn))
11781 gcc_assert (operands[2] == const1_rtx);
11782 return "add{b}\t%0, %0";
11785 if (REG_P (operands[2]))
11786 return "sal{b}\t{%b2, %0|%0, %b2}";
11787 else if (operands[2] == const1_rtx
11788 && (TARGET_SHIFT1 || optimize_size))
11789 return "sal{b}\t%0";
11791 return "sal{b}\t{%2, %0|%0, %2}";
11794 [(set (attr "type")
11795 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11797 (match_operand 0 "register_operand" ""))
11798 (match_operand 2 "const1_operand" ""))
11799 (const_string "alu")
11801 (const_string "ishift")))
11802 (set_attr "mode" "QI")])
11804 (define_insn "*ashlqi3_cconly"
11805 [(set (reg FLAGS_REG)
11807 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11808 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11810 (clobber (match_scratch:QI 0 "=q"))]
11812 || !TARGET_PARTIAL_FLAG_REG_STALL
11813 || (operands[2] == const1_rtx
11815 || TARGET_DOUBLE_WITH_ADD)))
11816 && ix86_match_ccmode (insn, CCGOCmode)
11817 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11819 switch (get_attr_type (insn))
11822 gcc_assert (operands[2] == const1_rtx);
11823 return "add{b}\t%0, %0";
11826 if (REG_P (operands[2]))
11827 return "sal{b}\t{%b2, %0|%0, %b2}";
11828 else if (operands[2] == const1_rtx
11829 && (TARGET_SHIFT1 || optimize_size))
11830 return "sal{b}\t%0";
11832 return "sal{b}\t{%2, %0|%0, %2}";
11835 [(set (attr "type")
11836 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11838 (match_operand 0 "register_operand" ""))
11839 (match_operand 2 "const1_operand" ""))
11840 (const_string "alu")
11842 (const_string "ishift")))
11843 (set_attr "mode" "QI")])
11845 ;; See comment above `ashldi3' about how this works.
11847 (define_expand "ashrti3"
11848 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11849 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11850 (match_operand:QI 2 "nonmemory_operand" "")))
11851 (clobber (reg:CC FLAGS_REG))])]
11854 if (! immediate_operand (operands[2], QImode))
11856 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11859 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11863 (define_insn "ashrti3_1"
11864 [(set (match_operand:TI 0 "register_operand" "=r")
11865 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11866 (match_operand:QI 2 "register_operand" "c")))
11867 (clobber (match_scratch:DI 3 "=&r"))
11868 (clobber (reg:CC FLAGS_REG))]
11871 [(set_attr "type" "multi")])
11873 (define_insn "*ashrti3_2"
11874 [(set (match_operand:TI 0 "register_operand" "=r")
11875 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11876 (match_operand:QI 2 "immediate_operand" "O")))
11877 (clobber (reg:CC FLAGS_REG))]
11880 [(set_attr "type" "multi")])
11883 [(set (match_operand:TI 0 "register_operand" "")
11884 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11885 (match_operand:QI 2 "register_operand" "")))
11886 (clobber (match_scratch:DI 3 ""))
11887 (clobber (reg:CC FLAGS_REG))]
11888 "TARGET_64BIT && reload_completed"
11890 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11893 [(set (match_operand:TI 0 "register_operand" "")
11894 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11895 (match_operand:QI 2 "immediate_operand" "")))
11896 (clobber (reg:CC FLAGS_REG))]
11897 "TARGET_64BIT && reload_completed"
11899 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11901 (define_insn "x86_64_shrd"
11902 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11903 (ior:DI (ashiftrt:DI (match_dup 0)
11904 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11905 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11906 (minus:QI (const_int 64) (match_dup 2)))))
11907 (clobber (reg:CC FLAGS_REG))]
11910 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11911 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11912 [(set_attr "type" "ishift")
11913 (set_attr "prefix_0f" "1")
11914 (set_attr "mode" "DI")
11915 (set_attr "athlon_decode" "vector")
11916 (set_attr "amdfam10_decode" "vector")])
11918 (define_expand "ashrdi3"
11919 [(set (match_operand:DI 0 "shiftdi_operand" "")
11920 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11921 (match_operand:QI 2 "nonmemory_operand" "")))]
11923 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11925 (define_insn "*ashrdi3_63_rex64"
11926 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11927 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11928 (match_operand:DI 2 "const_int_operand" "i,i")))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "TARGET_64BIT && INTVAL (operands[2]) == 63
11931 && (TARGET_USE_CLTD || optimize_size)
11932 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11935 sar{q}\t{%2, %0|%0, %2}"
11936 [(set_attr "type" "imovx,ishift")
11937 (set_attr "prefix_0f" "0,*")
11938 (set_attr "length_immediate" "0,*")
11939 (set_attr "modrm" "0,1")
11940 (set_attr "mode" "DI")])
11942 (define_insn "*ashrdi3_1_one_bit_rex64"
11943 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11944 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11945 (match_operand:QI 2 "const1_operand" "")))
11946 (clobber (reg:CC FLAGS_REG))]
11948 && (TARGET_SHIFT1 || optimize_size)
11949 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11951 [(set_attr "type" "ishift")
11952 (set (attr "length")
11953 (if_then_else (match_operand:DI 0 "register_operand" "")
11955 (const_string "*")))])
11957 (define_insn "*ashrdi3_1_rex64"
11958 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11959 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11960 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11961 (clobber (reg:CC FLAGS_REG))]
11962 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11964 sar{q}\t{%2, %0|%0, %2}
11965 sar{q}\t{%b2, %0|%0, %b2}"
11966 [(set_attr "type" "ishift")
11967 (set_attr "mode" "DI")])
11969 ;; This pattern can't accept a variable shift count, since shifts by
11970 ;; zero don't affect the flags. We assume that shifts by constant
11971 ;; zero are optimized away.
11972 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11973 [(set (reg FLAGS_REG)
11975 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11976 (match_operand:QI 2 "const1_operand" ""))
11978 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11979 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11981 && (TARGET_SHIFT1 || optimize_size)
11982 && ix86_match_ccmode (insn, CCGOCmode)
11983 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11985 [(set_attr "type" "ishift")
11986 (set (attr "length")
11987 (if_then_else (match_operand:DI 0 "register_operand" "")
11989 (const_string "*")))])
11991 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11992 [(set (reg FLAGS_REG)
11994 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11995 (match_operand:QI 2 "const1_operand" ""))
11997 (clobber (match_scratch:DI 0 "=r"))]
11999 && (TARGET_SHIFT1 || optimize_size)
12000 && ix86_match_ccmode (insn, CCGOCmode)
12001 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12003 [(set_attr "type" "ishift")
12004 (set_attr "length" "2")])
12006 ;; This pattern can't accept a variable shift count, since shifts by
12007 ;; zero don't affect the flags. We assume that shifts by constant
12008 ;; zero are optimized away.
12009 (define_insn "*ashrdi3_cmp_rex64"
12010 [(set (reg FLAGS_REG)
12012 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12013 (match_operand:QI 2 "const_int_operand" "n"))
12015 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12016 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12018 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12019 && ix86_match_ccmode (insn, CCGOCmode)
12020 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12021 "sar{q}\t{%2, %0|%0, %2}"
12022 [(set_attr "type" "ishift")
12023 (set_attr "mode" "DI")])
12025 (define_insn "*ashrdi3_cconly_rex64"
12026 [(set (reg FLAGS_REG)
12028 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12029 (match_operand:QI 2 "const_int_operand" "n"))
12031 (clobber (match_scratch:DI 0 "=r"))]
12033 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12034 && ix86_match_ccmode (insn, CCGOCmode)
12035 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12036 "sar{q}\t{%2, %0|%0, %2}"
12037 [(set_attr "type" "ishift")
12038 (set_attr "mode" "DI")])
12040 (define_insn "*ashrdi3_1"
12041 [(set (match_operand:DI 0 "register_operand" "=r")
12042 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12043 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12044 (clobber (reg:CC FLAGS_REG))]
12047 [(set_attr "type" "multi")])
12049 ;; By default we don't ask for a scratch register, because when DImode
12050 ;; values are manipulated, registers are already at a premium. But if
12051 ;; we have one handy, we won't turn it away.
12053 [(match_scratch:SI 3 "r")
12054 (parallel [(set (match_operand:DI 0 "register_operand" "")
12055 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12056 (match_operand:QI 2 "nonmemory_operand" "")))
12057 (clobber (reg:CC FLAGS_REG))])
12059 "!TARGET_64BIT && TARGET_CMOVE"
12061 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12064 [(set (match_operand:DI 0 "register_operand" "")
12065 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12066 (match_operand:QI 2 "nonmemory_operand" "")))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12069 ? epilogue_completed : reload_completed)"
12071 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12073 (define_insn "x86_shrd_1"
12074 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12075 (ior:SI (ashiftrt:SI (match_dup 0)
12076 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12077 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12078 (minus:QI (const_int 32) (match_dup 2)))))
12079 (clobber (reg:CC FLAGS_REG))]
12082 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12083 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12084 [(set_attr "type" "ishift")
12085 (set_attr "prefix_0f" "1")
12086 (set_attr "pent_pair" "np")
12087 (set_attr "mode" "SI")])
12089 (define_expand "x86_shift_adj_3"
12090 [(use (match_operand:SI 0 "register_operand" ""))
12091 (use (match_operand:SI 1 "register_operand" ""))
12092 (use (match_operand:QI 2 "register_operand" ""))]
12095 rtx label = gen_label_rtx ();
12098 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12100 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12101 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12102 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12103 gen_rtx_LABEL_REF (VOIDmode, label),
12105 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12106 JUMP_LABEL (tmp) = label;
12108 emit_move_insn (operands[0], operands[1]);
12109 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12111 emit_label (label);
12112 LABEL_NUSES (label) = 1;
12117 (define_insn "ashrsi3_31"
12118 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12119 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12120 (match_operand:SI 2 "const_int_operand" "i,i")))
12121 (clobber (reg:CC FLAGS_REG))]
12122 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12123 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12126 sar{l}\t{%2, %0|%0, %2}"
12127 [(set_attr "type" "imovx,ishift")
12128 (set_attr "prefix_0f" "0,*")
12129 (set_attr "length_immediate" "0,*")
12130 (set_attr "modrm" "0,1")
12131 (set_attr "mode" "SI")])
12133 (define_insn "*ashrsi3_31_zext"
12134 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12135 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12136 (match_operand:SI 2 "const_int_operand" "i,i"))))
12137 (clobber (reg:CC FLAGS_REG))]
12138 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12139 && INTVAL (operands[2]) == 31
12140 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12143 sar{l}\t{%2, %k0|%k0, %2}"
12144 [(set_attr "type" "imovx,ishift")
12145 (set_attr "prefix_0f" "0,*")
12146 (set_attr "length_immediate" "0,*")
12147 (set_attr "modrm" "0,1")
12148 (set_attr "mode" "SI")])
12150 (define_expand "ashrsi3"
12151 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12152 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12153 (match_operand:QI 2 "nonmemory_operand" "")))
12154 (clobber (reg:CC FLAGS_REG))]
12156 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12158 (define_insn "*ashrsi3_1_one_bit"
12159 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12160 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12161 (match_operand:QI 2 "const1_operand" "")))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "(TARGET_SHIFT1 || optimize_size)
12164 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12166 [(set_attr "type" "ishift")
12167 (set (attr "length")
12168 (if_then_else (match_operand:SI 0 "register_operand" "")
12170 (const_string "*")))])
12172 (define_insn "*ashrsi3_1_one_bit_zext"
12173 [(set (match_operand:DI 0 "register_operand" "=r")
12174 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12175 (match_operand:QI 2 "const1_operand" ""))))
12176 (clobber (reg:CC FLAGS_REG))]
12178 && (TARGET_SHIFT1 || optimize_size)
12179 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12181 [(set_attr "type" "ishift")
12182 (set_attr "length" "2")])
12184 (define_insn "*ashrsi3_1"
12185 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12186 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12187 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188 (clobber (reg:CC FLAGS_REG))]
12189 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12191 sar{l}\t{%2, %0|%0, %2}
12192 sar{l}\t{%b2, %0|%0, %b2}"
12193 [(set_attr "type" "ishift")
12194 (set_attr "mode" "SI")])
12196 (define_insn "*ashrsi3_1_zext"
12197 [(set (match_operand:DI 0 "register_operand" "=r,r")
12198 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12199 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12203 sar{l}\t{%2, %k0|%k0, %2}
12204 sar{l}\t{%b2, %k0|%k0, %b2}"
12205 [(set_attr "type" "ishift")
12206 (set_attr "mode" "SI")])
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags. We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*ashrsi3_one_bit_cmp"
12212 [(set (reg FLAGS_REG)
12214 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12215 (match_operand:QI 2 "const1_operand" ""))
12217 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12218 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12219 "(TARGET_SHIFT1 || optimize_size)
12220 && ix86_match_ccmode (insn, CCGOCmode)
12221 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12223 [(set_attr "type" "ishift")
12224 (set (attr "length")
12225 (if_then_else (match_operand:SI 0 "register_operand" "")
12227 (const_string "*")))])
12229 (define_insn "*ashrsi3_one_bit_cconly"
12230 [(set (reg FLAGS_REG)
12232 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12233 (match_operand:QI 2 "const1_operand" ""))
12235 (clobber (match_scratch:SI 0 "=r"))]
12236 "(TARGET_SHIFT1 || optimize_size)
12237 && ix86_match_ccmode (insn, CCGOCmode)
12238 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12240 [(set_attr "type" "ishift")
12241 (set_attr "length" "2")])
12243 (define_insn "*ashrsi3_one_bit_cmp_zext"
12244 [(set (reg FLAGS_REG)
12246 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12247 (match_operand:QI 2 "const1_operand" ""))
12249 (set (match_operand:DI 0 "register_operand" "=r")
12250 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12252 && (TARGET_SHIFT1 || optimize_size)
12253 && ix86_match_ccmode (insn, CCmode)
12254 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12256 [(set_attr "type" "ishift")
12257 (set_attr "length" "2")])
12259 ;; This pattern can't accept a variable shift count, since shifts by
12260 ;; zero don't affect the flags. We assume that shifts by constant
12261 ;; zero are optimized away.
12262 (define_insn "*ashrsi3_cmp"
12263 [(set (reg FLAGS_REG)
12265 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12266 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12269 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12270 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12271 && ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12273 "sar{l}\t{%2, %0|%0, %2}"
12274 [(set_attr "type" "ishift")
12275 (set_attr "mode" "SI")])
12277 (define_insn "*ashrsi3_cconly"
12278 [(set (reg FLAGS_REG)
12280 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12281 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12283 (clobber (match_scratch:SI 0 "=r"))]
12284 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12285 && ix86_match_ccmode (insn, CCGOCmode)
12286 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12287 "sar{l}\t{%2, %0|%0, %2}"
12288 [(set_attr "type" "ishift")
12289 (set_attr "mode" "SI")])
12291 (define_insn "*ashrsi3_cmp_zext"
12292 [(set (reg FLAGS_REG)
12294 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12295 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12297 (set (match_operand:DI 0 "register_operand" "=r")
12298 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12300 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12301 && ix86_match_ccmode (insn, CCGOCmode)
12302 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12303 "sar{l}\t{%2, %k0|%k0, %2}"
12304 [(set_attr "type" "ishift")
12305 (set_attr "mode" "SI")])
12307 (define_expand "ashrhi3"
12308 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12309 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12310 (match_operand:QI 2 "nonmemory_operand" "")))
12311 (clobber (reg:CC FLAGS_REG))]
12312 "TARGET_HIMODE_MATH"
12313 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12315 (define_insn "*ashrhi3_1_one_bit"
12316 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12317 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12318 (match_operand:QI 2 "const1_operand" "")))
12319 (clobber (reg:CC FLAGS_REG))]
12320 "(TARGET_SHIFT1 || optimize_size)
12321 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12323 [(set_attr "type" "ishift")
12324 (set (attr "length")
12325 (if_then_else (match_operand 0 "register_operand" "")
12327 (const_string "*")))])
12329 (define_insn "*ashrhi3_1"
12330 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12331 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12332 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12333 (clobber (reg:CC FLAGS_REG))]
12334 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12336 sar{w}\t{%2, %0|%0, %2}
12337 sar{w}\t{%b2, %0|%0, %b2}"
12338 [(set_attr "type" "ishift")
12339 (set_attr "mode" "HI")])
12341 ;; This pattern can't accept a variable shift count, since shifts by
12342 ;; zero don't affect the flags. We assume that shifts by constant
12343 ;; zero are optimized away.
12344 (define_insn "*ashrhi3_one_bit_cmp"
12345 [(set (reg FLAGS_REG)
12347 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12348 (match_operand:QI 2 "const1_operand" ""))
12350 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12351 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12352 "(TARGET_SHIFT1 || optimize_size)
12353 && ix86_match_ccmode (insn, CCGOCmode)
12354 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12356 [(set_attr "type" "ishift")
12357 (set (attr "length")
12358 (if_then_else (match_operand 0 "register_operand" "")
12360 (const_string "*")))])
12362 (define_insn "*ashrhi3_one_bit_cconly"
12363 [(set (reg FLAGS_REG)
12365 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12366 (match_operand:QI 2 "const1_operand" ""))
12368 (clobber (match_scratch:HI 0 "=r"))]
12369 "(TARGET_SHIFT1 || optimize_size)
12370 && ix86_match_ccmode (insn, CCGOCmode)
12371 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12373 [(set_attr "type" "ishift")
12374 (set_attr "length" "2")])
12376 ;; This pattern can't accept a variable shift count, since shifts by
12377 ;; zero don't affect the flags. We assume that shifts by constant
12378 ;; zero are optimized away.
12379 (define_insn "*ashrhi3_cmp"
12380 [(set (reg FLAGS_REG)
12382 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12383 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12385 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12386 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12387 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12388 && ix86_match_ccmode (insn, CCGOCmode)
12389 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12390 "sar{w}\t{%2, %0|%0, %2}"
12391 [(set_attr "type" "ishift")
12392 (set_attr "mode" "HI")])
12394 (define_insn "*ashrhi3_cconly"
12395 [(set (reg FLAGS_REG)
12397 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12400 (clobber (match_scratch:HI 0 "=r"))]
12401 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12402 && ix86_match_ccmode (insn, CCGOCmode)
12403 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12404 "sar{w}\t{%2, %0|%0, %2}"
12405 [(set_attr "type" "ishift")
12406 (set_attr "mode" "HI")])
12408 (define_expand "ashrqi3"
12409 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12410 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12411 (match_operand:QI 2 "nonmemory_operand" "")))
12412 (clobber (reg:CC FLAGS_REG))]
12413 "TARGET_QIMODE_MATH"
12414 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12416 (define_insn "*ashrqi3_1_one_bit"
12417 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12418 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12419 (match_operand:QI 2 "const1_operand" "")))
12420 (clobber (reg:CC FLAGS_REG))]
12421 "(TARGET_SHIFT1 || optimize_size)
12422 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12424 [(set_attr "type" "ishift")
12425 (set (attr "length")
12426 (if_then_else (match_operand 0 "register_operand" "")
12428 (const_string "*")))])
12430 (define_insn "*ashrqi3_1_one_bit_slp"
12431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12432 (ashiftrt:QI (match_dup 0)
12433 (match_operand:QI 1 "const1_operand" "")))
12434 (clobber (reg:CC FLAGS_REG))]
12435 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12436 && (TARGET_SHIFT1 || optimize_size)
12437 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12439 [(set_attr "type" "ishift1")
12440 (set (attr "length")
12441 (if_then_else (match_operand 0 "register_operand" "")
12443 (const_string "*")))])
12445 (define_insn "*ashrqi3_1"
12446 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12447 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12448 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12449 (clobber (reg:CC FLAGS_REG))]
12450 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12452 sar{b}\t{%2, %0|%0, %2}
12453 sar{b}\t{%b2, %0|%0, %b2}"
12454 [(set_attr "type" "ishift")
12455 (set_attr "mode" "QI")])
12457 (define_insn "*ashrqi3_1_slp"
12458 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12459 (ashiftrt:QI (match_dup 0)
12460 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12461 (clobber (reg:CC FLAGS_REG))]
12462 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12463 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12465 sar{b}\t{%1, %0|%0, %1}
12466 sar{b}\t{%b1, %0|%0, %b1}"
12467 [(set_attr "type" "ishift1")
12468 (set_attr "mode" "QI")])
12470 ;; This pattern can't accept a variable shift count, since shifts by
12471 ;; zero don't affect the flags. We assume that shifts by constant
12472 ;; zero are optimized away.
12473 (define_insn "*ashrqi3_one_bit_cmp"
12474 [(set (reg FLAGS_REG)
12476 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12477 (match_operand:QI 2 "const1_operand" "I"))
12479 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12480 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12481 "(TARGET_SHIFT1 || optimize_size)
12482 && ix86_match_ccmode (insn, CCGOCmode)
12483 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12485 [(set_attr "type" "ishift")
12486 (set (attr "length")
12487 (if_then_else (match_operand 0 "register_operand" "")
12489 (const_string "*")))])
12491 (define_insn "*ashrqi3_one_bit_cconly"
12492 [(set (reg FLAGS_REG)
12494 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12495 (match_operand:QI 2 "const1_operand" "I"))
12497 (clobber (match_scratch:QI 0 "=q"))]
12498 "(TARGET_SHIFT1 || optimize_size)
12499 && ix86_match_ccmode (insn, CCGOCmode)
12500 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12502 [(set_attr "type" "ishift")
12503 (set_attr "length" "2")])
12505 ;; This pattern can't accept a variable shift count, since shifts by
12506 ;; zero don't affect the flags. We assume that shifts by constant
12507 ;; zero are optimized away.
12508 (define_insn "*ashrqi3_cmp"
12509 [(set (reg FLAGS_REG)
12511 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12512 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12514 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12515 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12516 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12517 && ix86_match_ccmode (insn, CCGOCmode)
12518 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12519 "sar{b}\t{%2, %0|%0, %2}"
12520 [(set_attr "type" "ishift")
12521 (set_attr "mode" "QI")])
12523 (define_insn "*ashrqi3_cconly"
12524 [(set (reg FLAGS_REG)
12526 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12527 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12529 (clobber (match_scratch:QI 0 "=q"))]
12530 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12531 && ix86_match_ccmode (insn, CCGOCmode)
12532 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12533 "sar{b}\t{%2, %0|%0, %2}"
12534 [(set_attr "type" "ishift")
12535 (set_attr "mode" "QI")])
12538 ;; Logical shift instructions
12540 ;; See comment above `ashldi3' about how this works.
12542 (define_expand "lshrti3"
12543 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12544 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12545 (match_operand:QI 2 "nonmemory_operand" "")))
12546 (clobber (reg:CC FLAGS_REG))])]
12549 if (! immediate_operand (operands[2], QImode))
12551 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12554 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12558 (define_insn "lshrti3_1"
12559 [(set (match_operand:TI 0 "register_operand" "=r")
12560 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12561 (match_operand:QI 2 "register_operand" "c")))
12562 (clobber (match_scratch:DI 3 "=&r"))
12563 (clobber (reg:CC FLAGS_REG))]
12566 [(set_attr "type" "multi")])
12568 ;; This pattern must be defined before *lshrti3_2 to prevent
12569 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12571 (define_insn "sse2_lshrti3"
12572 [(set (match_operand:TI 0 "register_operand" "=x")
12573 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12574 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12577 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12578 return "psrldq\t{%2, %0|%0, %2}";
12580 [(set_attr "type" "sseishft")
12581 (set_attr "prefix_data16" "1")
12582 (set_attr "mode" "TI")])
12584 (define_insn "*lshrti3_2"
12585 [(set (match_operand:TI 0 "register_operand" "=r")
12586 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12587 (match_operand:QI 2 "immediate_operand" "O")))
12588 (clobber (reg:CC FLAGS_REG))]
12591 [(set_attr "type" "multi")])
12594 [(set (match_operand:TI 0 "register_operand" "")
12595 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12596 (match_operand:QI 2 "register_operand" "")))
12597 (clobber (match_scratch:DI 3 ""))
12598 (clobber (reg:CC FLAGS_REG))]
12599 "TARGET_64BIT && reload_completed"
12601 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12604 [(set (match_operand:TI 0 "register_operand" "")
12605 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12606 (match_operand:QI 2 "immediate_operand" "")))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "TARGET_64BIT && reload_completed"
12610 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12612 (define_expand "lshrdi3"
12613 [(set (match_operand:DI 0 "shiftdi_operand" "")
12614 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12615 (match_operand:QI 2 "nonmemory_operand" "")))]
12617 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12619 (define_insn "*lshrdi3_1_one_bit_rex64"
12620 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12621 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12622 (match_operand:QI 2 "const1_operand" "")))
12623 (clobber (reg:CC FLAGS_REG))]
12625 && (TARGET_SHIFT1 || optimize_size)
12626 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12628 [(set_attr "type" "ishift")
12629 (set (attr "length")
12630 (if_then_else (match_operand:DI 0 "register_operand" "")
12632 (const_string "*")))])
12634 (define_insn "*lshrdi3_1_rex64"
12635 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12636 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12637 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12641 shr{q}\t{%2, %0|%0, %2}
12642 shr{q}\t{%b2, %0|%0, %b2}"
12643 [(set_attr "type" "ishift")
12644 (set_attr "mode" "DI")])
12646 ;; This pattern can't accept a variable shift count, since shifts by
12647 ;; zero don't affect the flags. We assume that shifts by constant
12648 ;; zero are optimized away.
12649 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12650 [(set (reg FLAGS_REG)
12652 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12653 (match_operand:QI 2 "const1_operand" ""))
12655 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12656 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12658 && (TARGET_SHIFT1 || optimize_size)
12659 && ix86_match_ccmode (insn, CCGOCmode)
12660 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12662 [(set_attr "type" "ishift")
12663 (set (attr "length")
12664 (if_then_else (match_operand:DI 0 "register_operand" "")
12666 (const_string "*")))])
12668 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12669 [(set (reg FLAGS_REG)
12671 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12672 (match_operand:QI 2 "const1_operand" ""))
12674 (clobber (match_scratch:DI 0 "=r"))]
12676 && (TARGET_SHIFT1 || optimize_size)
12677 && ix86_match_ccmode (insn, CCGOCmode)
12678 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12680 [(set_attr "type" "ishift")
12681 (set_attr "length" "2")])
12683 ;; This pattern can't accept a variable shift count, since shifts by
12684 ;; zero don't affect the flags. We assume that shifts by constant
12685 ;; zero are optimized away.
12686 (define_insn "*lshrdi3_cmp_rex64"
12687 [(set (reg FLAGS_REG)
12689 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12690 (match_operand:QI 2 "const_int_operand" "e"))
12692 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12693 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12695 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12696 && ix86_match_ccmode (insn, CCGOCmode)
12697 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12698 "shr{q}\t{%2, %0|%0, %2}"
12699 [(set_attr "type" "ishift")
12700 (set_attr "mode" "DI")])
12702 (define_insn "*lshrdi3_cconly_rex64"
12703 [(set (reg FLAGS_REG)
12705 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12706 (match_operand:QI 2 "const_int_operand" "e"))
12708 (clobber (match_scratch:DI 0 "=r"))]
12710 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12711 && ix86_match_ccmode (insn, CCGOCmode)
12712 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12713 "shr{q}\t{%2, %0|%0, %2}"
12714 [(set_attr "type" "ishift")
12715 (set_attr "mode" "DI")])
12717 (define_insn "*lshrdi3_1"
12718 [(set (match_operand:DI 0 "register_operand" "=r")
12719 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12720 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12721 (clobber (reg:CC FLAGS_REG))]
12724 [(set_attr "type" "multi")])
12726 ;; By default we don't ask for a scratch register, because when DImode
12727 ;; values are manipulated, registers are already at a premium. But if
12728 ;; we have one handy, we won't turn it away.
12730 [(match_scratch:SI 3 "r")
12731 (parallel [(set (match_operand:DI 0 "register_operand" "")
12732 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12733 (match_operand:QI 2 "nonmemory_operand" "")))
12734 (clobber (reg:CC FLAGS_REG))])
12736 "!TARGET_64BIT && TARGET_CMOVE"
12738 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12741 [(set (match_operand:DI 0 "register_operand" "")
12742 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12743 (match_operand:QI 2 "nonmemory_operand" "")))
12744 (clobber (reg:CC FLAGS_REG))]
12745 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12746 ? epilogue_completed : reload_completed)"
12748 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12750 (define_expand "lshrsi3"
12751 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12752 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12753 (match_operand:QI 2 "nonmemory_operand" "")))
12754 (clobber (reg:CC FLAGS_REG))]
12756 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12758 (define_insn "*lshrsi3_1_one_bit"
12759 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12760 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12761 (match_operand:QI 2 "const1_operand" "")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "(TARGET_SHIFT1 || optimize_size)
12764 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12766 [(set_attr "type" "ishift")
12767 (set (attr "length")
12768 (if_then_else (match_operand:SI 0 "register_operand" "")
12770 (const_string "*")))])
12772 (define_insn "*lshrsi3_1_one_bit_zext"
12773 [(set (match_operand:DI 0 "register_operand" "=r")
12774 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12775 (match_operand:QI 2 "const1_operand" "")))
12776 (clobber (reg:CC FLAGS_REG))]
12778 && (TARGET_SHIFT1 || optimize_size)
12779 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781 [(set_attr "type" "ishift")
12782 (set_attr "length" "2")])
12784 (define_insn "*lshrsi3_1"
12785 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12786 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12787 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12788 (clobber (reg:CC FLAGS_REG))]
12789 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12791 shr{l}\t{%2, %0|%0, %2}
12792 shr{l}\t{%b2, %0|%0, %b2}"
12793 [(set_attr "type" "ishift")
12794 (set_attr "mode" "SI")])
12796 (define_insn "*lshrsi3_1_zext"
12797 [(set (match_operand:DI 0 "register_operand" "=r,r")
12799 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12800 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12801 (clobber (reg:CC FLAGS_REG))]
12802 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12804 shr{l}\t{%2, %k0|%k0, %2}
12805 shr{l}\t{%b2, %k0|%k0, %b2}"
12806 [(set_attr "type" "ishift")
12807 (set_attr "mode" "SI")])
12809 ;; This pattern can't accept a variable shift count, since shifts by
12810 ;; zero don't affect the flags. We assume that shifts by constant
12811 ;; zero are optimized away.
12812 (define_insn "*lshrsi3_one_bit_cmp"
12813 [(set (reg FLAGS_REG)
12815 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12816 (match_operand:QI 2 "const1_operand" ""))
12818 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12819 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12820 "(TARGET_SHIFT1 || optimize_size)
12821 && ix86_match_ccmode (insn, CCGOCmode)
12822 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12824 [(set_attr "type" "ishift")
12825 (set (attr "length")
12826 (if_then_else (match_operand:SI 0 "register_operand" "")
12828 (const_string "*")))])
12830 (define_insn "*lshrsi3_one_bit_cconly"
12831 [(set (reg FLAGS_REG)
12833 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12834 (match_operand:QI 2 "const1_operand" ""))
12836 (clobber (match_scratch:SI 0 "=r"))]
12837 "(TARGET_SHIFT1 || optimize_size)
12838 && ix86_match_ccmode (insn, CCGOCmode)
12839 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12841 [(set_attr "type" "ishift")
12842 (set_attr "length" "2")])
12844 (define_insn "*lshrsi3_cmp_one_bit_zext"
12845 [(set (reg FLAGS_REG)
12847 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12848 (match_operand:QI 2 "const1_operand" ""))
12850 (set (match_operand:DI 0 "register_operand" "=r")
12851 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12853 && (TARGET_SHIFT1 || optimize_size)
12854 && ix86_match_ccmode (insn, CCGOCmode)
12855 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12857 [(set_attr "type" "ishift")
12858 (set_attr "length" "2")])
12860 ;; This pattern can't accept a variable shift count, since shifts by
12861 ;; zero don't affect the flags. We assume that shifts by constant
12862 ;; zero are optimized away.
12863 (define_insn "*lshrsi3_cmp"
12864 [(set (reg FLAGS_REG)
12866 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12867 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12869 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12870 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12871 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12872 && ix86_match_ccmode (insn, CCGOCmode)
12873 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12874 "shr{l}\t{%2, %0|%0, %2}"
12875 [(set_attr "type" "ishift")
12876 (set_attr "mode" "SI")])
12878 (define_insn "*lshrsi3_cconly"
12879 [(set (reg FLAGS_REG)
12881 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12882 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12884 (clobber (match_scratch:SI 0 "=r"))]
12885 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12886 && ix86_match_ccmode (insn, CCGOCmode)
12887 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12888 "shr{l}\t{%2, %0|%0, %2}"
12889 [(set_attr "type" "ishift")
12890 (set_attr "mode" "SI")])
12892 (define_insn "*lshrsi3_cmp_zext"
12893 [(set (reg FLAGS_REG)
12895 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12896 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12898 (set (match_operand:DI 0 "register_operand" "=r")
12899 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12901 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12902 && ix86_match_ccmode (insn, CCGOCmode)
12903 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12904 "shr{l}\t{%2, %k0|%k0, %2}"
12905 [(set_attr "type" "ishift")
12906 (set_attr "mode" "SI")])
12908 (define_expand "lshrhi3"
12909 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12910 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12911 (match_operand:QI 2 "nonmemory_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "TARGET_HIMODE_MATH"
12914 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12916 (define_insn "*lshrhi3_1_one_bit"
12917 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12918 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12919 (match_operand:QI 2 "const1_operand" "")))
12920 (clobber (reg:CC FLAGS_REG))]
12921 "(TARGET_SHIFT1 || optimize_size)
12922 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12924 [(set_attr "type" "ishift")
12925 (set (attr "length")
12926 (if_then_else (match_operand 0 "register_operand" "")
12928 (const_string "*")))])
12930 (define_insn "*lshrhi3_1"
12931 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12932 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12933 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12934 (clobber (reg:CC FLAGS_REG))]
12935 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12937 shr{w}\t{%2, %0|%0, %2}
12938 shr{w}\t{%b2, %0|%0, %b2}"
12939 [(set_attr "type" "ishift")
12940 (set_attr "mode" "HI")])
12942 ;; This pattern can't accept a variable shift count, since shifts by
12943 ;; zero don't affect the flags. We assume that shifts by constant
12944 ;; zero are optimized away.
12945 (define_insn "*lshrhi3_one_bit_cmp"
12946 [(set (reg FLAGS_REG)
12948 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12949 (match_operand:QI 2 "const1_operand" ""))
12951 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12952 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12953 "(TARGET_SHIFT1 || optimize_size)
12954 && ix86_match_ccmode (insn, CCGOCmode)
12955 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12957 [(set_attr "type" "ishift")
12958 (set (attr "length")
12959 (if_then_else (match_operand:SI 0 "register_operand" "")
12961 (const_string "*")))])
12963 (define_insn "*lshrhi3_one_bit_cconly"
12964 [(set (reg FLAGS_REG)
12966 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12967 (match_operand:QI 2 "const1_operand" ""))
12969 (clobber (match_scratch:HI 0 "=r"))]
12970 "(TARGET_SHIFT1 || optimize_size)
12971 && ix86_match_ccmode (insn, CCGOCmode)
12972 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12974 [(set_attr "type" "ishift")
12975 (set_attr "length" "2")])
12977 ;; This pattern can't accept a variable shift count, since shifts by
12978 ;; zero don't affect the flags. We assume that shifts by constant
12979 ;; zero are optimized away.
12980 (define_insn "*lshrhi3_cmp"
12981 [(set (reg FLAGS_REG)
12983 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12984 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12986 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12987 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12988 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12989 && ix86_match_ccmode (insn, CCGOCmode)
12990 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12991 "shr{w}\t{%2, %0|%0, %2}"
12992 [(set_attr "type" "ishift")
12993 (set_attr "mode" "HI")])
12995 (define_insn "*lshrhi3_cconly"
12996 [(set (reg FLAGS_REG)
12998 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12999 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13001 (clobber (match_scratch:HI 0 "=r"))]
13002 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13003 && ix86_match_ccmode (insn, CCGOCmode)
13004 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13005 "shr{w}\t{%2, %0|%0, %2}"
13006 [(set_attr "type" "ishift")
13007 (set_attr "mode" "HI")])
13009 (define_expand "lshrqi3"
13010 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13011 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13012 (match_operand:QI 2 "nonmemory_operand" "")))
13013 (clobber (reg:CC FLAGS_REG))]
13014 "TARGET_QIMODE_MATH"
13015 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13017 (define_insn "*lshrqi3_1_one_bit"
13018 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13019 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13020 (match_operand:QI 2 "const1_operand" "")))
13021 (clobber (reg:CC FLAGS_REG))]
13022 "(TARGET_SHIFT1 || optimize_size)
13023 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13025 [(set_attr "type" "ishift")
13026 (set (attr "length")
13027 (if_then_else (match_operand 0 "register_operand" "")
13029 (const_string "*")))])
13031 (define_insn "*lshrqi3_1_one_bit_slp"
13032 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13033 (lshiftrt:QI (match_dup 0)
13034 (match_operand:QI 1 "const1_operand" "")))
13035 (clobber (reg:CC FLAGS_REG))]
13036 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13037 && (TARGET_SHIFT1 || optimize_size)"
13039 [(set_attr "type" "ishift1")
13040 (set (attr "length")
13041 (if_then_else (match_operand 0 "register_operand" "")
13043 (const_string "*")))])
13045 (define_insn "*lshrqi3_1"
13046 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13047 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13048 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13049 (clobber (reg:CC FLAGS_REG))]
13050 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13052 shr{b}\t{%2, %0|%0, %2}
13053 shr{b}\t{%b2, %0|%0, %b2}"
13054 [(set_attr "type" "ishift")
13055 (set_attr "mode" "QI")])
13057 (define_insn "*lshrqi3_1_slp"
13058 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13059 (lshiftrt:QI (match_dup 0)
13060 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13061 (clobber (reg:CC FLAGS_REG))]
13062 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13063 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13065 shr{b}\t{%1, %0|%0, %1}
13066 shr{b}\t{%b1, %0|%0, %b1}"
13067 [(set_attr "type" "ishift1")
13068 (set_attr "mode" "QI")])
13070 ;; This pattern can't accept a variable shift count, since shifts by
13071 ;; zero don't affect the flags. We assume that shifts by constant
13072 ;; zero are optimized away.
13073 (define_insn "*lshrqi2_one_bit_cmp"
13074 [(set (reg FLAGS_REG)
13076 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13077 (match_operand:QI 2 "const1_operand" ""))
13079 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13080 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13081 "(TARGET_SHIFT1 || optimize_size)
13082 && ix86_match_ccmode (insn, CCGOCmode)
13083 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13085 [(set_attr "type" "ishift")
13086 (set (attr "length")
13087 (if_then_else (match_operand:SI 0 "register_operand" "")
13089 (const_string "*")))])
13091 (define_insn "*lshrqi2_one_bit_cconly"
13092 [(set (reg FLAGS_REG)
13094 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13095 (match_operand:QI 2 "const1_operand" ""))
13097 (clobber (match_scratch:QI 0 "=q"))]
13098 "(TARGET_SHIFT1 || optimize_size)
13099 && ix86_match_ccmode (insn, CCGOCmode)
13100 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13102 [(set_attr "type" "ishift")
13103 (set_attr "length" "2")])
13105 ;; This pattern can't accept a variable shift count, since shifts by
13106 ;; zero don't affect the flags. We assume that shifts by constant
13107 ;; zero are optimized away.
13108 (define_insn "*lshrqi2_cmp"
13109 [(set (reg FLAGS_REG)
13111 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13112 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13114 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13115 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13116 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13117 && ix86_match_ccmode (insn, CCGOCmode)
13118 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13119 "shr{b}\t{%2, %0|%0, %2}"
13120 [(set_attr "type" "ishift")
13121 (set_attr "mode" "QI")])
13123 (define_insn "*lshrqi2_cconly"
13124 [(set (reg FLAGS_REG)
13126 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13127 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13129 (clobber (match_scratch:QI 0 "=q"))]
13130 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13131 && ix86_match_ccmode (insn, CCGOCmode)
13132 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13133 "shr{b}\t{%2, %0|%0, %2}"
13134 [(set_attr "type" "ishift")
13135 (set_attr "mode" "QI")])
13137 ;; Rotate instructions
13139 (define_expand "rotldi3"
13140 [(set (match_operand:DI 0 "shiftdi_operand" "")
13141 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13142 (match_operand:QI 2 "nonmemory_operand" "")))
13143 (clobber (reg:CC FLAGS_REG))]
13148 ix86_expand_binary_operator (ROTATE, DImode, operands);
13151 if (!const_1_to_31_operand (operands[2], VOIDmode))
13153 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13157 ;; Implement rotation using two double-precision shift instructions
13158 ;; and a scratch register.
13159 (define_insn_and_split "ix86_rotldi3"
13160 [(set (match_operand:DI 0 "register_operand" "=r")
13161 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13162 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13163 (clobber (reg:CC FLAGS_REG))
13164 (clobber (match_scratch:SI 3 "=&r"))]
13167 "&& reload_completed"
13168 [(set (match_dup 3) (match_dup 4))
13170 [(set (match_dup 4)
13171 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13172 (lshiftrt:SI (match_dup 5)
13173 (minus:QI (const_int 32) (match_dup 2)))))
13174 (clobber (reg:CC FLAGS_REG))])
13176 [(set (match_dup 5)
13177 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13178 (lshiftrt:SI (match_dup 3)
13179 (minus:QI (const_int 32) (match_dup 2)))))
13180 (clobber (reg:CC FLAGS_REG))])]
13181 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13183 (define_insn "*rotlsi3_1_one_bit_rex64"
13184 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13185 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13186 (match_operand:QI 2 "const1_operand" "")))
13187 (clobber (reg:CC FLAGS_REG))]
13189 && (TARGET_SHIFT1 || optimize_size)
13190 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13192 [(set_attr "type" "rotate")
13193 (set (attr "length")
13194 (if_then_else (match_operand:DI 0 "register_operand" "")
13196 (const_string "*")))])
13198 (define_insn "*rotldi3_1_rex64"
13199 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13200 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13201 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13202 (clobber (reg:CC FLAGS_REG))]
13203 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13205 rol{q}\t{%2, %0|%0, %2}
13206 rol{q}\t{%b2, %0|%0, %b2}"
13207 [(set_attr "type" "rotate")
13208 (set_attr "mode" "DI")])
13210 (define_expand "rotlsi3"
13211 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13212 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13213 (match_operand:QI 2 "nonmemory_operand" "")))
13214 (clobber (reg:CC FLAGS_REG))]
13216 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13218 (define_insn "*rotlsi3_1_one_bit"
13219 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13220 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13221 (match_operand:QI 2 "const1_operand" "")))
13222 (clobber (reg:CC FLAGS_REG))]
13223 "(TARGET_SHIFT1 || optimize_size)
13224 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13226 [(set_attr "type" "rotate")
13227 (set (attr "length")
13228 (if_then_else (match_operand:SI 0 "register_operand" "")
13230 (const_string "*")))])
13232 (define_insn "*rotlsi3_1_one_bit_zext"
13233 [(set (match_operand:DI 0 "register_operand" "=r")
13235 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13236 (match_operand:QI 2 "const1_operand" ""))))
13237 (clobber (reg:CC FLAGS_REG))]
13239 && (TARGET_SHIFT1 || optimize_size)
13240 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13242 [(set_attr "type" "rotate")
13243 (set_attr "length" "2")])
13245 (define_insn "*rotlsi3_1"
13246 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13247 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13248 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13249 (clobber (reg:CC FLAGS_REG))]
13250 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13252 rol{l}\t{%2, %0|%0, %2}
13253 rol{l}\t{%b2, %0|%0, %b2}"
13254 [(set_attr "type" "rotate")
13255 (set_attr "mode" "SI")])
13257 (define_insn "*rotlsi3_1_zext"
13258 [(set (match_operand:DI 0 "register_operand" "=r,r")
13260 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13261 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13262 (clobber (reg:CC FLAGS_REG))]
13263 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13265 rol{l}\t{%2, %k0|%k0, %2}
13266 rol{l}\t{%b2, %k0|%k0, %b2}"
13267 [(set_attr "type" "rotate")
13268 (set_attr "mode" "SI")])
13270 (define_expand "rotlhi3"
13271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13272 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13273 (match_operand:QI 2 "nonmemory_operand" "")))
13274 (clobber (reg:CC FLAGS_REG))]
13275 "TARGET_HIMODE_MATH"
13276 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13278 (define_insn "*rotlhi3_1_one_bit"
13279 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13280 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13281 (match_operand:QI 2 "const1_operand" "")))
13282 (clobber (reg:CC FLAGS_REG))]
13283 "(TARGET_SHIFT1 || optimize_size)
13284 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13286 [(set_attr "type" "rotate")
13287 (set (attr "length")
13288 (if_then_else (match_operand 0 "register_operand" "")
13290 (const_string "*")))])
13292 (define_insn "*rotlhi3_1"
13293 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13294 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13295 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13296 (clobber (reg:CC FLAGS_REG))]
13297 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13299 rol{w}\t{%2, %0|%0, %2}
13300 rol{w}\t{%b2, %0|%0, %b2}"
13301 [(set_attr "type" "rotate")
13302 (set_attr "mode" "HI")])
13305 [(set (match_operand:HI 0 "register_operand" "")
13306 (rotate:HI (match_dup 0) (const_int 8)))
13307 (clobber (reg:CC FLAGS_REG))]
13309 [(parallel [(set (strict_low_part (match_dup 0))
13310 (bswap:HI (match_dup 0)))
13311 (clobber (reg:CC FLAGS_REG))])]
13314 (define_expand "rotlqi3"
13315 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13316 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13317 (match_operand:QI 2 "nonmemory_operand" "")))
13318 (clobber (reg:CC FLAGS_REG))]
13319 "TARGET_QIMODE_MATH"
13320 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13322 (define_insn "*rotlqi3_1_one_bit_slp"
13323 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13324 (rotate:QI (match_dup 0)
13325 (match_operand:QI 1 "const1_operand" "")))
13326 (clobber (reg:CC FLAGS_REG))]
13327 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13328 && (TARGET_SHIFT1 || optimize_size)"
13330 [(set_attr "type" "rotate1")
13331 (set (attr "length")
13332 (if_then_else (match_operand 0 "register_operand" "")
13334 (const_string "*")))])
13336 (define_insn "*rotlqi3_1_one_bit"
13337 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13338 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13339 (match_operand:QI 2 "const1_operand" "")))
13340 (clobber (reg:CC FLAGS_REG))]
13341 "(TARGET_SHIFT1 || optimize_size)
13342 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13344 [(set_attr "type" "rotate")
13345 (set (attr "length")
13346 (if_then_else (match_operand 0 "register_operand" "")
13348 (const_string "*")))])
13350 (define_insn "*rotlqi3_1_slp"
13351 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13352 (rotate:QI (match_dup 0)
13353 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13354 (clobber (reg:CC FLAGS_REG))]
13355 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13356 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13358 rol{b}\t{%1, %0|%0, %1}
13359 rol{b}\t{%b1, %0|%0, %b1}"
13360 [(set_attr "type" "rotate1")
13361 (set_attr "mode" "QI")])
13363 (define_insn "*rotlqi3_1"
13364 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13365 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13366 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13367 (clobber (reg:CC FLAGS_REG))]
13368 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13370 rol{b}\t{%2, %0|%0, %2}
13371 rol{b}\t{%b2, %0|%0, %b2}"
13372 [(set_attr "type" "rotate")
13373 (set_attr "mode" "QI")])
13375 (define_expand "rotrdi3"
13376 [(set (match_operand:DI 0 "shiftdi_operand" "")
13377 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13378 (match_operand:QI 2 "nonmemory_operand" "")))
13379 (clobber (reg:CC FLAGS_REG))]
13384 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13387 if (!const_1_to_31_operand (operands[2], VOIDmode))
13389 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13393 ;; Implement rotation using two double-precision shift instructions
13394 ;; and a scratch register.
13395 (define_insn_and_split "ix86_rotrdi3"
13396 [(set (match_operand:DI 0 "register_operand" "=r")
13397 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13398 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13399 (clobber (reg:CC FLAGS_REG))
13400 (clobber (match_scratch:SI 3 "=&r"))]
13403 "&& reload_completed"
13404 [(set (match_dup 3) (match_dup 4))
13406 [(set (match_dup 4)
13407 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13408 (ashift:SI (match_dup 5)
13409 (minus:QI (const_int 32) (match_dup 2)))))
13410 (clobber (reg:CC FLAGS_REG))])
13412 [(set (match_dup 5)
13413 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13414 (ashift:SI (match_dup 3)
13415 (minus:QI (const_int 32) (match_dup 2)))))
13416 (clobber (reg:CC FLAGS_REG))])]
13417 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13419 (define_insn "*rotrdi3_1_one_bit_rex64"
13420 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13421 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13422 (match_operand:QI 2 "const1_operand" "")))
13423 (clobber (reg:CC FLAGS_REG))]
13425 && (TARGET_SHIFT1 || optimize_size)
13426 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13428 [(set_attr "type" "rotate")
13429 (set (attr "length")
13430 (if_then_else (match_operand:DI 0 "register_operand" "")
13432 (const_string "*")))])
13434 (define_insn "*rotrdi3_1_rex64"
13435 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13436 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13437 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13438 (clobber (reg:CC FLAGS_REG))]
13439 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13441 ror{q}\t{%2, %0|%0, %2}
13442 ror{q}\t{%b2, %0|%0, %b2}"
13443 [(set_attr "type" "rotate")
13444 (set_attr "mode" "DI")])
13446 (define_expand "rotrsi3"
13447 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13448 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13449 (match_operand:QI 2 "nonmemory_operand" "")))
13450 (clobber (reg:CC FLAGS_REG))]
13452 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13454 (define_insn "*rotrsi3_1_one_bit"
13455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13456 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13457 (match_operand:QI 2 "const1_operand" "")))
13458 (clobber (reg:CC FLAGS_REG))]
13459 "(TARGET_SHIFT1 || optimize_size)
13460 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13462 [(set_attr "type" "rotate")
13463 (set (attr "length")
13464 (if_then_else (match_operand:SI 0 "register_operand" "")
13466 (const_string "*")))])
13468 (define_insn "*rotrsi3_1_one_bit_zext"
13469 [(set (match_operand:DI 0 "register_operand" "=r")
13471 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13472 (match_operand:QI 2 "const1_operand" ""))))
13473 (clobber (reg:CC FLAGS_REG))]
13475 && (TARGET_SHIFT1 || optimize_size)
13476 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13478 [(set_attr "type" "rotate")
13479 (set (attr "length")
13480 (if_then_else (match_operand:SI 0 "register_operand" "")
13482 (const_string "*")))])
13484 (define_insn "*rotrsi3_1"
13485 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13486 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13487 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13488 (clobber (reg:CC FLAGS_REG))]
13489 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13491 ror{l}\t{%2, %0|%0, %2}
13492 ror{l}\t{%b2, %0|%0, %b2}"
13493 [(set_attr "type" "rotate")
13494 (set_attr "mode" "SI")])
13496 (define_insn "*rotrsi3_1_zext"
13497 [(set (match_operand:DI 0 "register_operand" "=r,r")
13499 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13500 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13501 (clobber (reg:CC FLAGS_REG))]
13502 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13504 ror{l}\t{%2, %k0|%k0, %2}
13505 ror{l}\t{%b2, %k0|%k0, %b2}"
13506 [(set_attr "type" "rotate")
13507 (set_attr "mode" "SI")])
13509 (define_expand "rotrhi3"
13510 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13511 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13512 (match_operand:QI 2 "nonmemory_operand" "")))
13513 (clobber (reg:CC FLAGS_REG))]
13514 "TARGET_HIMODE_MATH"
13515 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13517 (define_insn "*rotrhi3_one_bit"
13518 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13519 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13520 (match_operand:QI 2 "const1_operand" "")))
13521 (clobber (reg:CC FLAGS_REG))]
13522 "(TARGET_SHIFT1 || optimize_size)
13523 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13525 [(set_attr "type" "rotate")
13526 (set (attr "length")
13527 (if_then_else (match_operand 0 "register_operand" "")
13529 (const_string "*")))])
13531 (define_insn "*rotrhi3_1"
13532 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13533 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13534 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13535 (clobber (reg:CC FLAGS_REG))]
13536 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13538 ror{w}\t{%2, %0|%0, %2}
13539 ror{w}\t{%b2, %0|%0, %b2}"
13540 [(set_attr "type" "rotate")
13541 (set_attr "mode" "HI")])
13544 [(set (match_operand:HI 0 "register_operand" "")
13545 (rotatert:HI (match_dup 0) (const_int 8)))
13546 (clobber (reg:CC FLAGS_REG))]
13548 [(parallel [(set (strict_low_part (match_dup 0))
13549 (bswap:HI (match_dup 0)))
13550 (clobber (reg:CC FLAGS_REG))])]
13553 (define_expand "rotrqi3"
13554 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13555 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13556 (match_operand:QI 2 "nonmemory_operand" "")))
13557 (clobber (reg:CC FLAGS_REG))]
13558 "TARGET_QIMODE_MATH"
13559 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13561 (define_insn "*rotrqi3_1_one_bit"
13562 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13563 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13564 (match_operand:QI 2 "const1_operand" "")))
13565 (clobber (reg:CC FLAGS_REG))]
13566 "(TARGET_SHIFT1 || optimize_size)
13567 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13569 [(set_attr "type" "rotate")
13570 (set (attr "length")
13571 (if_then_else (match_operand 0 "register_operand" "")
13573 (const_string "*")))])
13575 (define_insn "*rotrqi3_1_one_bit_slp"
13576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13577 (rotatert:QI (match_dup 0)
13578 (match_operand:QI 1 "const1_operand" "")))
13579 (clobber (reg:CC FLAGS_REG))]
13580 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13581 && (TARGET_SHIFT1 || optimize_size)"
13583 [(set_attr "type" "rotate1")
13584 (set (attr "length")
13585 (if_then_else (match_operand 0 "register_operand" "")
13587 (const_string "*")))])
13589 (define_insn "*rotrqi3_1"
13590 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13591 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13592 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13593 (clobber (reg:CC FLAGS_REG))]
13594 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13596 ror{b}\t{%2, %0|%0, %2}
13597 ror{b}\t{%b2, %0|%0, %b2}"
13598 [(set_attr "type" "rotate")
13599 (set_attr "mode" "QI")])
13601 (define_insn "*rotrqi3_1_slp"
13602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13603 (rotatert:QI (match_dup 0)
13604 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13605 (clobber (reg:CC FLAGS_REG))]
13606 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13607 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13609 ror{b}\t{%1, %0|%0, %1}
13610 ror{b}\t{%b1, %0|%0, %b1}"
13611 [(set_attr "type" "rotate1")
13612 (set_attr "mode" "QI")])
13614 ;; Bit set / bit test instructions
13616 (define_expand "extv"
13617 [(set (match_operand:SI 0 "register_operand" "")
13618 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13619 (match_operand:SI 2 "const8_operand" "")
13620 (match_operand:SI 3 "const8_operand" "")))]
13623 /* Handle extractions from %ah et al. */
13624 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13627 /* From mips.md: extract_bit_field doesn't verify that our source
13628 matches the predicate, so check it again here. */
13629 if (! ext_register_operand (operands[1], VOIDmode))
13633 (define_expand "extzv"
13634 [(set (match_operand:SI 0 "register_operand" "")
13635 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13636 (match_operand:SI 2 "const8_operand" "")
13637 (match_operand:SI 3 "const8_operand" "")))]
13640 /* Handle extractions from %ah et al. */
13641 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13644 /* From mips.md: extract_bit_field doesn't verify that our source
13645 matches the predicate, so check it again here. */
13646 if (! ext_register_operand (operands[1], VOIDmode))
13650 (define_expand "insv"
13651 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13652 (match_operand 1 "const8_operand" "")
13653 (match_operand 2 "const8_operand" ""))
13654 (match_operand 3 "register_operand" ""))]
13657 /* Handle insertions to %ah et al. */
13658 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13661 /* From mips.md: insert_bit_field doesn't verify that our source
13662 matches the predicate, so check it again here. */
13663 if (! ext_register_operand (operands[0], VOIDmode))
13667 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13669 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13674 ;; %%% bts, btr, btc, bt.
13675 ;; In general these instructions are *slow* when applied to memory,
13676 ;; since they enforce atomic operation. When applied to registers,
13677 ;; it depends on the cpu implementation. They're never faster than
13678 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13679 ;; no point. But in 64-bit, we can't hold the relevant immediates
13680 ;; within the instruction itself, so operating on bits in the high
13681 ;; 32-bits of a register becomes easier.
13683 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13684 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13685 ;; negdf respectively, so they can never be disabled entirely.
13687 (define_insn "*btsq"
13688 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13690 (match_operand:DI 1 "const_0_to_63_operand" ""))
13692 (clobber (reg:CC FLAGS_REG))]
13693 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13694 "bts{q}\t{%1, %0|%0, %1}"
13695 [(set_attr "type" "alu1")])
13697 (define_insn "*btrq"
13698 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13700 (match_operand:DI 1 "const_0_to_63_operand" ""))
13702 (clobber (reg:CC FLAGS_REG))]
13703 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13704 "btr{q}\t{%1, %0|%0, %1}"
13705 [(set_attr "type" "alu1")])
13707 (define_insn "*btcq"
13708 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13710 (match_operand:DI 1 "const_0_to_63_operand" ""))
13711 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13712 (clobber (reg:CC FLAGS_REG))]
13713 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13714 "btc{q}\t{%1, %0|%0, %1}"
13715 [(set_attr "type" "alu1")])
13717 ;; Allow Nocona to avoid these instructions if a register is available.
13720 [(match_scratch:DI 2 "r")
13721 (parallel [(set (zero_extract:DI
13722 (match_operand:DI 0 "register_operand" "")
13724 (match_operand:DI 1 "const_0_to_63_operand" ""))
13726 (clobber (reg:CC FLAGS_REG))])]
13727 "TARGET_64BIT && !TARGET_USE_BT"
13730 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13733 if (HOST_BITS_PER_WIDE_INT >= 64)
13734 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13735 else if (i < HOST_BITS_PER_WIDE_INT)
13736 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13738 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13740 op1 = immed_double_const (lo, hi, DImode);
13743 emit_move_insn (operands[2], op1);
13747 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13752 [(match_scratch:DI 2 "r")
13753 (parallel [(set (zero_extract:DI
13754 (match_operand:DI 0 "register_operand" "")
13756 (match_operand:DI 1 "const_0_to_63_operand" ""))
13758 (clobber (reg:CC FLAGS_REG))])]
13759 "TARGET_64BIT && !TARGET_USE_BT"
13762 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13765 if (HOST_BITS_PER_WIDE_INT >= 64)
13766 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13767 else if (i < HOST_BITS_PER_WIDE_INT)
13768 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13770 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13772 op1 = immed_double_const (~lo, ~hi, DImode);
13775 emit_move_insn (operands[2], op1);
13779 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13784 [(match_scratch:DI 2 "r")
13785 (parallel [(set (zero_extract:DI
13786 (match_operand:DI 0 "register_operand" "")
13788 (match_operand:DI 1 "const_0_to_63_operand" ""))
13789 (not:DI (zero_extract:DI
13790 (match_dup 0) (const_int 1) (match_dup 1))))
13791 (clobber (reg:CC FLAGS_REG))])]
13792 "TARGET_64BIT && !TARGET_USE_BT"
13795 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13798 if (HOST_BITS_PER_WIDE_INT >= 64)
13799 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13800 else if (i < HOST_BITS_PER_WIDE_INT)
13801 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13803 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13805 op1 = immed_double_const (lo, hi, DImode);
13808 emit_move_insn (operands[2], op1);
13812 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13816 (define_insn "*btdi_rex64"
13817 [(set (reg:CCC FLAGS_REG)
13820 (match_operand:DI 0 "register_operand" "r")
13822 (match_operand:DI 1 "nonmemory_operand" "rN"))
13824 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
13825 "bt{q}\t{%1, %0|%0, %1}"
13826 [(set_attr "type" "alu1")])
13828 (define_insn "*btsi"
13829 [(set (reg:CCC FLAGS_REG)
13832 (match_operand:SI 0 "register_operand" "r")
13834 (match_operand:SI 1 "nonmemory_operand" "rN"))
13836 "TARGET_USE_BT || optimize_size"
13837 "bt{l}\t{%1, %0|%0, %1}"
13838 [(set_attr "type" "alu1")])
13840 ;; Store-flag instructions.
13842 ;; For all sCOND expanders, also expand the compare or test insn that
13843 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13845 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13846 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13847 ;; way, which can later delete the movzx if only QImode is needed.
13849 (define_expand "s<code>"
13850 [(set (match_operand:QI 0 "register_operand" "")
13851 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13853 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13855 (define_expand "s<code>"
13856 [(set (match_operand:QI 0 "register_operand" "")
13857 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858 "TARGET_80387 || TARGET_SSE"
13859 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13861 (define_insn "*setcc_1"
13862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13863 (match_operator:QI 1 "ix86_comparison_operator"
13864 [(reg FLAGS_REG) (const_int 0)]))]
13867 [(set_attr "type" "setcc")
13868 (set_attr "mode" "QI")])
13870 (define_insn "*setcc_2"
13871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13872 (match_operator:QI 1 "ix86_comparison_operator"
13873 [(reg FLAGS_REG) (const_int 0)]))]
13876 [(set_attr "type" "setcc")
13877 (set_attr "mode" "QI")])
13879 ;; In general it is not safe to assume too much about CCmode registers,
13880 ;; so simplify-rtx stops when it sees a second one. Under certain
13881 ;; conditions this is safe on x86, so help combine not create
13888 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13889 (ne:QI (match_operator 1 "ix86_comparison_operator"
13890 [(reg FLAGS_REG) (const_int 0)])
13893 [(set (match_dup 0) (match_dup 1))]
13895 PUT_MODE (operands[1], QImode);
13899 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13900 (ne:QI (match_operator 1 "ix86_comparison_operator"
13901 [(reg FLAGS_REG) (const_int 0)])
13904 [(set (match_dup 0) (match_dup 1))]
13906 PUT_MODE (operands[1], QImode);
13910 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13911 (eq:QI (match_operator 1 "ix86_comparison_operator"
13912 [(reg FLAGS_REG) (const_int 0)])
13915 [(set (match_dup 0) (match_dup 1))]
13917 rtx new_op1 = copy_rtx (operands[1]);
13918 operands[1] = new_op1;
13919 PUT_MODE (new_op1, QImode);
13920 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13921 GET_MODE (XEXP (new_op1, 0))));
13923 /* Make sure that (a) the CCmode we have for the flags is strong
13924 enough for the reversed compare or (b) we have a valid FP compare. */
13925 if (! ix86_comparison_operator (new_op1, VOIDmode))
13930 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13931 (eq:QI (match_operator 1 "ix86_comparison_operator"
13932 [(reg FLAGS_REG) (const_int 0)])
13935 [(set (match_dup 0) (match_dup 1))]
13937 rtx new_op1 = copy_rtx (operands[1]);
13938 operands[1] = new_op1;
13939 PUT_MODE (new_op1, QImode);
13940 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13941 GET_MODE (XEXP (new_op1, 0))));
13943 /* Make sure that (a) the CCmode we have for the flags is strong
13944 enough for the reversed compare or (b) we have a valid FP compare. */
13945 if (! ix86_comparison_operator (new_op1, VOIDmode))
13949 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13950 ;; subsequent logical operations are used to imitate conditional moves.
13951 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13954 (define_insn "*sse_setcc<mode>"
13955 [(set (match_operand:MODEF 0 "register_operand" "=x")
13956 (match_operator:MODEF 1 "sse_comparison_operator"
13957 [(match_operand:MODEF 2 "register_operand" "0")
13958 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13959 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13960 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13961 [(set_attr "type" "ssecmp")
13962 (set_attr "mode" "<MODE>")])
13964 (define_insn "*sse5_setcc<mode>"
13965 [(set (match_operand:MODEF 0 "register_operand" "=x")
13966 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13967 [(match_operand:MODEF 2 "register_operand" "x")
13968 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13970 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13971 [(set_attr "type" "sse4arg")
13972 (set_attr "mode" "<MODE>")])
13975 ;; Basic conditional jump instructions.
13976 ;; We ignore the overflow flag for signed branch instructions.
13978 ;; For all bCOND expanders, also expand the compare or test insn that
13979 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13981 (define_expand "b<code>"
13983 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13985 (label_ref (match_operand 0 ""))
13988 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13990 (define_expand "b<code>"
13992 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13994 (label_ref (match_operand 0 ""))
13996 "TARGET_80387 || TARGET_SSE_MATH"
13997 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13999 (define_insn "*jcc_1"
14001 (if_then_else (match_operator 1 "ix86_comparison_operator"
14002 [(reg FLAGS_REG) (const_int 0)])
14003 (label_ref (match_operand 0 "" ""))
14007 [(set_attr "type" "ibr")
14008 (set_attr "modrm" "0")
14009 (set (attr "length")
14010 (if_then_else (and (ge (minus (match_dup 0) (pc))
14012 (lt (minus (match_dup 0) (pc))
14017 (define_insn "*jcc_2"
14019 (if_then_else (match_operator 1 "ix86_comparison_operator"
14020 [(reg FLAGS_REG) (const_int 0)])
14022 (label_ref (match_operand 0 "" ""))))]
14025 [(set_attr "type" "ibr")
14026 (set_attr "modrm" "0")
14027 (set (attr "length")
14028 (if_then_else (and (ge (minus (match_dup 0) (pc))
14030 (lt (minus (match_dup 0) (pc))
14035 ;; In general it is not safe to assume too much about CCmode registers,
14036 ;; so simplify-rtx stops when it sees a second one. Under certain
14037 ;; conditions this is safe on x86, so help combine not create
14045 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14046 [(reg FLAGS_REG) (const_int 0)])
14048 (label_ref (match_operand 1 "" ""))
14052 (if_then_else (match_dup 0)
14053 (label_ref (match_dup 1))
14056 PUT_MODE (operands[0], VOIDmode);
14061 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14062 [(reg FLAGS_REG) (const_int 0)])
14064 (label_ref (match_operand 1 "" ""))
14068 (if_then_else (match_dup 0)
14069 (label_ref (match_dup 1))
14072 rtx new_op0 = copy_rtx (operands[0]);
14073 operands[0] = new_op0;
14074 PUT_MODE (new_op0, VOIDmode);
14075 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14076 GET_MODE (XEXP (new_op0, 0))));
14078 /* Make sure that (a) the CCmode we have for the flags is strong
14079 enough for the reversed compare or (b) we have a valid FP compare. */
14080 if (! ix86_comparison_operator (new_op0, VOIDmode))
14084 ;; zero_extend in SImode is correct, since this is what combine pass
14085 ;; generates from shift insn with QImode operand. Actually, the mode of
14086 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14087 ;; appropriate modulo of the bit offset value.
14089 (define_insn_and_split "*jcc_btdi_rex64"
14091 (if_then_else (match_operator 0 "bt_comparison_operator"
14093 (match_operand:DI 1 "register_operand" "r")
14096 (match_operand:QI 2 "register_operand" "r")))
14098 (label_ref (match_operand 3 "" ""))
14100 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
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 3))
14115 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14117 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14120 ;; avoid useless masking of bit offset operand
14121 (define_insn_and_split "*jcc_btdi_mask_rex64"
14123 (if_then_else (match_operator 0 "bt_comparison_operator"
14125 (match_operand:DI 1 "register_operand" "r")
14128 (match_operand:SI 2 "register_operand" "r")
14129 (match_operand:SI 3 "const_int_operand" "n")))])
14130 (label_ref (match_operand 4 "" ""))
14132 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)
14133 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14136 [(set (reg:CCC FLAGS_REG)
14144 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14145 (label_ref (match_dup 4))
14148 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14150 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14153 (define_insn_and_split "*jcc_btsi"
14155 (if_then_else (match_operator 0 "bt_comparison_operator"
14157 (match_operand:SI 1 "register_operand" "r")
14160 (match_operand:QI 2 "register_operand" "r")))
14162 (label_ref (match_operand 3 "" ""))
14164 "TARGET_USE_BT || optimize_size"
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 3))
14179 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14181 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14184 ;; avoid useless masking of bit offset operand
14185 (define_insn_and_split "*jcc_btsi_mask"
14187 (if_then_else (match_operator 0 "bt_comparison_operator"
14189 (match_operand:SI 1 "register_operand" "r")
14192 (match_operand:SI 2 "register_operand" "r")
14193 (match_operand:SI 3 "const_int_operand" "n")))])
14194 (label_ref (match_operand 4 "" ""))
14196 "(TARGET_USE_BT || optimize_size)
14197 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14200 [(set (reg:CCC FLAGS_REG)
14208 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14209 (label_ref (match_dup 4))
14211 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14213 (define_insn_and_split "*jcc_btsi_1"
14215 (if_then_else (match_operator 0 "bt_comparison_operator"
14218 (match_operand:SI 1 "register_operand" "r")
14219 (match_operand:QI 2 "register_operand" "r"))
14222 (label_ref (match_operand 3 "" ""))
14224 "TARGET_USE_BT || optimize_size"
14227 [(set (reg:CCC FLAGS_REG)
14235 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14236 (label_ref (match_dup 3))
14239 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14241 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14244 ;; avoid useless masking of bit offset operand
14245 (define_insn_and_split "*jcc_btsi_mask_1"
14248 (match_operator 0 "bt_comparison_operator"
14251 (match_operand:SI 1 "register_operand" "r")
14254 (match_operand:SI 2 "register_operand" "r")
14255 (match_operand:SI 3 "const_int_operand" "n")) 0))
14258 (label_ref (match_operand 4 "" ""))
14260 "(TARGET_USE_BT || optimize_size)
14261 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14264 [(set (reg:CCC FLAGS_REG)
14272 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14273 (label_ref (match_dup 4))
14275 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14277 ;; Define combination compare-and-branch fp compare instructions to use
14278 ;; during early optimization. Splitting the operation apart early makes
14279 ;; for bad code when we want to reverse the operation.
14281 (define_insn "*fp_jcc_1_mixed"
14283 (if_then_else (match_operator 0 "comparison_operator"
14284 [(match_operand 1 "register_operand" "f,x")
14285 (match_operand 2 "nonimmediate_operand" "f,xm")])
14286 (label_ref (match_operand 3 "" ""))
14288 (clobber (reg:CCFP FPSR_REG))
14289 (clobber (reg:CCFP FLAGS_REG))]
14290 "TARGET_MIX_SSE_I387
14291 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14292 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14293 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14296 (define_insn "*fp_jcc_1_sse"
14298 (if_then_else (match_operator 0 "comparison_operator"
14299 [(match_operand 1 "register_operand" "x")
14300 (match_operand 2 "nonimmediate_operand" "xm")])
14301 (label_ref (match_operand 3 "" ""))
14303 (clobber (reg:CCFP FPSR_REG))
14304 (clobber (reg:CCFP FLAGS_REG))]
14306 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14307 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14308 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14311 (define_insn "*fp_jcc_1_387"
14313 (if_then_else (match_operator 0 "comparison_operator"
14314 [(match_operand 1 "register_operand" "f")
14315 (match_operand 2 "register_operand" "f")])
14316 (label_ref (match_operand 3 "" ""))
14318 (clobber (reg:CCFP FPSR_REG))
14319 (clobber (reg:CCFP FLAGS_REG))]
14320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14322 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14323 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14326 (define_insn "*fp_jcc_2_mixed"
14328 (if_then_else (match_operator 0 "comparison_operator"
14329 [(match_operand 1 "register_operand" "f,x")
14330 (match_operand 2 "nonimmediate_operand" "f,xm")])
14332 (label_ref (match_operand 3 "" ""))))
14333 (clobber (reg:CCFP FPSR_REG))
14334 (clobber (reg:CCFP FLAGS_REG))]
14335 "TARGET_MIX_SSE_I387
14336 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14337 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14338 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14341 (define_insn "*fp_jcc_2_sse"
14343 (if_then_else (match_operator 0 "comparison_operator"
14344 [(match_operand 1 "register_operand" "x")
14345 (match_operand 2 "nonimmediate_operand" "xm")])
14347 (label_ref (match_operand 3 "" ""))))
14348 (clobber (reg:CCFP FPSR_REG))
14349 (clobber (reg:CCFP FLAGS_REG))]
14351 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14352 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14353 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14356 (define_insn "*fp_jcc_2_387"
14358 (if_then_else (match_operator 0 "comparison_operator"
14359 [(match_operand 1 "register_operand" "f")
14360 (match_operand 2 "register_operand" "f")])
14362 (label_ref (match_operand 3 "" ""))))
14363 (clobber (reg:CCFP FPSR_REG))
14364 (clobber (reg:CCFP FLAGS_REG))]
14365 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14367 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14368 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14371 (define_insn "*fp_jcc_3_387"
14373 (if_then_else (match_operator 0 "comparison_operator"
14374 [(match_operand 1 "register_operand" "f")
14375 (match_operand 2 "nonimmediate_operand" "fm")])
14376 (label_ref (match_operand 3 "" ""))
14378 (clobber (reg:CCFP FPSR_REG))
14379 (clobber (reg:CCFP FLAGS_REG))
14380 (clobber (match_scratch:HI 4 "=a"))]
14382 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14383 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14384 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14385 && SELECT_CC_MODE (GET_CODE (operands[0]),
14386 operands[1], operands[2]) == CCFPmode
14387 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14390 (define_insn "*fp_jcc_4_387"
14392 (if_then_else (match_operator 0 "comparison_operator"
14393 [(match_operand 1 "register_operand" "f")
14394 (match_operand 2 "nonimmediate_operand" "fm")])
14396 (label_ref (match_operand 3 "" ""))))
14397 (clobber (reg:CCFP FPSR_REG))
14398 (clobber (reg:CCFP FLAGS_REG))
14399 (clobber (match_scratch:HI 4 "=a"))]
14401 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14402 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14403 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14404 && SELECT_CC_MODE (GET_CODE (operands[0]),
14405 operands[1], operands[2]) == CCFPmode
14406 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14409 (define_insn "*fp_jcc_5_387"
14411 (if_then_else (match_operator 0 "comparison_operator"
14412 [(match_operand 1 "register_operand" "f")
14413 (match_operand 2 "register_operand" "f")])
14414 (label_ref (match_operand 3 "" ""))
14416 (clobber (reg:CCFP FPSR_REG))
14417 (clobber (reg:CCFP FLAGS_REG))
14418 (clobber (match_scratch:HI 4 "=a"))]
14419 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14420 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14421 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14424 (define_insn "*fp_jcc_6_387"
14426 (if_then_else (match_operator 0 "comparison_operator"
14427 [(match_operand 1 "register_operand" "f")
14428 (match_operand 2 "register_operand" "f")])
14430 (label_ref (match_operand 3 "" ""))))
14431 (clobber (reg:CCFP FPSR_REG))
14432 (clobber (reg:CCFP FLAGS_REG))
14433 (clobber (match_scratch:HI 4 "=a"))]
14434 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14435 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14436 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14439 (define_insn "*fp_jcc_7_387"
14441 (if_then_else (match_operator 0 "comparison_operator"
14442 [(match_operand 1 "register_operand" "f")
14443 (match_operand 2 "const0_operand" "X")])
14444 (label_ref (match_operand 3 "" ""))
14446 (clobber (reg:CCFP FPSR_REG))
14447 (clobber (reg:CCFP FLAGS_REG))
14448 (clobber (match_scratch:HI 4 "=a"))]
14449 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14450 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14451 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14452 && SELECT_CC_MODE (GET_CODE (operands[0]),
14453 operands[1], operands[2]) == CCFPmode
14454 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14457 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14458 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14459 ;; with a precedence over other operators and is always put in the first
14460 ;; place. Swap condition and operands to match ficom instruction.
14462 (define_insn "*fp_jcc_8<mode>_387"
14464 (if_then_else (match_operator 0 "comparison_operator"
14465 [(match_operator 1 "float_operator"
14466 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14467 (match_operand 3 "register_operand" "f,f")])
14468 (label_ref (match_operand 4 "" ""))
14470 (clobber (reg:CCFP FPSR_REG))
14471 (clobber (reg:CCFP FLAGS_REG))
14472 (clobber (match_scratch:HI 5 "=a,a"))]
14473 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14474 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
14475 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14476 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14477 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14478 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14483 (if_then_else (match_operator 0 "comparison_operator"
14484 [(match_operand 1 "register_operand" "")
14485 (match_operand 2 "nonimmediate_operand" "")])
14486 (match_operand 3 "" "")
14487 (match_operand 4 "" "")))
14488 (clobber (reg:CCFP FPSR_REG))
14489 (clobber (reg:CCFP FLAGS_REG))]
14493 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14494 operands[3], operands[4], NULL_RTX, NULL_RTX);
14500 (if_then_else (match_operator 0 "comparison_operator"
14501 [(match_operand 1 "register_operand" "")
14502 (match_operand 2 "general_operand" "")])
14503 (match_operand 3 "" "")
14504 (match_operand 4 "" "")))
14505 (clobber (reg:CCFP FPSR_REG))
14506 (clobber (reg:CCFP FLAGS_REG))
14507 (clobber (match_scratch:HI 5 "=a"))]
14511 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14512 operands[3], operands[4], operands[5], NULL_RTX);
14518 (if_then_else (match_operator 0 "comparison_operator"
14519 [(match_operator 1 "float_operator"
14520 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14521 (match_operand 3 "register_operand" "")])
14522 (match_operand 4 "" "")
14523 (match_operand 5 "" "")))
14524 (clobber (reg:CCFP FPSR_REG))
14525 (clobber (reg:CCFP FLAGS_REG))
14526 (clobber (match_scratch:HI 6 "=a"))]
14530 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14531 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14532 operands[3], operands[7],
14533 operands[4], operands[5], operands[6], NULL_RTX);
14537 ;; %%% Kill this when reload knows how to do it.
14540 (if_then_else (match_operator 0 "comparison_operator"
14541 [(match_operator 1 "float_operator"
14542 [(match_operand:X87MODEI12 2 "register_operand" "")])
14543 (match_operand 3 "register_operand" "")])
14544 (match_operand 4 "" "")
14545 (match_operand 5 "" "")))
14546 (clobber (reg:CCFP FPSR_REG))
14547 (clobber (reg:CCFP FLAGS_REG))
14548 (clobber (match_scratch:HI 6 "=a"))]
14552 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14553 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14554 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14555 operands[3], operands[7],
14556 operands[4], operands[5], operands[6], operands[2]);
14560 ;; Unconditional and other jump instructions
14562 (define_insn "jump"
14564 (label_ref (match_operand 0 "" "")))]
14567 [(set_attr "type" "ibr")
14568 (set (attr "length")
14569 (if_then_else (and (ge (minus (match_dup 0) (pc))
14571 (lt (minus (match_dup 0) (pc))
14575 (set_attr "modrm" "0")])
14577 (define_expand "indirect_jump"
14578 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14582 (define_insn "*indirect_jump"
14583 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14586 [(set_attr "type" "ibr")
14587 (set_attr "length_immediate" "0")])
14589 (define_expand "tablejump"
14590 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14591 (use (label_ref (match_operand 1 "" "")))])]
14594 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14595 relative. Convert the relative address to an absolute address. */
14599 enum rtx_code code;
14601 /* We can't use @GOTOFF for text labels on VxWorks;
14602 see gotoff_operand. */
14603 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14607 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14609 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14613 op1 = pic_offset_table_rtx;
14618 op0 = pic_offset_table_rtx;
14622 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14627 (define_insn "*tablejump_1"
14628 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14629 (use (label_ref (match_operand 1 "" "")))]
14632 [(set_attr "type" "ibr")
14633 (set_attr "length_immediate" "0")])
14635 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14638 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14639 (set (match_operand:QI 1 "register_operand" "")
14640 (match_operator:QI 2 "ix86_comparison_operator"
14641 [(reg FLAGS_REG) (const_int 0)]))
14642 (set (match_operand 3 "q_regs_operand" "")
14643 (zero_extend (match_dup 1)))]
14644 "(peep2_reg_dead_p (3, operands[1])
14645 || operands_match_p (operands[1], operands[3]))
14646 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14647 [(set (match_dup 4) (match_dup 0))
14648 (set (strict_low_part (match_dup 5))
14651 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14652 operands[5] = gen_lowpart (QImode, operands[3]);
14653 ix86_expand_clear (operands[3]);
14656 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14659 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14660 (set (match_operand:QI 1 "register_operand" "")
14661 (match_operator:QI 2 "ix86_comparison_operator"
14662 [(reg FLAGS_REG) (const_int 0)]))
14663 (parallel [(set (match_operand 3 "q_regs_operand" "")
14664 (zero_extend (match_dup 1)))
14665 (clobber (reg:CC FLAGS_REG))])]
14666 "(peep2_reg_dead_p (3, operands[1])
14667 || operands_match_p (operands[1], operands[3]))
14668 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14669 [(set (match_dup 4) (match_dup 0))
14670 (set (strict_low_part (match_dup 5))
14673 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14674 operands[5] = gen_lowpart (QImode, operands[3]);
14675 ix86_expand_clear (operands[3]);
14678 ;; Call instructions.
14680 ;; The predicates normally associated with named expanders are not properly
14681 ;; checked for calls. This is a bug in the generic code, but it isn't that
14682 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14684 ;; Call subroutine returning no value.
14686 (define_expand "call_pop"
14687 [(parallel [(call (match_operand:QI 0 "" "")
14688 (match_operand:SI 1 "" ""))
14689 (set (reg:SI SP_REG)
14690 (plus:SI (reg:SI SP_REG)
14691 (match_operand:SI 3 "" "")))])]
14694 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14698 (define_insn "*call_pop_0"
14699 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14700 (match_operand:SI 1 "" ""))
14701 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14702 (match_operand:SI 2 "immediate_operand" "")))]
14705 if (SIBLING_CALL_P (insn))
14708 return "call\t%P0";
14710 [(set_attr "type" "call")])
14712 (define_insn "*call_pop_1"
14713 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14714 (match_operand:SI 1 "" ""))
14715 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14716 (match_operand:SI 2 "immediate_operand" "i")))]
14719 if (constant_call_address_operand (operands[0], Pmode))
14721 if (SIBLING_CALL_P (insn))
14724 return "call\t%P0";
14726 if (SIBLING_CALL_P (insn))
14729 return "call\t%A0";
14731 [(set_attr "type" "call")])
14733 (define_expand "call"
14734 [(call (match_operand:QI 0 "" "")
14735 (match_operand 1 "" ""))
14736 (use (match_operand 2 "" ""))]
14739 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14743 (define_expand "sibcall"
14744 [(call (match_operand:QI 0 "" "")
14745 (match_operand 1 "" ""))
14746 (use (match_operand 2 "" ""))]
14749 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14753 (define_insn "*call_0"
14754 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14755 (match_operand 1 "" ""))]
14758 if (SIBLING_CALL_P (insn))
14761 return "call\t%P0";
14763 [(set_attr "type" "call")])
14765 (define_insn "*call_1"
14766 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14767 (match_operand 1 "" ""))]
14768 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14770 if (constant_call_address_operand (operands[0], Pmode))
14771 return "call\t%P0";
14772 return "call\t%A0";
14774 [(set_attr "type" "call")])
14776 (define_insn "*sibcall_1"
14777 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14778 (match_operand 1 "" ""))]
14779 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14781 if (constant_call_address_operand (operands[0], Pmode))
14785 [(set_attr "type" "call")])
14787 (define_insn "*call_1_rex64"
14788 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14789 (match_operand 1 "" ""))]
14790 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14791 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14793 if (constant_call_address_operand (operands[0], Pmode))
14794 return "call\t%P0";
14795 return "call\t%A0";
14797 [(set_attr "type" "call")])
14799 (define_insn "*call_1_rex64_large"
14800 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14801 (match_operand 1 "" ""))]
14802 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14804 [(set_attr "type" "call")])
14806 (define_insn "*sibcall_1_rex64"
14807 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14808 (match_operand 1 "" ""))]
14809 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14811 [(set_attr "type" "call")])
14813 (define_insn "*sibcall_1_rex64_v"
14814 [(call (mem:QI (reg:DI R11_REG))
14815 (match_operand 0 "" ""))]
14816 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14818 [(set_attr "type" "call")])
14821 ;; Call subroutine, returning value in operand 0
14823 (define_expand "call_value_pop"
14824 [(parallel [(set (match_operand 0 "" "")
14825 (call (match_operand:QI 1 "" "")
14826 (match_operand:SI 2 "" "")))
14827 (set (reg:SI SP_REG)
14828 (plus:SI (reg:SI SP_REG)
14829 (match_operand:SI 4 "" "")))])]
14832 ix86_expand_call (operands[0], operands[1], operands[2],
14833 operands[3], operands[4], 0);
14837 (define_expand "call_value"
14838 [(set (match_operand 0 "" "")
14839 (call (match_operand:QI 1 "" "")
14840 (match_operand:SI 2 "" "")))
14841 (use (match_operand:SI 3 "" ""))]
14842 ;; Operand 2 not used on the i386.
14845 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14849 (define_expand "sibcall_value"
14850 [(set (match_operand 0 "" "")
14851 (call (match_operand:QI 1 "" "")
14852 (match_operand:SI 2 "" "")))
14853 (use (match_operand:SI 3 "" ""))]
14854 ;; Operand 2 not used on the i386.
14857 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14861 ;; Call subroutine returning any type.
14863 (define_expand "untyped_call"
14864 [(parallel [(call (match_operand 0 "" "")
14866 (match_operand 1 "" "")
14867 (match_operand 2 "" "")])]
14872 /* In order to give reg-stack an easier job in validating two
14873 coprocessor registers as containing a possible return value,
14874 simply pretend the untyped call returns a complex long double
14877 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14878 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14879 operands[0], const0_rtx,
14880 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
14881 : X64_SSE_REGPARM_MAX)
14885 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14887 rtx set = XVECEXP (operands[2], 0, i);
14888 emit_move_insn (SET_DEST (set), SET_SRC (set));
14891 /* The optimizer does not know that the call sets the function value
14892 registers we stored in the result block. We avoid problems by
14893 claiming that all hard registers are used and clobbered at this
14895 emit_insn (gen_blockage ());
14900 ;; Prologue and epilogue instructions
14902 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14903 ;; all of memory. This blocks insns from being moved across this point.
14905 (define_insn "blockage"
14906 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14909 [(set_attr "length" "0")])
14911 ;; As USE insns aren't meaningful after reload, this is used instead
14912 ;; to prevent deleting instructions setting registers for PIC code
14913 (define_insn "prologue_use"
14914 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14917 [(set_attr "length" "0")])
14919 ;; Insn emitted into the body of a function to return from a function.
14920 ;; This is only done if the function's epilogue is known to be simple.
14921 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14923 (define_expand "return"
14925 "ix86_can_use_return_insn_p ()"
14927 if (crtl->args.pops_args)
14929 rtx popc = GEN_INT (crtl->args.pops_args);
14930 emit_jump_insn (gen_return_pop_internal (popc));
14935 (define_insn "return_internal"
14939 [(set_attr "length" "1")
14940 (set_attr "length_immediate" "0")
14941 (set_attr "modrm" "0")])
14943 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14944 ;; instruction Athlon and K8 have.
14946 (define_insn "return_internal_long"
14948 (unspec [(const_int 0)] UNSPEC_REP)]
14951 [(set_attr "length" "1")
14952 (set_attr "length_immediate" "0")
14953 (set_attr "prefix_rep" "1")
14954 (set_attr "modrm" "0")])
14956 (define_insn "return_pop_internal"
14958 (use (match_operand:SI 0 "const_int_operand" ""))]
14961 [(set_attr "length" "3")
14962 (set_attr "length_immediate" "2")
14963 (set_attr "modrm" "0")])
14965 (define_insn "return_indirect_internal"
14967 (use (match_operand:SI 0 "register_operand" "r"))]
14970 [(set_attr "type" "ibr")
14971 (set_attr "length_immediate" "0")])
14977 [(set_attr "length" "1")
14978 (set_attr "length_immediate" "0")
14979 (set_attr "modrm" "0")])
14981 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14982 ;; branch prediction penalty for the third jump in a 16-byte
14985 (define_insn "align"
14986 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14989 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14990 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14992 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14993 The align insn is used to avoid 3 jump instructions in the row to improve
14994 branch prediction and the benefits hardly outweigh the cost of extra 8
14995 nops on the average inserted by full alignment pseudo operation. */
14999 [(set_attr "length" "16")])
15001 (define_expand "prologue"
15004 "ix86_expand_prologue (); DONE;")
15006 (define_insn "set_got"
15007 [(set (match_operand:SI 0 "register_operand" "=r")
15008 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15009 (clobber (reg:CC FLAGS_REG))]
15011 { return output_set_got (operands[0], NULL_RTX); }
15012 [(set_attr "type" "multi")
15013 (set_attr "length" "12")])
15015 (define_insn "set_got_labelled"
15016 [(set (match_operand:SI 0 "register_operand" "=r")
15017 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15019 (clobber (reg:CC FLAGS_REG))]
15021 { return output_set_got (operands[0], operands[1]); }
15022 [(set_attr "type" "multi")
15023 (set_attr "length" "12")])
15025 (define_insn "set_got_rex64"
15026 [(set (match_operand:DI 0 "register_operand" "=r")
15027 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15029 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15030 [(set_attr "type" "lea")
15031 (set_attr "length" "6")])
15033 (define_insn "set_rip_rex64"
15034 [(set (match_operand:DI 0 "register_operand" "=r")
15035 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15037 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15038 [(set_attr "type" "lea")
15039 (set_attr "length" "6")])
15041 (define_insn "set_got_offset_rex64"
15042 [(set (match_operand:DI 0 "register_operand" "=r")
15043 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15045 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15046 [(set_attr "type" "imov")
15047 (set_attr "length" "11")])
15049 (define_expand "epilogue"
15052 "ix86_expand_epilogue (1); DONE;")
15054 (define_expand "sibcall_epilogue"
15057 "ix86_expand_epilogue (0); DONE;")
15059 (define_expand "eh_return"
15060 [(use (match_operand 0 "register_operand" ""))]
15063 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15065 /* Tricky bit: we write the address of the handler to which we will
15066 be returning into someone else's stack frame, one word below the
15067 stack address we wish to restore. */
15068 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15069 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15070 tmp = gen_rtx_MEM (Pmode, tmp);
15071 emit_move_insn (tmp, ra);
15073 if (Pmode == SImode)
15074 emit_jump_insn (gen_eh_return_si (sa));
15076 emit_jump_insn (gen_eh_return_di (sa));
15081 (define_insn_and_split "eh_return_<mode>"
15083 (unspec [(match_operand:P 0 "register_operand" "c")]
15084 UNSPEC_EH_RETURN))]
15089 "ix86_expand_epilogue (2); DONE;")
15091 (define_insn "leave"
15092 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15093 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15094 (clobber (mem:BLK (scratch)))]
15097 [(set_attr "type" "leave")])
15099 (define_insn "leave_rex64"
15100 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15101 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15102 (clobber (mem:BLK (scratch)))]
15105 [(set_attr "type" "leave")])
15107 (define_expand "ffssi2"
15109 [(set (match_operand:SI 0 "register_operand" "")
15110 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15111 (clobber (match_scratch:SI 2 ""))
15112 (clobber (reg:CC FLAGS_REG))])]
15117 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15122 (define_expand "ffs_cmove"
15123 [(set (match_dup 2) (const_int -1))
15124 (parallel [(set (reg:CCZ FLAGS_REG)
15125 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15127 (set (match_operand:SI 0 "nonimmediate_operand" "")
15128 (ctz:SI (match_dup 1)))])
15129 (set (match_dup 0) (if_then_else:SI
15130 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15133 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15134 (clobber (reg:CC FLAGS_REG))])]
15136 "operands[2] = gen_reg_rtx (SImode);")
15138 (define_insn_and_split "*ffs_no_cmove"
15139 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15140 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15141 (clobber (match_scratch:SI 2 "=&q"))
15142 (clobber (reg:CC FLAGS_REG))]
15145 "&& reload_completed"
15146 [(parallel [(set (reg:CCZ FLAGS_REG)
15147 (compare:CCZ (match_dup 1) (const_int 0)))
15148 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15149 (set (strict_low_part (match_dup 3))
15150 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15151 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15152 (clobber (reg:CC FLAGS_REG))])
15153 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15154 (clobber (reg:CC FLAGS_REG))])
15155 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15156 (clobber (reg:CC FLAGS_REG))])]
15158 operands[3] = gen_lowpart (QImode, operands[2]);
15159 ix86_expand_clear (operands[2]);
15162 (define_insn "*ffssi_1"
15163 [(set (reg:CCZ FLAGS_REG)
15164 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15166 (set (match_operand:SI 0 "register_operand" "=r")
15167 (ctz:SI (match_dup 1)))]
15169 "bsf{l}\t{%1, %0|%0, %1}"
15170 [(set_attr "prefix_0f" "1")])
15172 (define_expand "ffsdi2"
15173 [(set (match_dup 2) (const_int -1))
15174 (parallel [(set (reg:CCZ FLAGS_REG)
15175 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15177 (set (match_operand:DI 0 "nonimmediate_operand" "")
15178 (ctz:DI (match_dup 1)))])
15179 (set (match_dup 0) (if_then_else:DI
15180 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15183 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15184 (clobber (reg:CC FLAGS_REG))])]
15186 "operands[2] = gen_reg_rtx (DImode);")
15188 (define_insn "*ffsdi_1"
15189 [(set (reg:CCZ FLAGS_REG)
15190 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15192 (set (match_operand:DI 0 "register_operand" "=r")
15193 (ctz:DI (match_dup 1)))]
15195 "bsf{q}\t{%1, %0|%0, %1}"
15196 [(set_attr "prefix_0f" "1")])
15198 (define_insn "ctzsi2"
15199 [(set (match_operand:SI 0 "register_operand" "=r")
15200 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15201 (clobber (reg:CC FLAGS_REG))]
15203 "bsf{l}\t{%1, %0|%0, %1}"
15204 [(set_attr "prefix_0f" "1")])
15206 (define_insn "ctzdi2"
15207 [(set (match_operand:DI 0 "register_operand" "=r")
15208 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15209 (clobber (reg:CC FLAGS_REG))]
15211 "bsf{q}\t{%1, %0|%0, %1}"
15212 [(set_attr "prefix_0f" "1")])
15214 (define_expand "clzsi2"
15216 [(set (match_operand:SI 0 "register_operand" "")
15217 (minus:SI (const_int 31)
15218 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15219 (clobber (reg:CC FLAGS_REG))])
15221 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15222 (clobber (reg:CC FLAGS_REG))])]
15227 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15232 (define_insn "clzsi2_abm"
15233 [(set (match_operand:SI 0 "register_operand" "=r")
15234 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15235 (clobber (reg:CC FLAGS_REG))]
15237 "lzcnt{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 "*bsr"
15243 [(set (match_operand:SI 0 "register_operand" "=r")
15244 (minus:SI (const_int 31)
15245 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15246 (clobber (reg:CC FLAGS_REG))]
15248 "bsr{l}\t{%1, %0|%0, %1}"
15249 [(set_attr "prefix_0f" "1")
15250 (set_attr "mode" "SI")])
15252 (define_insn "popcountsi2"
15253 [(set (match_operand:SI 0 "register_operand" "=r")
15254 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15255 (clobber (reg:CC FLAGS_REG))]
15257 "popcnt{l}\t{%1, %0|%0, %1}"
15258 [(set_attr "prefix_rep" "1")
15259 (set_attr "type" "bitmanip")
15260 (set_attr "mode" "SI")])
15262 (define_insn "*popcountsi2_cmp"
15263 [(set (reg FLAGS_REG)
15265 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15267 (set (match_operand:SI 0 "register_operand" "=r")
15268 (popcount:SI (match_dup 1)))]
15269 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15270 "popcnt{l}\t{%1, %0|%0, %1}"
15271 [(set_attr "prefix_rep" "1")
15272 (set_attr "type" "bitmanip")
15273 (set_attr "mode" "SI")])
15275 (define_insn "*popcountsi2_cmp_zext"
15276 [(set (reg FLAGS_REG)
15278 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15280 (set (match_operand:DI 0 "register_operand" "=r")
15281 (zero_extend:DI(popcount:SI (match_dup 1))))]
15282 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15283 "popcnt{l}\t{%1, %0|%0, %1}"
15284 [(set_attr "prefix_rep" "1")
15285 (set_attr "type" "bitmanip")
15286 (set_attr "mode" "SI")])
15288 (define_expand "bswapsi2"
15289 [(set (match_operand:SI 0 "register_operand" "")
15290 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15295 rtx x = operands[0];
15297 emit_move_insn (x, operands[1]);
15298 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15299 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15300 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15305 (define_insn "*bswapsi_1"
15306 [(set (match_operand:SI 0 "register_operand" "=r")
15307 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15310 [(set_attr "prefix_0f" "1")
15311 (set_attr "length" "2")])
15313 (define_insn "*bswaphi_lowpart_1"
15314 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15315 (bswap:HI (match_dup 0)))
15316 (clobber (reg:CC FLAGS_REG))]
15317 "TARGET_USE_XCHGB || optimize_size"
15319 xchg{b}\t{%h0, %b0|%b0, %h0}
15320 rol{w}\t{$8, %0|%0, 8}"
15321 [(set_attr "length" "2,4")
15322 (set_attr "mode" "QI,HI")])
15324 (define_insn "bswaphi_lowpart"
15325 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15326 (bswap:HI (match_dup 0)))
15327 (clobber (reg:CC FLAGS_REG))]
15329 "rol{w}\t{$8, %0|%0, 8}"
15330 [(set_attr "length" "4")
15331 (set_attr "mode" "HI")])
15333 (define_insn "bswapdi2"
15334 [(set (match_operand:DI 0 "register_operand" "=r")
15335 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15338 [(set_attr "prefix_0f" "1")
15339 (set_attr "length" "3")])
15341 (define_expand "clzdi2"
15343 [(set (match_operand:DI 0 "register_operand" "")
15344 (minus:DI (const_int 63)
15345 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15346 (clobber (reg:CC FLAGS_REG))])
15348 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15349 (clobber (reg:CC FLAGS_REG))])]
15354 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15359 (define_insn "clzdi2_abm"
15360 [(set (match_operand:DI 0 "register_operand" "=r")
15361 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15362 (clobber (reg:CC FLAGS_REG))]
15363 "TARGET_64BIT && TARGET_ABM"
15364 "lzcnt{q}\t{%1, %0|%0, %1}"
15365 [(set_attr "prefix_rep" "1")
15366 (set_attr "type" "bitmanip")
15367 (set_attr "mode" "DI")])
15369 (define_insn "*bsr_rex64"
15370 [(set (match_operand:DI 0 "register_operand" "=r")
15371 (minus:DI (const_int 63)
15372 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15373 (clobber (reg:CC FLAGS_REG))]
15375 "bsr{q}\t{%1, %0|%0, %1}"
15376 [(set_attr "prefix_0f" "1")
15377 (set_attr "mode" "DI")])
15379 (define_insn "popcountdi2"
15380 [(set (match_operand:DI 0 "register_operand" "=r")
15381 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15382 (clobber (reg:CC FLAGS_REG))]
15383 "TARGET_64BIT && TARGET_POPCNT"
15384 "popcnt{q}\t{%1, %0|%0, %1}"
15385 [(set_attr "prefix_rep" "1")
15386 (set_attr "type" "bitmanip")
15387 (set_attr "mode" "DI")])
15389 (define_insn "*popcountdi2_cmp"
15390 [(set (reg FLAGS_REG)
15392 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15394 (set (match_operand:DI 0 "register_operand" "=r")
15395 (popcount:DI (match_dup 1)))]
15396 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15397 "popcnt{q}\t{%1, %0|%0, %1}"
15398 [(set_attr "prefix_rep" "1")
15399 (set_attr "type" "bitmanip")
15400 (set_attr "mode" "DI")])
15402 (define_expand "clzhi2"
15404 [(set (match_operand:HI 0 "register_operand" "")
15405 (minus:HI (const_int 15)
15406 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15407 (clobber (reg:CC FLAGS_REG))])
15409 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15410 (clobber (reg:CC FLAGS_REG))])]
15415 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15420 (define_insn "clzhi2_abm"
15421 [(set (match_operand:HI 0 "register_operand" "=r")
15422 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15423 (clobber (reg:CC FLAGS_REG))]
15425 "lzcnt{w}\t{%1, %0|%0, %1}"
15426 [(set_attr "prefix_rep" "1")
15427 (set_attr "type" "bitmanip")
15428 (set_attr "mode" "HI")])
15430 (define_insn "*bsrhi"
15431 [(set (match_operand:HI 0 "register_operand" "=r")
15432 (minus:HI (const_int 15)
15433 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15434 (clobber (reg:CC FLAGS_REG))]
15436 "bsr{w}\t{%1, %0|%0, %1}"
15437 [(set_attr "prefix_0f" "1")
15438 (set_attr "mode" "HI")])
15440 (define_insn "popcounthi2"
15441 [(set (match_operand:HI 0 "register_operand" "=r")
15442 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15443 (clobber (reg:CC FLAGS_REG))]
15445 "popcnt{w}\t{%1, %0|%0, %1}"
15446 [(set_attr "prefix_rep" "1")
15447 (set_attr "type" "bitmanip")
15448 (set_attr "mode" "HI")])
15450 (define_insn "*popcounthi2_cmp"
15451 [(set (reg FLAGS_REG)
15453 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15455 (set (match_operand:HI 0 "register_operand" "=r")
15456 (popcount:HI (match_dup 1)))]
15457 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15458 "popcnt{w}\t{%1, %0|%0, %1}"
15459 [(set_attr "prefix_rep" "1")
15460 (set_attr "type" "bitmanip")
15461 (set_attr "mode" "HI")])
15463 (define_expand "paritydi2"
15464 [(set (match_operand:DI 0 "register_operand" "")
15465 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15468 rtx scratch = gen_reg_rtx (QImode);
15471 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15472 NULL_RTX, operands[1]));
15474 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15475 gen_rtx_REG (CCmode, FLAGS_REG),
15477 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15480 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15483 rtx tmp = gen_reg_rtx (SImode);
15485 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15486 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15491 (define_insn_and_split "paritydi2_cmp"
15492 [(set (reg:CC FLAGS_REG)
15493 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15494 (clobber (match_scratch:DI 0 "=r"))
15495 (clobber (match_scratch:SI 1 "=&r"))
15496 (clobber (match_scratch:HI 2 "=Q"))]
15499 "&& reload_completed"
15501 [(set (match_dup 1)
15502 (xor:SI (match_dup 1) (match_dup 4)))
15503 (clobber (reg:CC FLAGS_REG))])
15505 [(set (reg:CC FLAGS_REG)
15506 (parity:CC (match_dup 1)))
15507 (clobber (match_dup 1))
15508 (clobber (match_dup 2))])]
15510 operands[4] = gen_lowpart (SImode, operands[3]);
15514 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15515 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15518 operands[1] = gen_highpart (SImode, operands[3]);
15521 (define_expand "paritysi2"
15522 [(set (match_operand:SI 0 "register_operand" "")
15523 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15526 rtx scratch = gen_reg_rtx (QImode);
15529 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15531 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15532 gen_rtx_REG (CCmode, FLAGS_REG),
15534 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15536 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15540 (define_insn_and_split "paritysi2_cmp"
15541 [(set (reg:CC FLAGS_REG)
15542 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15543 (clobber (match_scratch:SI 0 "=r"))
15544 (clobber (match_scratch:HI 1 "=&Q"))]
15547 "&& reload_completed"
15549 [(set (match_dup 1)
15550 (xor:HI (match_dup 1) (match_dup 3)))
15551 (clobber (reg:CC FLAGS_REG))])
15553 [(set (reg:CC FLAGS_REG)
15554 (parity:CC (match_dup 1)))
15555 (clobber (match_dup 1))])]
15557 operands[3] = gen_lowpart (HImode, operands[2]);
15559 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15560 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15563 (define_insn "*parityhi2_cmp"
15564 [(set (reg:CC FLAGS_REG)
15565 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15566 (clobber (match_scratch:HI 0 "=Q"))]
15568 "xor{b}\t{%h0, %b0|%b0, %h0}"
15569 [(set_attr "length" "2")
15570 (set_attr "mode" "HI")])
15572 (define_insn "*parityqi2_cmp"
15573 [(set (reg:CC FLAGS_REG)
15574 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15577 [(set_attr "length" "2")
15578 (set_attr "mode" "QI")])
15580 ;; Thread-local storage patterns for ELF.
15582 ;; Note that these code sequences must appear exactly as shown
15583 ;; in order to allow linker relaxation.
15585 (define_insn "*tls_global_dynamic_32_gnu"
15586 [(set (match_operand:SI 0 "register_operand" "=a")
15587 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15588 (match_operand:SI 2 "tls_symbolic_operand" "")
15589 (match_operand:SI 3 "call_insn_operand" "")]
15591 (clobber (match_scratch:SI 4 "=d"))
15592 (clobber (match_scratch:SI 5 "=c"))
15593 (clobber (reg:CC FLAGS_REG))]
15594 "!TARGET_64BIT && TARGET_GNU_TLS"
15595 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15596 [(set_attr "type" "multi")
15597 (set_attr "length" "12")])
15599 (define_insn "*tls_global_dynamic_32_sun"
15600 [(set (match_operand:SI 0 "register_operand" "=a")
15601 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15602 (match_operand:SI 2 "tls_symbolic_operand" "")
15603 (match_operand:SI 3 "call_insn_operand" "")]
15605 (clobber (match_scratch:SI 4 "=d"))
15606 (clobber (match_scratch:SI 5 "=c"))
15607 (clobber (reg:CC FLAGS_REG))]
15608 "!TARGET_64BIT && TARGET_SUN_TLS"
15609 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15610 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15611 [(set_attr "type" "multi")
15612 (set_attr "length" "14")])
15614 (define_expand "tls_global_dynamic_32"
15615 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15618 (match_operand:SI 1 "tls_symbolic_operand" "")
15621 (clobber (match_scratch:SI 4 ""))
15622 (clobber (match_scratch:SI 5 ""))
15623 (clobber (reg:CC FLAGS_REG))])]
15627 operands[2] = pic_offset_table_rtx;
15630 operands[2] = gen_reg_rtx (Pmode);
15631 emit_insn (gen_set_got (operands[2]));
15633 if (TARGET_GNU2_TLS)
15635 emit_insn (gen_tls_dynamic_gnu2_32
15636 (operands[0], operands[1], operands[2]));
15639 operands[3] = ix86_tls_get_addr ();
15642 (define_insn "*tls_global_dynamic_64"
15643 [(set (match_operand:DI 0 "register_operand" "=a")
15644 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15645 (match_operand:DI 3 "" "")))
15646 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15649 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15650 [(set_attr "type" "multi")
15651 (set_attr "length" "16")])
15653 (define_expand "tls_global_dynamic_64"
15654 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15655 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15656 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15660 if (TARGET_GNU2_TLS)
15662 emit_insn (gen_tls_dynamic_gnu2_64
15663 (operands[0], operands[1]));
15666 operands[2] = ix86_tls_get_addr ();
15669 (define_insn "*tls_local_dynamic_base_32_gnu"
15670 [(set (match_operand:SI 0 "register_operand" "=a")
15671 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15672 (match_operand:SI 2 "call_insn_operand" "")]
15673 UNSPEC_TLS_LD_BASE))
15674 (clobber (match_scratch:SI 3 "=d"))
15675 (clobber (match_scratch:SI 4 "=c"))
15676 (clobber (reg:CC FLAGS_REG))]
15677 "!TARGET_64BIT && TARGET_GNU_TLS"
15678 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15679 [(set_attr "type" "multi")
15680 (set_attr "length" "11")])
15682 (define_insn "*tls_local_dynamic_base_32_sun"
15683 [(set (match_operand:SI 0 "register_operand" "=a")
15684 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15685 (match_operand:SI 2 "call_insn_operand" "")]
15686 UNSPEC_TLS_LD_BASE))
15687 (clobber (match_scratch:SI 3 "=d"))
15688 (clobber (match_scratch:SI 4 "=c"))
15689 (clobber (reg:CC FLAGS_REG))]
15690 "!TARGET_64BIT && TARGET_SUN_TLS"
15691 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15692 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15693 [(set_attr "type" "multi")
15694 (set_attr "length" "13")])
15696 (define_expand "tls_local_dynamic_base_32"
15697 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15698 (unspec:SI [(match_dup 1) (match_dup 2)]
15699 UNSPEC_TLS_LD_BASE))
15700 (clobber (match_scratch:SI 3 ""))
15701 (clobber (match_scratch:SI 4 ""))
15702 (clobber (reg:CC FLAGS_REG))])]
15706 operands[1] = pic_offset_table_rtx;
15709 operands[1] = gen_reg_rtx (Pmode);
15710 emit_insn (gen_set_got (operands[1]));
15712 if (TARGET_GNU2_TLS)
15714 emit_insn (gen_tls_dynamic_gnu2_32
15715 (operands[0], ix86_tls_module_base (), operands[1]));
15718 operands[2] = ix86_tls_get_addr ();
15721 (define_insn "*tls_local_dynamic_base_64"
15722 [(set (match_operand:DI 0 "register_operand" "=a")
15723 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15724 (match_operand:DI 2 "" "")))
15725 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15727 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15728 [(set_attr "type" "multi")
15729 (set_attr "length" "12")])
15731 (define_expand "tls_local_dynamic_base_64"
15732 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15733 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15734 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15737 if (TARGET_GNU2_TLS)
15739 emit_insn (gen_tls_dynamic_gnu2_64
15740 (operands[0], ix86_tls_module_base ()));
15743 operands[1] = ix86_tls_get_addr ();
15746 ;; Local dynamic of a single variable is a lose. Show combine how
15747 ;; to convert that back to global dynamic.
15749 (define_insn_and_split "*tls_local_dynamic_32_once"
15750 [(set (match_operand:SI 0 "register_operand" "=a")
15751 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15752 (match_operand:SI 2 "call_insn_operand" "")]
15753 UNSPEC_TLS_LD_BASE)
15754 (const:SI (unspec:SI
15755 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15757 (clobber (match_scratch:SI 4 "=d"))
15758 (clobber (match_scratch:SI 5 "=c"))
15759 (clobber (reg:CC FLAGS_REG))]
15763 [(parallel [(set (match_dup 0)
15764 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15766 (clobber (match_dup 4))
15767 (clobber (match_dup 5))
15768 (clobber (reg:CC FLAGS_REG))])]
15771 ;; Load and add the thread base pointer from %gs:0.
15773 (define_insn "*load_tp_si"
15774 [(set (match_operand:SI 0 "register_operand" "=r")
15775 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15777 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15778 [(set_attr "type" "imov")
15779 (set_attr "modrm" "0")
15780 (set_attr "length" "7")
15781 (set_attr "memory" "load")
15782 (set_attr "imm_disp" "false")])
15784 (define_insn "*add_tp_si"
15785 [(set (match_operand:SI 0 "register_operand" "=r")
15786 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15787 (match_operand:SI 1 "register_operand" "0")))
15788 (clobber (reg:CC FLAGS_REG))]
15790 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15791 [(set_attr "type" "alu")
15792 (set_attr "modrm" "0")
15793 (set_attr "length" "7")
15794 (set_attr "memory" "load")
15795 (set_attr "imm_disp" "false")])
15797 (define_insn "*load_tp_di"
15798 [(set (match_operand:DI 0 "register_operand" "=r")
15799 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15801 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15802 [(set_attr "type" "imov")
15803 (set_attr "modrm" "0")
15804 (set_attr "length" "7")
15805 (set_attr "memory" "load")
15806 (set_attr "imm_disp" "false")])
15808 (define_insn "*add_tp_di"
15809 [(set (match_operand:DI 0 "register_operand" "=r")
15810 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15811 (match_operand:DI 1 "register_operand" "0")))
15812 (clobber (reg:CC FLAGS_REG))]
15814 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15815 [(set_attr "type" "alu")
15816 (set_attr "modrm" "0")
15817 (set_attr "length" "7")
15818 (set_attr "memory" "load")
15819 (set_attr "imm_disp" "false")])
15821 ;; GNU2 TLS patterns can be split.
15823 (define_expand "tls_dynamic_gnu2_32"
15824 [(set (match_dup 3)
15825 (plus:SI (match_operand:SI 2 "register_operand" "")
15827 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15830 [(set (match_operand:SI 0 "register_operand" "")
15831 (unspec:SI [(match_dup 1) (match_dup 3)
15832 (match_dup 2) (reg:SI SP_REG)]
15834 (clobber (reg:CC FLAGS_REG))])]
15835 "!TARGET_64BIT && TARGET_GNU2_TLS"
15837 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15838 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15841 (define_insn "*tls_dynamic_lea_32"
15842 [(set (match_operand:SI 0 "register_operand" "=r")
15843 (plus:SI (match_operand:SI 1 "register_operand" "b")
15845 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15846 UNSPEC_TLSDESC))))]
15847 "!TARGET_64BIT && TARGET_GNU2_TLS"
15848 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15849 [(set_attr "type" "lea")
15850 (set_attr "mode" "SI")
15851 (set_attr "length" "6")
15852 (set_attr "length_address" "4")])
15854 (define_insn "*tls_dynamic_call_32"
15855 [(set (match_operand:SI 0 "register_operand" "=a")
15856 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15857 (match_operand:SI 2 "register_operand" "0")
15858 ;; we have to make sure %ebx still points to the GOT
15859 (match_operand:SI 3 "register_operand" "b")
15862 (clobber (reg:CC FLAGS_REG))]
15863 "!TARGET_64BIT && TARGET_GNU2_TLS"
15864 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15865 [(set_attr "type" "call")
15866 (set_attr "length" "2")
15867 (set_attr "length_address" "0")])
15869 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15870 [(set (match_operand:SI 0 "register_operand" "=&a")
15872 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15873 (match_operand:SI 4 "" "")
15874 (match_operand:SI 2 "register_operand" "b")
15877 (const:SI (unspec:SI
15878 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15880 (clobber (reg:CC FLAGS_REG))]
15881 "!TARGET_64BIT && TARGET_GNU2_TLS"
15884 [(set (match_dup 0) (match_dup 5))]
15886 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15887 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15890 (define_expand "tls_dynamic_gnu2_64"
15891 [(set (match_dup 2)
15892 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15895 [(set (match_operand:DI 0 "register_operand" "")
15896 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15898 (clobber (reg:CC FLAGS_REG))])]
15899 "TARGET_64BIT && TARGET_GNU2_TLS"
15901 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15902 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15905 (define_insn "*tls_dynamic_lea_64"
15906 [(set (match_operand:DI 0 "register_operand" "=r")
15907 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15909 "TARGET_64BIT && TARGET_GNU2_TLS"
15910 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15911 [(set_attr "type" "lea")
15912 (set_attr "mode" "DI")
15913 (set_attr "length" "7")
15914 (set_attr "length_address" "4")])
15916 (define_insn "*tls_dynamic_call_64"
15917 [(set (match_operand:DI 0 "register_operand" "=a")
15918 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15919 (match_operand:DI 2 "register_operand" "0")
15922 (clobber (reg:CC FLAGS_REG))]
15923 "TARGET_64BIT && TARGET_GNU2_TLS"
15924 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15925 [(set_attr "type" "call")
15926 (set_attr "length" "2")
15927 (set_attr "length_address" "0")])
15929 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15930 [(set (match_operand:DI 0 "register_operand" "=&a")
15932 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15933 (match_operand:DI 3 "" "")
15936 (const:DI (unspec:DI
15937 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15939 (clobber (reg:CC FLAGS_REG))]
15940 "TARGET_64BIT && TARGET_GNU2_TLS"
15943 [(set (match_dup 0) (match_dup 4))]
15945 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15946 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15951 ;; These patterns match the binary 387 instructions for addM3, subM3,
15952 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15953 ;; SFmode. The first is the normal insn, the second the same insn but
15954 ;; with one operand a conversion, and the third the same insn but with
15955 ;; the other operand a conversion. The conversion may be SFmode or
15956 ;; SImode if the target mode DFmode, but only SImode if the target mode
15959 ;; Gcc is slightly more smart about handling normal two address instructions
15960 ;; so use special patterns for add and mull.
15962 (define_insn "*fop_<mode>_comm_mixed"
15963 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15964 (match_operator:MODEF 3 "binary_fp_operator"
15965 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15966 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15967 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15968 && COMMUTATIVE_ARITH_P (operands[3])
15969 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15970 "* return output_387_binary_op (insn, operands);"
15971 [(set (attr "type")
15972 (if_then_else (eq_attr "alternative" "1")
15973 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15974 (const_string "ssemul")
15975 (const_string "sseadd"))
15976 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15977 (const_string "fmul")
15978 (const_string "fop"))))
15979 (set_attr "mode" "<MODE>")])
15981 (define_insn "*fop_<mode>_comm_sse"
15982 [(set (match_operand:MODEF 0 "register_operand" "=x")
15983 (match_operator:MODEF 3 "binary_fp_operator"
15984 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15985 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15986 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15987 && COMMUTATIVE_ARITH_P (operands[3])
15988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15989 "* return output_387_binary_op (insn, operands);"
15990 [(set (attr "type")
15991 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15992 (const_string "ssemul")
15993 (const_string "sseadd")))
15994 (set_attr "mode" "<MODE>")])
15996 (define_insn "*fop_<mode>_comm_i387"
15997 [(set (match_operand:MODEF 0 "register_operand" "=f")
15998 (match_operator:MODEF 3 "binary_fp_operator"
15999 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16000 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16002 && COMMUTATIVE_ARITH_P (operands[3])
16003 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16004 "* return output_387_binary_op (insn, operands);"
16005 [(set (attr "type")
16006 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16007 (const_string "fmul")
16008 (const_string "fop")))
16009 (set_attr "mode" "<MODE>")])
16011 (define_insn "*fop_<mode>_1_mixed"
16012 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16013 (match_operator:MODEF 3 "binary_fp_operator"
16014 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16015 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16016 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16017 && !COMMUTATIVE_ARITH_P (operands[3])
16018 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16019 "* return output_387_binary_op (insn, operands);"
16020 [(set (attr "type")
16021 (cond [(and (eq_attr "alternative" "2")
16022 (match_operand:MODEF 3 "mult_operator" ""))
16023 (const_string "ssemul")
16024 (and (eq_attr "alternative" "2")
16025 (match_operand:MODEF 3 "div_operator" ""))
16026 (const_string "ssediv")
16027 (eq_attr "alternative" "2")
16028 (const_string "sseadd")
16029 (match_operand:MODEF 3 "mult_operator" "")
16030 (const_string "fmul")
16031 (match_operand:MODEF 3 "div_operator" "")
16032 (const_string "fdiv")
16034 (const_string "fop")))
16035 (set_attr "mode" "<MODE>")])
16037 (define_insn "*rcpsf2_sse"
16038 [(set (match_operand:SF 0 "register_operand" "=x")
16039 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16042 "rcpss\t{%1, %0|%0, %1}"
16043 [(set_attr "type" "sse")
16044 (set_attr "mode" "SF")])
16046 (define_insn "*fop_<mode>_1_sse"
16047 [(set (match_operand:MODEF 0 "register_operand" "=x")
16048 (match_operator:MODEF 3 "binary_fp_operator"
16049 [(match_operand:MODEF 1 "register_operand" "0")
16050 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16051 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16052 && !COMMUTATIVE_ARITH_P (operands[3])"
16053 "* return output_387_binary_op (insn, operands);"
16054 [(set (attr "type")
16055 (cond [(match_operand:MODEF 3 "mult_operator" "")
16056 (const_string "ssemul")
16057 (match_operand:MODEF 3 "div_operator" "")
16058 (const_string "ssediv")
16060 (const_string "sseadd")))
16061 (set_attr "mode" "<MODE>")])
16063 ;; This pattern is not fully shadowed by the pattern above.
16064 (define_insn "*fop_<mode>_1_i387"
16065 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16066 (match_operator:MODEF 3 "binary_fp_operator"
16067 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16068 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16069 "TARGET_80387 && !TARGET_SSE_MATH
16070 && !COMMUTATIVE_ARITH_P (operands[3])
16071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16072 "* return output_387_binary_op (insn, operands);"
16073 [(set (attr "type")
16074 (cond [(match_operand:MODEF 3 "mult_operator" "")
16075 (const_string "fmul")
16076 (match_operand:MODEF 3 "div_operator" "")
16077 (const_string "fdiv")
16079 (const_string "fop")))
16080 (set_attr "mode" "<MODE>")])
16082 ;; ??? Add SSE splitters for these!
16083 (define_insn "*fop_<MODEF:mode>_2_i387"
16084 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16085 (match_operator:MODEF 3 "binary_fp_operator"
16087 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16088 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16089 "TARGET_80387 && !TARGET_SSE_MATH
16090 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16091 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16092 [(set (attr "type")
16093 (cond [(match_operand:MODEF 3 "mult_operator" "")
16094 (const_string "fmul")
16095 (match_operand:MODEF 3 "div_operator" "")
16096 (const_string "fdiv")
16098 (const_string "fop")))
16099 (set_attr "fp_int_src" "true")
16100 (set_attr "mode" "<X87MODEI12:MODE>")])
16102 (define_insn "*fop_<MODEF:mode>_3_i387"
16103 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16104 (match_operator:MODEF 3 "binary_fp_operator"
16105 [(match_operand:MODEF 1 "register_operand" "0,0")
16107 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16108 "TARGET_80387 && !TARGET_SSE_MATH
16109 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16110 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16111 [(set (attr "type")
16112 (cond [(match_operand:MODEF 3 "mult_operator" "")
16113 (const_string "fmul")
16114 (match_operand:MODEF 3 "div_operator" "")
16115 (const_string "fdiv")
16117 (const_string "fop")))
16118 (set_attr "fp_int_src" "true")
16119 (set_attr "mode" "<MODE>")])
16121 (define_insn "*fop_df_4_i387"
16122 [(set (match_operand:DF 0 "register_operand" "=f,f")
16123 (match_operator:DF 3 "binary_fp_operator"
16125 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16126 (match_operand:DF 2 "register_operand" "0,f")]))]
16127 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16128 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16129 "* return output_387_binary_op (insn, operands);"
16130 [(set (attr "type")
16131 (cond [(match_operand:DF 3 "mult_operator" "")
16132 (const_string "fmul")
16133 (match_operand:DF 3 "div_operator" "")
16134 (const_string "fdiv")
16136 (const_string "fop")))
16137 (set_attr "mode" "SF")])
16139 (define_insn "*fop_df_5_i387"
16140 [(set (match_operand:DF 0 "register_operand" "=f,f")
16141 (match_operator:DF 3 "binary_fp_operator"
16142 [(match_operand:DF 1 "register_operand" "0,f")
16144 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16145 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16146 "* return output_387_binary_op (insn, operands);"
16147 [(set (attr "type")
16148 (cond [(match_operand:DF 3 "mult_operator" "")
16149 (const_string "fmul")
16150 (match_operand:DF 3 "div_operator" "")
16151 (const_string "fdiv")
16153 (const_string "fop")))
16154 (set_attr "mode" "SF")])
16156 (define_insn "*fop_df_6_i387"
16157 [(set (match_operand:DF 0 "register_operand" "=f,f")
16158 (match_operator:DF 3 "binary_fp_operator"
16160 (match_operand:SF 1 "register_operand" "0,f"))
16162 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16163 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16164 "* return output_387_binary_op (insn, operands);"
16165 [(set (attr "type")
16166 (cond [(match_operand:DF 3 "mult_operator" "")
16167 (const_string "fmul")
16168 (match_operand:DF 3 "div_operator" "")
16169 (const_string "fdiv")
16171 (const_string "fop")))
16172 (set_attr "mode" "SF")])
16174 (define_insn "*fop_xf_comm_i387"
16175 [(set (match_operand:XF 0 "register_operand" "=f")
16176 (match_operator:XF 3 "binary_fp_operator"
16177 [(match_operand:XF 1 "register_operand" "%0")
16178 (match_operand:XF 2 "register_operand" "f")]))]
16180 && COMMUTATIVE_ARITH_P (operands[3])"
16181 "* return output_387_binary_op (insn, operands);"
16182 [(set (attr "type")
16183 (if_then_else (match_operand:XF 3 "mult_operator" "")
16184 (const_string "fmul")
16185 (const_string "fop")))
16186 (set_attr "mode" "XF")])
16188 (define_insn "*fop_xf_1_i387"
16189 [(set (match_operand:XF 0 "register_operand" "=f,f")
16190 (match_operator:XF 3 "binary_fp_operator"
16191 [(match_operand:XF 1 "register_operand" "0,f")
16192 (match_operand:XF 2 "register_operand" "f,0")]))]
16194 && !COMMUTATIVE_ARITH_P (operands[3])"
16195 "* return output_387_binary_op (insn, operands);"
16196 [(set (attr "type")
16197 (cond [(match_operand:XF 3 "mult_operator" "")
16198 (const_string "fmul")
16199 (match_operand:XF 3 "div_operator" "")
16200 (const_string "fdiv")
16202 (const_string "fop")))
16203 (set_attr "mode" "XF")])
16205 (define_insn "*fop_xf_2_i387"
16206 [(set (match_operand:XF 0 "register_operand" "=f,f")
16207 (match_operator:XF 3 "binary_fp_operator"
16209 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16210 (match_operand:XF 2 "register_operand" "0,0")]))]
16211 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16212 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16213 [(set (attr "type")
16214 (cond [(match_operand:XF 3 "mult_operator" "")
16215 (const_string "fmul")
16216 (match_operand:XF 3 "div_operator" "")
16217 (const_string "fdiv")
16219 (const_string "fop")))
16220 (set_attr "fp_int_src" "true")
16221 (set_attr "mode" "<MODE>")])
16223 (define_insn "*fop_xf_3_i387"
16224 [(set (match_operand:XF 0 "register_operand" "=f,f")
16225 (match_operator:XF 3 "binary_fp_operator"
16226 [(match_operand:XF 1 "register_operand" "0,0")
16228 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16229 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16230 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16231 [(set (attr "type")
16232 (cond [(match_operand:XF 3 "mult_operator" "")
16233 (const_string "fmul")
16234 (match_operand:XF 3 "div_operator" "")
16235 (const_string "fdiv")
16237 (const_string "fop")))
16238 (set_attr "fp_int_src" "true")
16239 (set_attr "mode" "<MODE>")])
16241 (define_insn "*fop_xf_4_i387"
16242 [(set (match_operand:XF 0 "register_operand" "=f,f")
16243 (match_operator:XF 3 "binary_fp_operator"
16245 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16246 (match_operand:XF 2 "register_operand" "0,f")]))]
16248 "* return output_387_binary_op (insn, operands);"
16249 [(set (attr "type")
16250 (cond [(match_operand:XF 3 "mult_operator" "")
16251 (const_string "fmul")
16252 (match_operand:XF 3 "div_operator" "")
16253 (const_string "fdiv")
16255 (const_string "fop")))
16256 (set_attr "mode" "<MODE>")])
16258 (define_insn "*fop_xf_5_i387"
16259 [(set (match_operand:XF 0 "register_operand" "=f,f")
16260 (match_operator:XF 3 "binary_fp_operator"
16261 [(match_operand:XF 1 "register_operand" "0,f")
16263 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16265 "* return output_387_binary_op (insn, operands);"
16266 [(set (attr "type")
16267 (cond [(match_operand:XF 3 "mult_operator" "")
16268 (const_string "fmul")
16269 (match_operand:XF 3 "div_operator" "")
16270 (const_string "fdiv")
16272 (const_string "fop")))
16273 (set_attr "mode" "<MODE>")])
16275 (define_insn "*fop_xf_6_i387"
16276 [(set (match_operand:XF 0 "register_operand" "=f,f")
16277 (match_operator:XF 3 "binary_fp_operator"
16279 (match_operand:MODEF 1 "register_operand" "0,f"))
16281 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16283 "* return output_387_binary_op (insn, operands);"
16284 [(set (attr "type")
16285 (cond [(match_operand:XF 3 "mult_operator" "")
16286 (const_string "fmul")
16287 (match_operand:XF 3 "div_operator" "")
16288 (const_string "fdiv")
16290 (const_string "fop")))
16291 (set_attr "mode" "<MODE>")])
16294 [(set (match_operand 0 "register_operand" "")
16295 (match_operator 3 "binary_fp_operator"
16296 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16297 (match_operand 2 "register_operand" "")]))]
16299 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16302 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16303 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16304 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16305 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16306 GET_MODE (operands[3]),
16309 ix86_free_from_memory (GET_MODE (operands[1]));
16314 [(set (match_operand 0 "register_operand" "")
16315 (match_operator 3 "binary_fp_operator"
16316 [(match_operand 1 "register_operand" "")
16317 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16319 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16322 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16323 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16324 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16325 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16326 GET_MODE (operands[3]),
16329 ix86_free_from_memory (GET_MODE (operands[2]));
16333 ;; FPU special functions.
16335 ;; This pattern implements a no-op XFmode truncation for
16336 ;; all fancy i386 XFmode math functions.
16338 (define_insn "truncxf<mode>2_i387_noop_unspec"
16339 [(set (match_operand:MODEF 0 "register_operand" "=f")
16340 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16341 UNSPEC_TRUNC_NOOP))]
16342 "TARGET_USE_FANCY_MATH_387"
16343 "* return output_387_reg_move (insn, operands);"
16344 [(set_attr "type" "fmov")
16345 (set_attr "mode" "<MODE>")])
16347 (define_insn "sqrtxf2"
16348 [(set (match_operand:XF 0 "register_operand" "=f")
16349 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16350 "TARGET_USE_FANCY_MATH_387"
16352 [(set_attr "type" "fpspc")
16353 (set_attr "mode" "XF")
16354 (set_attr "athlon_decode" "direct")
16355 (set_attr "amdfam10_decode" "direct")])
16357 (define_insn "sqrt_extend<mode>xf2_i387"
16358 [(set (match_operand:XF 0 "register_operand" "=f")
16361 (match_operand:MODEF 1 "register_operand" "0"))))]
16362 "TARGET_USE_FANCY_MATH_387"
16364 [(set_attr "type" "fpspc")
16365 (set_attr "mode" "XF")
16366 (set_attr "athlon_decode" "direct")
16367 (set_attr "amdfam10_decode" "direct")])
16369 (define_insn "*rsqrtsf2_sse"
16370 [(set (match_operand:SF 0 "register_operand" "=x")
16371 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16374 "rsqrtss\t{%1, %0|%0, %1}"
16375 [(set_attr "type" "sse")
16376 (set_attr "mode" "SF")])
16378 (define_expand "rsqrtsf2"
16379 [(set (match_operand:SF 0 "register_operand" "")
16380 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16384 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16388 (define_insn "*sqrt<mode>2_sse"
16389 [(set (match_operand:MODEF 0 "register_operand" "=x")
16391 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16392 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16393 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16394 [(set_attr "type" "sse")
16395 (set_attr "mode" "<MODE>")
16396 (set_attr "athlon_decode" "*")
16397 (set_attr "amdfam10_decode" "*")])
16399 (define_expand "sqrt<mode>2"
16400 [(set (match_operand:MODEF 0 "register_operand" "")
16402 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16403 "TARGET_USE_FANCY_MATH_387
16404 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16406 if (<MODE>mode == SFmode
16407 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16408 && flag_finite_math_only && !flag_trapping_math
16409 && flag_unsafe_math_optimizations)
16411 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16415 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16417 rtx op0 = gen_reg_rtx (XFmode);
16418 rtx op1 = force_reg (<MODE>mode, operands[1]);
16420 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16421 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16426 (define_insn "fpremxf4_i387"
16427 [(set (match_operand:XF 0 "register_operand" "=f")
16428 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16429 (match_operand:XF 3 "register_operand" "1")]
16431 (set (match_operand:XF 1 "register_operand" "=u")
16432 (unspec:XF [(match_dup 2) (match_dup 3)]
16434 (set (reg:CCFP FPSR_REG)
16435 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16437 "TARGET_USE_FANCY_MATH_387"
16439 [(set_attr "type" "fpspc")
16440 (set_attr "mode" "XF")])
16442 (define_expand "fmodxf3"
16443 [(use (match_operand:XF 0 "register_operand" ""))
16444 (use (match_operand:XF 1 "general_operand" ""))
16445 (use (match_operand:XF 2 "general_operand" ""))]
16446 "TARGET_USE_FANCY_MATH_387"
16448 rtx label = gen_label_rtx ();
16450 rtx op1 = gen_reg_rtx (XFmode);
16451 rtx op2 = gen_reg_rtx (XFmode);
16453 emit_move_insn (op1, operands[1]);
16454 emit_move_insn (op2, operands[2]);
16456 emit_label (label);
16457 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16458 ix86_emit_fp_unordered_jump (label);
16459 LABEL_NUSES (label) = 1;
16461 emit_move_insn (operands[0], op1);
16465 (define_expand "fmod<mode>3"
16466 [(use (match_operand:MODEF 0 "register_operand" ""))
16467 (use (match_operand:MODEF 1 "general_operand" ""))
16468 (use (match_operand:MODEF 2 "general_operand" ""))]
16469 "TARGET_USE_FANCY_MATH_387"
16471 rtx label = gen_label_rtx ();
16473 rtx op1 = gen_reg_rtx (XFmode);
16474 rtx op2 = gen_reg_rtx (XFmode);
16476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16477 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16479 emit_label (label);
16480 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16481 ix86_emit_fp_unordered_jump (label);
16482 LABEL_NUSES (label) = 1;
16484 /* Truncate the result properly for strict SSE math. */
16485 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16486 && !TARGET_MIX_SSE_I387)
16487 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16489 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16494 (define_insn "fprem1xf4_i387"
16495 [(set (match_operand:XF 0 "register_operand" "=f")
16496 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16497 (match_operand:XF 3 "register_operand" "1")]
16499 (set (match_operand:XF 1 "register_operand" "=u")
16500 (unspec:XF [(match_dup 2) (match_dup 3)]
16502 (set (reg:CCFP FPSR_REG)
16503 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16505 "TARGET_USE_FANCY_MATH_387"
16507 [(set_attr "type" "fpspc")
16508 (set_attr "mode" "XF")])
16510 (define_expand "remainderxf3"
16511 [(use (match_operand:XF 0 "register_operand" ""))
16512 (use (match_operand:XF 1 "general_operand" ""))
16513 (use (match_operand:XF 2 "general_operand" ""))]
16514 "TARGET_USE_FANCY_MATH_387"
16516 rtx label = gen_label_rtx ();
16518 rtx op1 = gen_reg_rtx (XFmode);
16519 rtx op2 = gen_reg_rtx (XFmode);
16521 emit_move_insn (op1, operands[1]);
16522 emit_move_insn (op2, operands[2]);
16524 emit_label (label);
16525 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16526 ix86_emit_fp_unordered_jump (label);
16527 LABEL_NUSES (label) = 1;
16529 emit_move_insn (operands[0], op1);
16533 (define_expand "remainder<mode>3"
16534 [(use (match_operand:MODEF 0 "register_operand" ""))
16535 (use (match_operand:MODEF 1 "general_operand" ""))
16536 (use (match_operand:MODEF 2 "general_operand" ""))]
16537 "TARGET_USE_FANCY_MATH_387"
16539 rtx label = gen_label_rtx ();
16541 rtx op1 = gen_reg_rtx (XFmode);
16542 rtx op2 = gen_reg_rtx (XFmode);
16544 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16545 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16547 emit_label (label);
16549 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16550 ix86_emit_fp_unordered_jump (label);
16551 LABEL_NUSES (label) = 1;
16553 /* Truncate the result properly for strict SSE math. */
16554 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16555 && !TARGET_MIX_SSE_I387)
16556 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16558 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16563 (define_insn "*sinxf2_i387"
16564 [(set (match_operand:XF 0 "register_operand" "=f")
16565 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16566 "TARGET_USE_FANCY_MATH_387
16567 && flag_unsafe_math_optimizations"
16569 [(set_attr "type" "fpspc")
16570 (set_attr "mode" "XF")])
16572 (define_insn "*sin_extend<mode>xf2_i387"
16573 [(set (match_operand:XF 0 "register_operand" "=f")
16574 (unspec:XF [(float_extend:XF
16575 (match_operand:MODEF 1 "register_operand" "0"))]
16577 "TARGET_USE_FANCY_MATH_387
16578 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16579 || TARGET_MIX_SSE_I387)
16580 && flag_unsafe_math_optimizations"
16582 [(set_attr "type" "fpspc")
16583 (set_attr "mode" "XF")])
16585 (define_insn "*cosxf2_i387"
16586 [(set (match_operand:XF 0 "register_operand" "=f")
16587 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16588 "TARGET_USE_FANCY_MATH_387
16589 && flag_unsafe_math_optimizations"
16591 [(set_attr "type" "fpspc")
16592 (set_attr "mode" "XF")])
16594 (define_insn "*cos_extend<mode>xf2_i387"
16595 [(set (match_operand:XF 0 "register_operand" "=f")
16596 (unspec:XF [(float_extend:XF
16597 (match_operand:MODEF 1 "register_operand" "0"))]
16599 "TARGET_USE_FANCY_MATH_387
16600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16601 || TARGET_MIX_SSE_I387)
16602 && flag_unsafe_math_optimizations"
16604 [(set_attr "type" "fpspc")
16605 (set_attr "mode" "XF")])
16607 ;; When sincos pattern is defined, sin and cos builtin functions will be
16608 ;; expanded to sincos pattern with one of its outputs left unused.
16609 ;; CSE pass will figure out if two sincos patterns can be combined,
16610 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16611 ;; depending on the unused output.
16613 (define_insn "sincosxf3"
16614 [(set (match_operand:XF 0 "register_operand" "=f")
16615 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16616 UNSPEC_SINCOS_COS))
16617 (set (match_operand:XF 1 "register_operand" "=u")
16618 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16619 "TARGET_USE_FANCY_MATH_387
16620 && flag_unsafe_math_optimizations"
16622 [(set_attr "type" "fpspc")
16623 (set_attr "mode" "XF")])
16626 [(set (match_operand:XF 0 "register_operand" "")
16627 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16628 UNSPEC_SINCOS_COS))
16629 (set (match_operand:XF 1 "register_operand" "")
16630 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16631 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16632 && !(reload_completed || reload_in_progress)"
16633 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16637 [(set (match_operand:XF 0 "register_operand" "")
16638 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16639 UNSPEC_SINCOS_COS))
16640 (set (match_operand:XF 1 "register_operand" "")
16641 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16642 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16643 && !(reload_completed || reload_in_progress)"
16644 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16647 (define_insn "sincos_extend<mode>xf3_i387"
16648 [(set (match_operand:XF 0 "register_operand" "=f")
16649 (unspec:XF [(float_extend:XF
16650 (match_operand:MODEF 2 "register_operand" "0"))]
16651 UNSPEC_SINCOS_COS))
16652 (set (match_operand:XF 1 "register_operand" "=u")
16653 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16654 "TARGET_USE_FANCY_MATH_387
16655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16656 || TARGET_MIX_SSE_I387)
16657 && flag_unsafe_math_optimizations"
16659 [(set_attr "type" "fpspc")
16660 (set_attr "mode" "XF")])
16663 [(set (match_operand:XF 0 "register_operand" "")
16664 (unspec:XF [(float_extend:XF
16665 (match_operand:MODEF 2 "register_operand" ""))]
16666 UNSPEC_SINCOS_COS))
16667 (set (match_operand:XF 1 "register_operand" "")
16668 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16669 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16670 && !(reload_completed || reload_in_progress)"
16671 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16675 [(set (match_operand:XF 0 "register_operand" "")
16676 (unspec:XF [(float_extend:XF
16677 (match_operand:MODEF 2 "register_operand" ""))]
16678 UNSPEC_SINCOS_COS))
16679 (set (match_operand:XF 1 "register_operand" "")
16680 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16681 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16682 && !(reload_completed || reload_in_progress)"
16683 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16686 (define_expand "sincos<mode>3"
16687 [(use (match_operand:MODEF 0 "register_operand" ""))
16688 (use (match_operand:MODEF 1 "register_operand" ""))
16689 (use (match_operand:MODEF 2 "register_operand" ""))]
16690 "TARGET_USE_FANCY_MATH_387
16691 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16692 || TARGET_MIX_SSE_I387)
16693 && flag_unsafe_math_optimizations"
16695 rtx op0 = gen_reg_rtx (XFmode);
16696 rtx op1 = gen_reg_rtx (XFmode);
16698 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16699 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16704 (define_insn "fptanxf4_i387"
16705 [(set (match_operand:XF 0 "register_operand" "=f")
16706 (match_operand:XF 3 "const_double_operand" "F"))
16707 (set (match_operand:XF 1 "register_operand" "=u")
16708 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16710 "TARGET_USE_FANCY_MATH_387
16711 && flag_unsafe_math_optimizations
16712 && standard_80387_constant_p (operands[3]) == 2"
16714 [(set_attr "type" "fpspc")
16715 (set_attr "mode" "XF")])
16717 (define_insn "fptan_extend<mode>xf4_i387"
16718 [(set (match_operand:MODEF 0 "register_operand" "=f")
16719 (match_operand:MODEF 3 "const_double_operand" "F"))
16720 (set (match_operand:XF 1 "register_operand" "=u")
16721 (unspec:XF [(float_extend:XF
16722 (match_operand:MODEF 2 "register_operand" "0"))]
16724 "TARGET_USE_FANCY_MATH_387
16725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16726 || TARGET_MIX_SSE_I387)
16727 && flag_unsafe_math_optimizations
16728 && standard_80387_constant_p (operands[3]) == 2"
16730 [(set_attr "type" "fpspc")
16731 (set_attr "mode" "XF")])
16733 (define_expand "tanxf2"
16734 [(use (match_operand:XF 0 "register_operand" ""))
16735 (use (match_operand:XF 1 "register_operand" ""))]
16736 "TARGET_USE_FANCY_MATH_387
16737 && flag_unsafe_math_optimizations"
16739 rtx one = gen_reg_rtx (XFmode);
16740 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16742 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16746 (define_expand "tan<mode>2"
16747 [(use (match_operand:MODEF 0 "register_operand" ""))
16748 (use (match_operand:MODEF 1 "register_operand" ""))]
16749 "TARGET_USE_FANCY_MATH_387
16750 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16751 || TARGET_MIX_SSE_I387)
16752 && flag_unsafe_math_optimizations"
16754 rtx op0 = gen_reg_rtx (XFmode);
16756 rtx one = gen_reg_rtx (<MODE>mode);
16757 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16759 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16760 operands[1], op2));
16761 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16765 (define_insn "*fpatanxf3_i387"
16766 [(set (match_operand:XF 0 "register_operand" "=f")
16767 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16768 (match_operand:XF 2 "register_operand" "u")]
16770 (clobber (match_scratch:XF 3 "=2"))]
16771 "TARGET_USE_FANCY_MATH_387
16772 && flag_unsafe_math_optimizations"
16774 [(set_attr "type" "fpspc")
16775 (set_attr "mode" "XF")])
16777 (define_insn "fpatan_extend<mode>xf3_i387"
16778 [(set (match_operand:XF 0 "register_operand" "=f")
16779 (unspec:XF [(float_extend:XF
16780 (match_operand:MODEF 1 "register_operand" "0"))
16782 (match_operand:MODEF 2 "register_operand" "u"))]
16784 (clobber (match_scratch:XF 3 "=2"))]
16785 "TARGET_USE_FANCY_MATH_387
16786 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16787 || TARGET_MIX_SSE_I387)
16788 && flag_unsafe_math_optimizations"
16790 [(set_attr "type" "fpspc")
16791 (set_attr "mode" "XF")])
16793 (define_expand "atan2xf3"
16794 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16795 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16796 (match_operand:XF 1 "register_operand" "")]
16798 (clobber (match_scratch:XF 3 ""))])]
16799 "TARGET_USE_FANCY_MATH_387
16800 && flag_unsafe_math_optimizations"
16803 (define_expand "atan2<mode>3"
16804 [(use (match_operand:MODEF 0 "register_operand" ""))
16805 (use (match_operand:MODEF 1 "register_operand" ""))
16806 (use (match_operand:MODEF 2 "register_operand" ""))]
16807 "TARGET_USE_FANCY_MATH_387
16808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16809 || TARGET_MIX_SSE_I387)
16810 && flag_unsafe_math_optimizations"
16812 rtx op0 = gen_reg_rtx (XFmode);
16814 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16815 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16819 (define_expand "atanxf2"
16820 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16821 (unspec:XF [(match_dup 2)
16822 (match_operand:XF 1 "register_operand" "")]
16824 (clobber (match_scratch:XF 3 ""))])]
16825 "TARGET_USE_FANCY_MATH_387
16826 && flag_unsafe_math_optimizations"
16828 operands[2] = gen_reg_rtx (XFmode);
16829 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16832 (define_expand "atan<mode>2"
16833 [(use (match_operand:MODEF 0 "register_operand" ""))
16834 (use (match_operand:MODEF 1 "register_operand" ""))]
16835 "TARGET_USE_FANCY_MATH_387
16836 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16837 || TARGET_MIX_SSE_I387)
16838 && flag_unsafe_math_optimizations"
16840 rtx op0 = gen_reg_rtx (XFmode);
16842 rtx op2 = gen_reg_rtx (<MODE>mode);
16843 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16845 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16846 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16850 (define_expand "asinxf2"
16851 [(set (match_dup 2)
16852 (mult:XF (match_operand:XF 1 "register_operand" "")
16854 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16855 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16856 (parallel [(set (match_operand:XF 0 "register_operand" "")
16857 (unspec:XF [(match_dup 5) (match_dup 1)]
16859 (clobber (match_scratch:XF 6 ""))])]
16860 "TARGET_USE_FANCY_MATH_387
16861 && flag_unsafe_math_optimizations && !optimize_size"
16865 for (i = 2; i < 6; i++)
16866 operands[i] = gen_reg_rtx (XFmode);
16868 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16871 (define_expand "asin<mode>2"
16872 [(use (match_operand:MODEF 0 "register_operand" ""))
16873 (use (match_operand:MODEF 1 "general_operand" ""))]
16874 "TARGET_USE_FANCY_MATH_387
16875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16876 || TARGET_MIX_SSE_I387)
16877 && flag_unsafe_math_optimizations && !optimize_size"
16879 rtx op0 = gen_reg_rtx (XFmode);
16880 rtx op1 = gen_reg_rtx (XFmode);
16882 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16883 emit_insn (gen_asinxf2 (op0, op1));
16884 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16888 (define_expand "acosxf2"
16889 [(set (match_dup 2)
16890 (mult:XF (match_operand:XF 1 "register_operand" "")
16892 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16893 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16894 (parallel [(set (match_operand:XF 0 "register_operand" "")
16895 (unspec:XF [(match_dup 1) (match_dup 5)]
16897 (clobber (match_scratch:XF 6 ""))])]
16898 "TARGET_USE_FANCY_MATH_387
16899 && flag_unsafe_math_optimizations && !optimize_size"
16903 for (i = 2; i < 6; i++)
16904 operands[i] = gen_reg_rtx (XFmode);
16906 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16909 (define_expand "acos<mode>2"
16910 [(use (match_operand:MODEF 0 "register_operand" ""))
16911 (use (match_operand:MODEF 1 "general_operand" ""))]
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 && !optimize_size"
16917 rtx op0 = gen_reg_rtx (XFmode);
16918 rtx op1 = gen_reg_rtx (XFmode);
16920 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16921 emit_insn (gen_acosxf2 (op0, op1));
16922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16926 (define_insn "fyl2xxf3_i387"
16927 [(set (match_operand:XF 0 "register_operand" "=f")
16928 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16929 (match_operand:XF 2 "register_operand" "u")]
16931 (clobber (match_scratch:XF 3 "=2"))]
16932 "TARGET_USE_FANCY_MATH_387
16933 && flag_unsafe_math_optimizations"
16935 [(set_attr "type" "fpspc")
16936 (set_attr "mode" "XF")])
16938 (define_insn "fyl2x_extend<mode>xf3_i387"
16939 [(set (match_operand:XF 0 "register_operand" "=f")
16940 (unspec:XF [(float_extend:XF
16941 (match_operand:MODEF 1 "register_operand" "0"))
16942 (match_operand:XF 2 "register_operand" "u")]
16944 (clobber (match_scratch:XF 3 "=2"))]
16945 "TARGET_USE_FANCY_MATH_387
16946 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16947 || TARGET_MIX_SSE_I387)
16948 && flag_unsafe_math_optimizations"
16950 [(set_attr "type" "fpspc")
16951 (set_attr "mode" "XF")])
16953 (define_expand "logxf2"
16954 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16955 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16956 (match_dup 2)] UNSPEC_FYL2X))
16957 (clobber (match_scratch:XF 3 ""))])]
16958 "TARGET_USE_FANCY_MATH_387
16959 && flag_unsafe_math_optimizations"
16961 operands[2] = gen_reg_rtx (XFmode);
16962 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16965 (define_expand "log<mode>2"
16966 [(use (match_operand:MODEF 0 "register_operand" ""))
16967 (use (match_operand:MODEF 1 "register_operand" ""))]
16968 "TARGET_USE_FANCY_MATH_387
16969 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16970 || TARGET_MIX_SSE_I387)
16971 && flag_unsafe_math_optimizations"
16973 rtx op0 = gen_reg_rtx (XFmode);
16975 rtx op2 = gen_reg_rtx (XFmode);
16976 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16978 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16979 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16983 (define_expand "log10xf2"
16984 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16985 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16986 (match_dup 2)] UNSPEC_FYL2X))
16987 (clobber (match_scratch:XF 3 ""))])]
16988 "TARGET_USE_FANCY_MATH_387
16989 && flag_unsafe_math_optimizations"
16991 operands[2] = gen_reg_rtx (XFmode);
16992 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16995 (define_expand "log10<mode>2"
16996 [(use (match_operand:MODEF 0 "register_operand" ""))
16997 (use (match_operand:MODEF 1 "register_operand" ""))]
16998 "TARGET_USE_FANCY_MATH_387
16999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17000 || TARGET_MIX_SSE_I387)
17001 && flag_unsafe_math_optimizations"
17003 rtx op0 = gen_reg_rtx (XFmode);
17005 rtx op2 = gen_reg_rtx (XFmode);
17006 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17008 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17009 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17013 (define_expand "log2xf2"
17014 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17015 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17016 (match_dup 2)] UNSPEC_FYL2X))
17017 (clobber (match_scratch:XF 3 ""))])]
17018 "TARGET_USE_FANCY_MATH_387
17019 && flag_unsafe_math_optimizations"
17021 operands[2] = gen_reg_rtx (XFmode);
17022 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17025 (define_expand "log2<mode>2"
17026 [(use (match_operand:MODEF 0 "register_operand" ""))
17027 (use (match_operand:MODEF 1 "register_operand" ""))]
17028 "TARGET_USE_FANCY_MATH_387
17029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17030 || TARGET_MIX_SSE_I387)
17031 && flag_unsafe_math_optimizations"
17033 rtx op0 = gen_reg_rtx (XFmode);
17035 rtx op2 = gen_reg_rtx (XFmode);
17036 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17038 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17039 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17043 (define_insn "fyl2xp1xf3_i387"
17044 [(set (match_operand:XF 0 "register_operand" "=f")
17045 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17046 (match_operand:XF 2 "register_operand" "u")]
17048 (clobber (match_scratch:XF 3 "=2"))]
17049 "TARGET_USE_FANCY_MATH_387
17050 && flag_unsafe_math_optimizations"
17052 [(set_attr "type" "fpspc")
17053 (set_attr "mode" "XF")])
17055 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17056 [(set (match_operand:XF 0 "register_operand" "=f")
17057 (unspec:XF [(float_extend:XF
17058 (match_operand:MODEF 1 "register_operand" "0"))
17059 (match_operand:XF 2 "register_operand" "u")]
17061 (clobber (match_scratch:XF 3 "=2"))]
17062 "TARGET_USE_FANCY_MATH_387
17063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17064 || TARGET_MIX_SSE_I387)
17065 && flag_unsafe_math_optimizations"
17067 [(set_attr "type" "fpspc")
17068 (set_attr "mode" "XF")])
17070 (define_expand "log1pxf2"
17071 [(use (match_operand:XF 0 "register_operand" ""))
17072 (use (match_operand:XF 1 "register_operand" ""))]
17073 "TARGET_USE_FANCY_MATH_387
17074 && flag_unsafe_math_optimizations && !optimize_size"
17076 ix86_emit_i387_log1p (operands[0], operands[1]);
17080 (define_expand "log1p<mode>2"
17081 [(use (match_operand:MODEF 0 "register_operand" ""))
17082 (use (match_operand:MODEF 1 "register_operand" ""))]
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 && !optimize_size"
17088 rtx op0 = gen_reg_rtx (XFmode);
17090 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17092 ix86_emit_i387_log1p (op0, operands[1]);
17093 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17097 (define_insn "fxtractxf3_i387"
17098 [(set (match_operand:XF 0 "register_operand" "=f")
17099 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17100 UNSPEC_XTRACT_FRACT))
17101 (set (match_operand:XF 1 "register_operand" "=u")
17102 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17103 "TARGET_USE_FANCY_MATH_387
17104 && flag_unsafe_math_optimizations"
17106 [(set_attr "type" "fpspc")
17107 (set_attr "mode" "XF")])
17109 (define_insn "fxtract_extend<mode>xf3_i387"
17110 [(set (match_operand:XF 0 "register_operand" "=f")
17111 (unspec:XF [(float_extend:XF
17112 (match_operand:MODEF 2 "register_operand" "0"))]
17113 UNSPEC_XTRACT_FRACT))
17114 (set (match_operand:XF 1 "register_operand" "=u")
17115 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17116 "TARGET_USE_FANCY_MATH_387
17117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17118 || TARGET_MIX_SSE_I387)
17119 && flag_unsafe_math_optimizations"
17121 [(set_attr "type" "fpspc")
17122 (set_attr "mode" "XF")])
17124 (define_expand "logbxf2"
17125 [(parallel [(set (match_dup 2)
17126 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17127 UNSPEC_XTRACT_FRACT))
17128 (set (match_operand:XF 0 "register_operand" "")
17129 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17130 "TARGET_USE_FANCY_MATH_387
17131 && flag_unsafe_math_optimizations"
17133 operands[2] = gen_reg_rtx (XFmode);
17136 (define_expand "logb<mode>2"
17137 [(use (match_operand:MODEF 0 "register_operand" ""))
17138 (use (match_operand:MODEF 1 "register_operand" ""))]
17139 "TARGET_USE_FANCY_MATH_387
17140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17141 || TARGET_MIX_SSE_I387)
17142 && flag_unsafe_math_optimizations"
17144 rtx op0 = gen_reg_rtx (XFmode);
17145 rtx op1 = gen_reg_rtx (XFmode);
17147 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17148 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17152 (define_expand "ilogbxf2"
17153 [(use (match_operand:SI 0 "register_operand" ""))
17154 (use (match_operand:XF 1 "register_operand" ""))]
17155 "TARGET_USE_FANCY_MATH_387
17156 && flag_unsafe_math_optimizations && !optimize_size"
17158 rtx op0 = gen_reg_rtx (XFmode);
17159 rtx op1 = gen_reg_rtx (XFmode);
17161 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17162 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17166 (define_expand "ilogb<mode>2"
17167 [(use (match_operand:SI 0 "register_operand" ""))
17168 (use (match_operand:MODEF 1 "register_operand" ""))]
17169 "TARGET_USE_FANCY_MATH_387
17170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17171 || TARGET_MIX_SSE_I387)
17172 && flag_unsafe_math_optimizations && !optimize_size"
17174 rtx op0 = gen_reg_rtx (XFmode);
17175 rtx op1 = gen_reg_rtx (XFmode);
17177 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17178 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17182 (define_insn "*f2xm1xf2_i387"
17183 [(set (match_operand:XF 0 "register_operand" "=f")
17184 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17186 "TARGET_USE_FANCY_MATH_387
17187 && flag_unsafe_math_optimizations"
17189 [(set_attr "type" "fpspc")
17190 (set_attr "mode" "XF")])
17192 (define_insn "*fscalexf4_i387"
17193 [(set (match_operand:XF 0 "register_operand" "=f")
17194 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17195 (match_operand:XF 3 "register_operand" "1")]
17196 UNSPEC_FSCALE_FRACT))
17197 (set (match_operand:XF 1 "register_operand" "=u")
17198 (unspec:XF [(match_dup 2) (match_dup 3)]
17199 UNSPEC_FSCALE_EXP))]
17200 "TARGET_USE_FANCY_MATH_387
17201 && flag_unsafe_math_optimizations"
17203 [(set_attr "type" "fpspc")
17204 (set_attr "mode" "XF")])
17206 (define_expand "expNcorexf3"
17207 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17208 (match_operand:XF 2 "register_operand" "")))
17209 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17210 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17211 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17212 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17213 (parallel [(set (match_operand:XF 0 "register_operand" "")
17214 (unspec:XF [(match_dup 8) (match_dup 4)]
17215 UNSPEC_FSCALE_FRACT))
17217 (unspec:XF [(match_dup 8) (match_dup 4)]
17218 UNSPEC_FSCALE_EXP))])]
17219 "TARGET_USE_FANCY_MATH_387
17220 && flag_unsafe_math_optimizations && !optimize_size"
17224 for (i = 3; i < 10; i++)
17225 operands[i] = gen_reg_rtx (XFmode);
17227 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17230 (define_expand "expxf2"
17231 [(use (match_operand:XF 0 "register_operand" ""))
17232 (use (match_operand:XF 1 "register_operand" ""))]
17233 "TARGET_USE_FANCY_MATH_387
17234 && flag_unsafe_math_optimizations && !optimize_size"
17236 rtx op2 = gen_reg_rtx (XFmode);
17237 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17239 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17243 (define_expand "exp<mode>2"
17244 [(use (match_operand:MODEF 0 "register_operand" ""))
17245 (use (match_operand:MODEF 1 "general_operand" ""))]
17246 "TARGET_USE_FANCY_MATH_387
17247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17248 || TARGET_MIX_SSE_I387)
17249 && flag_unsafe_math_optimizations && !optimize_size"
17251 rtx op0 = gen_reg_rtx (XFmode);
17252 rtx op1 = gen_reg_rtx (XFmode);
17254 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17255 emit_insn (gen_expxf2 (op0, op1));
17256 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17260 (define_expand "exp10xf2"
17261 [(use (match_operand:XF 0 "register_operand" ""))
17262 (use (match_operand:XF 1 "register_operand" ""))]
17263 "TARGET_USE_FANCY_MATH_387
17264 && flag_unsafe_math_optimizations && !optimize_size"
17266 rtx op2 = gen_reg_rtx (XFmode);
17267 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17269 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17273 (define_expand "exp10<mode>2"
17274 [(use (match_operand:MODEF 0 "register_operand" ""))
17275 (use (match_operand:MODEF 1 "general_operand" ""))]
17276 "TARGET_USE_FANCY_MATH_387
17277 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17278 || TARGET_MIX_SSE_I387)
17279 && flag_unsafe_math_optimizations && !optimize_size"
17281 rtx op0 = gen_reg_rtx (XFmode);
17282 rtx op1 = gen_reg_rtx (XFmode);
17284 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17285 emit_insn (gen_exp10xf2 (op0, op1));
17286 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17290 (define_expand "exp2xf2"
17291 [(use (match_operand:XF 0 "register_operand" ""))
17292 (use (match_operand:XF 1 "register_operand" ""))]
17293 "TARGET_USE_FANCY_MATH_387
17294 && flag_unsafe_math_optimizations && !optimize_size"
17296 rtx op2 = gen_reg_rtx (XFmode);
17297 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17299 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17303 (define_expand "exp2<mode>2"
17304 [(use (match_operand:MODEF 0 "register_operand" ""))
17305 (use (match_operand:MODEF 1 "general_operand" ""))]
17306 "TARGET_USE_FANCY_MATH_387
17307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17308 || TARGET_MIX_SSE_I387)
17309 && flag_unsafe_math_optimizations && !optimize_size"
17311 rtx op0 = gen_reg_rtx (XFmode);
17312 rtx op1 = gen_reg_rtx (XFmode);
17314 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17315 emit_insn (gen_exp2xf2 (op0, op1));
17316 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17320 (define_expand "expm1xf2"
17321 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17323 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17324 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17325 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17326 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17327 (parallel [(set (match_dup 7)
17328 (unspec:XF [(match_dup 6) (match_dup 4)]
17329 UNSPEC_FSCALE_FRACT))
17331 (unspec:XF [(match_dup 6) (match_dup 4)]
17332 UNSPEC_FSCALE_EXP))])
17333 (parallel [(set (match_dup 10)
17334 (unspec:XF [(match_dup 9) (match_dup 8)]
17335 UNSPEC_FSCALE_FRACT))
17336 (set (match_dup 11)
17337 (unspec:XF [(match_dup 9) (match_dup 8)]
17338 UNSPEC_FSCALE_EXP))])
17339 (set (match_dup 12) (minus:XF (match_dup 10)
17340 (float_extend:XF (match_dup 13))))
17341 (set (match_operand:XF 0 "register_operand" "")
17342 (plus:XF (match_dup 12) (match_dup 7)))]
17343 "TARGET_USE_FANCY_MATH_387
17344 && flag_unsafe_math_optimizations && !optimize_size"
17348 for (i = 2; i < 13; i++)
17349 operands[i] = gen_reg_rtx (XFmode);
17352 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17354 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17357 (define_expand "expm1<mode>2"
17358 [(use (match_operand:MODEF 0 "register_operand" ""))
17359 (use (match_operand:MODEF 1 "general_operand" ""))]
17360 "TARGET_USE_FANCY_MATH_387
17361 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17362 || TARGET_MIX_SSE_I387)
17363 && flag_unsafe_math_optimizations && !optimize_size"
17365 rtx op0 = gen_reg_rtx (XFmode);
17366 rtx op1 = gen_reg_rtx (XFmode);
17368 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17369 emit_insn (gen_expm1xf2 (op0, op1));
17370 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17374 (define_expand "ldexpxf3"
17375 [(set (match_dup 3)
17376 (float:XF (match_operand:SI 2 "register_operand" "")))
17377 (parallel [(set (match_operand:XF 0 " register_operand" "")
17378 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17380 UNSPEC_FSCALE_FRACT))
17382 (unspec:XF [(match_dup 1) (match_dup 3)]
17383 UNSPEC_FSCALE_EXP))])]
17384 "TARGET_USE_FANCY_MATH_387
17385 && flag_unsafe_math_optimizations && !optimize_size"
17387 operands[3] = gen_reg_rtx (XFmode);
17388 operands[4] = gen_reg_rtx (XFmode);
17391 (define_expand "ldexp<mode>3"
17392 [(use (match_operand:MODEF 0 "register_operand" ""))
17393 (use (match_operand:MODEF 1 "general_operand" ""))
17394 (use (match_operand:SI 2 "register_operand" ""))]
17395 "TARGET_USE_FANCY_MATH_387
17396 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17397 || TARGET_MIX_SSE_I387)
17398 && flag_unsafe_math_optimizations && !optimize_size"
17400 rtx op0 = gen_reg_rtx (XFmode);
17401 rtx op1 = gen_reg_rtx (XFmode);
17403 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17404 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17405 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17409 (define_expand "scalbxf3"
17410 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17411 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17412 (match_operand:XF 2 "register_operand" "")]
17413 UNSPEC_FSCALE_FRACT))
17415 (unspec:XF [(match_dup 1) (match_dup 2)]
17416 UNSPEC_FSCALE_EXP))])]
17417 "TARGET_USE_FANCY_MATH_387
17418 && flag_unsafe_math_optimizations && !optimize_size"
17420 operands[3] = gen_reg_rtx (XFmode);
17423 (define_expand "scalb<mode>3"
17424 [(use (match_operand:MODEF 0 "register_operand" ""))
17425 (use (match_operand:MODEF 1 "general_operand" ""))
17426 (use (match_operand:MODEF 2 "register_operand" ""))]
17427 "TARGET_USE_FANCY_MATH_387
17428 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17429 || TARGET_MIX_SSE_I387)
17430 && flag_unsafe_math_optimizations && !optimize_size"
17432 rtx op0 = gen_reg_rtx (XFmode);
17433 rtx op1 = gen_reg_rtx (XFmode);
17434 rtx op2 = gen_reg_rtx (XFmode);
17436 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17437 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17438 emit_insn (gen_scalbxf3 (op0, op1, op2));
17439 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17444 (define_insn "sse4_1_round<mode>2"
17445 [(set (match_operand:MODEF 0 "register_operand" "=x")
17446 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17447 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17450 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17451 [(set_attr "type" "ssecvt")
17452 (set_attr "prefix_extra" "1")
17453 (set_attr "mode" "<MODE>")])
17455 (define_insn "rintxf2"
17456 [(set (match_operand:XF 0 "register_operand" "=f")
17457 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17459 "TARGET_USE_FANCY_MATH_387
17460 && flag_unsafe_math_optimizations"
17462 [(set_attr "type" "fpspc")
17463 (set_attr "mode" "XF")])
17465 (define_expand "rint<mode>2"
17466 [(use (match_operand:MODEF 0 "register_operand" ""))
17467 (use (match_operand:MODEF 1 "register_operand" ""))]
17468 "(TARGET_USE_FANCY_MATH_387
17469 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17470 || TARGET_MIX_SSE_I387)
17471 && flag_unsafe_math_optimizations)
17472 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17473 && !flag_trapping_math
17474 && (TARGET_ROUND || !optimize_size))"
17476 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17477 && !flag_trapping_math
17478 && (TARGET_ROUND || !optimize_size))
17481 emit_insn (gen_sse4_1_round<mode>2
17482 (operands[0], operands[1], GEN_INT (0x04)));
17484 ix86_expand_rint (operand0, operand1);
17488 rtx op0 = gen_reg_rtx (XFmode);
17489 rtx op1 = gen_reg_rtx (XFmode);
17491 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17492 emit_insn (gen_rintxf2 (op0, op1));
17494 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17499 (define_expand "round<mode>2"
17500 [(match_operand:MODEF 0 "register_operand" "")
17501 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17502 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17503 && !flag_trapping_math && !flag_rounding_math
17506 if (TARGET_64BIT || (<MODE>mode != DFmode))
17507 ix86_expand_round (operand0, operand1);
17509 ix86_expand_rounddf_32 (operand0, operand1);
17513 (define_insn_and_split "*fistdi2_1"
17514 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17515 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17517 "TARGET_USE_FANCY_MATH_387
17518 && !(reload_completed || reload_in_progress)"
17523 if (memory_operand (operands[0], VOIDmode))
17524 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17527 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17528 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17533 [(set_attr "type" "fpspc")
17534 (set_attr "mode" "DI")])
17536 (define_insn "fistdi2"
17537 [(set (match_operand:DI 0 "memory_operand" "=m")
17538 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17540 (clobber (match_scratch:XF 2 "=&1f"))]
17541 "TARGET_USE_FANCY_MATH_387"
17542 "* return output_fix_trunc (insn, operands, 0);"
17543 [(set_attr "type" "fpspc")
17544 (set_attr "mode" "DI")])
17546 (define_insn "fistdi2_with_temp"
17547 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17548 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17550 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17551 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17552 "TARGET_USE_FANCY_MATH_387"
17554 [(set_attr "type" "fpspc")
17555 (set_attr "mode" "DI")])
17558 [(set (match_operand:DI 0 "register_operand" "")
17559 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17561 (clobber (match_operand:DI 2 "memory_operand" ""))
17562 (clobber (match_scratch 3 ""))]
17564 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17565 (clobber (match_dup 3))])
17566 (set (match_dup 0) (match_dup 2))]
17570 [(set (match_operand:DI 0 "memory_operand" "")
17571 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17573 (clobber (match_operand:DI 2 "memory_operand" ""))
17574 (clobber (match_scratch 3 ""))]
17576 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17577 (clobber (match_dup 3))])]
17580 (define_insn_and_split "*fist<mode>2_1"
17581 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17582 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17584 "TARGET_USE_FANCY_MATH_387
17585 && !(reload_completed || reload_in_progress)"
17590 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17591 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17595 [(set_attr "type" "fpspc")
17596 (set_attr "mode" "<MODE>")])
17598 (define_insn "fist<mode>2"
17599 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17600 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17602 "TARGET_USE_FANCY_MATH_387"
17603 "* return output_fix_trunc (insn, operands, 0);"
17604 [(set_attr "type" "fpspc")
17605 (set_attr "mode" "<MODE>")])
17607 (define_insn "fist<mode>2_with_temp"
17608 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17609 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17611 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17612 "TARGET_USE_FANCY_MATH_387"
17614 [(set_attr "type" "fpspc")
17615 (set_attr "mode" "<MODE>")])
17618 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17619 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17621 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17623 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17624 (set (match_dup 0) (match_dup 2))]
17628 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17629 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17631 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17633 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17636 (define_expand "lrintxf<mode>2"
17637 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17638 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17640 "TARGET_USE_FANCY_MATH_387"
17643 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17644 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17645 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17646 UNSPEC_FIX_NOTRUNC))]
17647 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17648 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17651 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17652 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17653 (match_operand:MODEF 1 "register_operand" "")]
17654 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17655 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17656 && !flag_trapping_math && !flag_rounding_math
17659 ix86_expand_lround (operand0, operand1);
17663 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17664 (define_insn_and_split "frndintxf2_floor"
17665 [(set (match_operand:XF 0 "register_operand" "")
17666 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17667 UNSPEC_FRNDINT_FLOOR))
17668 (clobber (reg:CC FLAGS_REG))]
17669 "TARGET_USE_FANCY_MATH_387
17670 && flag_unsafe_math_optimizations
17671 && !(reload_completed || reload_in_progress)"
17676 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17678 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17679 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17681 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17682 operands[2], operands[3]));
17685 [(set_attr "type" "frndint")
17686 (set_attr "i387_cw" "floor")
17687 (set_attr "mode" "XF")])
17689 (define_insn "frndintxf2_floor_i387"
17690 [(set (match_operand:XF 0 "register_operand" "=f")
17691 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17692 UNSPEC_FRNDINT_FLOOR))
17693 (use (match_operand:HI 2 "memory_operand" "m"))
17694 (use (match_operand:HI 3 "memory_operand" "m"))]
17695 "TARGET_USE_FANCY_MATH_387
17696 && flag_unsafe_math_optimizations"
17697 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17698 [(set_attr "type" "frndint")
17699 (set_attr "i387_cw" "floor")
17700 (set_attr "mode" "XF")])
17702 (define_expand "floorxf2"
17703 [(use (match_operand:XF 0 "register_operand" ""))
17704 (use (match_operand:XF 1 "register_operand" ""))]
17705 "TARGET_USE_FANCY_MATH_387
17706 && flag_unsafe_math_optimizations && !optimize_size"
17708 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17712 (define_expand "floor<mode>2"
17713 [(use (match_operand:MODEF 0 "register_operand" ""))
17714 (use (match_operand:MODEF 1 "register_operand" ""))]
17715 "(TARGET_USE_FANCY_MATH_387
17716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17717 || TARGET_MIX_SSE_I387)
17718 && flag_unsafe_math_optimizations && !optimize_size)
17719 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17720 && !flag_trapping_math
17721 && (TARGET_ROUND || !optimize_size))"
17723 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17724 && !flag_trapping_math
17725 && (TARGET_ROUND || !optimize_size))
17728 emit_insn (gen_sse4_1_round<mode>2
17729 (operands[0], operands[1], GEN_INT (0x01)));
17730 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17731 ix86_expand_floorceil (operand0, operand1, true);
17733 ix86_expand_floorceildf_32 (operand0, operand1, true);
17737 rtx op0 = gen_reg_rtx (XFmode);
17738 rtx op1 = gen_reg_rtx (XFmode);
17740 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17741 emit_insn (gen_frndintxf2_floor (op0, op1));
17743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17748 (define_insn_and_split "*fist<mode>2_floor_1"
17749 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17750 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17751 UNSPEC_FIST_FLOOR))
17752 (clobber (reg:CC FLAGS_REG))]
17753 "TARGET_USE_FANCY_MATH_387
17754 && flag_unsafe_math_optimizations
17755 && !(reload_completed || reload_in_progress)"
17760 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17762 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17763 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17764 if (memory_operand (operands[0], VOIDmode))
17765 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17766 operands[2], operands[3]));
17769 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17770 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17771 operands[2], operands[3],
17776 [(set_attr "type" "fistp")
17777 (set_attr "i387_cw" "floor")
17778 (set_attr "mode" "<MODE>")])
17780 (define_insn "fistdi2_floor"
17781 [(set (match_operand:DI 0 "memory_operand" "=m")
17782 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17783 UNSPEC_FIST_FLOOR))
17784 (use (match_operand:HI 2 "memory_operand" "m"))
17785 (use (match_operand:HI 3 "memory_operand" "m"))
17786 (clobber (match_scratch:XF 4 "=&1f"))]
17787 "TARGET_USE_FANCY_MATH_387
17788 && flag_unsafe_math_optimizations"
17789 "* return output_fix_trunc (insn, operands, 0);"
17790 [(set_attr "type" "fistp")
17791 (set_attr "i387_cw" "floor")
17792 (set_attr "mode" "DI")])
17794 (define_insn "fistdi2_floor_with_temp"
17795 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17796 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17797 UNSPEC_FIST_FLOOR))
17798 (use (match_operand:HI 2 "memory_operand" "m,m"))
17799 (use (match_operand:HI 3 "memory_operand" "m,m"))
17800 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17801 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17802 "TARGET_USE_FANCY_MATH_387
17803 && flag_unsafe_math_optimizations"
17805 [(set_attr "type" "fistp")
17806 (set_attr "i387_cw" "floor")
17807 (set_attr "mode" "DI")])
17810 [(set (match_operand:DI 0 "register_operand" "")
17811 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17812 UNSPEC_FIST_FLOOR))
17813 (use (match_operand:HI 2 "memory_operand" ""))
17814 (use (match_operand:HI 3 "memory_operand" ""))
17815 (clobber (match_operand:DI 4 "memory_operand" ""))
17816 (clobber (match_scratch 5 ""))]
17818 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17819 (use (match_dup 2))
17820 (use (match_dup 3))
17821 (clobber (match_dup 5))])
17822 (set (match_dup 0) (match_dup 4))]
17826 [(set (match_operand:DI 0 "memory_operand" "")
17827 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17828 UNSPEC_FIST_FLOOR))
17829 (use (match_operand:HI 2 "memory_operand" ""))
17830 (use (match_operand:HI 3 "memory_operand" ""))
17831 (clobber (match_operand:DI 4 "memory_operand" ""))
17832 (clobber (match_scratch 5 ""))]
17834 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17835 (use (match_dup 2))
17836 (use (match_dup 3))
17837 (clobber (match_dup 5))])]
17840 (define_insn "fist<mode>2_floor"
17841 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17842 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17843 UNSPEC_FIST_FLOOR))
17844 (use (match_operand:HI 2 "memory_operand" "m"))
17845 (use (match_operand:HI 3 "memory_operand" "m"))]
17846 "TARGET_USE_FANCY_MATH_387
17847 && flag_unsafe_math_optimizations"
17848 "* return output_fix_trunc (insn, operands, 0);"
17849 [(set_attr "type" "fistp")
17850 (set_attr "i387_cw" "floor")
17851 (set_attr "mode" "<MODE>")])
17853 (define_insn "fist<mode>2_floor_with_temp"
17854 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17855 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17856 UNSPEC_FIST_FLOOR))
17857 (use (match_operand:HI 2 "memory_operand" "m,m"))
17858 (use (match_operand:HI 3 "memory_operand" "m,m"))
17859 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17860 "TARGET_USE_FANCY_MATH_387
17861 && flag_unsafe_math_optimizations"
17863 [(set_attr "type" "fistp")
17864 (set_attr "i387_cw" "floor")
17865 (set_attr "mode" "<MODE>")])
17868 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17869 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17870 UNSPEC_FIST_FLOOR))
17871 (use (match_operand:HI 2 "memory_operand" ""))
17872 (use (match_operand:HI 3 "memory_operand" ""))
17873 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17875 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17876 UNSPEC_FIST_FLOOR))
17877 (use (match_dup 2))
17878 (use (match_dup 3))])
17879 (set (match_dup 0) (match_dup 4))]
17883 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17884 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17885 UNSPEC_FIST_FLOOR))
17886 (use (match_operand:HI 2 "memory_operand" ""))
17887 (use (match_operand:HI 3 "memory_operand" ""))
17888 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17890 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17891 UNSPEC_FIST_FLOOR))
17892 (use (match_dup 2))
17893 (use (match_dup 3))])]
17896 (define_expand "lfloorxf<mode>2"
17897 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17898 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17899 UNSPEC_FIST_FLOOR))
17900 (clobber (reg:CC FLAGS_REG))])]
17901 "TARGET_USE_FANCY_MATH_387
17902 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17903 && flag_unsafe_math_optimizations"
17906 (define_expand "lfloor<mode>di2"
17907 [(match_operand:DI 0 "nonimmediate_operand" "")
17908 (match_operand:MODEF 1 "register_operand" "")]
17909 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17910 && !flag_trapping_math
17913 ix86_expand_lfloorceil (operand0, operand1, true);
17917 (define_expand "lfloor<mode>si2"
17918 [(match_operand:SI 0 "nonimmediate_operand" "")
17919 (match_operand:MODEF 1 "register_operand" "")]
17920 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17921 && !flag_trapping_math
17922 && (!optimize_size || !TARGET_64BIT)"
17924 ix86_expand_lfloorceil (operand0, operand1, true);
17928 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17929 (define_insn_and_split "frndintxf2_ceil"
17930 [(set (match_operand:XF 0 "register_operand" "")
17931 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17932 UNSPEC_FRNDINT_CEIL))
17933 (clobber (reg:CC FLAGS_REG))]
17934 "TARGET_USE_FANCY_MATH_387
17935 && flag_unsafe_math_optimizations
17936 && !(reload_completed || reload_in_progress)"
17941 ix86_optimize_mode_switching[I387_CEIL] = 1;
17943 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17944 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17946 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17947 operands[2], operands[3]));
17950 [(set_attr "type" "frndint")
17951 (set_attr "i387_cw" "ceil")
17952 (set_attr "mode" "XF")])
17954 (define_insn "frndintxf2_ceil_i387"
17955 [(set (match_operand:XF 0 "register_operand" "=f")
17956 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17957 UNSPEC_FRNDINT_CEIL))
17958 (use (match_operand:HI 2 "memory_operand" "m"))
17959 (use (match_operand:HI 3 "memory_operand" "m"))]
17960 "TARGET_USE_FANCY_MATH_387
17961 && flag_unsafe_math_optimizations"
17962 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17963 [(set_attr "type" "frndint")
17964 (set_attr "i387_cw" "ceil")
17965 (set_attr "mode" "XF")])
17967 (define_expand "ceilxf2"
17968 [(use (match_operand:XF 0 "register_operand" ""))
17969 (use (match_operand:XF 1 "register_operand" ""))]
17970 "TARGET_USE_FANCY_MATH_387
17971 && flag_unsafe_math_optimizations && !optimize_size"
17973 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17977 (define_expand "ceil<mode>2"
17978 [(use (match_operand:MODEF 0 "register_operand" ""))
17979 (use (match_operand:MODEF 1 "register_operand" ""))]
17980 "(TARGET_USE_FANCY_MATH_387
17981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17982 || TARGET_MIX_SSE_I387)
17983 && flag_unsafe_math_optimizations && !optimize_size)
17984 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17985 && !flag_trapping_math
17986 && (TARGET_ROUND || !optimize_size))"
17988 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17989 && !flag_trapping_math
17990 && (TARGET_ROUND || !optimize_size))
17993 emit_insn (gen_sse4_1_round<mode>2
17994 (operands[0], operands[1], GEN_INT (0x02)));
17995 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17996 ix86_expand_floorceil (operand0, operand1, false);
17998 ix86_expand_floorceildf_32 (operand0, operand1, false);
18002 rtx op0 = gen_reg_rtx (XFmode);
18003 rtx op1 = gen_reg_rtx (XFmode);
18005 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18006 emit_insn (gen_frndintxf2_ceil (op0, op1));
18008 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18013 (define_insn_and_split "*fist<mode>2_ceil_1"
18014 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18015 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18017 (clobber (reg:CC FLAGS_REG))]
18018 "TARGET_USE_FANCY_MATH_387
18019 && flag_unsafe_math_optimizations
18020 && !(reload_completed || reload_in_progress)"
18025 ix86_optimize_mode_switching[I387_CEIL] = 1;
18027 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18028 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18029 if (memory_operand (operands[0], VOIDmode))
18030 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18031 operands[2], operands[3]));
18034 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18035 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18036 operands[2], operands[3],
18041 [(set_attr "type" "fistp")
18042 (set_attr "i387_cw" "ceil")
18043 (set_attr "mode" "<MODE>")])
18045 (define_insn "fistdi2_ceil"
18046 [(set (match_operand:DI 0 "memory_operand" "=m")
18047 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18049 (use (match_operand:HI 2 "memory_operand" "m"))
18050 (use (match_operand:HI 3 "memory_operand" "m"))
18051 (clobber (match_scratch:XF 4 "=&1f"))]
18052 "TARGET_USE_FANCY_MATH_387
18053 && flag_unsafe_math_optimizations"
18054 "* return output_fix_trunc (insn, operands, 0);"
18055 [(set_attr "type" "fistp")
18056 (set_attr "i387_cw" "ceil")
18057 (set_attr "mode" "DI")])
18059 (define_insn "fistdi2_ceil_with_temp"
18060 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18061 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18063 (use (match_operand:HI 2 "memory_operand" "m,m"))
18064 (use (match_operand:HI 3 "memory_operand" "m,m"))
18065 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18066 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18067 "TARGET_USE_FANCY_MATH_387
18068 && flag_unsafe_math_optimizations"
18070 [(set_attr "type" "fistp")
18071 (set_attr "i387_cw" "ceil")
18072 (set_attr "mode" "DI")])
18075 [(set (match_operand:DI 0 "register_operand" "")
18076 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18078 (use (match_operand:HI 2 "memory_operand" ""))
18079 (use (match_operand:HI 3 "memory_operand" ""))
18080 (clobber (match_operand:DI 4 "memory_operand" ""))
18081 (clobber (match_scratch 5 ""))]
18083 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18084 (use (match_dup 2))
18085 (use (match_dup 3))
18086 (clobber (match_dup 5))])
18087 (set (match_dup 0) (match_dup 4))]
18091 [(set (match_operand:DI 0 "memory_operand" "")
18092 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18094 (use (match_operand:HI 2 "memory_operand" ""))
18095 (use (match_operand:HI 3 "memory_operand" ""))
18096 (clobber (match_operand:DI 4 "memory_operand" ""))
18097 (clobber (match_scratch 5 ""))]
18099 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18100 (use (match_dup 2))
18101 (use (match_dup 3))
18102 (clobber (match_dup 5))])]
18105 (define_insn "fist<mode>2_ceil"
18106 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18107 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18109 (use (match_operand:HI 2 "memory_operand" "m"))
18110 (use (match_operand:HI 3 "memory_operand" "m"))]
18111 "TARGET_USE_FANCY_MATH_387
18112 && flag_unsafe_math_optimizations"
18113 "* return output_fix_trunc (insn, operands, 0);"
18114 [(set_attr "type" "fistp")
18115 (set_attr "i387_cw" "ceil")
18116 (set_attr "mode" "<MODE>")])
18118 (define_insn "fist<mode>2_ceil_with_temp"
18119 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18120 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18122 (use (match_operand:HI 2 "memory_operand" "m,m"))
18123 (use (match_operand:HI 3 "memory_operand" "m,m"))
18124 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18125 "TARGET_USE_FANCY_MATH_387
18126 && flag_unsafe_math_optimizations"
18128 [(set_attr "type" "fistp")
18129 (set_attr "i387_cw" "ceil")
18130 (set_attr "mode" "<MODE>")])
18133 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18134 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18136 (use (match_operand:HI 2 "memory_operand" ""))
18137 (use (match_operand:HI 3 "memory_operand" ""))
18138 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18140 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18142 (use (match_dup 2))
18143 (use (match_dup 3))])
18144 (set (match_dup 0) (match_dup 4))]
18148 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18149 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18151 (use (match_operand:HI 2 "memory_operand" ""))
18152 (use (match_operand:HI 3 "memory_operand" ""))
18153 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18155 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18157 (use (match_dup 2))
18158 (use (match_dup 3))])]
18161 (define_expand "lceilxf<mode>2"
18162 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18163 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18165 (clobber (reg:CC FLAGS_REG))])]
18166 "TARGET_USE_FANCY_MATH_387
18167 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18168 && flag_unsafe_math_optimizations"
18171 (define_expand "lceil<mode>di2"
18172 [(match_operand:DI 0 "nonimmediate_operand" "")
18173 (match_operand:MODEF 1 "register_operand" "")]
18174 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18175 && !flag_trapping_math"
18177 ix86_expand_lfloorceil (operand0, operand1, false);
18181 (define_expand "lceil<mode>si2"
18182 [(match_operand:SI 0 "nonimmediate_operand" "")
18183 (match_operand:MODEF 1 "register_operand" "")]
18184 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18185 && !flag_trapping_math"
18187 ix86_expand_lfloorceil (operand0, operand1, false);
18191 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18192 (define_insn_and_split "frndintxf2_trunc"
18193 [(set (match_operand:XF 0 "register_operand" "")
18194 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18195 UNSPEC_FRNDINT_TRUNC))
18196 (clobber (reg:CC FLAGS_REG))]
18197 "TARGET_USE_FANCY_MATH_387
18198 && flag_unsafe_math_optimizations
18199 && !(reload_completed || reload_in_progress)"
18204 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18206 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18207 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18209 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18210 operands[2], operands[3]));
18213 [(set_attr "type" "frndint")
18214 (set_attr "i387_cw" "trunc")
18215 (set_attr "mode" "XF")])
18217 (define_insn "frndintxf2_trunc_i387"
18218 [(set (match_operand:XF 0 "register_operand" "=f")
18219 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18220 UNSPEC_FRNDINT_TRUNC))
18221 (use (match_operand:HI 2 "memory_operand" "m"))
18222 (use (match_operand:HI 3 "memory_operand" "m"))]
18223 "TARGET_USE_FANCY_MATH_387
18224 && flag_unsafe_math_optimizations"
18225 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18226 [(set_attr "type" "frndint")
18227 (set_attr "i387_cw" "trunc")
18228 (set_attr "mode" "XF")])
18230 (define_expand "btruncxf2"
18231 [(use (match_operand:XF 0 "register_operand" ""))
18232 (use (match_operand:XF 1 "register_operand" ""))]
18233 "TARGET_USE_FANCY_MATH_387
18234 && flag_unsafe_math_optimizations && !optimize_size"
18236 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18240 (define_expand "btrunc<mode>2"
18241 [(use (match_operand:MODEF 0 "register_operand" ""))
18242 (use (match_operand:MODEF 1 "register_operand" ""))]
18243 "(TARGET_USE_FANCY_MATH_387
18244 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18245 || TARGET_MIX_SSE_I387)
18246 && flag_unsafe_math_optimizations && !optimize_size)
18247 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18248 && !flag_trapping_math
18249 && (TARGET_ROUND || !optimize_size))"
18251 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18252 && !flag_trapping_math
18253 && (TARGET_ROUND || !optimize_size))
18256 emit_insn (gen_sse4_1_round<mode>2
18257 (operands[0], operands[1], GEN_INT (0x03)));
18258 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18259 ix86_expand_trunc (operand0, operand1);
18261 ix86_expand_truncdf_32 (operand0, operand1);
18265 rtx op0 = gen_reg_rtx (XFmode);
18266 rtx op1 = gen_reg_rtx (XFmode);
18268 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18269 emit_insn (gen_frndintxf2_trunc (op0, op1));
18271 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18276 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18277 (define_insn_and_split "frndintxf2_mask_pm"
18278 [(set (match_operand:XF 0 "register_operand" "")
18279 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18280 UNSPEC_FRNDINT_MASK_PM))
18281 (clobber (reg:CC FLAGS_REG))]
18282 "TARGET_USE_FANCY_MATH_387
18283 && flag_unsafe_math_optimizations
18284 && !(reload_completed || reload_in_progress)"
18289 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18291 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18292 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18294 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18295 operands[2], operands[3]));
18298 [(set_attr "type" "frndint")
18299 (set_attr "i387_cw" "mask_pm")
18300 (set_attr "mode" "XF")])
18302 (define_insn "frndintxf2_mask_pm_i387"
18303 [(set (match_operand:XF 0 "register_operand" "=f")
18304 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18305 UNSPEC_FRNDINT_MASK_PM))
18306 (use (match_operand:HI 2 "memory_operand" "m"))
18307 (use (match_operand:HI 3 "memory_operand" "m"))]
18308 "TARGET_USE_FANCY_MATH_387
18309 && flag_unsafe_math_optimizations"
18310 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18311 [(set_attr "type" "frndint")
18312 (set_attr "i387_cw" "mask_pm")
18313 (set_attr "mode" "XF")])
18315 (define_expand "nearbyintxf2"
18316 [(use (match_operand:XF 0 "register_operand" ""))
18317 (use (match_operand:XF 1 "register_operand" ""))]
18318 "TARGET_USE_FANCY_MATH_387
18319 && flag_unsafe_math_optimizations"
18321 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18326 (define_expand "nearbyint<mode>2"
18327 [(use (match_operand:MODEF 0 "register_operand" ""))
18328 (use (match_operand:MODEF 1 "register_operand" ""))]
18329 "TARGET_USE_FANCY_MATH_387
18330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18331 || TARGET_MIX_SSE_I387)
18332 && flag_unsafe_math_optimizations"
18334 rtx op0 = gen_reg_rtx (XFmode);
18335 rtx op1 = gen_reg_rtx (XFmode);
18337 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18338 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18344 (define_insn "fxam<mode>2_i387"
18345 [(set (match_operand:HI 0 "register_operand" "=a")
18347 [(match_operand:X87MODEF 1 "register_operand" "f")]
18349 "TARGET_USE_FANCY_MATH_387"
18350 "fxam\n\tfnstsw\t%0"
18351 [(set_attr "type" "multi")
18352 (set_attr "unit" "i387")
18353 (set_attr "mode" "<MODE>")])
18355 (define_expand "isinf<mode>2"
18356 [(use (match_operand:SI 0 "register_operand" ""))
18357 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18358 "TARGET_USE_FANCY_MATH_387
18359 && TARGET_C99_FUNCTIONS
18360 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18362 rtx mask = GEN_INT (0x45);
18363 rtx val = GEN_INT (0x05);
18367 rtx scratch = gen_reg_rtx (HImode);
18368 rtx res = gen_reg_rtx (QImode);
18370 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18371 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18372 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18373 cond = gen_rtx_fmt_ee (EQ, QImode,
18374 gen_rtx_REG (CCmode, FLAGS_REG),
18376 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18377 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18381 (define_expand "signbit<mode>2"
18382 [(use (match_operand:SI 0 "register_operand" ""))
18383 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18384 "TARGET_USE_FANCY_MATH_387
18385 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18387 rtx mask = GEN_INT (0x0200);
18389 rtx scratch = gen_reg_rtx (HImode);
18391 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18392 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18396 ;; Block operation instructions
18399 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18402 [(set_attr "length" "1")
18403 (set_attr "length_immediate" "0")
18404 (set_attr "modrm" "0")])
18406 (define_expand "movmemsi"
18407 [(use (match_operand:BLK 0 "memory_operand" ""))
18408 (use (match_operand:BLK 1 "memory_operand" ""))
18409 (use (match_operand:SI 2 "nonmemory_operand" ""))
18410 (use (match_operand:SI 3 "const_int_operand" ""))
18411 (use (match_operand:SI 4 "const_int_operand" ""))
18412 (use (match_operand:SI 5 "const_int_operand" ""))]
18415 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18416 operands[4], operands[5]))
18422 (define_expand "movmemdi"
18423 [(use (match_operand:BLK 0 "memory_operand" ""))
18424 (use (match_operand:BLK 1 "memory_operand" ""))
18425 (use (match_operand:DI 2 "nonmemory_operand" ""))
18426 (use (match_operand:DI 3 "const_int_operand" ""))
18427 (use (match_operand:SI 4 "const_int_operand" ""))
18428 (use (match_operand:SI 5 "const_int_operand" ""))]
18431 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18432 operands[4], operands[5]))
18438 ;; Most CPUs don't like single string operations
18439 ;; Handle this case here to simplify previous expander.
18441 (define_expand "strmov"
18442 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18443 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18444 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18445 (clobber (reg:CC FLAGS_REG))])
18446 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18447 (clobber (reg:CC FLAGS_REG))])]
18450 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18452 /* If .md ever supports :P for Pmode, these can be directly
18453 in the pattern above. */
18454 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18455 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18457 /* Can't use this if the user has appropriated esi or edi. */
18458 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18459 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18461 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18462 operands[2], operands[3],
18463 operands[5], operands[6]));
18467 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18470 (define_expand "strmov_singleop"
18471 [(parallel [(set (match_operand 1 "memory_operand" "")
18472 (match_operand 3 "memory_operand" ""))
18473 (set (match_operand 0 "register_operand" "")
18474 (match_operand 4 "" ""))
18475 (set (match_operand 2 "register_operand" "")
18476 (match_operand 5 "" ""))])]
18477 "TARGET_SINGLE_STRINGOP || optimize_size"
18478 "ix86_current_function_needs_cld = 1;")
18480 (define_insn "*strmovdi_rex_1"
18481 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18482 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18483 (set (match_operand:DI 0 "register_operand" "=D")
18484 (plus:DI (match_dup 2)
18486 (set (match_operand:DI 1 "register_operand" "=S")
18487 (plus:DI (match_dup 3)
18489 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18491 [(set_attr "type" "str")
18492 (set_attr "mode" "DI")
18493 (set_attr "memory" "both")])
18495 (define_insn "*strmovsi_1"
18496 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18497 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18498 (set (match_operand:SI 0 "register_operand" "=D")
18499 (plus:SI (match_dup 2)
18501 (set (match_operand:SI 1 "register_operand" "=S")
18502 (plus:SI (match_dup 3)
18504 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18506 [(set_attr "type" "str")
18507 (set_attr "mode" "SI")
18508 (set_attr "memory" "both")])
18510 (define_insn "*strmovsi_rex_1"
18511 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18512 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18513 (set (match_operand:DI 0 "register_operand" "=D")
18514 (plus:DI (match_dup 2)
18516 (set (match_operand:DI 1 "register_operand" "=S")
18517 (plus:DI (match_dup 3)
18519 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18521 [(set_attr "type" "str")
18522 (set_attr "mode" "SI")
18523 (set_attr "memory" "both")])
18525 (define_insn "*strmovhi_1"
18526 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18527 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18528 (set (match_operand:SI 0 "register_operand" "=D")
18529 (plus:SI (match_dup 2)
18531 (set (match_operand:SI 1 "register_operand" "=S")
18532 (plus:SI (match_dup 3)
18534 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18536 [(set_attr "type" "str")
18537 (set_attr "memory" "both")
18538 (set_attr "mode" "HI")])
18540 (define_insn "*strmovhi_rex_1"
18541 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18542 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18543 (set (match_operand:DI 0 "register_operand" "=D")
18544 (plus:DI (match_dup 2)
18546 (set (match_operand:DI 1 "register_operand" "=S")
18547 (plus:DI (match_dup 3)
18549 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18551 [(set_attr "type" "str")
18552 (set_attr "memory" "both")
18553 (set_attr "mode" "HI")])
18555 (define_insn "*strmovqi_1"
18556 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18557 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18558 (set (match_operand:SI 0 "register_operand" "=D")
18559 (plus:SI (match_dup 2)
18561 (set (match_operand:SI 1 "register_operand" "=S")
18562 (plus:SI (match_dup 3)
18564 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18566 [(set_attr "type" "str")
18567 (set_attr "memory" "both")
18568 (set_attr "mode" "QI")])
18570 (define_insn "*strmovqi_rex_1"
18571 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18572 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18573 (set (match_operand:DI 0 "register_operand" "=D")
18574 (plus:DI (match_dup 2)
18576 (set (match_operand:DI 1 "register_operand" "=S")
18577 (plus:DI (match_dup 3)
18579 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18581 [(set_attr "type" "str")
18582 (set_attr "memory" "both")
18583 (set_attr "mode" "QI")])
18585 (define_expand "rep_mov"
18586 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18587 (set (match_operand 0 "register_operand" "")
18588 (match_operand 5 "" ""))
18589 (set (match_operand 2 "register_operand" "")
18590 (match_operand 6 "" ""))
18591 (set (match_operand 1 "memory_operand" "")
18592 (match_operand 3 "memory_operand" ""))
18593 (use (match_dup 4))])]
18595 "ix86_current_function_needs_cld = 1;")
18597 (define_insn "*rep_movdi_rex64"
18598 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18599 (set (match_operand:DI 0 "register_operand" "=D")
18600 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18602 (match_operand:DI 3 "register_operand" "0")))
18603 (set (match_operand:DI 1 "register_operand" "=S")
18604 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18605 (match_operand:DI 4 "register_operand" "1")))
18606 (set (mem:BLK (match_dup 3))
18607 (mem:BLK (match_dup 4)))
18608 (use (match_dup 5))]
18611 [(set_attr "type" "str")
18612 (set_attr "prefix_rep" "1")
18613 (set_attr "memory" "both")
18614 (set_attr "mode" "DI")])
18616 (define_insn "*rep_movsi"
18617 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18618 (set (match_operand:SI 0 "register_operand" "=D")
18619 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18621 (match_operand:SI 3 "register_operand" "0")))
18622 (set (match_operand:SI 1 "register_operand" "=S")
18623 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18624 (match_operand:SI 4 "register_operand" "1")))
18625 (set (mem:BLK (match_dup 3))
18626 (mem:BLK (match_dup 4)))
18627 (use (match_dup 5))]
18630 [(set_attr "type" "str")
18631 (set_attr "prefix_rep" "1")
18632 (set_attr "memory" "both")
18633 (set_attr "mode" "SI")])
18635 (define_insn "*rep_movsi_rex64"
18636 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18637 (set (match_operand:DI 0 "register_operand" "=D")
18638 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18640 (match_operand:DI 3 "register_operand" "0")))
18641 (set (match_operand:DI 1 "register_operand" "=S")
18642 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18643 (match_operand:DI 4 "register_operand" "1")))
18644 (set (mem:BLK (match_dup 3))
18645 (mem:BLK (match_dup 4)))
18646 (use (match_dup 5))]
18649 [(set_attr "type" "str")
18650 (set_attr "prefix_rep" "1")
18651 (set_attr "memory" "both")
18652 (set_attr "mode" "SI")])
18654 (define_insn "*rep_movqi"
18655 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18656 (set (match_operand:SI 0 "register_operand" "=D")
18657 (plus:SI (match_operand:SI 3 "register_operand" "0")
18658 (match_operand:SI 5 "register_operand" "2")))
18659 (set (match_operand:SI 1 "register_operand" "=S")
18660 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18661 (set (mem:BLK (match_dup 3))
18662 (mem:BLK (match_dup 4)))
18663 (use (match_dup 5))]
18666 [(set_attr "type" "str")
18667 (set_attr "prefix_rep" "1")
18668 (set_attr "memory" "both")
18669 (set_attr "mode" "SI")])
18671 (define_insn "*rep_movqi_rex64"
18672 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18673 (set (match_operand:DI 0 "register_operand" "=D")
18674 (plus:DI (match_operand:DI 3 "register_operand" "0")
18675 (match_operand:DI 5 "register_operand" "2")))
18676 (set (match_operand:DI 1 "register_operand" "=S")
18677 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18678 (set (mem:BLK (match_dup 3))
18679 (mem:BLK (match_dup 4)))
18680 (use (match_dup 5))]
18683 [(set_attr "type" "str")
18684 (set_attr "prefix_rep" "1")
18685 (set_attr "memory" "both")
18686 (set_attr "mode" "SI")])
18688 (define_expand "setmemsi"
18689 [(use (match_operand:BLK 0 "memory_operand" ""))
18690 (use (match_operand:SI 1 "nonmemory_operand" ""))
18691 (use (match_operand 2 "const_int_operand" ""))
18692 (use (match_operand 3 "const_int_operand" ""))
18693 (use (match_operand:SI 4 "const_int_operand" ""))
18694 (use (match_operand:SI 5 "const_int_operand" ""))]
18697 if (ix86_expand_setmem (operands[0], operands[1],
18698 operands[2], operands[3],
18699 operands[4], operands[5]))
18705 (define_expand "setmemdi"
18706 [(use (match_operand:BLK 0 "memory_operand" ""))
18707 (use (match_operand:DI 1 "nonmemory_operand" ""))
18708 (use (match_operand 2 "const_int_operand" ""))
18709 (use (match_operand 3 "const_int_operand" ""))
18710 (use (match_operand 4 "const_int_operand" ""))
18711 (use (match_operand 5 "const_int_operand" ""))]
18714 if (ix86_expand_setmem (operands[0], operands[1],
18715 operands[2], operands[3],
18716 operands[4], operands[5]))
18722 ;; Most CPUs don't like single string operations
18723 ;; Handle this case here to simplify previous expander.
18725 (define_expand "strset"
18726 [(set (match_operand 1 "memory_operand" "")
18727 (match_operand 2 "register_operand" ""))
18728 (parallel [(set (match_operand 0 "register_operand" "")
18730 (clobber (reg:CC FLAGS_REG))])]
18733 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18734 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18736 /* If .md ever supports :P for Pmode, this can be directly
18737 in the pattern above. */
18738 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18739 GEN_INT (GET_MODE_SIZE (GET_MODE
18741 if (TARGET_SINGLE_STRINGOP || optimize_size)
18743 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18749 (define_expand "strset_singleop"
18750 [(parallel [(set (match_operand 1 "memory_operand" "")
18751 (match_operand 2 "register_operand" ""))
18752 (set (match_operand 0 "register_operand" "")
18753 (match_operand 3 "" ""))])]
18754 "TARGET_SINGLE_STRINGOP || optimize_size"
18755 "ix86_current_function_needs_cld = 1;")
18757 (define_insn "*strsetdi_rex_1"
18758 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18759 (match_operand:DI 2 "register_operand" "a"))
18760 (set (match_operand:DI 0 "register_operand" "=D")
18761 (plus:DI (match_dup 1)
18763 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18765 [(set_attr "type" "str")
18766 (set_attr "memory" "store")
18767 (set_attr "mode" "DI")])
18769 (define_insn "*strsetsi_1"
18770 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18771 (match_operand:SI 2 "register_operand" "a"))
18772 (set (match_operand:SI 0 "register_operand" "=D")
18773 (plus:SI (match_dup 1)
18775 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18777 [(set_attr "type" "str")
18778 (set_attr "memory" "store")
18779 (set_attr "mode" "SI")])
18781 (define_insn "*strsetsi_rex_1"
18782 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18783 (match_operand:SI 2 "register_operand" "a"))
18784 (set (match_operand:DI 0 "register_operand" "=D")
18785 (plus:DI (match_dup 1)
18787 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18789 [(set_attr "type" "str")
18790 (set_attr "memory" "store")
18791 (set_attr "mode" "SI")])
18793 (define_insn "*strsethi_1"
18794 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18795 (match_operand:HI 2 "register_operand" "a"))
18796 (set (match_operand:SI 0 "register_operand" "=D")
18797 (plus:SI (match_dup 1)
18799 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18801 [(set_attr "type" "str")
18802 (set_attr "memory" "store")
18803 (set_attr "mode" "HI")])
18805 (define_insn "*strsethi_rex_1"
18806 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18807 (match_operand:HI 2 "register_operand" "a"))
18808 (set (match_operand:DI 0 "register_operand" "=D")
18809 (plus:DI (match_dup 1)
18811 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18813 [(set_attr "type" "str")
18814 (set_attr "memory" "store")
18815 (set_attr "mode" "HI")])
18817 (define_insn "*strsetqi_1"
18818 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18819 (match_operand:QI 2 "register_operand" "a"))
18820 (set (match_operand:SI 0 "register_operand" "=D")
18821 (plus:SI (match_dup 1)
18823 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18825 [(set_attr "type" "str")
18826 (set_attr "memory" "store")
18827 (set_attr "mode" "QI")])
18829 (define_insn "*strsetqi_rex_1"
18830 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18831 (match_operand:QI 2 "register_operand" "a"))
18832 (set (match_operand:DI 0 "register_operand" "=D")
18833 (plus:DI (match_dup 1)
18835 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18837 [(set_attr "type" "str")
18838 (set_attr "memory" "store")
18839 (set_attr "mode" "QI")])
18841 (define_expand "rep_stos"
18842 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18843 (set (match_operand 0 "register_operand" "")
18844 (match_operand 4 "" ""))
18845 (set (match_operand 2 "memory_operand" "") (const_int 0))
18846 (use (match_operand 3 "register_operand" ""))
18847 (use (match_dup 1))])]
18849 "ix86_current_function_needs_cld = 1;")
18851 (define_insn "*rep_stosdi_rex64"
18852 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18853 (set (match_operand:DI 0 "register_operand" "=D")
18854 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18856 (match_operand:DI 3 "register_operand" "0")))
18857 (set (mem:BLK (match_dup 3))
18859 (use (match_operand:DI 2 "register_operand" "a"))
18860 (use (match_dup 4))]
18863 [(set_attr "type" "str")
18864 (set_attr "prefix_rep" "1")
18865 (set_attr "memory" "store")
18866 (set_attr "mode" "DI")])
18868 (define_insn "*rep_stossi"
18869 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18870 (set (match_operand:SI 0 "register_operand" "=D")
18871 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18873 (match_operand:SI 3 "register_operand" "0")))
18874 (set (mem:BLK (match_dup 3))
18876 (use (match_operand:SI 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" "SI")])
18885 (define_insn "*rep_stossi_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 (ashift:DI (match_operand:DI 4 "register_operand" "1")
18890 (match_operand:DI 3 "register_operand" "0")))
18891 (set (mem:BLK (match_dup 3))
18893 (use (match_operand:SI 2 "register_operand" "a"))
18894 (use (match_dup 4))]
18897 [(set_attr "type" "str")
18898 (set_attr "prefix_rep" "1")
18899 (set_attr "memory" "store")
18900 (set_attr "mode" "SI")])
18902 (define_insn "*rep_stosqi"
18903 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18904 (set (match_operand:SI 0 "register_operand" "=D")
18905 (plus:SI (match_operand:SI 3 "register_operand" "0")
18906 (match_operand:SI 4 "register_operand" "1")))
18907 (set (mem:BLK (match_dup 3))
18909 (use (match_operand:QI 2 "register_operand" "a"))
18910 (use (match_dup 4))]
18913 [(set_attr "type" "str")
18914 (set_attr "prefix_rep" "1")
18915 (set_attr "memory" "store")
18916 (set_attr "mode" "QI")])
18918 (define_insn "*rep_stosqi_rex64"
18919 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18920 (set (match_operand:DI 0 "register_operand" "=D")
18921 (plus:DI (match_operand:DI 3 "register_operand" "0")
18922 (match_operand:DI 4 "register_operand" "1")))
18923 (set (mem:BLK (match_dup 3))
18925 (use (match_operand:QI 2 "register_operand" "a"))
18926 (use (match_dup 4))]
18929 [(set_attr "type" "str")
18930 (set_attr "prefix_rep" "1")
18931 (set_attr "memory" "store")
18932 (set_attr "mode" "QI")])
18934 (define_expand "cmpstrnsi"
18935 [(set (match_operand:SI 0 "register_operand" "")
18936 (compare:SI (match_operand:BLK 1 "general_operand" "")
18937 (match_operand:BLK 2 "general_operand" "")))
18938 (use (match_operand 3 "general_operand" ""))
18939 (use (match_operand 4 "immediate_operand" ""))]
18940 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18942 rtx addr1, addr2, out, outlow, count, countreg, align;
18944 /* Can't use this if the user has appropriated esi or edi. */
18945 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18950 out = gen_reg_rtx (SImode);
18952 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18953 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18954 if (addr1 != XEXP (operands[1], 0))
18955 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18956 if (addr2 != XEXP (operands[2], 0))
18957 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18959 count = operands[3];
18960 countreg = ix86_zero_extend_to_Pmode (count);
18962 /* %%% Iff we are testing strict equality, we can use known alignment
18963 to good advantage. This may be possible with combine, particularly
18964 once cc0 is dead. */
18965 align = operands[4];
18967 if (CONST_INT_P (count))
18969 if (INTVAL (count) == 0)
18971 emit_move_insn (operands[0], const0_rtx);
18974 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18975 operands[1], operands[2]));
18980 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18982 emit_insn (gen_cmpsi_1 (countreg, countreg));
18983 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18984 operands[1], operands[2]));
18987 outlow = gen_lowpart (QImode, out);
18988 emit_insn (gen_cmpintqi (outlow));
18989 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18991 if (operands[0] != out)
18992 emit_move_insn (operands[0], out);
18997 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18999 (define_expand "cmpintqi"
19000 [(set (match_dup 1)
19001 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19003 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19004 (parallel [(set (match_operand:QI 0 "register_operand" "")
19005 (minus:QI (match_dup 1)
19007 (clobber (reg:CC FLAGS_REG))])]
19009 "operands[1] = gen_reg_rtx (QImode);
19010 operands[2] = gen_reg_rtx (QImode);")
19012 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19013 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19015 (define_expand "cmpstrnqi_nz_1"
19016 [(parallel [(set (reg:CC FLAGS_REG)
19017 (compare:CC (match_operand 4 "memory_operand" "")
19018 (match_operand 5 "memory_operand" "")))
19019 (use (match_operand 2 "register_operand" ""))
19020 (use (match_operand:SI 3 "immediate_operand" ""))
19021 (clobber (match_operand 0 "register_operand" ""))
19022 (clobber (match_operand 1 "register_operand" ""))
19023 (clobber (match_dup 2))])]
19025 "ix86_current_function_needs_cld = 1;")
19027 (define_insn "*cmpstrnqi_nz_1"
19028 [(set (reg:CC FLAGS_REG)
19029 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19030 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19031 (use (match_operand:SI 6 "register_operand" "2"))
19032 (use (match_operand:SI 3 "immediate_operand" "i"))
19033 (clobber (match_operand:SI 0 "register_operand" "=S"))
19034 (clobber (match_operand:SI 1 "register_operand" "=D"))
19035 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19038 [(set_attr "type" "str")
19039 (set_attr "mode" "QI")
19040 (set_attr "prefix_rep" "1")])
19042 (define_insn "*cmpstrnqi_nz_rex_1"
19043 [(set (reg:CC FLAGS_REG)
19044 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19045 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19046 (use (match_operand:DI 6 "register_operand" "2"))
19047 (use (match_operand:SI 3 "immediate_operand" "i"))
19048 (clobber (match_operand:DI 0 "register_operand" "=S"))
19049 (clobber (match_operand:DI 1 "register_operand" "=D"))
19050 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19053 [(set_attr "type" "str")
19054 (set_attr "mode" "QI")
19055 (set_attr "prefix_rep" "1")])
19057 ;; The same, but the count is not known to not be zero.
19059 (define_expand "cmpstrnqi_1"
19060 [(parallel [(set (reg:CC FLAGS_REG)
19061 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19063 (compare:CC (match_operand 4 "memory_operand" "")
19064 (match_operand 5 "memory_operand" ""))
19066 (use (match_operand:SI 3 "immediate_operand" ""))
19067 (use (reg:CC FLAGS_REG))
19068 (clobber (match_operand 0 "register_operand" ""))
19069 (clobber (match_operand 1 "register_operand" ""))
19070 (clobber (match_dup 2))])]
19072 "ix86_current_function_needs_cld = 1;")
19074 (define_insn "*cmpstrnqi_1"
19075 [(set (reg:CC FLAGS_REG)
19076 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19078 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19079 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19081 (use (match_operand:SI 3 "immediate_operand" "i"))
19082 (use (reg:CC FLAGS_REG))
19083 (clobber (match_operand:SI 0 "register_operand" "=S"))
19084 (clobber (match_operand:SI 1 "register_operand" "=D"))
19085 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19088 [(set_attr "type" "str")
19089 (set_attr "mode" "QI")
19090 (set_attr "prefix_rep" "1")])
19092 (define_insn "*cmpstrnqi_rex_1"
19093 [(set (reg:CC FLAGS_REG)
19094 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19096 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19097 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19099 (use (match_operand:SI 3 "immediate_operand" "i"))
19100 (use (reg:CC FLAGS_REG))
19101 (clobber (match_operand:DI 0 "register_operand" "=S"))
19102 (clobber (match_operand:DI 1 "register_operand" "=D"))
19103 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19106 [(set_attr "type" "str")
19107 (set_attr "mode" "QI")
19108 (set_attr "prefix_rep" "1")])
19110 (define_expand "strlensi"
19111 [(set (match_operand:SI 0 "register_operand" "")
19112 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19113 (match_operand:QI 2 "immediate_operand" "")
19114 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19117 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19123 (define_expand "strlendi"
19124 [(set (match_operand:DI 0 "register_operand" "")
19125 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19126 (match_operand:QI 2 "immediate_operand" "")
19127 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19130 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19136 (define_expand "strlenqi_1"
19137 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19138 (clobber (match_operand 1 "register_operand" ""))
19139 (clobber (reg:CC FLAGS_REG))])]
19141 "ix86_current_function_needs_cld = 1;")
19143 (define_insn "*strlenqi_1"
19144 [(set (match_operand:SI 0 "register_operand" "=&c")
19145 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19146 (match_operand:QI 2 "register_operand" "a")
19147 (match_operand:SI 3 "immediate_operand" "i")
19148 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19149 (clobber (match_operand:SI 1 "register_operand" "=D"))
19150 (clobber (reg:CC FLAGS_REG))]
19153 [(set_attr "type" "str")
19154 (set_attr "mode" "QI")
19155 (set_attr "prefix_rep" "1")])
19157 (define_insn "*strlenqi_rex_1"
19158 [(set (match_operand:DI 0 "register_operand" "=&c")
19159 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19160 (match_operand:QI 2 "register_operand" "a")
19161 (match_operand:DI 3 "immediate_operand" "i")
19162 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19163 (clobber (match_operand:DI 1 "register_operand" "=D"))
19164 (clobber (reg:CC FLAGS_REG))]
19167 [(set_attr "type" "str")
19168 (set_attr "mode" "QI")
19169 (set_attr "prefix_rep" "1")])
19171 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19172 ;; handled in combine, but it is not currently up to the task.
19173 ;; When used for their truth value, the cmpstrn* expanders generate
19182 ;; The intermediate three instructions are unnecessary.
19184 ;; This one handles cmpstrn*_nz_1...
19187 (set (reg:CC FLAGS_REG)
19188 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19189 (mem:BLK (match_operand 5 "register_operand" ""))))
19190 (use (match_operand 6 "register_operand" ""))
19191 (use (match_operand:SI 3 "immediate_operand" ""))
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 (compare:CC (mem:BLK (match_dup 4))
19206 (mem:BLK (match_dup 5))))
19207 (use (match_dup 6))
19208 (use (match_dup 3))
19209 (clobber (match_dup 0))
19210 (clobber (match_dup 1))
19211 (clobber (match_dup 2))])]
19214 ;; ...and this one handles cmpstrn*_1.
19217 (set (reg:CC FLAGS_REG)
19218 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19220 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19221 (mem:BLK (match_operand 5 "register_operand" "")))
19223 (use (match_operand:SI 3 "immediate_operand" ""))
19224 (use (reg:CC FLAGS_REG))
19225 (clobber (match_operand 0 "register_operand" ""))
19226 (clobber (match_operand 1 "register_operand" ""))
19227 (clobber (match_operand 2 "register_operand" ""))])
19228 (set (match_operand:QI 7 "register_operand" "")
19229 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19230 (set (match_operand:QI 8 "register_operand" "")
19231 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19232 (set (reg FLAGS_REG)
19233 (compare (match_dup 7) (match_dup 8)))
19235 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19237 (set (reg:CC FLAGS_REG)
19238 (if_then_else:CC (ne (match_dup 6)
19240 (compare:CC (mem:BLK (match_dup 4))
19241 (mem:BLK (match_dup 5)))
19243 (use (match_dup 3))
19244 (use (reg:CC FLAGS_REG))
19245 (clobber (match_dup 0))
19246 (clobber (match_dup 1))
19247 (clobber (match_dup 2))])]
19252 ;; Conditional move instructions.
19254 (define_expand "movdicc"
19255 [(set (match_operand:DI 0 "register_operand" "")
19256 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19257 (match_operand:DI 2 "general_operand" "")
19258 (match_operand:DI 3 "general_operand" "")))]
19260 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19262 (define_insn "x86_movdicc_0_m1_rex64"
19263 [(set (match_operand:DI 0 "register_operand" "=r")
19264 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19267 (clobber (reg:CC FLAGS_REG))]
19270 ; Since we don't have the proper number of operands for an alu insn,
19271 ; fill in all the blanks.
19272 [(set_attr "type" "alu")
19273 (set_attr "pent_pair" "pu")
19274 (set_attr "memory" "none")
19275 (set_attr "imm_disp" "false")
19276 (set_attr "mode" "DI")
19277 (set_attr "length_immediate" "0")])
19279 (define_insn "*x86_movdicc_0_m1_se"
19280 [(set (match_operand:DI 0 "register_operand" "=r")
19281 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19284 (clobber (reg:CC FLAGS_REG))]
19287 [(set_attr "type" "alu")
19288 (set_attr "pent_pair" "pu")
19289 (set_attr "memory" "none")
19290 (set_attr "imm_disp" "false")
19291 (set_attr "mode" "DI")
19292 (set_attr "length_immediate" "0")])
19294 (define_insn "*movdicc_c_rex64"
19295 [(set (match_operand:DI 0 "register_operand" "=r,r")
19296 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19297 [(reg FLAGS_REG) (const_int 0)])
19298 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19299 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19300 "TARGET_64BIT && TARGET_CMOVE
19301 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19303 cmov%O2%C1\t{%2, %0|%0, %2}
19304 cmov%O2%c1\t{%3, %0|%0, %3}"
19305 [(set_attr "type" "icmov")
19306 (set_attr "mode" "DI")])
19308 (define_expand "movsicc"
19309 [(set (match_operand:SI 0 "register_operand" "")
19310 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19311 (match_operand:SI 2 "general_operand" "")
19312 (match_operand:SI 3 "general_operand" "")))]
19314 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19316 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19317 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19318 ;; So just document what we're doing explicitly.
19320 (define_insn "x86_movsicc_0_m1"
19321 [(set (match_operand:SI 0 "register_operand" "=r")
19322 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19325 (clobber (reg:CC FLAGS_REG))]
19328 ; Since we don't have the proper number of operands for an alu insn,
19329 ; fill in all the blanks.
19330 [(set_attr "type" "alu")
19331 (set_attr "pent_pair" "pu")
19332 (set_attr "memory" "none")
19333 (set_attr "imm_disp" "false")
19334 (set_attr "mode" "SI")
19335 (set_attr "length_immediate" "0")])
19337 (define_insn "*x86_movsicc_0_m1_se"
19338 [(set (match_operand:SI 0 "register_operand" "=r")
19339 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19342 (clobber (reg:CC FLAGS_REG))]
19345 [(set_attr "type" "alu")
19346 (set_attr "pent_pair" "pu")
19347 (set_attr "memory" "none")
19348 (set_attr "imm_disp" "false")
19349 (set_attr "mode" "SI")
19350 (set_attr "length_immediate" "0")])
19352 (define_insn "*movsicc_noc"
19353 [(set (match_operand:SI 0 "register_operand" "=r,r")
19354 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19355 [(reg FLAGS_REG) (const_int 0)])
19356 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19357 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19359 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19361 cmov%O2%C1\t{%2, %0|%0, %2}
19362 cmov%O2%c1\t{%3, %0|%0, %3}"
19363 [(set_attr "type" "icmov")
19364 (set_attr "mode" "SI")])
19366 (define_expand "movhicc"
19367 [(set (match_operand:HI 0 "register_operand" "")
19368 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19369 (match_operand:HI 2 "general_operand" "")
19370 (match_operand:HI 3 "general_operand" "")))]
19371 "TARGET_HIMODE_MATH"
19372 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19374 (define_insn "*movhicc_noc"
19375 [(set (match_operand:HI 0 "register_operand" "=r,r")
19376 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19377 [(reg FLAGS_REG) (const_int 0)])
19378 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19379 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19381 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19383 cmov%O2%C1\t{%2, %0|%0, %2}
19384 cmov%O2%c1\t{%3, %0|%0, %3}"
19385 [(set_attr "type" "icmov")
19386 (set_attr "mode" "HI")])
19388 (define_expand "movqicc"
19389 [(set (match_operand:QI 0 "register_operand" "")
19390 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19391 (match_operand:QI 2 "general_operand" "")
19392 (match_operand:QI 3 "general_operand" "")))]
19393 "TARGET_QIMODE_MATH"
19394 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19396 (define_insn_and_split "*movqicc_noc"
19397 [(set (match_operand:QI 0 "register_operand" "=r,r")
19398 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19399 [(match_operand 4 "flags_reg_operand" "")
19401 (match_operand:QI 2 "register_operand" "r,0")
19402 (match_operand:QI 3 "register_operand" "0,r")))]
19403 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19405 "&& reload_completed"
19406 [(set (match_dup 0)
19407 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19410 "operands[0] = gen_lowpart (SImode, operands[0]);
19411 operands[2] = gen_lowpart (SImode, operands[2]);
19412 operands[3] = gen_lowpart (SImode, operands[3]);"
19413 [(set_attr "type" "icmov")
19414 (set_attr "mode" "SI")])
19416 (define_expand "mov<mode>cc"
19417 [(set (match_operand:X87MODEF 0 "register_operand" "")
19418 (if_then_else:X87MODEF
19419 (match_operand 1 "comparison_operator" "")
19420 (match_operand:X87MODEF 2 "register_operand" "")
19421 (match_operand:X87MODEF 3 "register_operand" "")))]
19422 "(TARGET_80387 && TARGET_CMOVE)
19423 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19424 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19426 (define_insn "*movsfcc_1_387"
19427 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19428 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19429 [(reg FLAGS_REG) (const_int 0)])
19430 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19431 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19432 "TARGET_80387 && TARGET_CMOVE
19433 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19435 fcmov%F1\t{%2, %0|%0, %2}
19436 fcmov%f1\t{%3, %0|%0, %3}
19437 cmov%O2%C1\t{%2, %0|%0, %2}
19438 cmov%O2%c1\t{%3, %0|%0, %3}"
19439 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19440 (set_attr "mode" "SF,SF,SI,SI")])
19442 (define_insn "*movdfcc_1"
19443 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19444 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19445 [(reg FLAGS_REG) (const_int 0)])
19446 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19447 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19448 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19449 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19451 fcmov%F1\t{%2, %0|%0, %2}
19452 fcmov%f1\t{%3, %0|%0, %3}
19455 [(set_attr "type" "fcmov,fcmov,multi,multi")
19456 (set_attr "mode" "DF")])
19458 (define_insn "*movdfcc_1_rex64"
19459 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19460 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19461 [(reg FLAGS_REG) (const_int 0)])
19462 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19463 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19464 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19465 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19467 fcmov%F1\t{%2, %0|%0, %2}
19468 fcmov%f1\t{%3, %0|%0, %3}
19469 cmov%O2%C1\t{%2, %0|%0, %2}
19470 cmov%O2%c1\t{%3, %0|%0, %3}"
19471 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19472 (set_attr "mode" "DF")])
19475 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19476 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19477 [(match_operand 4 "flags_reg_operand" "")
19479 (match_operand:DF 2 "nonimmediate_operand" "")
19480 (match_operand:DF 3 "nonimmediate_operand" "")))]
19481 "!TARGET_64BIT && reload_completed"
19482 [(set (match_dup 2)
19483 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19487 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19490 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19491 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19493 (define_insn "*movxfcc_1"
19494 [(set (match_operand:XF 0 "register_operand" "=f,f")
19495 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19496 [(reg FLAGS_REG) (const_int 0)])
19497 (match_operand:XF 2 "register_operand" "f,0")
19498 (match_operand:XF 3 "register_operand" "0,f")))]
19499 "TARGET_80387 && TARGET_CMOVE"
19501 fcmov%F1\t{%2, %0|%0, %2}
19502 fcmov%f1\t{%3, %0|%0, %3}"
19503 [(set_attr "type" "fcmov")
19504 (set_attr "mode" "XF")])
19506 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19507 ;; the scalar versions to have only XMM registers as operands.
19509 ;; SSE5 conditional move
19510 (define_insn "*sse5_pcmov_<mode>"
19511 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19512 (if_then_else:MODEF
19513 (match_operand:MODEF 1 "register_operand" "x,0")
19514 (match_operand:MODEF 2 "register_operand" "0,x")
19515 (match_operand:MODEF 3 "register_operand" "x,x")))]
19516 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19517 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19518 [(set_attr "type" "sse4arg")])
19520 ;; These versions of the min/max patterns are intentionally ignorant of
19521 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19522 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19523 ;; are undefined in this condition, we're certain this is correct.
19525 (define_insn "<code><mode>3"
19526 [(set (match_operand:MODEF 0 "register_operand" "=x")
19528 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19529 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19530 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19531 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19532 [(set_attr "type" "sseadd")
19533 (set_attr "mode" "<MODE>")])
19535 ;; These versions of the min/max patterns implement exactly the operations
19536 ;; min = (op1 < op2 ? op1 : op2)
19537 ;; max = (!(op1 < op2) ? op1 : op2)
19538 ;; Their operands are not commutative, and thus they may be used in the
19539 ;; presence of -0.0 and NaN.
19541 (define_insn "*ieee_smin<mode>3"
19542 [(set (match_operand:MODEF 0 "register_operand" "=x")
19544 [(match_operand:MODEF 1 "register_operand" "0")
19545 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19547 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19548 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19549 [(set_attr "type" "sseadd")
19550 (set_attr "mode" "<MODE>")])
19552 (define_insn "*ieee_smax<mode>3"
19553 [(set (match_operand:MODEF 0 "register_operand" "=x")
19555 [(match_operand:MODEF 1 "register_operand" "0")
19556 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19558 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19559 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19560 [(set_attr "type" "sseadd")
19561 (set_attr "mode" "<MODE>")])
19563 ;; Make two stack loads independent:
19565 ;; fld %st(0) -> fld bb
19566 ;; fmul bb fmul %st(1), %st
19568 ;; Actually we only match the last two instructions for simplicity.
19570 [(set (match_operand 0 "fp_register_operand" "")
19571 (match_operand 1 "fp_register_operand" ""))
19573 (match_operator 2 "binary_fp_operator"
19575 (match_operand 3 "memory_operand" "")]))]
19576 "REGNO (operands[0]) != REGNO (operands[1])"
19577 [(set (match_dup 0) (match_dup 3))
19578 (set (match_dup 0) (match_dup 4))]
19580 ;; The % modifier is not operational anymore in peephole2's, so we have to
19581 ;; swap the operands manually in the case of addition and multiplication.
19582 "if (COMMUTATIVE_ARITH_P (operands[2]))
19583 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19584 operands[0], operands[1]);
19586 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19587 operands[1], operands[0]);")
19589 ;; Conditional addition patterns
19590 (define_expand "add<mode>cc"
19591 [(match_operand:SWI 0 "register_operand" "")
19592 (match_operand 1 "comparison_operator" "")
19593 (match_operand:SWI 2 "register_operand" "")
19594 (match_operand:SWI 3 "const_int_operand" "")]
19596 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19599 ;; Misc patterns (?)
19601 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19602 ;; Otherwise there will be nothing to keep
19604 ;; [(set (reg ebp) (reg esp))]
19605 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19606 ;; (clobber (eflags)]
19607 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19609 ;; in proper program order.
19610 (define_insn "pro_epilogue_adjust_stack_1"
19611 [(set (match_operand:SI 0 "register_operand" "=r,r")
19612 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19613 (match_operand:SI 2 "immediate_operand" "i,i")))
19614 (clobber (reg:CC FLAGS_REG))
19615 (clobber (mem:BLK (scratch)))]
19618 switch (get_attr_type (insn))
19621 return "mov{l}\t{%1, %0|%0, %1}";
19624 if (CONST_INT_P (operands[2])
19625 && (INTVAL (operands[2]) == 128
19626 || (INTVAL (operands[2]) < 0
19627 && INTVAL (operands[2]) != -128)))
19629 operands[2] = GEN_INT (-INTVAL (operands[2]));
19630 return "sub{l}\t{%2, %0|%0, %2}";
19632 return "add{l}\t{%2, %0|%0, %2}";
19635 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19636 return "lea{l}\t{%a2, %0|%0, %a2}";
19639 gcc_unreachable ();
19642 [(set (attr "type")
19643 (cond [(eq_attr "alternative" "0")
19644 (const_string "alu")
19645 (match_operand:SI 2 "const0_operand" "")
19646 (const_string "imov")
19648 (const_string "lea")))
19649 (set_attr "mode" "SI")])
19651 (define_insn "pro_epilogue_adjust_stack_rex64"
19652 [(set (match_operand:DI 0 "register_operand" "=r,r")
19653 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19654 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19655 (clobber (reg:CC FLAGS_REG))
19656 (clobber (mem:BLK (scratch)))]
19659 switch (get_attr_type (insn))
19662 return "mov{q}\t{%1, %0|%0, %1}";
19665 if (CONST_INT_P (operands[2])
19666 /* Avoid overflows. */
19667 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19668 && (INTVAL (operands[2]) == 128
19669 || (INTVAL (operands[2]) < 0
19670 && INTVAL (operands[2]) != -128)))
19672 operands[2] = GEN_INT (-INTVAL (operands[2]));
19673 return "sub{q}\t{%2, %0|%0, %2}";
19675 return "add{q}\t{%2, %0|%0, %2}";
19678 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19679 return "lea{q}\t{%a2, %0|%0, %a2}";
19682 gcc_unreachable ();
19685 [(set (attr "type")
19686 (cond [(eq_attr "alternative" "0")
19687 (const_string "alu")
19688 (match_operand:DI 2 "const0_operand" "")
19689 (const_string "imov")
19691 (const_string "lea")))
19692 (set_attr "mode" "DI")])
19694 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19695 [(set (match_operand:DI 0 "register_operand" "=r,r")
19696 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19697 (match_operand:DI 3 "immediate_operand" "i,i")))
19698 (use (match_operand:DI 2 "register_operand" "r,r"))
19699 (clobber (reg:CC FLAGS_REG))
19700 (clobber (mem:BLK (scratch)))]
19703 switch (get_attr_type (insn))
19706 return "add{q}\t{%2, %0|%0, %2}";
19709 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19710 return "lea{q}\t{%a2, %0|%0, %a2}";
19713 gcc_unreachable ();
19716 [(set_attr "type" "alu,lea")
19717 (set_attr "mode" "DI")])
19719 (define_insn "allocate_stack_worker_32"
19720 [(set (match_operand:SI 0 "register_operand" "+a")
19721 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19722 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19723 (clobber (reg:CC FLAGS_REG))]
19724 "!TARGET_64BIT && TARGET_STACK_PROBE"
19726 [(set_attr "type" "multi")
19727 (set_attr "length" "5")])
19729 (define_insn "allocate_stack_worker_64"
19730 [(set (match_operand:DI 0 "register_operand" "+a")
19731 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19732 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19733 (clobber (reg:DI R10_REG))
19734 (clobber (reg:DI R11_REG))
19735 (clobber (reg:CC FLAGS_REG))]
19736 "TARGET_64BIT && TARGET_STACK_PROBE"
19738 [(set_attr "type" "multi")
19739 (set_attr "length" "5")])
19741 (define_expand "allocate_stack"
19742 [(match_operand 0 "register_operand" "")
19743 (match_operand 1 "general_operand" "")]
19744 "TARGET_STACK_PROBE"
19748 #ifndef CHECK_STACK_LIMIT
19749 #define CHECK_STACK_LIMIT 0
19752 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19753 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19755 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19756 stack_pointer_rtx, 0, OPTAB_DIRECT);
19757 if (x != stack_pointer_rtx)
19758 emit_move_insn (stack_pointer_rtx, x);
19762 x = copy_to_mode_reg (Pmode, operands[1]);
19764 x = gen_allocate_stack_worker_64 (x);
19766 x = gen_allocate_stack_worker_32 (x);
19770 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19774 (define_expand "builtin_setjmp_receiver"
19775 [(label_ref (match_operand 0 "" ""))]
19776 "!TARGET_64BIT && flag_pic"
19781 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19782 rtx label_rtx = gen_label_rtx ();
19783 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19784 xops[0] = xops[1] = picreg;
19785 xops[2] = gen_rtx_CONST (SImode,
19786 gen_rtx_MINUS (SImode,
19787 gen_rtx_LABEL_REF (SImode, label_rtx),
19788 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19789 ix86_expand_binary_operator (MINUS, SImode, xops);
19792 emit_insn (gen_set_got (pic_offset_table_rtx));
19796 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19799 [(set (match_operand 0 "register_operand" "")
19800 (match_operator 3 "promotable_binary_operator"
19801 [(match_operand 1 "register_operand" "")
19802 (match_operand 2 "aligned_operand" "")]))
19803 (clobber (reg:CC FLAGS_REG))]
19804 "! TARGET_PARTIAL_REG_STALL && reload_completed
19805 && ((GET_MODE (operands[0]) == HImode
19806 && ((!optimize_size && !TARGET_FAST_PREFIX)
19807 /* ??? next two lines just !satisfies_constraint_K (...) */
19808 || !CONST_INT_P (operands[2])
19809 || satisfies_constraint_K (operands[2])))
19810 || (GET_MODE (operands[0]) == QImode
19811 && (TARGET_PROMOTE_QImode || optimize_size)))"
19812 [(parallel [(set (match_dup 0)
19813 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19814 (clobber (reg:CC FLAGS_REG))])]
19815 "operands[0] = gen_lowpart (SImode, operands[0]);
19816 operands[1] = gen_lowpart (SImode, operands[1]);
19817 if (GET_CODE (operands[3]) != ASHIFT)
19818 operands[2] = gen_lowpart (SImode, operands[2]);
19819 PUT_MODE (operands[3], SImode);")
19821 ; Promote the QImode tests, as i386 has encoding of the AND
19822 ; instruction with 32-bit sign-extended immediate and thus the
19823 ; instruction size is unchanged, except in the %eax case for
19824 ; which it is increased by one byte, hence the ! optimize_size.
19826 [(set (match_operand 0 "flags_reg_operand" "")
19827 (match_operator 2 "compare_operator"
19828 [(and (match_operand 3 "aligned_operand" "")
19829 (match_operand 4 "const_int_operand" ""))
19831 (set (match_operand 1 "register_operand" "")
19832 (and (match_dup 3) (match_dup 4)))]
19833 "! TARGET_PARTIAL_REG_STALL && reload_completed
19835 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19836 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19837 /* Ensure that the operand will remain sign-extended immediate. */
19838 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19839 [(parallel [(set (match_dup 0)
19840 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19843 (and:SI (match_dup 3) (match_dup 4)))])]
19846 = gen_int_mode (INTVAL (operands[4])
19847 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19848 operands[1] = gen_lowpart (SImode, operands[1]);
19849 operands[3] = gen_lowpart (SImode, operands[3]);
19852 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19853 ; the TEST instruction with 32-bit sign-extended immediate and thus
19854 ; the instruction size would at least double, which is not what we
19855 ; want even with ! optimize_size.
19857 [(set (match_operand 0 "flags_reg_operand" "")
19858 (match_operator 1 "compare_operator"
19859 [(and (match_operand:HI 2 "aligned_operand" "")
19860 (match_operand:HI 3 "const_int_operand" ""))
19862 "! TARGET_PARTIAL_REG_STALL && reload_completed
19863 && ! TARGET_FAST_PREFIX
19865 /* Ensure that the operand will remain sign-extended immediate. */
19866 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19867 [(set (match_dup 0)
19868 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19872 = gen_int_mode (INTVAL (operands[3])
19873 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19874 operands[2] = gen_lowpart (SImode, operands[2]);
19878 [(set (match_operand 0 "register_operand" "")
19879 (neg (match_operand 1 "register_operand" "")))
19880 (clobber (reg:CC FLAGS_REG))]
19881 "! TARGET_PARTIAL_REG_STALL && reload_completed
19882 && (GET_MODE (operands[0]) == HImode
19883 || (GET_MODE (operands[0]) == QImode
19884 && (TARGET_PROMOTE_QImode || optimize_size)))"
19885 [(parallel [(set (match_dup 0)
19886 (neg:SI (match_dup 1)))
19887 (clobber (reg:CC FLAGS_REG))])]
19888 "operands[0] = gen_lowpart (SImode, operands[0]);
19889 operands[1] = gen_lowpart (SImode, operands[1]);")
19892 [(set (match_operand 0 "register_operand" "")
19893 (not (match_operand 1 "register_operand" "")))]
19894 "! TARGET_PARTIAL_REG_STALL && reload_completed
19895 && (GET_MODE (operands[0]) == HImode
19896 || (GET_MODE (operands[0]) == QImode
19897 && (TARGET_PROMOTE_QImode || optimize_size)))"
19898 [(set (match_dup 0)
19899 (not:SI (match_dup 1)))]
19900 "operands[0] = gen_lowpart (SImode, operands[0]);
19901 operands[1] = gen_lowpart (SImode, operands[1]);")
19904 [(set (match_operand 0 "register_operand" "")
19905 (if_then_else (match_operator 1 "comparison_operator"
19906 [(reg FLAGS_REG) (const_int 0)])
19907 (match_operand 2 "register_operand" "")
19908 (match_operand 3 "register_operand" "")))]
19909 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19910 && (GET_MODE (operands[0]) == HImode
19911 || (GET_MODE (operands[0]) == QImode
19912 && (TARGET_PROMOTE_QImode || optimize_size)))"
19913 [(set (match_dup 0)
19914 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19915 "operands[0] = gen_lowpart (SImode, operands[0]);
19916 operands[2] = gen_lowpart (SImode, operands[2]);
19917 operands[3] = gen_lowpart (SImode, operands[3]);")
19920 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19921 ;; transform a complex memory operation into two memory to register operations.
19923 ;; Don't push memory operands
19925 [(set (match_operand:SI 0 "push_operand" "")
19926 (match_operand:SI 1 "memory_operand" ""))
19927 (match_scratch:SI 2 "r")]
19928 "!optimize_size && !TARGET_PUSH_MEMORY
19929 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930 [(set (match_dup 2) (match_dup 1))
19931 (set (match_dup 0) (match_dup 2))]
19935 [(set (match_operand:DI 0 "push_operand" "")
19936 (match_operand:DI 1 "memory_operand" ""))
19937 (match_scratch:DI 2 "r")]
19938 "!optimize_size && !TARGET_PUSH_MEMORY
19939 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19940 [(set (match_dup 2) (match_dup 1))
19941 (set (match_dup 0) (match_dup 2))]
19944 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19947 [(set (match_operand:SF 0 "push_operand" "")
19948 (match_operand:SF 1 "memory_operand" ""))
19949 (match_scratch:SF 2 "r")]
19950 "!optimize_size && !TARGET_PUSH_MEMORY
19951 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19952 [(set (match_dup 2) (match_dup 1))
19953 (set (match_dup 0) (match_dup 2))]
19957 [(set (match_operand:HI 0 "push_operand" "")
19958 (match_operand:HI 1 "memory_operand" ""))
19959 (match_scratch:HI 2 "r")]
19960 "!optimize_size && !TARGET_PUSH_MEMORY
19961 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19962 [(set (match_dup 2) (match_dup 1))
19963 (set (match_dup 0) (match_dup 2))]
19967 [(set (match_operand:QI 0 "push_operand" "")
19968 (match_operand:QI 1 "memory_operand" ""))
19969 (match_scratch:QI 2 "q")]
19970 "!optimize_size && !TARGET_PUSH_MEMORY
19971 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19972 [(set (match_dup 2) (match_dup 1))
19973 (set (match_dup 0) (match_dup 2))]
19976 ;; Don't move an immediate directly to memory when the instruction
19979 [(match_scratch:SI 1 "r")
19980 (set (match_operand:SI 0 "memory_operand" "")
19983 && ! TARGET_USE_MOV0
19984 && TARGET_SPLIT_LONG_MOVES
19985 && get_attr_length (insn) >= ix86_cost->large_insn
19986 && peep2_regno_dead_p (0, FLAGS_REG)"
19987 [(parallel [(set (match_dup 1) (const_int 0))
19988 (clobber (reg:CC FLAGS_REG))])
19989 (set (match_dup 0) (match_dup 1))]
19993 [(match_scratch:HI 1 "r")
19994 (set (match_operand:HI 0 "memory_operand" "")
19997 && ! TARGET_USE_MOV0
19998 && TARGET_SPLIT_LONG_MOVES
19999 && get_attr_length (insn) >= ix86_cost->large_insn
20000 && peep2_regno_dead_p (0, FLAGS_REG)"
20001 [(parallel [(set (match_dup 2) (const_int 0))
20002 (clobber (reg:CC FLAGS_REG))])
20003 (set (match_dup 0) (match_dup 1))]
20004 "operands[2] = gen_lowpart (SImode, operands[1]);")
20007 [(match_scratch:QI 1 "q")
20008 (set (match_operand:QI 0 "memory_operand" "")
20011 && ! TARGET_USE_MOV0
20012 && TARGET_SPLIT_LONG_MOVES
20013 && get_attr_length (insn) >= ix86_cost->large_insn
20014 && peep2_regno_dead_p (0, FLAGS_REG)"
20015 [(parallel [(set (match_dup 2) (const_int 0))
20016 (clobber (reg:CC FLAGS_REG))])
20017 (set (match_dup 0) (match_dup 1))]
20018 "operands[2] = gen_lowpart (SImode, operands[1]);")
20021 [(match_scratch:SI 2 "r")
20022 (set (match_operand:SI 0 "memory_operand" "")
20023 (match_operand:SI 1 "immediate_operand" ""))]
20025 && TARGET_SPLIT_LONG_MOVES
20026 && get_attr_length (insn) >= ix86_cost->large_insn"
20027 [(set (match_dup 2) (match_dup 1))
20028 (set (match_dup 0) (match_dup 2))]
20032 [(match_scratch:HI 2 "r")
20033 (set (match_operand:HI 0 "memory_operand" "")
20034 (match_operand:HI 1 "immediate_operand" ""))]
20036 && TARGET_SPLIT_LONG_MOVES
20037 && get_attr_length (insn) >= ix86_cost->large_insn"
20038 [(set (match_dup 2) (match_dup 1))
20039 (set (match_dup 0) (match_dup 2))]
20043 [(match_scratch:QI 2 "q")
20044 (set (match_operand:QI 0 "memory_operand" "")
20045 (match_operand:QI 1 "immediate_operand" ""))]
20047 && TARGET_SPLIT_LONG_MOVES
20048 && get_attr_length (insn) >= ix86_cost->large_insn"
20049 [(set (match_dup 2) (match_dup 1))
20050 (set (match_dup 0) (match_dup 2))]
20053 ;; Don't compare memory with zero, load and use a test instead.
20055 [(set (match_operand 0 "flags_reg_operand" "")
20056 (match_operator 1 "compare_operator"
20057 [(match_operand:SI 2 "memory_operand" "")
20059 (match_scratch:SI 3 "r")]
20060 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20061 [(set (match_dup 3) (match_dup 2))
20062 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20065 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20066 ;; Don't split NOTs with a displacement operand, because resulting XOR
20067 ;; will not be pairable anyway.
20069 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20070 ;; represented using a modRM byte. The XOR replacement is long decoded,
20071 ;; so this split helps here as well.
20073 ;; Note: Can't do this as a regular split because we can't get proper
20074 ;; lifetime information then.
20077 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20078 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20080 && ((TARGET_NOT_UNPAIRABLE
20081 && (!MEM_P (operands[0])
20082 || !memory_displacement_operand (operands[0], SImode)))
20083 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20084 && peep2_regno_dead_p (0, FLAGS_REG)"
20085 [(parallel [(set (match_dup 0)
20086 (xor:SI (match_dup 1) (const_int -1)))
20087 (clobber (reg:CC FLAGS_REG))])]
20091 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20092 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20094 && ((TARGET_NOT_UNPAIRABLE
20095 && (!MEM_P (operands[0])
20096 || !memory_displacement_operand (operands[0], HImode)))
20097 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20098 && peep2_regno_dead_p (0, FLAGS_REG)"
20099 [(parallel [(set (match_dup 0)
20100 (xor:HI (match_dup 1) (const_int -1)))
20101 (clobber (reg:CC FLAGS_REG))])]
20105 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20106 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20108 && ((TARGET_NOT_UNPAIRABLE
20109 && (!MEM_P (operands[0])
20110 || !memory_displacement_operand (operands[0], QImode)))
20111 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20112 && peep2_regno_dead_p (0, FLAGS_REG)"
20113 [(parallel [(set (match_dup 0)
20114 (xor:QI (match_dup 1) (const_int -1)))
20115 (clobber (reg:CC FLAGS_REG))])]
20118 ;; Non pairable "test imm, reg" instructions can be translated to
20119 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20120 ;; byte opcode instead of two, have a short form for byte operands),
20121 ;; so do it for other CPUs as well. Given that the value was dead,
20122 ;; this should not create any new dependencies. Pass on the sub-word
20123 ;; versions if we're concerned about partial register stalls.
20126 [(set (match_operand 0 "flags_reg_operand" "")
20127 (match_operator 1 "compare_operator"
20128 [(and:SI (match_operand:SI 2 "register_operand" "")
20129 (match_operand:SI 3 "immediate_operand" ""))
20131 "ix86_match_ccmode (insn, CCNOmode)
20132 && (true_regnum (operands[2]) != AX_REG
20133 || satisfies_constraint_K (operands[3]))
20134 && peep2_reg_dead_p (1, operands[2])"
20136 [(set (match_dup 0)
20137 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20140 (and:SI (match_dup 2) (match_dup 3)))])]
20143 ;; We don't need to handle HImode case, because it will be promoted to SImode
20144 ;; on ! TARGET_PARTIAL_REG_STALL
20147 [(set (match_operand 0 "flags_reg_operand" "")
20148 (match_operator 1 "compare_operator"
20149 [(and:QI (match_operand:QI 2 "register_operand" "")
20150 (match_operand:QI 3 "immediate_operand" ""))
20152 "! TARGET_PARTIAL_REG_STALL
20153 && ix86_match_ccmode (insn, CCNOmode)
20154 && true_regnum (operands[2]) != AX_REG
20155 && peep2_reg_dead_p (1, operands[2])"
20157 [(set (match_dup 0)
20158 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20161 (and:QI (match_dup 2) (match_dup 3)))])]
20165 [(set (match_operand 0 "flags_reg_operand" "")
20166 (match_operator 1 "compare_operator"
20169 (match_operand 2 "ext_register_operand" "")
20172 (match_operand 3 "const_int_operand" ""))
20174 "! TARGET_PARTIAL_REG_STALL
20175 && ix86_match_ccmode (insn, CCNOmode)
20176 && true_regnum (operands[2]) != AX_REG
20177 && peep2_reg_dead_p (1, operands[2])"
20178 [(parallel [(set (match_dup 0)
20187 (set (zero_extract:SI (match_dup 2)
20198 ;; Don't do logical operations with memory inputs.
20200 [(match_scratch:SI 2 "r")
20201 (parallel [(set (match_operand:SI 0 "register_operand" "")
20202 (match_operator:SI 3 "arith_or_logical_operator"
20204 (match_operand:SI 1 "memory_operand" "")]))
20205 (clobber (reg:CC FLAGS_REG))])]
20206 "! optimize_size && ! TARGET_READ_MODIFY"
20207 [(set (match_dup 2) (match_dup 1))
20208 (parallel [(set (match_dup 0)
20209 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20210 (clobber (reg:CC FLAGS_REG))])]
20214 [(match_scratch:SI 2 "r")
20215 (parallel [(set (match_operand:SI 0 "register_operand" "")
20216 (match_operator:SI 3 "arith_or_logical_operator"
20217 [(match_operand:SI 1 "memory_operand" "")
20219 (clobber (reg:CC FLAGS_REG))])]
20220 "! optimize_size && ! TARGET_READ_MODIFY"
20221 [(set (match_dup 2) (match_dup 1))
20222 (parallel [(set (match_dup 0)
20223 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20224 (clobber (reg:CC FLAGS_REG))])]
20227 ; Don't do logical operations with memory outputs
20229 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20230 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20231 ; the same decoder scheduling characteristics as the original.
20234 [(match_scratch:SI 2 "r")
20235 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20236 (match_operator:SI 3 "arith_or_logical_operator"
20238 (match_operand:SI 1 "nonmemory_operand" "")]))
20239 (clobber (reg:CC FLAGS_REG))])]
20240 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20241 [(set (match_dup 2) (match_dup 0))
20242 (parallel [(set (match_dup 2)
20243 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20244 (clobber (reg:CC FLAGS_REG))])
20245 (set (match_dup 0) (match_dup 2))]
20249 [(match_scratch:SI 2 "r")
20250 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20251 (match_operator:SI 3 "arith_or_logical_operator"
20252 [(match_operand:SI 1 "nonmemory_operand" "")
20254 (clobber (reg:CC FLAGS_REG))])]
20255 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20256 [(set (match_dup 2) (match_dup 0))
20257 (parallel [(set (match_dup 2)
20258 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20259 (clobber (reg:CC FLAGS_REG))])
20260 (set (match_dup 0) (match_dup 2))]
20263 ;; Attempt to always use XOR for zeroing registers.
20265 [(set (match_operand 0 "register_operand" "")
20266 (match_operand 1 "const0_operand" ""))]
20267 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20268 && (! TARGET_USE_MOV0 || optimize_size)
20269 && GENERAL_REG_P (operands[0])
20270 && peep2_regno_dead_p (0, FLAGS_REG)"
20271 [(parallel [(set (match_dup 0) (const_int 0))
20272 (clobber (reg:CC FLAGS_REG))])]
20274 operands[0] = gen_lowpart (word_mode, operands[0]);
20278 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20280 "(GET_MODE (operands[0]) == QImode
20281 || GET_MODE (operands[0]) == HImode)
20282 && (! TARGET_USE_MOV0 || optimize_size)
20283 && peep2_regno_dead_p (0, FLAGS_REG)"
20284 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20285 (clobber (reg:CC FLAGS_REG))])])
20287 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20289 [(set (match_operand 0 "register_operand" "")
20291 "(GET_MODE (operands[0]) == HImode
20292 || GET_MODE (operands[0]) == SImode
20293 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20294 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20295 && peep2_regno_dead_p (0, FLAGS_REG)"
20296 [(parallel [(set (match_dup 0) (const_int -1))
20297 (clobber (reg:CC FLAGS_REG))])]
20298 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20301 ;; Attempt to convert simple leas to adds. These can be created by
20304 [(set (match_operand:SI 0 "register_operand" "")
20305 (plus:SI (match_dup 0)
20306 (match_operand:SI 1 "nonmemory_operand" "")))]
20307 "peep2_regno_dead_p (0, FLAGS_REG)"
20308 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20309 (clobber (reg:CC FLAGS_REG))])]
20313 [(set (match_operand:SI 0 "register_operand" "")
20314 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20315 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20316 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20317 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20318 (clobber (reg:CC FLAGS_REG))])]
20319 "operands[2] = gen_lowpart (SImode, operands[2]);")
20322 [(set (match_operand:DI 0 "register_operand" "")
20323 (plus:DI (match_dup 0)
20324 (match_operand:DI 1 "x86_64_general_operand" "")))]
20325 "peep2_regno_dead_p (0, FLAGS_REG)"
20326 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20327 (clobber (reg:CC FLAGS_REG))])]
20331 [(set (match_operand:SI 0 "register_operand" "")
20332 (mult:SI (match_dup 0)
20333 (match_operand:SI 1 "const_int_operand" "")))]
20334 "exact_log2 (INTVAL (operands[1])) >= 0
20335 && peep2_regno_dead_p (0, FLAGS_REG)"
20336 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20337 (clobber (reg:CC FLAGS_REG))])]
20338 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20341 [(set (match_operand:DI 0 "register_operand" "")
20342 (mult:DI (match_dup 0)
20343 (match_operand:DI 1 "const_int_operand" "")))]
20344 "exact_log2 (INTVAL (operands[1])) >= 0
20345 && peep2_regno_dead_p (0, FLAGS_REG)"
20346 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20347 (clobber (reg:CC FLAGS_REG))])]
20348 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20351 [(set (match_operand:SI 0 "register_operand" "")
20352 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20353 (match_operand:DI 2 "const_int_operand" "")) 0))]
20354 "exact_log2 (INTVAL (operands[2])) >= 0
20355 && REGNO (operands[0]) == REGNO (operands[1])
20356 && peep2_regno_dead_p (0, FLAGS_REG)"
20357 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20358 (clobber (reg:CC FLAGS_REG))])]
20359 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20361 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20362 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20363 ;; many CPUs it is also faster, since special hardware to avoid esp
20364 ;; dependencies is present.
20366 ;; While some of these conversions may be done using splitters, we use peepholes
20367 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20369 ;; Convert prologue esp subtractions to push.
20370 ;; We need register to push. In order to keep verify_flow_info happy we have
20372 ;; - use scratch and clobber it in order to avoid dependencies
20373 ;; - use already live register
20374 ;; We can't use the second way right now, since there is no reliable way how to
20375 ;; verify that given register is live. First choice will also most likely in
20376 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20377 ;; call clobbered registers are dead. We may want to use base pointer as an
20378 ;; alternative when no register is available later.
20381 [(match_scratch:SI 0 "r")
20382 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20383 (clobber (reg:CC FLAGS_REG))
20384 (clobber (mem:BLK (scratch)))])]
20385 "optimize_size || !TARGET_SUB_ESP_4"
20386 [(clobber (match_dup 0))
20387 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20388 (clobber (mem:BLK (scratch)))])])
20391 [(match_scratch:SI 0 "r")
20392 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20393 (clobber (reg:CC FLAGS_REG))
20394 (clobber (mem:BLK (scratch)))])]
20395 "optimize_size || !TARGET_SUB_ESP_8"
20396 [(clobber (match_dup 0))
20397 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20398 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20399 (clobber (mem:BLK (scratch)))])])
20401 ;; Convert esp subtractions to push.
20403 [(match_scratch:SI 0 "r")
20404 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20405 (clobber (reg:CC FLAGS_REG))])]
20406 "optimize_size || !TARGET_SUB_ESP_4"
20407 [(clobber (match_dup 0))
20408 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20411 [(match_scratch:SI 0 "r")
20412 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20413 (clobber (reg:CC FLAGS_REG))])]
20414 "optimize_size || !TARGET_SUB_ESP_8"
20415 [(clobber (match_dup 0))
20416 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20417 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20419 ;; Convert epilogue deallocator to pop.
20421 [(match_scratch:SI 0 "r")
20422 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20423 (clobber (reg:CC FLAGS_REG))
20424 (clobber (mem:BLK (scratch)))])]
20425 "optimize_size || !TARGET_ADD_ESP_4"
20426 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20427 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20428 (clobber (mem:BLK (scratch)))])]
20431 ;; Two pops case is tricky, since pop causes dependency on destination register.
20432 ;; We use two registers if available.
20434 [(match_scratch:SI 0 "r")
20435 (match_scratch:SI 1 "r")
20436 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20437 (clobber (reg:CC FLAGS_REG))
20438 (clobber (mem:BLK (scratch)))])]
20439 "optimize_size || !TARGET_ADD_ESP_8"
20440 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20441 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20442 (clobber (mem:BLK (scratch)))])
20443 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20444 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20448 [(match_scratch:SI 0 "r")
20449 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20450 (clobber (reg:CC FLAGS_REG))
20451 (clobber (mem:BLK (scratch)))])]
20453 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20454 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20455 (clobber (mem:BLK (scratch)))])
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)))])]
20460 ;; Convert esp additions to pop.
20462 [(match_scratch:SI 0 "r")
20463 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20464 (clobber (reg:CC FLAGS_REG))])]
20466 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20467 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20470 ;; Two pops case is tricky, since pop causes dependency on destination register.
20471 ;; We use two registers if available.
20473 [(match_scratch:SI 0 "r")
20474 (match_scratch:SI 1 "r")
20475 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20476 (clobber (reg:CC FLAGS_REG))])]
20478 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20479 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20480 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20481 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20485 [(match_scratch:SI 0 "r")
20486 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20487 (clobber (reg:CC FLAGS_REG))])]
20489 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20490 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20491 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20492 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20495 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20496 ;; required and register dies. Similarly for 128 to plus -128.
20498 [(set (match_operand 0 "flags_reg_operand" "")
20499 (match_operator 1 "compare_operator"
20500 [(match_operand 2 "register_operand" "")
20501 (match_operand 3 "const_int_operand" "")]))]
20502 "(INTVAL (operands[3]) == -1
20503 || INTVAL (operands[3]) == 1
20504 || INTVAL (operands[3]) == 128)
20505 && ix86_match_ccmode (insn, CCGCmode)
20506 && peep2_reg_dead_p (1, operands[2])"
20507 [(parallel [(set (match_dup 0)
20508 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20509 (clobber (match_dup 2))])]
20513 [(match_scratch:DI 0 "r")
20514 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20515 (clobber (reg:CC FLAGS_REG))
20516 (clobber (mem:BLK (scratch)))])]
20517 "optimize_size || !TARGET_SUB_ESP_4"
20518 [(clobber (match_dup 0))
20519 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20520 (clobber (mem:BLK (scratch)))])])
20523 [(match_scratch:DI 0 "r")
20524 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20525 (clobber (reg:CC FLAGS_REG))
20526 (clobber (mem:BLK (scratch)))])]
20527 "optimize_size || !TARGET_SUB_ESP_8"
20528 [(clobber (match_dup 0))
20529 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20530 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20531 (clobber (mem:BLK (scratch)))])])
20533 ;; Convert esp subtractions to push.
20535 [(match_scratch:DI 0 "r")
20536 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20537 (clobber (reg:CC FLAGS_REG))])]
20538 "optimize_size || !TARGET_SUB_ESP_4"
20539 [(clobber (match_dup 0))
20540 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20543 [(match_scratch:DI 0 "r")
20544 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20545 (clobber (reg:CC FLAGS_REG))])]
20546 "optimize_size || !TARGET_SUB_ESP_8"
20547 [(clobber (match_dup 0))
20548 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20549 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20551 ;; Convert epilogue deallocator to pop.
20553 [(match_scratch:DI 0 "r")
20554 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20555 (clobber (reg:CC FLAGS_REG))
20556 (clobber (mem:BLK (scratch)))])]
20557 "optimize_size || !TARGET_ADD_ESP_4"
20558 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20559 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20560 (clobber (mem:BLK (scratch)))])]
20563 ;; Two pops case is tricky, since pop causes dependency on destination register.
20564 ;; We use two registers if available.
20566 [(match_scratch:DI 0 "r")
20567 (match_scratch:DI 1 "r")
20568 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20569 (clobber (reg:CC FLAGS_REG))
20570 (clobber (mem:BLK (scratch)))])]
20571 "optimize_size || !TARGET_ADD_ESP_8"
20572 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20573 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20574 (clobber (mem:BLK (scratch)))])
20575 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20576 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20580 [(match_scratch:DI 0 "r")
20581 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20582 (clobber (reg:CC FLAGS_REG))
20583 (clobber (mem:BLK (scratch)))])]
20585 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20586 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20587 (clobber (mem:BLK (scratch)))])
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)))])]
20592 ;; Convert esp additions to pop.
20594 [(match_scratch:DI 0 "r")
20595 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20596 (clobber (reg:CC FLAGS_REG))])]
20598 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20599 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20602 ;; Two pops case is tricky, since pop causes dependency on destination register.
20603 ;; We use two registers if available.
20605 [(match_scratch:DI 0 "r")
20606 (match_scratch:DI 1 "r")
20607 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20608 (clobber (reg:CC FLAGS_REG))])]
20610 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20611 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20612 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20613 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20617 [(match_scratch:DI 0 "r")
20618 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20619 (clobber (reg:CC FLAGS_REG))])]
20621 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20622 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20623 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20624 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20627 ;; Convert imul by three, five and nine into lea
20630 [(set (match_operand:SI 0 "register_operand" "")
20631 (mult:SI (match_operand:SI 1 "register_operand" "")
20632 (match_operand:SI 2 "const_int_operand" "")))
20633 (clobber (reg:CC FLAGS_REG))])]
20634 "INTVAL (operands[2]) == 3
20635 || INTVAL (operands[2]) == 5
20636 || INTVAL (operands[2]) == 9"
20637 [(set (match_dup 0)
20638 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20640 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20644 [(set (match_operand:SI 0 "register_operand" "")
20645 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20646 (match_operand:SI 2 "const_int_operand" "")))
20647 (clobber (reg:CC FLAGS_REG))])]
20649 && (INTVAL (operands[2]) == 3
20650 || INTVAL (operands[2]) == 5
20651 || INTVAL (operands[2]) == 9)"
20652 [(set (match_dup 0) (match_dup 1))
20654 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20656 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20660 [(set (match_operand:DI 0 "register_operand" "")
20661 (mult:DI (match_operand:DI 1 "register_operand" "")
20662 (match_operand:DI 2 "const_int_operand" "")))
20663 (clobber (reg:CC FLAGS_REG))])]
20665 && (INTVAL (operands[2]) == 3
20666 || INTVAL (operands[2]) == 5
20667 || INTVAL (operands[2]) == 9)"
20668 [(set (match_dup 0)
20669 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20671 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20675 [(set (match_operand:DI 0 "register_operand" "")
20676 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20677 (match_operand:DI 2 "const_int_operand" "")))
20678 (clobber (reg:CC FLAGS_REG))])]
20681 && (INTVAL (operands[2]) == 3
20682 || INTVAL (operands[2]) == 5
20683 || INTVAL (operands[2]) == 9)"
20684 [(set (match_dup 0) (match_dup 1))
20686 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20688 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20690 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20691 ;; imul $32bit_imm, reg, reg is direct decoded.
20693 [(match_scratch:DI 3 "r")
20694 (parallel [(set (match_operand:DI 0 "register_operand" "")
20695 (mult:DI (match_operand:DI 1 "memory_operand" "")
20696 (match_operand:DI 2 "immediate_operand" "")))
20697 (clobber (reg:CC FLAGS_REG))])]
20698 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20699 && !satisfies_constraint_K (operands[2])"
20700 [(set (match_dup 3) (match_dup 1))
20701 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20702 (clobber (reg:CC FLAGS_REG))])]
20706 [(match_scratch:SI 3 "r")
20707 (parallel [(set (match_operand:SI 0 "register_operand" "")
20708 (mult:SI (match_operand:SI 1 "memory_operand" "")
20709 (match_operand:SI 2 "immediate_operand" "")))
20710 (clobber (reg:CC FLAGS_REG))])]
20711 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20712 && !satisfies_constraint_K (operands[2])"
20713 [(set (match_dup 3) (match_dup 1))
20714 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20715 (clobber (reg:CC FLAGS_REG))])]
20719 [(match_scratch:SI 3 "r")
20720 (parallel [(set (match_operand:DI 0 "register_operand" "")
20722 (mult:SI (match_operand:SI 1 "memory_operand" "")
20723 (match_operand:SI 2 "immediate_operand" ""))))
20724 (clobber (reg:CC FLAGS_REG))])]
20725 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20726 && !satisfies_constraint_K (operands[2])"
20727 [(set (match_dup 3) (match_dup 1))
20728 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20729 (clobber (reg:CC FLAGS_REG))])]
20732 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20733 ;; Convert it into imul reg, reg
20734 ;; It would be better to force assembler to encode instruction using long
20735 ;; immediate, but there is apparently no way to do so.
20737 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20738 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20739 (match_operand:DI 2 "const_int_operand" "")))
20740 (clobber (reg:CC FLAGS_REG))])
20741 (match_scratch:DI 3 "r")]
20742 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20743 && satisfies_constraint_K (operands[2])"
20744 [(set (match_dup 3) (match_dup 2))
20745 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20746 (clobber (reg:CC FLAGS_REG))])]
20748 if (!rtx_equal_p (operands[0], operands[1]))
20749 emit_move_insn (operands[0], operands[1]);
20753 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20754 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20755 (match_operand:SI 2 "const_int_operand" "")))
20756 (clobber (reg:CC FLAGS_REG))])
20757 (match_scratch:SI 3 "r")]
20758 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20759 && satisfies_constraint_K (operands[2])"
20760 [(set (match_dup 3) (match_dup 2))
20761 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20762 (clobber (reg:CC FLAGS_REG))])]
20764 if (!rtx_equal_p (operands[0], operands[1]))
20765 emit_move_insn (operands[0], operands[1]);
20769 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20770 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20771 (match_operand:HI 2 "immediate_operand" "")))
20772 (clobber (reg:CC FLAGS_REG))])
20773 (match_scratch:HI 3 "r")]
20774 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20775 [(set (match_dup 3) (match_dup 2))
20776 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20777 (clobber (reg:CC FLAGS_REG))])]
20779 if (!rtx_equal_p (operands[0], operands[1]))
20780 emit_move_insn (operands[0], operands[1]);
20783 ;; After splitting up read-modify operations, array accesses with memory
20784 ;; operands might end up in form:
20786 ;; movl 4(%esp), %edx
20788 ;; instead of pre-splitting:
20790 ;; addl 4(%esp), %eax
20792 ;; movl 4(%esp), %edx
20793 ;; leal (%edx,%eax,4), %eax
20796 [(parallel [(set (match_operand 0 "register_operand" "")
20797 (ashift (match_operand 1 "register_operand" "")
20798 (match_operand 2 "const_int_operand" "")))
20799 (clobber (reg:CC FLAGS_REG))])
20800 (set (match_operand 3 "register_operand")
20801 (match_operand 4 "x86_64_general_operand" ""))
20802 (parallel [(set (match_operand 5 "register_operand" "")
20803 (plus (match_operand 6 "register_operand" "")
20804 (match_operand 7 "register_operand" "")))
20805 (clobber (reg:CC FLAGS_REG))])]
20806 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20807 /* Validate MODE for lea. */
20808 && ((!TARGET_PARTIAL_REG_STALL
20809 && (GET_MODE (operands[0]) == QImode
20810 || GET_MODE (operands[0]) == HImode))
20811 || GET_MODE (operands[0]) == SImode
20812 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20813 /* We reorder load and the shift. */
20814 && !rtx_equal_p (operands[1], operands[3])
20815 && !reg_overlap_mentioned_p (operands[0], operands[4])
20816 /* Last PLUS must consist of operand 0 and 3. */
20817 && !rtx_equal_p (operands[0], operands[3])
20818 && (rtx_equal_p (operands[3], operands[6])
20819 || rtx_equal_p (operands[3], operands[7]))
20820 && (rtx_equal_p (operands[0], operands[6])
20821 || rtx_equal_p (operands[0], operands[7]))
20822 /* The intermediate operand 0 must die or be same as output. */
20823 && (rtx_equal_p (operands[0], operands[5])
20824 || peep2_reg_dead_p (3, operands[0]))"
20825 [(set (match_dup 3) (match_dup 4))
20826 (set (match_dup 0) (match_dup 1))]
20828 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20829 int scale = 1 << INTVAL (operands[2]);
20830 rtx index = gen_lowpart (Pmode, operands[1]);
20831 rtx base = gen_lowpart (Pmode, operands[3]);
20832 rtx dest = gen_lowpart (mode, operands[5]);
20834 operands[1] = gen_rtx_PLUS (Pmode, base,
20835 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20837 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20838 operands[0] = dest;
20841 ;; Call-value patterns last so that the wildcard operand does not
20842 ;; disrupt insn-recog's switch tables.
20844 (define_insn "*call_value_pop_0"
20845 [(set (match_operand 0 "" "")
20846 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20847 (match_operand:SI 2 "" "")))
20848 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20849 (match_operand:SI 3 "immediate_operand" "")))]
20852 if (SIBLING_CALL_P (insn))
20855 return "call\t%P1";
20857 [(set_attr "type" "callv")])
20859 (define_insn "*call_value_pop_1"
20860 [(set (match_operand 0 "" "")
20861 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20862 (match_operand:SI 2 "" "")))
20863 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20864 (match_operand:SI 3 "immediate_operand" "i")))]
20867 if (constant_call_address_operand (operands[1], Pmode))
20869 if (SIBLING_CALL_P (insn))
20872 return "call\t%P1";
20874 if (SIBLING_CALL_P (insn))
20877 return "call\t%A1";
20879 [(set_attr "type" "callv")])
20881 (define_insn "*call_value_0"
20882 [(set (match_operand 0 "" "")
20883 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20884 (match_operand:SI 2 "" "")))]
20887 if (SIBLING_CALL_P (insn))
20890 return "call\t%P1";
20892 [(set_attr "type" "callv")])
20894 (define_insn "*call_value_0_rex64"
20895 [(set (match_operand 0 "" "")
20896 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20897 (match_operand:DI 2 "const_int_operand" "")))]
20900 if (SIBLING_CALL_P (insn))
20903 return "call\t%P1";
20905 [(set_attr "type" "callv")])
20907 (define_insn "*call_value_1"
20908 [(set (match_operand 0 "" "")
20909 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20910 (match_operand:SI 2 "" "")))]
20911 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20913 if (constant_call_address_operand (operands[1], Pmode))
20914 return "call\t%P1";
20915 return "call\t%A1";
20917 [(set_attr "type" "callv")])
20919 (define_insn "*sibcall_value_1"
20920 [(set (match_operand 0 "" "")
20921 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20922 (match_operand:SI 2 "" "")))]
20923 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20925 if (constant_call_address_operand (operands[1], Pmode))
20929 [(set_attr "type" "callv")])
20931 (define_insn "*call_value_1_rex64"
20932 [(set (match_operand 0 "" "")
20933 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20934 (match_operand:DI 2 "" "")))]
20935 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20936 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20938 if (constant_call_address_operand (operands[1], Pmode))
20939 return "call\t%P1";
20940 return "call\t%A1";
20942 [(set_attr "type" "callv")])
20944 (define_insn "*call_value_1_rex64_large"
20945 [(set (match_operand 0 "" "")
20946 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20947 (match_operand:DI 2 "" "")))]
20948 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20950 [(set_attr "type" "callv")])
20952 (define_insn "*sibcall_value_1_rex64"
20953 [(set (match_operand 0 "" "")
20954 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20955 (match_operand:DI 2 "" "")))]
20956 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20958 [(set_attr "type" "callv")])
20960 (define_insn "*sibcall_value_1_rex64_v"
20961 [(set (match_operand 0 "" "")
20962 (call (mem:QI (reg:DI R11_REG))
20963 (match_operand:DI 1 "" "")))]
20964 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20966 [(set_attr "type" "callv")])
20968 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20969 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20970 ;; caught for use by garbage collectors and the like. Using an insn that
20971 ;; maps to SIGILL makes it more likely the program will rightfully die.
20972 ;; Keeping with tradition, "6" is in honor of #UD.
20973 (define_insn "trap"
20974 [(trap_if (const_int 1) (const_int 6))]
20976 { return ASM_SHORT "0x0b0f"; }
20977 [(set_attr "length" "2")])
20979 (define_expand "sse_prologue_save"
20980 [(parallel [(set (match_operand:BLK 0 "" "")
20981 (unspec:BLK [(reg:DI 21)
20988 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20989 (use (match_operand:DI 1 "register_operand" ""))
20990 (use (match_operand:DI 2 "immediate_operand" ""))
20991 (use (label_ref:DI (match_operand 3 "" "")))])]
20995 (define_insn "*sse_prologue_save_insn"
20996 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20997 (match_operand:DI 4 "const_int_operand" "n")))
20998 (unspec:BLK [(reg:DI 21)
21005 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21006 (use (match_operand:DI 1 "register_operand" "r"))
21007 (use (match_operand:DI 2 "const_int_operand" "i"))
21008 (use (label_ref:DI (match_operand 3 "" "X")))]
21010 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21011 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21014 operands[0] = gen_rtx_MEM (Pmode,
21015 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21016 output_asm_insn ("jmp\t%A1", operands);
21017 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21019 operands[4] = adjust_address (operands[0], DImode, i*16);
21020 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21021 PUT_MODE (operands[4], TImode);
21022 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21023 output_asm_insn ("rex", operands);
21024 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21026 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21027 CODE_LABEL_NUMBER (operands[3]));
21030 [(set_attr "type" "other")
21031 (set_attr "length_immediate" "0")
21032 (set_attr "length_address" "0")
21033 (set_attr "length" "34")
21034 (set_attr "memory" "store")
21035 (set_attr "modrm" "0")
21036 (set_attr "mode" "DI")])
21038 (define_expand "prefetch"
21039 [(prefetch (match_operand 0 "address_operand" "")
21040 (match_operand:SI 1 "const_int_operand" "")
21041 (match_operand:SI 2 "const_int_operand" ""))]
21042 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21044 int rw = INTVAL (operands[1]);
21045 int locality = INTVAL (operands[2]);
21047 gcc_assert (rw == 0 || rw == 1);
21048 gcc_assert (locality >= 0 && locality <= 3);
21049 gcc_assert (GET_MODE (operands[0]) == Pmode
21050 || GET_MODE (operands[0]) == VOIDmode);
21052 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21053 supported by SSE counterpart or the SSE prefetch is not available
21054 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21056 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21057 operands[2] = GEN_INT (3);
21059 operands[1] = const0_rtx;
21062 (define_insn "*prefetch_sse"
21063 [(prefetch (match_operand:SI 0 "address_operand" "p")
21065 (match_operand:SI 1 "const_int_operand" ""))]
21066 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21068 static const char * const patterns[4] = {
21069 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21072 int locality = INTVAL (operands[1]);
21073 gcc_assert (locality >= 0 && locality <= 3);
21075 return patterns[locality];
21077 [(set_attr "type" "sse")
21078 (set_attr "memory" "none")])
21080 (define_insn "*prefetch_sse_rex"
21081 [(prefetch (match_operand:DI 0 "address_operand" "p")
21083 (match_operand:SI 1 "const_int_operand" ""))]
21084 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21086 static const char * const patterns[4] = {
21087 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21090 int locality = INTVAL (operands[1]);
21091 gcc_assert (locality >= 0 && locality <= 3);
21093 return patterns[locality];
21095 [(set_attr "type" "sse")
21096 (set_attr "memory" "none")])
21098 (define_insn "*prefetch_3dnow"
21099 [(prefetch (match_operand:SI 0 "address_operand" "p")
21100 (match_operand:SI 1 "const_int_operand" "n")
21102 "TARGET_3DNOW && !TARGET_64BIT"
21104 if (INTVAL (operands[1]) == 0)
21105 return "prefetch\t%a0";
21107 return "prefetchw\t%a0";
21109 [(set_attr "type" "mmx")
21110 (set_attr "memory" "none")])
21112 (define_insn "*prefetch_3dnow_rex"
21113 [(prefetch (match_operand:DI 0 "address_operand" "p")
21114 (match_operand:SI 1 "const_int_operand" "n")
21116 "TARGET_3DNOW && TARGET_64BIT"
21118 if (INTVAL (operands[1]) == 0)
21119 return "prefetch\t%a0";
21121 return "prefetchw\t%a0";
21123 [(set_attr "type" "mmx")
21124 (set_attr "memory" "none")])
21126 (define_expand "stack_protect_set"
21127 [(match_operand 0 "memory_operand" "")
21128 (match_operand 1 "memory_operand" "")]
21131 #ifdef TARGET_THREAD_SSP_OFFSET
21133 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21134 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21136 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21137 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21140 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21142 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21147 (define_insn "stack_protect_set_si"
21148 [(set (match_operand:SI 0 "memory_operand" "=m")
21149 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21150 (set (match_scratch:SI 2 "=&r") (const_int 0))
21151 (clobber (reg:CC FLAGS_REG))]
21153 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21154 [(set_attr "type" "multi")])
21156 (define_insn "stack_protect_set_di"
21157 [(set (match_operand:DI 0 "memory_operand" "=m")
21158 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21159 (set (match_scratch:DI 2 "=&r") (const_int 0))
21160 (clobber (reg:CC FLAGS_REG))]
21162 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21163 [(set_attr "type" "multi")])
21165 (define_insn "stack_tls_protect_set_si"
21166 [(set (match_operand:SI 0 "memory_operand" "=m")
21167 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21168 (set (match_scratch:SI 2 "=&r") (const_int 0))
21169 (clobber (reg:CC FLAGS_REG))]
21171 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21172 [(set_attr "type" "multi")])
21174 (define_insn "stack_tls_protect_set_di"
21175 [(set (match_operand:DI 0 "memory_operand" "=m")
21176 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21177 (set (match_scratch:DI 2 "=&r") (const_int 0))
21178 (clobber (reg:CC FLAGS_REG))]
21181 /* The kernel uses a different segment register for performance reasons; a
21182 system call would not have to trash the userspace segment register,
21183 which would be expensive */
21184 if (ix86_cmodel != CM_KERNEL)
21185 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21187 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21189 [(set_attr "type" "multi")])
21191 (define_expand "stack_protect_test"
21192 [(match_operand 0 "memory_operand" "")
21193 (match_operand 1 "memory_operand" "")
21194 (match_operand 2 "" "")]
21197 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21198 ix86_compare_op0 = operands[0];
21199 ix86_compare_op1 = operands[1];
21200 ix86_compare_emitted = flags;
21202 #ifdef TARGET_THREAD_SSP_OFFSET
21204 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21205 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21207 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21208 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21211 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21213 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21215 emit_jump_insn (gen_beq (operands[2]));
21219 (define_insn "stack_protect_test_si"
21220 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21221 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21222 (match_operand:SI 2 "memory_operand" "m")]
21224 (clobber (match_scratch:SI 3 "=&r"))]
21226 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21227 [(set_attr "type" "multi")])
21229 (define_insn "stack_protect_test_di"
21230 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21231 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21232 (match_operand:DI 2 "memory_operand" "m")]
21234 (clobber (match_scratch:DI 3 "=&r"))]
21236 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21237 [(set_attr "type" "multi")])
21239 (define_insn "stack_tls_protect_test_si"
21240 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21241 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21242 (match_operand:SI 2 "const_int_operand" "i")]
21243 UNSPEC_SP_TLS_TEST))
21244 (clobber (match_scratch:SI 3 "=r"))]
21246 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21247 [(set_attr "type" "multi")])
21249 (define_insn "stack_tls_protect_test_di"
21250 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21251 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21252 (match_operand:DI 2 "const_int_operand" "i")]
21253 UNSPEC_SP_TLS_TEST))
21254 (clobber (match_scratch:DI 3 "=r"))]
21257 /* The kernel uses a different segment register for performance reasons; a
21258 system call would not have to trash the userspace segment register,
21259 which would be expensive */
21260 if (ix86_cmodel != CM_KERNEL)
21261 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21263 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21265 [(set_attr "type" "multi")])
21267 (define_mode_iterator CRC32MODE [QI HI SI])
21268 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21269 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21271 (define_insn "sse4_2_crc32<mode>"
21272 [(set (match_operand:SI 0 "register_operand" "=r")
21274 [(match_operand:SI 1 "register_operand" "0")
21275 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21278 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21279 [(set_attr "type" "sselog1")
21280 (set_attr "prefix_rep" "1")
21281 (set_attr "prefix_extra" "1")
21282 (set_attr "mode" "SI")])
21284 (define_insn "sse4_2_crc32di"
21285 [(set (match_operand:DI 0 "register_operand" "=r")
21287 [(match_operand:DI 1 "register_operand" "0")
21288 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21290 "TARGET_SSE4_2 && TARGET_64BIT"
21291 "crc32q\t{%2, %0|%0, %2}"
21292 [(set_attr "type" "sselog1")
21293 (set_attr "prefix_rep" "1")
21294 (set_attr "prefix_extra" "1")
21295 (set_attr "mode" "DI")])
21299 (include "sync.md")