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)
218 ;; Constants to represent pcomtrue/pcomfalse variants
228 ;; Constants used in the SSE5 pperm instruction
230 [(PPERM_SRC 0x00) /* copy source */
231 (PPERM_INVERT 0x20) /* invert source */
232 (PPERM_REVERSE 0x40) /* bit reverse source */
233 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
234 (PPERM_ZERO 0x80) /* all 0's */
235 (PPERM_ONES 0xa0) /* all 1's */
236 (PPERM_SIGN 0xc0) /* propagate sign bit */
237 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
238 (PPERM_SRC1 0x00) /* use first source byte */
239 (PPERM_SRC2 0x10) /* use second source byte */
242 ;; Registers by name.
258 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
261 ;; In C guard expressions, put expressions which may be compile-time
262 ;; constants first. This allows for better optimization. For
263 ;; example, write "TARGET_64BIT && reload_completed", not
264 ;; "reload_completed && TARGET_64BIT".
267 ;; Processor type. This attribute must exactly match the processor_type
268 ;; enumeration in i386.h.
269 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
270 nocona,core2,generic32,generic64,amdfam10"
271 (const (symbol_ref "ix86_tune")))
273 ;; A basic instruction type. Refinements due to arguments to be
274 ;; provided in other attributes.
277 alu,alu1,negnot,imov,imovx,lea,
278 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
279 icmp,test,ibr,setcc,icmov,
280 push,pop,call,callv,leave,
282 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
283 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
284 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
286 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
287 (const_string "other"))
289 ;; Main data type used by the insn
291 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
292 (const_string "unknown"))
294 ;; The CPU unit operations uses.
295 (define_attr "unit" "integer,i387,sse,mmx,unknown"
296 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
297 (const_string "i387")
298 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
299 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
300 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
302 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
304 (eq_attr "type" "other")
305 (const_string "unknown")]
306 (const_string "integer")))
308 ;; The (bounding maximum) length of an instruction immediate.
309 (define_attr "length_immediate" ""
310 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
313 (eq_attr "unit" "i387,sse,mmx")
315 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
317 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
318 (eq_attr "type" "imov,test")
319 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
320 (eq_attr "type" "call")
321 (if_then_else (match_operand 0 "constant_call_address_operand" "")
324 (eq_attr "type" "callv")
325 (if_then_else (match_operand 1 "constant_call_address_operand" "")
328 ;; We don't know the size before shorten_branches. Expect
329 ;; the instruction to fit for better scheduling.
330 (eq_attr "type" "ibr")
333 (symbol_ref "/* Update immediate_length and other attributes! */
334 gcc_unreachable (),1")))
336 ;; The (bounding maximum) length of an instruction address.
337 (define_attr "length_address" ""
338 (cond [(eq_attr "type" "str,other,multi,fxch")
340 (and (eq_attr "type" "call")
341 (match_operand 0 "constant_call_address_operand" ""))
343 (and (eq_attr "type" "callv")
344 (match_operand 1 "constant_call_address_operand" ""))
347 (symbol_ref "ix86_attr_length_address_default (insn)")))
349 ;; Set when length prefix is used.
350 (define_attr "prefix_data16" ""
351 (if_then_else (ior (eq_attr "mode" "HI")
352 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
356 ;; Set when string REP prefix is used.
357 (define_attr "prefix_rep" ""
358 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
362 ;; Set when 0f opcode prefix is used.
363 (define_attr "prefix_0f" ""
365 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
366 (eq_attr "unit" "sse,mmx"))
370 ;; Set when REX opcode prefix is used.
371 (define_attr "prefix_rex" ""
372 (cond [(and (eq_attr "mode" "DI")
373 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
375 (and (eq_attr "mode" "QI")
376 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
379 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
385 ;; There are also additional prefixes in SSSE3.
386 (define_attr "prefix_extra" "" (const_int 0))
388 ;; Set when modrm byte is used.
389 (define_attr "modrm" ""
390 (cond [(eq_attr "type" "str,leave")
392 (eq_attr "unit" "i387")
394 (and (eq_attr "type" "incdec")
395 (ior (match_operand:SI 1 "register_operand" "")
396 (match_operand:HI 1 "register_operand" "")))
398 (and (eq_attr "type" "push")
399 (not (match_operand 1 "memory_operand" "")))
401 (and (eq_attr "type" "pop")
402 (not (match_operand 0 "memory_operand" "")))
404 (and (eq_attr "type" "imov")
405 (ior (and (match_operand 0 "register_operand" "")
406 (match_operand 1 "immediate_operand" ""))
407 (ior (and (match_operand 0 "ax_reg_operand" "")
408 (match_operand 1 "memory_displacement_only_operand" ""))
409 (and (match_operand 0 "memory_displacement_only_operand" "")
410 (match_operand 1 "ax_reg_operand" "")))))
412 (and (eq_attr "type" "call")
413 (match_operand 0 "constant_call_address_operand" ""))
415 (and (eq_attr "type" "callv")
416 (match_operand 1 "constant_call_address_operand" ""))
421 ;; The (bounding maximum) length of an instruction in bytes.
422 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
423 ;; Later we may want to split them and compute proper length as for
425 (define_attr "length" ""
426 (cond [(eq_attr "type" "other,multi,fistp,frndint")
428 (eq_attr "type" "fcmp")
430 (eq_attr "unit" "i387")
432 (plus (attr "prefix_data16")
433 (attr "length_address")))]
434 (plus (plus (attr "modrm")
435 (plus (attr "prefix_0f")
436 (plus (attr "prefix_rex")
437 (plus (attr "prefix_extra")
439 (plus (attr "prefix_rep")
440 (plus (attr "prefix_data16")
441 (plus (attr "length_immediate")
442 (attr "length_address")))))))
444 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
445 ;; `store' if there is a simple memory reference therein, or `unknown'
446 ;; if the instruction is complex.
448 (define_attr "memory" "none,load,store,both,unknown"
449 (cond [(eq_attr "type" "other,multi,str")
450 (const_string "unknown")
451 (eq_attr "type" "lea,fcmov,fpspc")
452 (const_string "none")
453 (eq_attr "type" "fistp,leave")
454 (const_string "both")
455 (eq_attr "type" "frndint")
456 (const_string "load")
457 (eq_attr "type" "push")
458 (if_then_else (match_operand 1 "memory_operand" "")
459 (const_string "both")
460 (const_string "store"))
461 (eq_attr "type" "pop")
462 (if_then_else (match_operand 0 "memory_operand" "")
463 (const_string "both")
464 (const_string "load"))
465 (eq_attr "type" "setcc")
466 (if_then_else (match_operand 0 "memory_operand" "")
467 (const_string "store")
468 (const_string "none"))
469 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
470 (if_then_else (ior (match_operand 0 "memory_operand" "")
471 (match_operand 1 "memory_operand" ""))
472 (const_string "load")
473 (const_string "none"))
474 (eq_attr "type" "ibr")
475 (if_then_else (match_operand 0 "memory_operand" "")
476 (const_string "load")
477 (const_string "none"))
478 (eq_attr "type" "call")
479 (if_then_else (match_operand 0 "constant_call_address_operand" "")
480 (const_string "none")
481 (const_string "load"))
482 (eq_attr "type" "callv")
483 (if_then_else (match_operand 1 "constant_call_address_operand" "")
484 (const_string "none")
485 (const_string "load"))
486 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
487 (match_operand 1 "memory_operand" ""))
488 (const_string "both")
489 (and (match_operand 0 "memory_operand" "")
490 (match_operand 1 "memory_operand" ""))
491 (const_string "both")
492 (match_operand 0 "memory_operand" "")
493 (const_string "store")
494 (match_operand 1 "memory_operand" "")
495 (const_string "load")
497 "!alu1,negnot,ishift1,
498 imov,imovx,icmp,test,bitmanip,
500 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
501 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
502 (match_operand 2 "memory_operand" ""))
503 (const_string "load")
504 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
505 (match_operand 3 "memory_operand" ""))
506 (const_string "load")
508 (const_string "none")))
510 ;; Indicates if an instruction has both an immediate and a displacement.
512 (define_attr "imm_disp" "false,true,unknown"
513 (cond [(eq_attr "type" "other,multi")
514 (const_string "unknown")
515 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
516 (and (match_operand 0 "memory_displacement_operand" "")
517 (match_operand 1 "immediate_operand" "")))
518 (const_string "true")
519 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
520 (and (match_operand 0 "memory_displacement_operand" "")
521 (match_operand 2 "immediate_operand" "")))
522 (const_string "true")
524 (const_string "false")))
526 ;; Indicates if an FP operation has an integer source.
528 (define_attr "fp_int_src" "false,true"
529 (const_string "false"))
531 ;; Defines rounding mode of an FP operation.
533 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
534 (const_string "any"))
536 ;; Describe a user's asm statement.
537 (define_asm_attributes
538 [(set_attr "length" "128")
539 (set_attr "type" "multi")])
541 ;; All integer comparison codes.
542 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
544 ;; All floating-point comparison codes.
545 (define_code_iterator fp_cond [unordered ordered
546 uneq unge ungt unle unlt ltgt ])
548 (define_code_iterator plusminus [plus minus])
550 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
552 ;; Base name for define_insn
553 (define_code_attr plusminus_insn
554 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
555 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
557 ;; Base name for insn mnemonic.
558 (define_code_attr plusminus_mnemonic
559 [(plus "add") (ss_plus "adds") (us_plus "addus")
560 (minus "sub") (ss_minus "subs") (us_minus "subus")])
562 ;; Mark commutative operators as such in constraints.
563 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
564 (minus "") (ss_minus "") (us_minus "")])
566 ;; Mapping of signed max and min
567 (define_code_iterator smaxmin [smax smin])
569 ;; Mapping of unsigned max and min
570 (define_code_iterator umaxmin [umax umin])
572 ;; Base name for integer and FP insn mnemonic
573 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
574 (umax "maxu") (umin "minu")])
575 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
577 ;; Mapping of parallel logic operators
578 (define_code_iterator plogic [and ior xor])
580 ;; Base name for insn mnemonic.
581 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
583 ;; Mapping of abs neg operators
584 (define_code_iterator absneg [abs neg])
586 ;; Base name for x87 insn mnemonic.
587 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
589 ;; All single word integer modes.
590 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
592 ;; Instruction suffix for integer modes.
593 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
595 ;; Register class for integer modes.
596 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
598 ;; Immediate operand constraint for integer modes.
599 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
601 ;; General operand predicate for integer modes.
602 (define_mode_attr general_operand
603 [(QI "general_operand")
604 (HI "general_operand")
605 (SI "general_operand")
606 (DI "x86_64_general_operand")])
608 ;; SSE and x87 SFmode and DFmode floating point modes
609 (define_mode_iterator MODEF [SF DF])
611 ;; All x87 floating point modes
612 (define_mode_iterator X87MODEF [SF DF XF])
614 ;; All integer modes handled by x87 fisttp operator.
615 (define_mode_iterator X87MODEI [HI SI DI])
617 ;; All integer modes handled by integer x87 operators.
618 (define_mode_iterator X87MODEI12 [HI SI])
620 ;; All integer modes handled by SSE cvtts?2si* operators.
621 (define_mode_iterator SSEMODEI24 [SI DI])
623 ;; SSE asm suffix for floating point modes
624 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
626 ;; SSE vector mode corresponding to a scalar mode
627 (define_mode_attr ssevecmode
628 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
630 ;; Instruction suffix for REX 64bit operators.
631 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
633 ;; Scheduling descriptions
635 (include "pentium.md")
638 (include "athlon.md")
642 ;; Operand and operator predicates and constraints
644 (include "predicates.md")
645 (include "constraints.md")
648 ;; Compare instructions.
650 ;; All compare insns have expanders that save the operands away without
651 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
652 ;; after the cmp) will actually emit the cmpM.
654 (define_expand "cmpti"
655 [(set (reg:CC FLAGS_REG)
656 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
657 (match_operand:TI 1 "x86_64_general_operand" "")))]
660 if (MEM_P (operands[0]) && MEM_P (operands[1]))
661 operands[0] = force_reg (TImode, operands[0]);
662 ix86_compare_op0 = operands[0];
663 ix86_compare_op1 = operands[1];
667 (define_expand "cmpdi"
668 [(set (reg:CC FLAGS_REG)
669 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
670 (match_operand:DI 1 "x86_64_general_operand" "")))]
673 if (MEM_P (operands[0]) && MEM_P (operands[1]))
674 operands[0] = force_reg (DImode, operands[0]);
675 ix86_compare_op0 = operands[0];
676 ix86_compare_op1 = operands[1];
680 (define_expand "cmpsi"
681 [(set (reg:CC FLAGS_REG)
682 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
683 (match_operand:SI 1 "general_operand" "")))]
686 if (MEM_P (operands[0]) && MEM_P (operands[1]))
687 operands[0] = force_reg (SImode, operands[0]);
688 ix86_compare_op0 = operands[0];
689 ix86_compare_op1 = operands[1];
693 (define_expand "cmphi"
694 [(set (reg:CC FLAGS_REG)
695 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
696 (match_operand:HI 1 "general_operand" "")))]
699 if (MEM_P (operands[0]) && MEM_P (operands[1]))
700 operands[0] = force_reg (HImode, operands[0]);
701 ix86_compare_op0 = operands[0];
702 ix86_compare_op1 = operands[1];
706 (define_expand "cmpqi"
707 [(set (reg:CC FLAGS_REG)
708 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
709 (match_operand:QI 1 "general_operand" "")))]
712 if (MEM_P (operands[0]) && MEM_P (operands[1]))
713 operands[0] = force_reg (QImode, operands[0]);
714 ix86_compare_op0 = operands[0];
715 ix86_compare_op1 = operands[1];
719 (define_insn "cmpdi_ccno_1_rex64"
720 [(set (reg FLAGS_REG)
721 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
722 (match_operand:DI 1 "const0_operand" "n,n")))]
723 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
726 cmp{q}\t{%1, %0|%0, %1}"
727 [(set_attr "type" "test,icmp")
728 (set_attr "length_immediate" "0,1")
729 (set_attr "mode" "DI")])
731 (define_insn "*cmpdi_minus_1_rex64"
732 [(set (reg FLAGS_REG)
733 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
734 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
736 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
737 "cmp{q}\t{%1, %0|%0, %1}"
738 [(set_attr "type" "icmp")
739 (set_attr "mode" "DI")])
741 (define_expand "cmpdi_1_rex64"
742 [(set (reg:CC FLAGS_REG)
743 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
744 (match_operand:DI 1 "general_operand" "")))]
748 (define_insn "cmpdi_1_insn_rex64"
749 [(set (reg FLAGS_REG)
750 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
751 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
752 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
753 "cmp{q}\t{%1, %0|%0, %1}"
754 [(set_attr "type" "icmp")
755 (set_attr "mode" "DI")])
758 (define_insn "*cmpsi_ccno_1"
759 [(set (reg FLAGS_REG)
760 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
761 (match_operand:SI 1 "const0_operand" "n,n")))]
762 "ix86_match_ccmode (insn, CCNOmode)"
765 cmp{l}\t{%1, %0|%0, %1}"
766 [(set_attr "type" "test,icmp")
767 (set_attr "length_immediate" "0,1")
768 (set_attr "mode" "SI")])
770 (define_insn "*cmpsi_minus_1"
771 [(set (reg FLAGS_REG)
772 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
773 (match_operand:SI 1 "general_operand" "ri,mr"))
775 "ix86_match_ccmode (insn, CCGOCmode)"
776 "cmp{l}\t{%1, %0|%0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "SI")])
780 (define_expand "cmpsi_1"
781 [(set (reg:CC FLAGS_REG)
782 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
783 (match_operand:SI 1 "general_operand" "")))]
787 (define_insn "*cmpsi_1_insn"
788 [(set (reg FLAGS_REG)
789 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
790 (match_operand:SI 1 "general_operand" "ri,mr")))]
791 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
792 && ix86_match_ccmode (insn, CCmode)"
793 "cmp{l}\t{%1, %0|%0, %1}"
794 [(set_attr "type" "icmp")
795 (set_attr "mode" "SI")])
797 (define_insn "*cmphi_ccno_1"
798 [(set (reg FLAGS_REG)
799 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
800 (match_operand:HI 1 "const0_operand" "n,n")))]
801 "ix86_match_ccmode (insn, CCNOmode)"
804 cmp{w}\t{%1, %0|%0, %1}"
805 [(set_attr "type" "test,icmp")
806 (set_attr "length_immediate" "0,1")
807 (set_attr "mode" "HI")])
809 (define_insn "*cmphi_minus_1"
810 [(set (reg FLAGS_REG)
811 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
812 (match_operand:HI 1 "general_operand" "ri,mr"))
814 "ix86_match_ccmode (insn, CCGOCmode)"
815 "cmp{w}\t{%1, %0|%0, %1}"
816 [(set_attr "type" "icmp")
817 (set_attr "mode" "HI")])
819 (define_insn "*cmphi_1"
820 [(set (reg FLAGS_REG)
821 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
822 (match_operand:HI 1 "general_operand" "ri,mr")))]
823 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
824 && ix86_match_ccmode (insn, CCmode)"
825 "cmp{w}\t{%1, %0|%0, %1}"
826 [(set_attr "type" "icmp")
827 (set_attr "mode" "HI")])
829 (define_insn "*cmpqi_ccno_1"
830 [(set (reg FLAGS_REG)
831 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
832 (match_operand:QI 1 "const0_operand" "n,n")))]
833 "ix86_match_ccmode (insn, CCNOmode)"
836 cmp{b}\t{$0, %0|%0, 0}"
837 [(set_attr "type" "test,icmp")
838 (set_attr "length_immediate" "0,1")
839 (set_attr "mode" "QI")])
841 (define_insn "*cmpqi_1"
842 [(set (reg FLAGS_REG)
843 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
844 (match_operand:QI 1 "general_operand" "qi,mq")))]
845 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
846 && ix86_match_ccmode (insn, CCmode)"
847 "cmp{b}\t{%1, %0|%0, %1}"
848 [(set_attr "type" "icmp")
849 (set_attr "mode" "QI")])
851 (define_insn "*cmpqi_minus_1"
852 [(set (reg FLAGS_REG)
853 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
854 (match_operand:QI 1 "general_operand" "qi,mq"))
856 "ix86_match_ccmode (insn, CCGOCmode)"
857 "cmp{b}\t{%1, %0|%0, %1}"
858 [(set_attr "type" "icmp")
859 (set_attr "mode" "QI")])
861 (define_insn "*cmpqi_ext_1"
862 [(set (reg FLAGS_REG)
864 (match_operand:QI 0 "general_operand" "Qm")
867 (match_operand 1 "ext_register_operand" "Q")
870 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
871 "cmp{b}\t{%h1, %0|%0, %h1}"
872 [(set_attr "type" "icmp")
873 (set_attr "mode" "QI")])
875 (define_insn "*cmpqi_ext_1_rex64"
876 [(set (reg FLAGS_REG)
878 (match_operand:QI 0 "register_operand" "Q")
881 (match_operand 1 "ext_register_operand" "Q")
884 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
885 "cmp{b}\t{%h1, %0|%0, %h1}"
886 [(set_attr "type" "icmp")
887 (set_attr "mode" "QI")])
889 (define_insn "*cmpqi_ext_2"
890 [(set (reg FLAGS_REG)
894 (match_operand 0 "ext_register_operand" "Q")
897 (match_operand:QI 1 "const0_operand" "n")))]
898 "ix86_match_ccmode (insn, CCNOmode)"
900 [(set_attr "type" "test")
901 (set_attr "length_immediate" "0")
902 (set_attr "mode" "QI")])
904 (define_expand "cmpqi_ext_3"
905 [(set (reg:CC FLAGS_REG)
909 (match_operand 0 "ext_register_operand" "")
912 (match_operand:QI 1 "general_operand" "")))]
916 (define_insn "cmpqi_ext_3_insn"
917 [(set (reg FLAGS_REG)
921 (match_operand 0 "ext_register_operand" "Q")
924 (match_operand:QI 1 "general_operand" "Qmn")))]
925 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
926 "cmp{b}\t{%1, %h0|%h0, %1}"
927 [(set_attr "type" "icmp")
928 (set_attr "mode" "QI")])
930 (define_insn "cmpqi_ext_3_insn_rex64"
931 [(set (reg FLAGS_REG)
935 (match_operand 0 "ext_register_operand" "Q")
938 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
939 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
940 "cmp{b}\t{%1, %h0|%h0, %1}"
941 [(set_attr "type" "icmp")
942 (set_attr "mode" "QI")])
944 (define_insn "*cmpqi_ext_4"
945 [(set (reg FLAGS_REG)
949 (match_operand 0 "ext_register_operand" "Q")
954 (match_operand 1 "ext_register_operand" "Q")
957 "ix86_match_ccmode (insn, CCmode)"
958 "cmp{b}\t{%h1, %h0|%h0, %h1}"
959 [(set_attr "type" "icmp")
960 (set_attr "mode" "QI")])
962 ;; These implement float point compares.
963 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
964 ;; which would allow mix and match FP modes on the compares. Which is what
965 ;; the old patterns did, but with many more of them.
967 (define_expand "cmpxf"
968 [(set (reg:CC FLAGS_REG)
969 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
970 (match_operand:XF 1 "nonmemory_operand" "")))]
973 ix86_compare_op0 = operands[0];
974 ix86_compare_op1 = operands[1];
978 (define_expand "cmp<mode>"
979 [(set (reg:CC FLAGS_REG)
980 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
981 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
982 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
984 ix86_compare_op0 = operands[0];
985 ix86_compare_op1 = operands[1];
989 ;; FP compares, step 1:
990 ;; Set the FP condition codes.
992 ;; CCFPmode compare with exceptions
993 ;; CCFPUmode compare with no exceptions
995 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
996 ;; used to manage the reg stack popping would not be preserved.
998 (define_insn "*cmpfp_0"
999 [(set (match_operand:HI 0 "register_operand" "=a")
1002 (match_operand 1 "register_operand" "f")
1003 (match_operand 2 "const0_operand" "X"))]
1005 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1006 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1007 "* return output_fp_compare (insn, operands, 0, 0);"
1008 [(set_attr "type" "multi")
1009 (set_attr "unit" "i387")
1011 (cond [(match_operand:SF 1 "" "")
1013 (match_operand:DF 1 "" "")
1016 (const_string "XF")))])
1018 (define_insn_and_split "*cmpfp_0_cc"
1019 [(set (reg:CCFP FLAGS_REG)
1021 (match_operand 1 "register_operand" "f")
1022 (match_operand 2 "const0_operand" "X")))
1023 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1024 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1025 && TARGET_SAHF && !TARGET_CMOVE
1026 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1028 "&& reload_completed"
1031 [(compare:CCFP (match_dup 1)(match_dup 2))]
1033 (set (reg:CC FLAGS_REG)
1034 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1036 [(set_attr "type" "multi")
1037 (set_attr "unit" "i387")
1039 (cond [(match_operand:SF 1 "" "")
1041 (match_operand:DF 1 "" "")
1044 (const_string "XF")))])
1046 (define_insn "*cmpfp_xf"
1047 [(set (match_operand:HI 0 "register_operand" "=a")
1050 (match_operand:XF 1 "register_operand" "f")
1051 (match_operand:XF 2 "register_operand" "f"))]
1054 "* return output_fp_compare (insn, operands, 0, 0);"
1055 [(set_attr "type" "multi")
1056 (set_attr "unit" "i387")
1057 (set_attr "mode" "XF")])
1059 (define_insn_and_split "*cmpfp_xf_cc"
1060 [(set (reg:CCFP FLAGS_REG)
1062 (match_operand:XF 1 "register_operand" "f")
1063 (match_operand:XF 2 "register_operand" "f")))
1064 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1066 && TARGET_SAHF && !TARGET_CMOVE"
1068 "&& reload_completed"
1071 [(compare:CCFP (match_dup 1)(match_dup 2))]
1073 (set (reg:CC FLAGS_REG)
1074 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1076 [(set_attr "type" "multi")
1077 (set_attr "unit" "i387")
1078 (set_attr "mode" "XF")])
1080 (define_insn "*cmpfp_<mode>"
1081 [(set (match_operand:HI 0 "register_operand" "=a")
1084 (match_operand:MODEF 1 "register_operand" "f")
1085 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1088 "* return output_fp_compare (insn, operands, 0, 0);"
1089 [(set_attr "type" "multi")
1090 (set_attr "unit" "i387")
1091 (set_attr "mode" "<MODE>")])
1093 (define_insn_and_split "*cmpfp_<mode>_cc"
1094 [(set (reg:CCFP FLAGS_REG)
1096 (match_operand:MODEF 1 "register_operand" "f")
1097 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1098 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1100 && TARGET_SAHF && !TARGET_CMOVE"
1102 "&& reload_completed"
1105 [(compare:CCFP (match_dup 1)(match_dup 2))]
1107 (set (reg:CC FLAGS_REG)
1108 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1110 [(set_attr "type" "multi")
1111 (set_attr "unit" "i387")
1112 (set_attr "mode" "<MODE>")])
1114 (define_insn "*cmpfp_u"
1115 [(set (match_operand:HI 0 "register_operand" "=a")
1118 (match_operand 1 "register_operand" "f")
1119 (match_operand 2 "register_operand" "f"))]
1121 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1123 "* return output_fp_compare (insn, operands, 0, 1);"
1124 [(set_attr "type" "multi")
1125 (set_attr "unit" "i387")
1127 (cond [(match_operand:SF 1 "" "")
1129 (match_operand:DF 1 "" "")
1132 (const_string "XF")))])
1134 (define_insn_and_split "*cmpfp_u_cc"
1135 [(set (reg:CCFPU FLAGS_REG)
1137 (match_operand 1 "register_operand" "f")
1138 (match_operand 2 "register_operand" "f")))
1139 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1140 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1141 && TARGET_SAHF && !TARGET_CMOVE
1142 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1144 "&& reload_completed"
1147 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1149 (set (reg:CC FLAGS_REG)
1150 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1152 [(set_attr "type" "multi")
1153 (set_attr "unit" "i387")
1155 (cond [(match_operand:SF 1 "" "")
1157 (match_operand:DF 1 "" "")
1160 (const_string "XF")))])
1162 (define_insn "*cmpfp_<mode>"
1163 [(set (match_operand:HI 0 "register_operand" "=a")
1166 (match_operand 1 "register_operand" "f")
1167 (match_operator 3 "float_operator"
1168 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1170 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1171 && TARGET_USE_<MODE>MODE_FIOP
1172 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1173 "* return output_fp_compare (insn, operands, 0, 0);"
1174 [(set_attr "type" "multi")
1175 (set_attr "unit" "i387")
1176 (set_attr "fp_int_src" "true")
1177 (set_attr "mode" "<MODE>")])
1179 (define_insn_and_split "*cmpfp_<mode>_cc"
1180 [(set (reg:CCFP FLAGS_REG)
1182 (match_operand 1 "register_operand" "f")
1183 (match_operator 3 "float_operator"
1184 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1185 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1186 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1187 && TARGET_SAHF && !TARGET_CMOVE
1188 && TARGET_USE_<MODE>MODE_FIOP
1189 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1191 "&& reload_completed"
1196 (match_op_dup 3 [(match_dup 2)]))]
1198 (set (reg:CC FLAGS_REG)
1199 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1201 [(set_attr "type" "multi")
1202 (set_attr "unit" "i387")
1203 (set_attr "fp_int_src" "true")
1204 (set_attr "mode" "<MODE>")])
1206 ;; FP compares, step 2
1207 ;; Move the fpsw to ax.
1209 (define_insn "x86_fnstsw_1"
1210 [(set (match_operand:HI 0 "register_operand" "=a")
1211 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1214 [(set_attr "length" "2")
1215 (set_attr "mode" "SI")
1216 (set_attr "unit" "i387")])
1218 ;; FP compares, step 3
1219 ;; Get ax into flags, general case.
1221 (define_insn "x86_sahf_1"
1222 [(set (reg:CC FLAGS_REG)
1223 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1227 #ifdef HAVE_AS_IX86_SAHF
1230 return ".byte\t0x9e";
1233 [(set_attr "length" "1")
1234 (set_attr "athlon_decode" "vector")
1235 (set_attr "amdfam10_decode" "direct")
1236 (set_attr "mode" "SI")])
1238 ;; Pentium Pro can do steps 1 through 3 in one go.
1239 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1240 (define_insn "*cmpfp_i_mixed"
1241 [(set (reg:CCFP FLAGS_REG)
1242 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1243 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1244 "TARGET_MIX_SSE_I387
1245 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1246 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1247 "* return output_fp_compare (insn, operands, 1, 0);"
1248 [(set_attr "type" "fcmp,ssecomi")
1250 (if_then_else (match_operand:SF 1 "" "")
1252 (const_string "DF")))
1253 (set_attr "athlon_decode" "vector")
1254 (set_attr "amdfam10_decode" "direct")])
1256 (define_insn "*cmpfp_i_sse"
1257 [(set (reg:CCFP FLAGS_REG)
1258 (compare:CCFP (match_operand 0 "register_operand" "x")
1259 (match_operand 1 "nonimmediate_operand" "xm")))]
1261 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1262 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1263 "* return output_fp_compare (insn, operands, 1, 0);"
1264 [(set_attr "type" "ssecomi")
1266 (if_then_else (match_operand:SF 1 "" "")
1268 (const_string "DF")))
1269 (set_attr "athlon_decode" "vector")
1270 (set_attr "amdfam10_decode" "direct")])
1272 (define_insn "*cmpfp_i_i387"
1273 [(set (reg:CCFP FLAGS_REG)
1274 (compare:CCFP (match_operand 0 "register_operand" "f")
1275 (match_operand 1 "register_operand" "f")))]
1276 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1278 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1279 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1280 "* return output_fp_compare (insn, operands, 1, 0);"
1281 [(set_attr "type" "fcmp")
1283 (cond [(match_operand:SF 1 "" "")
1285 (match_operand:DF 1 "" "")
1288 (const_string "XF")))
1289 (set_attr "athlon_decode" "vector")
1290 (set_attr "amdfam10_decode" "direct")])
1292 (define_insn "*cmpfp_iu_mixed"
1293 [(set (reg:CCFPU FLAGS_REG)
1294 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1295 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1296 "TARGET_MIX_SSE_I387
1297 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1298 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1299 "* return output_fp_compare (insn, operands, 1, 1);"
1300 [(set_attr "type" "fcmp,ssecomi")
1302 (if_then_else (match_operand:SF 1 "" "")
1304 (const_string "DF")))
1305 (set_attr "athlon_decode" "vector")
1306 (set_attr "amdfam10_decode" "direct")])
1308 (define_insn "*cmpfp_iu_sse"
1309 [(set (reg:CCFPU FLAGS_REG)
1310 (compare:CCFPU (match_operand 0 "register_operand" "x")
1311 (match_operand 1 "nonimmediate_operand" "xm")))]
1313 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1314 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1315 "* return output_fp_compare (insn, operands, 1, 1);"
1316 [(set_attr "type" "ssecomi")
1318 (if_then_else (match_operand:SF 1 "" "")
1320 (const_string "DF")))
1321 (set_attr "athlon_decode" "vector")
1322 (set_attr "amdfam10_decode" "direct")])
1324 (define_insn "*cmpfp_iu_387"
1325 [(set (reg:CCFPU FLAGS_REG)
1326 (compare:CCFPU (match_operand 0 "register_operand" "f")
1327 (match_operand 1 "register_operand" "f")))]
1328 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1330 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1331 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1332 "* return output_fp_compare (insn, operands, 1, 1);"
1333 [(set_attr "type" "fcmp")
1335 (cond [(match_operand:SF 1 "" "")
1337 (match_operand:DF 1 "" "")
1340 (const_string "XF")))
1341 (set_attr "athlon_decode" "vector")
1342 (set_attr "amdfam10_decode" "direct")])
1344 ;; Move instructions.
1346 ;; General case of fullword move.
1348 (define_expand "movsi"
1349 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1350 (match_operand:SI 1 "general_operand" ""))]
1352 "ix86_expand_move (SImode, operands); DONE;")
1354 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1357 ;; %%% We don't use a post-inc memory reference because x86 is not a
1358 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1359 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1360 ;; targets without our curiosities, and it is just as easy to represent
1361 ;; this differently.
1363 (define_insn "*pushsi2"
1364 [(set (match_operand:SI 0 "push_operand" "=<")
1365 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1368 [(set_attr "type" "push")
1369 (set_attr "mode" "SI")])
1371 ;; For 64BIT abi we always round up to 8 bytes.
1372 (define_insn "*pushsi2_rex64"
1373 [(set (match_operand:SI 0 "push_operand" "=X")
1374 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1377 [(set_attr "type" "push")
1378 (set_attr "mode" "SI")])
1380 (define_insn "*pushsi2_prologue"
1381 [(set (match_operand:SI 0 "push_operand" "=<")
1382 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1383 (clobber (mem:BLK (scratch)))]
1386 [(set_attr "type" "push")
1387 (set_attr "mode" "SI")])
1389 (define_insn "*popsi1_epilogue"
1390 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1391 (mem:SI (reg:SI SP_REG)))
1392 (set (reg:SI SP_REG)
1393 (plus:SI (reg:SI SP_REG) (const_int 4)))
1394 (clobber (mem:BLK (scratch)))]
1397 [(set_attr "type" "pop")
1398 (set_attr "mode" "SI")])
1400 (define_insn "popsi1"
1401 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1402 (mem:SI (reg:SI SP_REG)))
1403 (set (reg:SI SP_REG)
1404 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1407 [(set_attr "type" "pop")
1408 (set_attr "mode" "SI")])
1410 (define_insn "*movsi_xor"
1411 [(set (match_operand:SI 0 "register_operand" "=r")
1412 (match_operand:SI 1 "const0_operand" "i"))
1413 (clobber (reg:CC FLAGS_REG))]
1414 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1416 [(set_attr "type" "alu1")
1417 (set_attr "mode" "SI")
1418 (set_attr "length_immediate" "0")])
1420 (define_insn "*movsi_or"
1421 [(set (match_operand:SI 0 "register_operand" "=r")
1422 (match_operand:SI 1 "immediate_operand" "i"))
1423 (clobber (reg:CC FLAGS_REG))]
1425 && operands[1] == constm1_rtx
1426 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1428 operands[1] = constm1_rtx;
1429 return "or{l}\t{%1, %0|%0, %1}";
1431 [(set_attr "type" "alu1")
1432 (set_attr "mode" "SI")
1433 (set_attr "length_immediate" "1")])
1435 (define_insn "*movsi_1"
1436 [(set (match_operand:SI 0 "nonimmediate_operand"
1437 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1438 (match_operand:SI 1 "general_operand"
1439 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1440 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1442 switch (get_attr_type (insn))
1445 if (get_attr_mode (insn) == MODE_TI)
1446 return "pxor\t%0, %0";
1447 return "xorps\t%0, %0";
1450 switch (get_attr_mode (insn))
1453 return "movdqa\t{%1, %0|%0, %1}";
1455 return "movaps\t{%1, %0|%0, %1}";
1457 return "movd\t{%1, %0|%0, %1}";
1459 return "movss\t{%1, %0|%0, %1}";
1465 return "pxor\t%0, %0";
1468 if (get_attr_mode (insn) == MODE_DI)
1469 return "movq\t{%1, %0|%0, %1}";
1470 return "movd\t{%1, %0|%0, %1}";
1473 return "lea{l}\t{%1, %0|%0, %1}";
1476 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1477 return "mov{l}\t{%1, %0|%0, %1}";
1481 (cond [(eq_attr "alternative" "2")
1482 (const_string "mmxadd")
1483 (eq_attr "alternative" "3,4,5")
1484 (const_string "mmxmov")
1485 (eq_attr "alternative" "6")
1486 (const_string "sselog1")
1487 (eq_attr "alternative" "7,8,9,10,11")
1488 (const_string "ssemov")
1489 (match_operand:DI 1 "pic_32bit_operand" "")
1490 (const_string "lea")
1492 (const_string "imov")))
1494 (cond [(eq_attr "alternative" "2,3")
1496 (eq_attr "alternative" "6,7")
1498 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1499 (const_string "V4SF")
1500 (const_string "TI"))
1501 (and (eq_attr "alternative" "8,9,10,11")
1502 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1505 (const_string "SI")))])
1507 ;; Stores and loads of ax to arbitrary constant address.
1508 ;; We fake an second form of instruction to force reload to load address
1509 ;; into register when rax is not available
1510 (define_insn "*movabssi_1_rex64"
1511 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1512 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1513 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1515 movabs{l}\t{%1, %P0|%P0, %1}
1516 mov{l}\t{%1, %a0|%a0, %1}"
1517 [(set_attr "type" "imov")
1518 (set_attr "modrm" "0,*")
1519 (set_attr "length_address" "8,0")
1520 (set_attr "length_immediate" "0,*")
1521 (set_attr "memory" "store")
1522 (set_attr "mode" "SI")])
1524 (define_insn "*movabssi_2_rex64"
1525 [(set (match_operand:SI 0 "register_operand" "=a,r")
1526 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1527 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1529 movabs{l}\t{%P1, %0|%0, %P1}
1530 mov{l}\t{%a1, %0|%0, %a1}"
1531 [(set_attr "type" "imov")
1532 (set_attr "modrm" "0,*")
1533 (set_attr "length_address" "8,0")
1534 (set_attr "length_immediate" "0")
1535 (set_attr "memory" "load")
1536 (set_attr "mode" "SI")])
1538 (define_insn "*swapsi"
1539 [(set (match_operand:SI 0 "register_operand" "+r")
1540 (match_operand:SI 1 "register_operand" "+r"))
1545 [(set_attr "type" "imov")
1546 (set_attr "mode" "SI")
1547 (set_attr "pent_pair" "np")
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "double")])
1551 (define_expand "movhi"
1552 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1553 (match_operand:HI 1 "general_operand" ""))]
1555 "ix86_expand_move (HImode, operands); DONE;")
1557 (define_insn "*pushhi2"
1558 [(set (match_operand:HI 0 "push_operand" "=X")
1559 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1562 [(set_attr "type" "push")
1563 (set_attr "mode" "SI")])
1565 ;; For 64BIT abi we always round up to 8 bytes.
1566 (define_insn "*pushhi2_rex64"
1567 [(set (match_operand:HI 0 "push_operand" "=X")
1568 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1571 [(set_attr "type" "push")
1572 (set_attr "mode" "DI")])
1574 (define_insn "*movhi_1"
1575 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1576 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1577 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1579 switch (get_attr_type (insn))
1582 /* movzwl is faster than movw on p2 due to partial word stalls,
1583 though not as fast as an aligned movl. */
1584 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1586 if (get_attr_mode (insn) == MODE_SI)
1587 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1589 return "mov{w}\t{%1, %0|%0, %1}";
1593 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1594 (const_string "imov")
1595 (and (eq_attr "alternative" "0")
1596 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1598 (eq (symbol_ref "TARGET_HIMODE_MATH")
1600 (const_string "imov")
1601 (and (eq_attr "alternative" "1,2")
1602 (match_operand:HI 1 "aligned_operand" ""))
1603 (const_string "imov")
1604 (and (ne (symbol_ref "TARGET_MOVX")
1606 (eq_attr "alternative" "0,2"))
1607 (const_string "imovx")
1609 (const_string "imov")))
1611 (cond [(eq_attr "type" "imovx")
1613 (and (eq_attr "alternative" "1,2")
1614 (match_operand:HI 1 "aligned_operand" ""))
1616 (and (eq_attr "alternative" "0")
1617 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1619 (eq (symbol_ref "TARGET_HIMODE_MATH")
1623 (const_string "HI")))])
1625 ;; Stores and loads of ax to arbitrary constant address.
1626 ;; We fake an second form of instruction to force reload to load address
1627 ;; into register when rax is not available
1628 (define_insn "*movabshi_1_rex64"
1629 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1630 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1631 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1633 movabs{w}\t{%1, %P0|%P0, %1}
1634 mov{w}\t{%1, %a0|%a0, %1}"
1635 [(set_attr "type" "imov")
1636 (set_attr "modrm" "0,*")
1637 (set_attr "length_address" "8,0")
1638 (set_attr "length_immediate" "0,*")
1639 (set_attr "memory" "store")
1640 (set_attr "mode" "HI")])
1642 (define_insn "*movabshi_2_rex64"
1643 [(set (match_operand:HI 0 "register_operand" "=a,r")
1644 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1645 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1647 movabs{w}\t{%P1, %0|%0, %P1}
1648 mov{w}\t{%a1, %0|%0, %a1}"
1649 [(set_attr "type" "imov")
1650 (set_attr "modrm" "0,*")
1651 (set_attr "length_address" "8,0")
1652 (set_attr "length_immediate" "0")
1653 (set_attr "memory" "load")
1654 (set_attr "mode" "HI")])
1656 (define_insn "*swaphi_1"
1657 [(set (match_operand:HI 0 "register_operand" "+r")
1658 (match_operand:HI 1 "register_operand" "+r"))
1661 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1663 [(set_attr "type" "imov")
1664 (set_attr "mode" "SI")
1665 (set_attr "pent_pair" "np")
1666 (set_attr "athlon_decode" "vector")
1667 (set_attr "amdfam10_decode" "double")])
1669 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1670 (define_insn "*swaphi_2"
1671 [(set (match_operand:HI 0 "register_operand" "+r")
1672 (match_operand:HI 1 "register_operand" "+r"))
1675 "TARGET_PARTIAL_REG_STALL"
1677 [(set_attr "type" "imov")
1678 (set_attr "mode" "HI")
1679 (set_attr "pent_pair" "np")
1680 (set_attr "athlon_decode" "vector")])
1682 (define_expand "movstricthi"
1683 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1684 (match_operand:HI 1 "general_operand" ""))]
1685 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1687 /* Don't generate memory->memory moves, go through a register */
1688 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1689 operands[1] = force_reg (HImode, operands[1]);
1692 (define_insn "*movstricthi_1"
1693 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1694 (match_operand:HI 1 "general_operand" "rn,m"))]
1695 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1696 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1697 "mov{w}\t{%1, %0|%0, %1}"
1698 [(set_attr "type" "imov")
1699 (set_attr "mode" "HI")])
1701 (define_insn "*movstricthi_xor"
1702 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1703 (match_operand:HI 1 "const0_operand" "i"))
1704 (clobber (reg:CC FLAGS_REG))]
1706 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1708 [(set_attr "type" "alu1")
1709 (set_attr "mode" "HI")
1710 (set_attr "length_immediate" "0")])
1712 (define_expand "movqi"
1713 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1714 (match_operand:QI 1 "general_operand" ""))]
1716 "ix86_expand_move (QImode, operands); DONE;")
1718 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1719 ;; "push a byte". But actually we use pushl, which has the effect
1720 ;; of rounding the amount pushed up to a word.
1722 (define_insn "*pushqi2"
1723 [(set (match_operand:QI 0 "push_operand" "=X")
1724 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1727 [(set_attr "type" "push")
1728 (set_attr "mode" "SI")])
1730 ;; For 64BIT abi we always round up to 8 bytes.
1731 (define_insn "*pushqi2_rex64"
1732 [(set (match_operand:QI 0 "push_operand" "=X")
1733 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1736 [(set_attr "type" "push")
1737 (set_attr "mode" "DI")])
1739 ;; Situation is quite tricky about when to choose full sized (SImode) move
1740 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1741 ;; partial register dependency machines (such as AMD Athlon), where QImode
1742 ;; moves issue extra dependency and for partial register stalls machines
1743 ;; that don't use QImode patterns (and QImode move cause stall on the next
1746 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1747 ;; register stall machines with, where we use QImode instructions, since
1748 ;; partial register stall can be caused there. Then we use movzx.
1749 (define_insn "*movqi_1"
1750 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1751 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1752 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1754 switch (get_attr_type (insn))
1757 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1758 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1760 if (get_attr_mode (insn) == MODE_SI)
1761 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1763 return "mov{b}\t{%1, %0|%0, %1}";
1767 (cond [(and (eq_attr "alternative" "5")
1768 (not (match_operand:QI 1 "aligned_operand" "")))
1769 (const_string "imovx")
1770 (ne (symbol_ref "optimize_size") (const_int 0))
1771 (const_string "imov")
1772 (and (eq_attr "alternative" "3")
1773 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1775 (eq (symbol_ref "TARGET_QIMODE_MATH")
1777 (const_string "imov")
1778 (eq_attr "alternative" "3,5")
1779 (const_string "imovx")
1780 (and (ne (symbol_ref "TARGET_MOVX")
1782 (eq_attr "alternative" "2"))
1783 (const_string "imovx")
1785 (const_string "imov")))
1787 (cond [(eq_attr "alternative" "3,4,5")
1789 (eq_attr "alternative" "6")
1791 (eq_attr "type" "imovx")
1793 (and (eq_attr "type" "imov")
1794 (and (eq_attr "alternative" "0,1")
1795 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1797 (and (eq (symbol_ref "optimize_size")
1799 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1802 ;; Avoid partial register stalls when not using QImode arithmetic
1803 (and (eq_attr "type" "imov")
1804 (and (eq_attr "alternative" "0,1")
1805 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1807 (eq (symbol_ref "TARGET_QIMODE_MATH")
1811 (const_string "QI")))])
1813 (define_insn "*swapqi_1"
1814 [(set (match_operand:QI 0 "register_operand" "+r")
1815 (match_operand:QI 1 "register_operand" "+r"))
1818 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1820 [(set_attr "type" "imov")
1821 (set_attr "mode" "SI")
1822 (set_attr "pent_pair" "np")
1823 (set_attr "athlon_decode" "vector")
1824 (set_attr "amdfam10_decode" "vector")])
1826 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1827 (define_insn "*swapqi_2"
1828 [(set (match_operand:QI 0 "register_operand" "+q")
1829 (match_operand:QI 1 "register_operand" "+q"))
1832 "TARGET_PARTIAL_REG_STALL"
1834 [(set_attr "type" "imov")
1835 (set_attr "mode" "QI")
1836 (set_attr "pent_pair" "np")
1837 (set_attr "athlon_decode" "vector")])
1839 (define_expand "movstrictqi"
1840 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1841 (match_operand:QI 1 "general_operand" ""))]
1842 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1844 /* Don't generate memory->memory moves, go through a register. */
1845 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1846 operands[1] = force_reg (QImode, operands[1]);
1849 (define_insn "*movstrictqi_1"
1850 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1851 (match_operand:QI 1 "general_operand" "*qn,m"))]
1852 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1853 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1854 "mov{b}\t{%1, %0|%0, %1}"
1855 [(set_attr "type" "imov")
1856 (set_attr "mode" "QI")])
1858 (define_insn "*movstrictqi_xor"
1859 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1860 (match_operand:QI 1 "const0_operand" "i"))
1861 (clobber (reg:CC FLAGS_REG))]
1862 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1864 [(set_attr "type" "alu1")
1865 (set_attr "mode" "QI")
1866 (set_attr "length_immediate" "0")])
1868 (define_insn "*movsi_extv_1"
1869 [(set (match_operand:SI 0 "register_operand" "=R")
1870 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1874 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1875 [(set_attr "type" "imovx")
1876 (set_attr "mode" "SI")])
1878 (define_insn "*movhi_extv_1"
1879 [(set (match_operand:HI 0 "register_operand" "=R")
1880 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1884 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1885 [(set_attr "type" "imovx")
1886 (set_attr "mode" "SI")])
1888 (define_insn "*movqi_extv_1"
1889 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1890 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1895 switch (get_attr_type (insn))
1898 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1900 return "mov{b}\t{%h1, %0|%0, %h1}";
1904 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1905 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1906 (ne (symbol_ref "TARGET_MOVX")
1908 (const_string "imovx")
1909 (const_string "imov")))
1911 (if_then_else (eq_attr "type" "imovx")
1913 (const_string "QI")))])
1915 (define_insn "*movqi_extv_1_rex64"
1916 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1917 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1922 switch (get_attr_type (insn))
1925 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1927 return "mov{b}\t{%h1, %0|%0, %h1}";
1931 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1932 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1933 (ne (symbol_ref "TARGET_MOVX")
1935 (const_string "imovx")
1936 (const_string "imov")))
1938 (if_then_else (eq_attr "type" "imovx")
1940 (const_string "QI")))])
1942 ;; Stores and loads of ax to arbitrary constant address.
1943 ;; We fake an second form of instruction to force reload to load address
1944 ;; into register when rax is not available
1945 (define_insn "*movabsqi_1_rex64"
1946 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1947 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1948 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1950 movabs{b}\t{%1, %P0|%P0, %1}
1951 mov{b}\t{%1, %a0|%a0, %1}"
1952 [(set_attr "type" "imov")
1953 (set_attr "modrm" "0,*")
1954 (set_attr "length_address" "8,0")
1955 (set_attr "length_immediate" "0,*")
1956 (set_attr "memory" "store")
1957 (set_attr "mode" "QI")])
1959 (define_insn "*movabsqi_2_rex64"
1960 [(set (match_operand:QI 0 "register_operand" "=a,r")
1961 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1962 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1964 movabs{b}\t{%P1, %0|%0, %P1}
1965 mov{b}\t{%a1, %0|%0, %a1}"
1966 [(set_attr "type" "imov")
1967 (set_attr "modrm" "0,*")
1968 (set_attr "length_address" "8,0")
1969 (set_attr "length_immediate" "0")
1970 (set_attr "memory" "load")
1971 (set_attr "mode" "QI")])
1973 (define_insn "*movdi_extzv_1"
1974 [(set (match_operand:DI 0 "register_operand" "=R")
1975 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1979 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1980 [(set_attr "type" "imovx")
1981 (set_attr "mode" "DI")])
1983 (define_insn "*movsi_extzv_1"
1984 [(set (match_operand:SI 0 "register_operand" "=R")
1985 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1989 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1990 [(set_attr "type" "imovx")
1991 (set_attr "mode" "SI")])
1993 (define_insn "*movqi_extzv_2"
1994 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1995 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2000 switch (get_attr_type (insn))
2003 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2005 return "mov{b}\t{%h1, %0|%0, %h1}";
2009 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2010 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2011 (ne (symbol_ref "TARGET_MOVX")
2013 (const_string "imovx")
2014 (const_string "imov")))
2016 (if_then_else (eq_attr "type" "imovx")
2018 (const_string "QI")))])
2020 (define_insn "*movqi_extzv_2_rex64"
2021 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2022 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2027 switch (get_attr_type (insn))
2030 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2032 return "mov{b}\t{%h1, %0|%0, %h1}";
2036 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2037 (ne (symbol_ref "TARGET_MOVX")
2039 (const_string "imovx")
2040 (const_string "imov")))
2042 (if_then_else (eq_attr "type" "imovx")
2044 (const_string "QI")))])
2046 (define_insn "movsi_insv_1"
2047 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2050 (match_operand:SI 1 "general_operand" "Qmn"))]
2052 "mov{b}\t{%b1, %h0|%h0, %b1}"
2053 [(set_attr "type" "imov")
2054 (set_attr "mode" "QI")])
2056 (define_insn "*movsi_insv_1_rex64"
2057 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2060 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2062 "mov{b}\t{%b1, %h0|%h0, %b1}"
2063 [(set_attr "type" "imov")
2064 (set_attr "mode" "QI")])
2066 (define_insn "movdi_insv_1_rex64"
2067 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2070 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2072 "mov{b}\t{%b1, %h0|%h0, %b1}"
2073 [(set_attr "type" "imov")
2074 (set_attr "mode" "QI")])
2076 (define_insn "*movqi_insv_2"
2077 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2080 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2083 "mov{b}\t{%h1, %h0|%h0, %h1}"
2084 [(set_attr "type" "imov")
2085 (set_attr "mode" "QI")])
2087 (define_expand "movdi"
2088 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2089 (match_operand:DI 1 "general_operand" ""))]
2091 "ix86_expand_move (DImode, operands); DONE;")
2093 (define_insn "*pushdi"
2094 [(set (match_operand:DI 0 "push_operand" "=<")
2095 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2099 (define_insn "*pushdi2_rex64"
2100 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2101 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2106 [(set_attr "type" "push,multi")
2107 (set_attr "mode" "DI")])
2109 ;; Convert impossible pushes of immediate to existing instructions.
2110 ;; First try to get scratch register and go through it. In case this
2111 ;; fails, push sign extended lower part first and then overwrite
2112 ;; upper part by 32bit move.
2114 [(match_scratch:DI 2 "r")
2115 (set (match_operand:DI 0 "push_operand" "")
2116 (match_operand:DI 1 "immediate_operand" ""))]
2117 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode)"
2119 [(set (match_dup 2) (match_dup 1))
2120 (set (match_dup 0) (match_dup 2))]
2123 ;; We need to define this as both peepholer and splitter for case
2124 ;; peephole2 pass is not run.
2125 ;; "&& 1" is needed to keep it from matching the previous pattern.
2127 [(set (match_operand:DI 0 "push_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2131 [(set (match_dup 0) (match_dup 1))
2132 (set (match_dup 2) (match_dup 3))]
2133 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2134 operands[1] = gen_lowpart (DImode, operands[2]);
2135 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2140 [(set (match_operand:DI 0 "push_operand" "")
2141 (match_operand:DI 1 "immediate_operand" ""))]
2142 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2143 ? epilogue_completed : reload_completed)
2144 && !symbolic_operand (operands[1], DImode)
2145 && !x86_64_immediate_operand (operands[1], DImode)"
2146 [(set (match_dup 0) (match_dup 1))
2147 (set (match_dup 2) (match_dup 3))]
2148 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2149 operands[1] = gen_lowpart (DImode, operands[2]);
2150 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2154 (define_insn "*pushdi2_prologue_rex64"
2155 [(set (match_operand:DI 0 "push_operand" "=<")
2156 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2157 (clobber (mem:BLK (scratch)))]
2160 [(set_attr "type" "push")
2161 (set_attr "mode" "DI")])
2163 (define_insn "*popdi1_epilogue_rex64"
2164 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2165 (mem:DI (reg:DI SP_REG)))
2166 (set (reg:DI SP_REG)
2167 (plus:DI (reg:DI SP_REG) (const_int 8)))
2168 (clobber (mem:BLK (scratch)))]
2171 [(set_attr "type" "pop")
2172 (set_attr "mode" "DI")])
2174 (define_insn "popdi1"
2175 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2176 (mem:DI (reg:DI SP_REG)))
2177 (set (reg:DI SP_REG)
2178 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2181 [(set_attr "type" "pop")
2182 (set_attr "mode" "DI")])
2184 (define_insn "*movdi_xor_rex64"
2185 [(set (match_operand:DI 0 "register_operand" "=r")
2186 (match_operand:DI 1 "const0_operand" "i"))
2187 (clobber (reg:CC FLAGS_REG))]
2188 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2189 && reload_completed"
2191 [(set_attr "type" "alu1")
2192 (set_attr "mode" "SI")
2193 (set_attr "length_immediate" "0")])
2195 (define_insn "*movdi_or_rex64"
2196 [(set (match_operand:DI 0 "register_operand" "=r")
2197 (match_operand:DI 1 "const_int_operand" "i"))
2198 (clobber (reg:CC FLAGS_REG))]
2199 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2201 && operands[1] == constm1_rtx"
2203 operands[1] = constm1_rtx;
2204 return "or{q}\t{%1, %0|%0, %1}";
2206 [(set_attr "type" "alu1")
2207 (set_attr "mode" "DI")
2208 (set_attr "length_immediate" "1")])
2210 (define_insn "*movdi_2"
2211 [(set (match_operand:DI 0 "nonimmediate_operand"
2212 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2213 (match_operand:DI 1 "general_operand"
2214 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2215 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2220 movq\t{%1, %0|%0, %1}
2221 movq\t{%1, %0|%0, %1}
2223 movq\t{%1, %0|%0, %1}
2224 movdqa\t{%1, %0|%0, %1}
2225 movq\t{%1, %0|%0, %1}
2227 movlps\t{%1, %0|%0, %1}
2228 movaps\t{%1, %0|%0, %1}
2229 movlps\t{%1, %0|%0, %1}"
2230 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2231 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2234 [(set (match_operand:DI 0 "push_operand" "")
2235 (match_operand:DI 1 "general_operand" ""))]
2236 "!TARGET_64BIT && reload_completed
2237 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2239 "ix86_split_long_move (operands); DONE;")
2241 ;; %%% This multiword shite has got to go.
2243 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2244 (match_operand:DI 1 "general_operand" ""))]
2245 "!TARGET_64BIT && reload_completed
2246 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2247 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2249 "ix86_split_long_move (operands); DONE;")
2251 (define_insn "*movdi_1_rex64"
2252 [(set (match_operand:DI 0 "nonimmediate_operand"
2253 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2254 (match_operand:DI 1 "general_operand"
2255 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2256 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2258 switch (get_attr_type (insn))
2261 if (SSE_REG_P (operands[0]))
2262 return "movq2dq\t{%1, %0|%0, %1}";
2264 return "movdq2q\t{%1, %0|%0, %1}";
2267 if (get_attr_mode (insn) == MODE_TI)
2268 return "movdqa\t{%1, %0|%0, %1}";
2272 /* Moves from and into integer register is done using movd
2273 opcode with REX prefix. */
2274 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2275 return "movd\t{%1, %0|%0, %1}";
2276 return "movq\t{%1, %0|%0, %1}";
2280 return "pxor\t%0, %0";
2286 return "lea{q}\t{%a1, %0|%0, %a1}";
2289 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2290 if (get_attr_mode (insn) == MODE_SI)
2291 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2292 else if (which_alternative == 2)
2293 return "movabs{q}\t{%1, %0|%0, %1}";
2295 return "mov{q}\t{%1, %0|%0, %1}";
2299 (cond [(eq_attr "alternative" "5")
2300 (const_string "mmxadd")
2301 (eq_attr "alternative" "6,7,8,9,10")
2302 (const_string "mmxmov")
2303 (eq_attr "alternative" "11")
2304 (const_string "sselog1")
2305 (eq_attr "alternative" "12,13,14,15,16")
2306 (const_string "ssemov")
2307 (eq_attr "alternative" "17,18")
2308 (const_string "ssecvt")
2309 (eq_attr "alternative" "4")
2310 (const_string "multi")
2311 (match_operand:DI 1 "pic_32bit_operand" "")
2312 (const_string "lea")
2314 (const_string "imov")))
2315 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2316 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2317 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2319 ;; Stores and loads of ax to arbitrary constant address.
2320 ;; We fake an second form of instruction to force reload to load address
2321 ;; into register when rax is not available
2322 (define_insn "*movabsdi_1_rex64"
2323 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2324 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2325 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2327 movabs{q}\t{%1, %P0|%P0, %1}
2328 mov{q}\t{%1, %a0|%a0, %1}"
2329 [(set_attr "type" "imov")
2330 (set_attr "modrm" "0,*")
2331 (set_attr "length_address" "8,0")
2332 (set_attr "length_immediate" "0,*")
2333 (set_attr "memory" "store")
2334 (set_attr "mode" "DI")])
2336 (define_insn "*movabsdi_2_rex64"
2337 [(set (match_operand:DI 0 "register_operand" "=a,r")
2338 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2339 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2341 movabs{q}\t{%P1, %0|%0, %P1}
2342 mov{q}\t{%a1, %0|%0, %a1}"
2343 [(set_attr "type" "imov")
2344 (set_attr "modrm" "0,*")
2345 (set_attr "length_address" "8,0")
2346 (set_attr "length_immediate" "0")
2347 (set_attr "memory" "load")
2348 (set_attr "mode" "DI")])
2350 ;; Convert impossible stores of immediate to existing instructions.
2351 ;; First try to get scratch register and go through it. In case this
2352 ;; fails, move by 32bit parts.
2354 [(match_scratch:DI 2 "r")
2355 (set (match_operand:DI 0 "memory_operand" "")
2356 (match_operand:DI 1 "immediate_operand" ""))]
2357 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2358 && !x86_64_immediate_operand (operands[1], DImode)"
2359 [(set (match_dup 2) (match_dup 1))
2360 (set (match_dup 0) (match_dup 2))]
2363 ;; We need to define this as both peepholer and splitter for case
2364 ;; peephole2 pass is not run.
2365 ;; "&& 1" is needed to keep it from matching the previous pattern.
2367 [(set (match_operand:DI 0 "memory_operand" "")
2368 (match_operand:DI 1 "immediate_operand" ""))]
2369 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2370 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2371 [(set (match_dup 2) (match_dup 3))
2372 (set (match_dup 4) (match_dup 5))]
2373 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2376 [(set (match_operand:DI 0 "memory_operand" "")
2377 (match_operand:DI 1 "immediate_operand" ""))]
2378 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2379 ? epilogue_completed : reload_completed)
2380 && !symbolic_operand (operands[1], DImode)
2381 && !x86_64_immediate_operand (operands[1], DImode)"
2382 [(set (match_dup 2) (match_dup 3))
2383 (set (match_dup 4) (match_dup 5))]
2384 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2386 (define_insn "*swapdi_rex64"
2387 [(set (match_operand:DI 0 "register_operand" "+r")
2388 (match_operand:DI 1 "register_operand" "+r"))
2393 [(set_attr "type" "imov")
2394 (set_attr "mode" "DI")
2395 (set_attr "pent_pair" "np")
2396 (set_attr "athlon_decode" "vector")
2397 (set_attr "amdfam10_decode" "double")])
2399 (define_expand "movti"
2400 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2401 (match_operand:TI 1 "nonimmediate_operand" ""))]
2402 "TARGET_SSE || TARGET_64BIT"
2405 ix86_expand_move (TImode, operands);
2406 else if (push_operand (operands[0], TImode))
2407 ix86_expand_push (TImode, operands[1]);
2409 ix86_expand_vector_move (TImode, operands);
2413 (define_insn "*movti_internal"
2414 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2415 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2416 "TARGET_SSE && !TARGET_64BIT
2417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2419 switch (which_alternative)
2422 if (get_attr_mode (insn) == MODE_V4SF)
2423 return "xorps\t%0, %0";
2425 return "pxor\t%0, %0";
2428 /* TDmode values are passed as TImode on the stack. Moving them
2429 to stack may result in unaligned memory access. */
2430 if (misaligned_operand (operands[0], TImode)
2431 || misaligned_operand (operands[1], TImode))
2433 if (get_attr_mode (insn) == MODE_V4SF)
2434 return "movups\t{%1, %0|%0, %1}";
2436 return "movdqu\t{%1, %0|%0, %1}";
2440 if (get_attr_mode (insn) == MODE_V4SF)
2441 return "movaps\t{%1, %0|%0, %1}";
2443 return "movdqa\t{%1, %0|%0, %1}";
2449 [(set_attr "type" "sselog1,ssemov,ssemov")
2451 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2452 (ne (symbol_ref "optimize_size") (const_int 0)))
2453 (const_string "V4SF")
2454 (and (eq_attr "alternative" "2")
2455 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2457 (const_string "V4SF")]
2458 (const_string "TI")))])
2460 (define_insn "*movti_rex64"
2461 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2462 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2466 switch (which_alternative)
2472 if (get_attr_mode (insn) == MODE_V4SF)
2473 return "xorps\t%0, %0";
2475 return "pxor\t%0, %0";
2478 /* TDmode values are passed as TImode on the stack. Moving them
2479 to stack may result in unaligned memory access. */
2480 if (misaligned_operand (operands[0], TImode)
2481 || misaligned_operand (operands[1], TImode))
2483 if (get_attr_mode (insn) == MODE_V4SF)
2484 return "movups\t{%1, %0|%0, %1}";
2486 return "movdqu\t{%1, %0|%0, %1}";
2490 if (get_attr_mode (insn) == MODE_V4SF)
2491 return "movaps\t{%1, %0|%0, %1}";
2493 return "movdqa\t{%1, %0|%0, %1}";
2499 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2501 (cond [(eq_attr "alternative" "2,3")
2503 (ne (symbol_ref "optimize_size")
2505 (const_string "V4SF")
2506 (const_string "TI"))
2507 (eq_attr "alternative" "4")
2509 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2511 (ne (symbol_ref "optimize_size")
2513 (const_string "V4SF")
2514 (const_string "TI"))]
2515 (const_string "DI")))])
2518 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2519 (match_operand:TI 1 "general_operand" ""))]
2520 "reload_completed && !SSE_REG_P (operands[0])
2521 && !SSE_REG_P (operands[1])"
2523 "ix86_split_long_move (operands); DONE;")
2525 ;; This expands to what emit_move_complex would generate if we didn't
2526 ;; have a movti pattern. Having this avoids problems with reload on
2527 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2528 ;; to have around all the time.
2529 (define_expand "movcdi"
2530 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2531 (match_operand:CDI 1 "general_operand" ""))]
2534 if (push_operand (operands[0], CDImode))
2535 emit_move_complex_push (CDImode, operands[0], operands[1]);
2537 emit_move_complex_parts (operands[0], operands[1]);
2541 (define_expand "movsf"
2542 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2543 (match_operand:SF 1 "general_operand" ""))]
2545 "ix86_expand_move (SFmode, operands); DONE;")
2547 (define_insn "*pushsf"
2548 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2549 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2552 /* Anything else should be already split before reg-stack. */
2553 gcc_assert (which_alternative == 1);
2554 return "push{l}\t%1";
2556 [(set_attr "type" "multi,push,multi")
2557 (set_attr "unit" "i387,*,*")
2558 (set_attr "mode" "SF,SI,SF")])
2560 (define_insn "*pushsf_rex64"
2561 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2562 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2565 /* Anything else should be already split before reg-stack. */
2566 gcc_assert (which_alternative == 1);
2567 return "push{q}\t%q1";
2569 [(set_attr "type" "multi,push,multi")
2570 (set_attr "unit" "i387,*,*")
2571 (set_attr "mode" "SF,DI,SF")])
2574 [(set (match_operand:SF 0 "push_operand" "")
2575 (match_operand:SF 1 "memory_operand" ""))]
2577 && MEM_P (operands[1])
2578 && (operands[2] = find_constant_src (insn))"
2583 ;; %%% Kill this when call knows how to work this out.
2585 [(set (match_operand:SF 0 "push_operand" "")
2586 (match_operand:SF 1 "any_fp_register_operand" ""))]
2588 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2589 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2592 [(set (match_operand:SF 0 "push_operand" "")
2593 (match_operand:SF 1 "any_fp_register_operand" ""))]
2595 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2596 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2598 (define_insn "*movsf_1"
2599 [(set (match_operand:SF 0 "nonimmediate_operand"
2600 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2601 (match_operand:SF 1 "general_operand"
2602 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2603 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2604 && (reload_in_progress || reload_completed
2605 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2606 || (!TARGET_SSE_MATH && optimize_size
2607 && standard_80387_constant_p (operands[1]))
2608 || GET_CODE (operands[1]) != CONST_DOUBLE
2609 || memory_operand (operands[0], SFmode))"
2611 switch (which_alternative)
2615 return output_387_reg_move (insn, operands);
2618 return standard_80387_constant_opcode (operands[1]);
2622 return "mov{l}\t{%1, %0|%0, %1}";
2624 if (get_attr_mode (insn) == MODE_TI)
2625 return "pxor\t%0, %0";
2627 return "xorps\t%0, %0";
2629 if (get_attr_mode (insn) == MODE_V4SF)
2630 return "movaps\t{%1, %0|%0, %1}";
2632 return "movss\t{%1, %0|%0, %1}";
2634 return "movss\t{%1, %0|%0, %1}";
2637 case 12: case 13: case 14: case 15:
2638 return "movd\t{%1, %0|%0, %1}";
2641 return "movq\t{%1, %0|%0, %1}";
2647 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2649 (cond [(eq_attr "alternative" "3,4,9,10")
2651 (eq_attr "alternative" "5")
2653 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2655 (ne (symbol_ref "TARGET_SSE2")
2657 (eq (symbol_ref "optimize_size")
2660 (const_string "V4SF"))
2661 /* For architectures resolving dependencies on
2662 whole SSE registers use APS move to break dependency
2663 chains, otherwise use short move to avoid extra work.
2665 Do the same for architectures resolving dependencies on
2666 the parts. While in DF mode it is better to always handle
2667 just register parts, the SF mode is different due to lack
2668 of instructions to load just part of the register. It is
2669 better to maintain the whole registers in single format
2670 to avoid problems on using packed logical operations. */
2671 (eq_attr "alternative" "6")
2673 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2675 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677 (const_string "V4SF")
2678 (const_string "SF"))
2679 (eq_attr "alternative" "11")
2680 (const_string "DI")]
2681 (const_string "SF")))])
2683 (define_insn "*swapsf"
2684 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2685 (match_operand:SF 1 "fp_register_operand" "+f"))
2688 "reload_completed || TARGET_80387"
2690 if (STACK_TOP_P (operands[0]))
2695 [(set_attr "type" "fxch")
2696 (set_attr "mode" "SF")])
2698 (define_expand "movdf"
2699 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2700 (match_operand:DF 1 "general_operand" ""))]
2702 "ix86_expand_move (DFmode, operands); DONE;")
2704 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2705 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2706 ;; On the average, pushdf using integers can be still shorter. Allow this
2707 ;; pattern for optimize_size too.
2709 (define_insn "*pushdf_nointeger"
2710 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2711 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2712 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2714 /* This insn should be already split before reg-stack. */
2717 [(set_attr "type" "multi")
2718 (set_attr "unit" "i387,*,*,*")
2719 (set_attr "mode" "DF,SI,SI,DF")])
2721 (define_insn "*pushdf_integer"
2722 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2723 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2724 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2726 /* This insn should be already split before reg-stack. */
2729 [(set_attr "type" "multi")
2730 (set_attr "unit" "i387,*,*")
2731 (set_attr "mode" "DF,SI,DF")])
2733 ;; %%% Kill this when call knows how to work this out.
2735 [(set (match_operand:DF 0 "push_operand" "")
2736 (match_operand:DF 1 "any_fp_register_operand" ""))]
2737 "!TARGET_64BIT && reload_completed"
2738 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2739 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2743 [(set (match_operand:DF 0 "push_operand" "")
2744 (match_operand:DF 1 "any_fp_register_operand" ""))]
2745 "TARGET_64BIT && reload_completed"
2746 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2747 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2751 [(set (match_operand:DF 0 "push_operand" "")
2752 (match_operand:DF 1 "general_operand" ""))]
2755 "ix86_split_long_move (operands); DONE;")
2757 ;; Moving is usually shorter when only FP registers are used. This separate
2758 ;; movdf pattern avoids the use of integer registers for FP operations
2759 ;; when optimizing for size.
2761 (define_insn "*movdf_nointeger"
2762 [(set (match_operand:DF 0 "nonimmediate_operand"
2763 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2764 (match_operand:DF 1 "general_operand"
2765 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2766 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2767 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2768 && (reload_in_progress || reload_completed
2769 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2770 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2771 && !memory_operand (operands[0], DFmode)
2772 && standard_80387_constant_p (operands[1]))
2773 || GET_CODE (operands[1]) != CONST_DOUBLE
2775 || !TARGET_MEMORY_MISMATCH_STALL
2776 || reload_in_progress || reload_completed)
2777 && memory_operand (operands[0], DFmode)))"
2779 switch (which_alternative)
2783 return output_387_reg_move (insn, operands);
2786 return standard_80387_constant_opcode (operands[1]);
2792 switch (get_attr_mode (insn))
2795 return "xorps\t%0, %0";
2797 return "xorpd\t%0, %0";
2799 return "pxor\t%0, %0";
2806 switch (get_attr_mode (insn))
2809 return "movaps\t{%1, %0|%0, %1}";
2811 return "movapd\t{%1, %0|%0, %1}";
2813 return "movdqa\t{%1, %0|%0, %1}";
2815 return "movq\t{%1, %0|%0, %1}";
2817 return "movsd\t{%1, %0|%0, %1}";
2819 return "movlpd\t{%1, %0|%0, %1}";
2821 return "movlps\t{%1, %0|%0, %1}";
2830 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2832 (cond [(eq_attr "alternative" "0,1,2")
2834 (eq_attr "alternative" "3,4")
2837 /* For SSE1, we have many fewer alternatives. */
2838 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2839 (cond [(eq_attr "alternative" "5,6")
2840 (const_string "V4SF")
2842 (const_string "V2SF"))
2844 /* xorps is one byte shorter. */
2845 (eq_attr "alternative" "5")
2846 (cond [(ne (symbol_ref "optimize_size")
2848 (const_string "V4SF")
2849 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2853 (const_string "V2DF"))
2855 /* For architectures resolving dependencies on
2856 whole SSE registers use APD move to break dependency
2857 chains, otherwise use short move to avoid extra work.
2859 movaps encodes one byte shorter. */
2860 (eq_attr "alternative" "6")
2862 [(ne (symbol_ref "optimize_size")
2864 (const_string "V4SF")
2865 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2867 (const_string "V2DF")
2869 (const_string "DF"))
2870 /* For architectures resolving dependencies on register
2871 parts we may avoid extra work to zero out upper part
2873 (eq_attr "alternative" "7")
2875 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2877 (const_string "V1DF")
2878 (const_string "DF"))
2880 (const_string "DF")))])
2882 (define_insn "*movdf_integer_rex64"
2883 [(set (match_operand:DF 0 "nonimmediate_operand"
2884 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2885 (match_operand:DF 1 "general_operand"
2886 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2887 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2888 && (reload_in_progress || reload_completed
2889 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2890 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2891 && standard_80387_constant_p (operands[1]))
2892 || GET_CODE (operands[1]) != CONST_DOUBLE
2893 || memory_operand (operands[0], DFmode))"
2895 switch (which_alternative)
2899 return output_387_reg_move (insn, operands);
2902 return standard_80387_constant_opcode (operands[1]);
2909 switch (get_attr_mode (insn))
2912 return "xorps\t%0, %0";
2914 return "xorpd\t%0, %0";
2916 return "pxor\t%0, %0";
2923 switch (get_attr_mode (insn))
2926 return "movaps\t{%1, %0|%0, %1}";
2928 return "movapd\t{%1, %0|%0, %1}";
2930 return "movdqa\t{%1, %0|%0, %1}";
2932 return "movq\t{%1, %0|%0, %1}";
2934 return "movsd\t{%1, %0|%0, %1}";
2936 return "movlpd\t{%1, %0|%0, %1}";
2938 return "movlps\t{%1, %0|%0, %1}";
2945 return "movd\t{%1, %0|%0, %1}";
2951 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2953 (cond [(eq_attr "alternative" "0,1,2")
2955 (eq_attr "alternative" "3,4,9,10")
2958 /* For SSE1, we have many fewer alternatives. */
2959 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2960 (cond [(eq_attr "alternative" "5,6")
2961 (const_string "V4SF")
2963 (const_string "V2SF"))
2965 /* xorps is one byte shorter. */
2966 (eq_attr "alternative" "5")
2967 (cond [(ne (symbol_ref "optimize_size")
2969 (const_string "V4SF")
2970 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2974 (const_string "V2DF"))
2976 /* For architectures resolving dependencies on
2977 whole SSE registers use APD move to break dependency
2978 chains, otherwise use short move to avoid extra work.
2980 movaps encodes one byte shorter. */
2981 (eq_attr "alternative" "6")
2983 [(ne (symbol_ref "optimize_size")
2985 (const_string "V4SF")
2986 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2988 (const_string "V2DF")
2990 (const_string "DF"))
2991 /* For architectures resolving dependencies on register
2992 parts we may avoid extra work to zero out upper part
2994 (eq_attr "alternative" "7")
2996 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2998 (const_string "V1DF")
2999 (const_string "DF"))
3001 (const_string "DF")))])
3003 (define_insn "*movdf_integer"
3004 [(set (match_operand:DF 0 "nonimmediate_operand"
3005 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3006 (match_operand:DF 1 "general_operand"
3007 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3008 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3009 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3010 && (reload_in_progress || reload_completed
3011 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3012 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3013 && standard_80387_constant_p (operands[1]))
3014 || GET_CODE (operands[1]) != CONST_DOUBLE
3015 || memory_operand (operands[0], DFmode))"
3017 switch (which_alternative)
3021 return output_387_reg_move (insn, operands);
3024 return standard_80387_constant_opcode (operands[1]);
3031 switch (get_attr_mode (insn))
3034 return "xorps\t%0, %0";
3036 return "xorpd\t%0, %0";
3038 return "pxor\t%0, %0";
3045 switch (get_attr_mode (insn))
3048 return "movaps\t{%1, %0|%0, %1}";
3050 return "movapd\t{%1, %0|%0, %1}";
3052 return "movdqa\t{%1, %0|%0, %1}";
3054 return "movq\t{%1, %0|%0, %1}";
3056 return "movsd\t{%1, %0|%0, %1}";
3058 return "movlpd\t{%1, %0|%0, %1}";
3060 return "movlps\t{%1, %0|%0, %1}";
3069 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3071 (cond [(eq_attr "alternative" "0,1,2")
3073 (eq_attr "alternative" "3,4")
3076 /* For SSE1, we have many fewer alternatives. */
3077 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3078 (cond [(eq_attr "alternative" "5,6")
3079 (const_string "V4SF")
3081 (const_string "V2SF"))
3083 /* xorps is one byte shorter. */
3084 (eq_attr "alternative" "5")
3085 (cond [(ne (symbol_ref "optimize_size")
3087 (const_string "V4SF")
3088 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3092 (const_string "V2DF"))
3094 /* For architectures resolving dependencies on
3095 whole SSE registers use APD move to break dependency
3096 chains, otherwise use short move to avoid extra work.
3098 movaps encodes one byte shorter. */
3099 (eq_attr "alternative" "6")
3101 [(ne (symbol_ref "optimize_size")
3103 (const_string "V4SF")
3104 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3106 (const_string "V2DF")
3108 (const_string "DF"))
3109 /* For architectures resolving dependencies on register
3110 parts we may avoid extra work to zero out upper part
3112 (eq_attr "alternative" "7")
3114 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3116 (const_string "V1DF")
3117 (const_string "DF"))
3119 (const_string "DF")))])
3122 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3123 (match_operand:DF 1 "general_operand" ""))]
3125 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3126 && ! (ANY_FP_REG_P (operands[0]) ||
3127 (GET_CODE (operands[0]) == SUBREG
3128 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3129 && ! (ANY_FP_REG_P (operands[1]) ||
3130 (GET_CODE (operands[1]) == SUBREG
3131 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3133 "ix86_split_long_move (operands); DONE;")
3135 (define_insn "*swapdf"
3136 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3137 (match_operand:DF 1 "fp_register_operand" "+f"))
3140 "reload_completed || TARGET_80387"
3142 if (STACK_TOP_P (operands[0]))
3147 [(set_attr "type" "fxch")
3148 (set_attr "mode" "DF")])
3150 (define_expand "movxf"
3151 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3152 (match_operand:XF 1 "general_operand" ""))]
3154 "ix86_expand_move (XFmode, operands); DONE;")
3156 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3157 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3158 ;; Pushing using integer instructions is longer except for constants
3159 ;; and direct memory references.
3160 ;; (assuming that any given constant is pushed only once, but this ought to be
3161 ;; handled elsewhere).
3163 (define_insn "*pushxf_nointeger"
3164 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3165 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3168 /* This insn should be already split before reg-stack. */
3171 [(set_attr "type" "multi")
3172 (set_attr "unit" "i387,*,*")
3173 (set_attr "mode" "XF,SI,SI")])
3175 (define_insn "*pushxf_integer"
3176 [(set (match_operand:XF 0 "push_operand" "=<,<")
3177 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3180 /* This insn should be already split before reg-stack. */
3183 [(set_attr "type" "multi")
3184 (set_attr "unit" "i387,*")
3185 (set_attr "mode" "XF,SI")])
3188 [(set (match_operand 0 "push_operand" "")
3189 (match_operand 1 "general_operand" ""))]
3191 && (GET_MODE (operands[0]) == XFmode
3192 || GET_MODE (operands[0]) == DFmode)
3193 && !ANY_FP_REG_P (operands[1])"
3195 "ix86_split_long_move (operands); DONE;")
3198 [(set (match_operand:XF 0 "push_operand" "")
3199 (match_operand:XF 1 "any_fp_register_operand" ""))]
3201 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3202 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3203 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3206 [(set (match_operand:XF 0 "push_operand" "")
3207 (match_operand:XF 1 "any_fp_register_operand" ""))]
3209 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3210 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3211 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3213 ;; Do not use integer registers when optimizing for size
3214 (define_insn "*movxf_nointeger"
3215 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3216 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3218 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3219 && (reload_in_progress || reload_completed
3220 || (optimize_size && standard_80387_constant_p (operands[1]))
3221 || GET_CODE (operands[1]) != CONST_DOUBLE
3222 || memory_operand (operands[0], XFmode))"
3224 switch (which_alternative)
3228 return output_387_reg_move (insn, operands);
3231 return standard_80387_constant_opcode (operands[1]);
3239 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3240 (set_attr "mode" "XF,XF,XF,SI,SI")])
3242 (define_insn "*movxf_integer"
3243 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3244 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3246 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3247 && (reload_in_progress || reload_completed
3248 || (optimize_size && standard_80387_constant_p (operands[1]))
3249 || GET_CODE (operands[1]) != CONST_DOUBLE
3250 || memory_operand (operands[0], XFmode))"
3252 switch (which_alternative)
3256 return output_387_reg_move (insn, operands);
3259 return standard_80387_constant_opcode (operands[1]);
3268 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3269 (set_attr "mode" "XF,XF,XF,SI,SI")])
3271 (define_expand "movtf"
3272 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3273 (match_operand:TF 1 "nonimmediate_operand" ""))]
3276 ix86_expand_move (TFmode, operands);
3280 (define_insn "*movtf_internal"
3281 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3282 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3284 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3286 switch (which_alternative)
3290 if (get_attr_mode (insn) == MODE_V4SF)
3291 return "movaps\t{%1, %0|%0, %1}";
3293 return "movdqa\t{%1, %0|%0, %1}";
3295 if (get_attr_mode (insn) == MODE_V4SF)
3296 return "xorps\t%0, %0";
3298 return "pxor\t%0, %0";
3306 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3308 (cond [(eq_attr "alternative" "0,2")
3310 (ne (symbol_ref "optimize_size")
3312 (const_string "V4SF")
3313 (const_string "TI"))
3314 (eq_attr "alternative" "1")
3316 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3318 (ne (symbol_ref "optimize_size")
3320 (const_string "V4SF")
3321 (const_string "TI"))]
3322 (const_string "DI")))])
3325 [(set (match_operand 0 "nonimmediate_operand" "")
3326 (match_operand 1 "general_operand" ""))]
3328 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3329 && GET_MODE (operands[0]) == XFmode
3330 && ! (ANY_FP_REG_P (operands[0]) ||
3331 (GET_CODE (operands[0]) == SUBREG
3332 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3333 && ! (ANY_FP_REG_P (operands[1]) ||
3334 (GET_CODE (operands[1]) == SUBREG
3335 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3337 "ix86_split_long_move (operands); DONE;")
3340 [(set (match_operand 0 "register_operand" "")
3341 (match_operand 1 "memory_operand" ""))]
3343 && MEM_P (operands[1])
3344 && (GET_MODE (operands[0]) == TFmode
3345 || GET_MODE (operands[0]) == XFmode
3346 || GET_MODE (operands[0]) == SFmode
3347 || GET_MODE (operands[0]) == DFmode)
3348 && (operands[2] = find_constant_src (insn))"
3349 [(set (match_dup 0) (match_dup 2))]
3351 rtx c = operands[2];
3352 rtx r = operands[0];
3354 if (GET_CODE (r) == SUBREG)
3359 if (!standard_sse_constant_p (c))
3362 else if (FP_REG_P (r))
3364 if (!standard_80387_constant_p (c))
3367 else if (MMX_REG_P (r))
3372 [(set (match_operand 0 "register_operand" "")
3373 (float_extend (match_operand 1 "memory_operand" "")))]
3375 && MEM_P (operands[1])
3376 && (GET_MODE (operands[0]) == TFmode
3377 || GET_MODE (operands[0]) == XFmode
3378 || GET_MODE (operands[0]) == SFmode
3379 || GET_MODE (operands[0]) == DFmode)
3380 && (operands[2] = find_constant_src (insn))"
3381 [(set (match_dup 0) (match_dup 2))]
3383 rtx c = operands[2];
3384 rtx r = operands[0];
3386 if (GET_CODE (r) == SUBREG)
3391 if (!standard_sse_constant_p (c))
3394 else if (FP_REG_P (r))
3396 if (!standard_80387_constant_p (c))
3399 else if (MMX_REG_P (r))
3403 (define_insn "swapxf"
3404 [(set (match_operand:XF 0 "register_operand" "+f")
3405 (match_operand:XF 1 "register_operand" "+f"))
3410 if (STACK_TOP_P (operands[0]))
3415 [(set_attr "type" "fxch")
3416 (set_attr "mode" "XF")])
3418 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3420 [(set (match_operand:X87MODEF 0 "register_operand" "")
3421 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3422 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3423 && (standard_80387_constant_p (operands[1]) == 8
3424 || standard_80387_constant_p (operands[1]) == 9)"
3425 [(set (match_dup 0)(match_dup 1))
3427 (neg:X87MODEF (match_dup 0)))]
3431 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3432 if (real_isnegzero (&r))
3433 operands[1] = CONST0_RTX (<MODE>mode);
3435 operands[1] = CONST1_RTX (<MODE>mode);
3439 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3440 (match_operand:TF 1 "general_operand" ""))]
3442 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3444 "ix86_split_long_move (operands); DONE;")
3446 ;; Zero extension instructions
3448 (define_expand "zero_extendhisi2"
3449 [(set (match_operand:SI 0 "register_operand" "")
3450 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3453 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3455 operands[1] = force_reg (HImode, operands[1]);
3456 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3461 (define_insn "zero_extendhisi2_and"
3462 [(set (match_operand:SI 0 "register_operand" "=r")
3463 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3464 (clobber (reg:CC FLAGS_REG))]
3465 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3467 [(set_attr "type" "alu1")
3468 (set_attr "mode" "SI")])
3471 [(set (match_operand:SI 0 "register_operand" "")
3472 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3473 (clobber (reg:CC FLAGS_REG))]
3474 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3475 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3476 (clobber (reg:CC FLAGS_REG))])]
3479 (define_insn "*zero_extendhisi2_movzwl"
3480 [(set (match_operand:SI 0 "register_operand" "=r")
3481 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3482 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3483 "movz{wl|x}\t{%1, %0|%0, %1}"
3484 [(set_attr "type" "imovx")
3485 (set_attr "mode" "SI")])
3487 (define_expand "zero_extendqihi2"
3489 [(set (match_operand:HI 0 "register_operand" "")
3490 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3491 (clobber (reg:CC FLAGS_REG))])]
3495 (define_insn "*zero_extendqihi2_and"
3496 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3497 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3498 (clobber (reg:CC FLAGS_REG))]
3499 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3501 [(set_attr "type" "alu1")
3502 (set_attr "mode" "HI")])
3504 (define_insn "*zero_extendqihi2_movzbw_and"
3505 [(set (match_operand:HI 0 "register_operand" "=r,r")
3506 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3507 (clobber (reg:CC FLAGS_REG))]
3508 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3510 [(set_attr "type" "imovx,alu1")
3511 (set_attr "mode" "HI")])
3513 ; zero extend to SImode here to avoid partial register stalls
3514 (define_insn "*zero_extendqihi2_movzbl"
3515 [(set (match_operand:HI 0 "register_operand" "=r")
3516 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3517 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3518 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3519 [(set_attr "type" "imovx")
3520 (set_attr "mode" "SI")])
3522 ;; For the movzbw case strip only the clobber
3524 [(set (match_operand:HI 0 "register_operand" "")
3525 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3526 (clobber (reg:CC FLAGS_REG))]
3528 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3529 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3530 [(set (match_operand:HI 0 "register_operand" "")
3531 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3533 ;; When source and destination does not overlap, clear destination
3534 ;; first and then do the movb
3536 [(set (match_operand:HI 0 "register_operand" "")
3537 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3538 (clobber (reg:CC FLAGS_REG))]
3540 && ANY_QI_REG_P (operands[0])
3541 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3542 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3543 [(set (match_dup 0) (const_int 0))
3544 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3545 "operands[2] = gen_lowpart (QImode, operands[0]);")
3547 ;; Rest is handled by single and.
3549 [(set (match_operand:HI 0 "register_operand" "")
3550 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3551 (clobber (reg:CC FLAGS_REG))]
3553 && true_regnum (operands[0]) == true_regnum (operands[1])"
3554 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3555 (clobber (reg:CC FLAGS_REG))])]
3558 (define_expand "zero_extendqisi2"
3560 [(set (match_operand:SI 0 "register_operand" "")
3561 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3562 (clobber (reg:CC FLAGS_REG))])]
3566 (define_insn "*zero_extendqisi2_and"
3567 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3568 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3569 (clobber (reg:CC FLAGS_REG))]
3570 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3572 [(set_attr "type" "alu1")
3573 (set_attr "mode" "SI")])
3575 (define_insn "*zero_extendqisi2_movzbw_and"
3576 [(set (match_operand:SI 0 "register_operand" "=r,r")
3577 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3578 (clobber (reg:CC FLAGS_REG))]
3579 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3581 [(set_attr "type" "imovx,alu1")
3582 (set_attr "mode" "SI")])
3584 (define_insn "*zero_extendqisi2_movzbw"
3585 [(set (match_operand:SI 0 "register_operand" "=r")
3586 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3587 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3588 "movz{bl|x}\t{%1, %0|%0, %1}"
3589 [(set_attr "type" "imovx")
3590 (set_attr "mode" "SI")])
3592 ;; For the movzbl case strip only the clobber
3594 [(set (match_operand:SI 0 "register_operand" "")
3595 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3596 (clobber (reg:CC FLAGS_REG))]
3598 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3599 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3601 (zero_extend:SI (match_dup 1)))])
3603 ;; When source and destination does not overlap, clear destination
3604 ;; first and then do the movb
3606 [(set (match_operand:SI 0 "register_operand" "")
3607 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3608 (clobber (reg:CC FLAGS_REG))]
3610 && ANY_QI_REG_P (operands[0])
3611 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3612 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3613 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3614 [(set (match_dup 0) (const_int 0))
3615 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3616 "operands[2] = gen_lowpart (QImode, operands[0]);")
3618 ;; Rest is handled by single and.
3620 [(set (match_operand:SI 0 "register_operand" "")
3621 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3622 (clobber (reg:CC FLAGS_REG))]
3624 && true_regnum (operands[0]) == true_regnum (operands[1])"
3625 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3626 (clobber (reg:CC FLAGS_REG))])]
3629 ;; %%% Kill me once multi-word ops are sane.
3630 (define_expand "zero_extendsidi2"
3631 [(set (match_operand:DI 0 "register_operand" "")
3632 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3637 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3642 (define_insn "zero_extendsidi2_32"
3643 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3645 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3646 (clobber (reg:CC FLAGS_REG))]
3652 movd\t{%1, %0|%0, %1}
3653 movd\t{%1, %0|%0, %1}
3654 movd\t{%1, %0|%0, %1}
3655 movd\t{%1, %0|%0, %1}"
3656 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3657 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3659 (define_insn "zero_extendsidi2_rex64"
3660 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3662 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3665 mov\t{%k1, %k0|%k0, %k1}
3667 movd\t{%1, %0|%0, %1}
3668 movd\t{%1, %0|%0, %1}
3669 movd\t{%1, %0|%0, %1}
3670 movd\t{%1, %0|%0, %1}"
3671 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3672 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3675 [(set (match_operand:DI 0 "memory_operand" "")
3676 (zero_extend:DI (match_dup 0)))]
3678 [(set (match_dup 4) (const_int 0))]
3679 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3682 [(set (match_operand:DI 0 "register_operand" "")
3683 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3684 (clobber (reg:CC FLAGS_REG))]
3685 "!TARGET_64BIT && reload_completed
3686 && true_regnum (operands[0]) == true_regnum (operands[1])"
3687 [(set (match_dup 4) (const_int 0))]
3688 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3691 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3692 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3693 (clobber (reg:CC FLAGS_REG))]
3694 "!TARGET_64BIT && reload_completed
3695 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3696 [(set (match_dup 3) (match_dup 1))
3697 (set (match_dup 4) (const_int 0))]
3698 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3700 (define_insn "zero_extendhidi2"
3701 [(set (match_operand:DI 0 "register_operand" "=r")
3702 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3704 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3705 [(set_attr "type" "imovx")
3706 (set_attr "mode" "DI")])
3708 (define_insn "zero_extendqidi2"
3709 [(set (match_operand:DI 0 "register_operand" "=r")
3710 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3712 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3713 [(set_attr "type" "imovx")
3714 (set_attr "mode" "DI")])
3716 ;; Sign extension instructions
3718 (define_expand "extendsidi2"
3719 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3720 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3721 (clobber (reg:CC FLAGS_REG))
3722 (clobber (match_scratch:SI 2 ""))])]
3727 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3732 (define_insn "*extendsidi2_1"
3733 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3734 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3735 (clobber (reg:CC FLAGS_REG))
3736 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3740 (define_insn "extendsidi2_rex64"
3741 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3742 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3746 movs{lq|x}\t{%1,%0|%0, %1}"
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "DI")
3749 (set_attr "prefix_0f" "0")
3750 (set_attr "modrm" "0,1")])
3752 (define_insn "extendhidi2"
3753 [(set (match_operand:DI 0 "register_operand" "=r")
3754 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3756 "movs{wq|x}\t{%1,%0|%0, %1}"
3757 [(set_attr "type" "imovx")
3758 (set_attr "mode" "DI")])
3760 (define_insn "extendqidi2"
3761 [(set (match_operand:DI 0 "register_operand" "=r")
3762 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3764 "movs{bq|x}\t{%1,%0|%0, %1}"
3765 [(set_attr "type" "imovx")
3766 (set_attr "mode" "DI")])
3768 ;; Extend to memory case when source register does die.
3770 [(set (match_operand:DI 0 "memory_operand" "")
3771 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3772 (clobber (reg:CC FLAGS_REG))
3773 (clobber (match_operand:SI 2 "register_operand" ""))]
3775 && dead_or_set_p (insn, operands[1])
3776 && !reg_mentioned_p (operands[1], operands[0]))"
3777 [(set (match_dup 3) (match_dup 1))
3778 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3779 (clobber (reg:CC FLAGS_REG))])
3780 (set (match_dup 4) (match_dup 1))]
3781 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3783 ;; Extend to memory case when source register does not die.
3785 [(set (match_operand:DI 0 "memory_operand" "")
3786 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3787 (clobber (reg:CC FLAGS_REG))
3788 (clobber (match_operand:SI 2 "register_operand" ""))]
3792 split_di (&operands[0], 1, &operands[3], &operands[4]);
3794 emit_move_insn (operands[3], operands[1]);
3796 /* Generate a cltd if possible and doing so it profitable. */
3797 if ((optimize_size || TARGET_USE_CLTD)
3798 && true_regnum (operands[1]) == AX_REG
3799 && true_regnum (operands[2]) == DX_REG)
3801 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3805 emit_move_insn (operands[2], operands[1]);
3806 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3808 emit_move_insn (operands[4], operands[2]);
3812 ;; Extend to register case. Optimize case where source and destination
3813 ;; registers match and cases where we can use cltd.
3815 [(set (match_operand:DI 0 "register_operand" "")
3816 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3817 (clobber (reg:CC FLAGS_REG))
3818 (clobber (match_scratch:SI 2 ""))]
3822 split_di (&operands[0], 1, &operands[3], &operands[4]);
3824 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3825 emit_move_insn (operands[3], operands[1]);
3827 /* Generate a cltd if possible and doing so it profitable. */
3828 if ((optimize_size || TARGET_USE_CLTD)
3829 && true_regnum (operands[3]) == AX_REG)
3831 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3835 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3836 emit_move_insn (operands[4], operands[1]);
3838 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3842 (define_insn "extendhisi2"
3843 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3844 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3847 switch (get_attr_prefix_0f (insn))
3850 return "{cwtl|cwde}";
3852 return "movs{wl|x}\t{%1,%0|%0, %1}";
3855 [(set_attr "type" "imovx")
3856 (set_attr "mode" "SI")
3857 (set (attr "prefix_0f")
3858 ;; movsx is short decodable while cwtl is vector decoded.
3859 (if_then_else (and (eq_attr "cpu" "!k6")
3860 (eq_attr "alternative" "0"))
3862 (const_string "1")))
3864 (if_then_else (eq_attr "prefix_0f" "0")
3866 (const_string "1")))])
3868 (define_insn "*extendhisi2_zext"
3869 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3871 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3874 switch (get_attr_prefix_0f (insn))
3877 return "{cwtl|cwde}";
3879 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3882 [(set_attr "type" "imovx")
3883 (set_attr "mode" "SI")
3884 (set (attr "prefix_0f")
3885 ;; movsx is short decodable while cwtl is vector decoded.
3886 (if_then_else (and (eq_attr "cpu" "!k6")
3887 (eq_attr "alternative" "0"))
3889 (const_string "1")))
3891 (if_then_else (eq_attr "prefix_0f" "0")
3893 (const_string "1")))])
3895 (define_insn "extendqihi2"
3896 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3897 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3900 switch (get_attr_prefix_0f (insn))
3903 return "{cbtw|cbw}";
3905 return "movs{bw|x}\t{%1,%0|%0, %1}";
3908 [(set_attr "type" "imovx")
3909 (set_attr "mode" "HI")
3910 (set (attr "prefix_0f")
3911 ;; movsx is short decodable while cwtl is vector decoded.
3912 (if_then_else (and (eq_attr "cpu" "!k6")
3913 (eq_attr "alternative" "0"))
3915 (const_string "1")))
3917 (if_then_else (eq_attr "prefix_0f" "0")
3919 (const_string "1")))])
3921 (define_insn "extendqisi2"
3922 [(set (match_operand:SI 0 "register_operand" "=r")
3923 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3925 "movs{bl|x}\t{%1,%0|%0, %1}"
3926 [(set_attr "type" "imovx")
3927 (set_attr "mode" "SI")])
3929 (define_insn "*extendqisi2_zext"
3930 [(set (match_operand:DI 0 "register_operand" "=r")
3932 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3934 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3935 [(set_attr "type" "imovx")
3936 (set_attr "mode" "SI")])
3938 ;; Conversions between float and double.
3940 ;; These are all no-ops in the model used for the 80387. So just
3943 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3944 (define_insn "*dummy_extendsfdf2"
3945 [(set (match_operand:DF 0 "push_operand" "=<")
3946 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3951 [(set (match_operand:DF 0 "push_operand" "")
3952 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3954 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3955 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3958 [(set (match_operand:DF 0 "push_operand" "")
3959 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3961 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3962 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3964 (define_insn "*dummy_extendsfxf2"
3965 [(set (match_operand:XF 0 "push_operand" "=<")
3966 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3971 [(set (match_operand:XF 0 "push_operand" "")
3972 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3974 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3975 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3976 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3979 [(set (match_operand:XF 0 "push_operand" "")
3980 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3982 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3983 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3984 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3987 [(set (match_operand:XF 0 "push_operand" "")
3988 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3990 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3991 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3992 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3995 [(set (match_operand:XF 0 "push_operand" "")
3996 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3998 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3999 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
4000 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4002 (define_expand "extendsfdf2"
4003 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4004 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4005 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4007 /* ??? Needed for compress_float_constant since all fp constants
4008 are LEGITIMATE_CONSTANT_P. */
4009 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4011 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4012 && standard_80387_constant_p (operands[1]) > 0)
4014 operands[1] = simplify_const_unary_operation
4015 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4016 emit_move_insn_1 (operands[0], operands[1]);
4019 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4023 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4025 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4027 We do the conversion post reload to avoid producing of 128bit spills
4028 that might lead to ICE on 32bit target. The sequence unlikely combine
4031 [(set (match_operand:DF 0 "register_operand" "")
4033 (match_operand:SF 1 "nonimmediate_operand" "")))]
4034 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4035 && reload_completed && SSE_REG_P (operands[0])"
4040 (parallel [(const_int 0) (const_int 1)]))))]
4042 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4043 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4044 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4045 Try to avoid move when unpacking can be done in source. */
4046 if (REG_P (operands[1]))
4048 /* If it is unsafe to overwrite upper half of source, we need
4049 to move to destination and unpack there. */
4050 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4051 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4052 && true_regnum (operands[0]) != true_regnum (operands[1]))
4054 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4055 emit_move_insn (tmp, operands[1]);
4058 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4059 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4062 emit_insn (gen_vec_setv4sf_0 (operands[3],
4063 CONST0_RTX (V4SFmode), operands[1]));
4066 (define_insn "*extendsfdf2_mixed"
4067 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4069 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4070 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4072 switch (which_alternative)
4076 return output_387_reg_move (insn, operands);
4079 return "cvtss2sd\t{%1, %0|%0, %1}";
4085 [(set_attr "type" "fmov,fmov,ssecvt")
4086 (set_attr "mode" "SF,XF,DF")])
4088 (define_insn "*extendsfdf2_sse"
4089 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4090 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4091 "TARGET_SSE2 && TARGET_SSE_MATH"
4092 "cvtss2sd\t{%1, %0|%0, %1}"
4093 [(set_attr "type" "ssecvt")
4094 (set_attr "mode" "DF")])
4096 (define_insn "*extendsfdf2_i387"
4097 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4098 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4100 "* return output_387_reg_move (insn, operands);"
4101 [(set_attr "type" "fmov")
4102 (set_attr "mode" "SF,XF")])
4104 (define_expand "extend<mode>xf2"
4105 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4106 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4109 /* ??? Needed for compress_float_constant since all fp constants
4110 are LEGITIMATE_CONSTANT_P. */
4111 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4113 if (standard_80387_constant_p (operands[1]) > 0)
4115 operands[1] = simplify_const_unary_operation
4116 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4117 emit_move_insn_1 (operands[0], operands[1]);
4120 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4124 (define_insn "*extend<mode>xf2_i387"
4125 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4127 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4129 "* return output_387_reg_move (insn, operands);"
4130 [(set_attr "type" "fmov")
4131 (set_attr "mode" "<MODE>,XF")])
4133 ;; %%% This seems bad bad news.
4134 ;; This cannot output into an f-reg because there is no way to be sure
4135 ;; of truncating in that case. Otherwise this is just like a simple move
4136 ;; insn. So we pretend we can output to a reg in order to get better
4137 ;; register preferencing, but we really use a stack slot.
4139 ;; Conversion from DFmode to SFmode.
4141 (define_expand "truncdfsf2"
4142 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4144 (match_operand:DF 1 "nonimmediate_operand" "")))]
4145 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4147 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4149 else if (flag_unsafe_math_optimizations)
4153 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4154 rtx temp = assign_386_stack_local (SFmode, slot);
4155 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4160 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4162 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4164 We do the conversion post reload to avoid producing of 128bit spills
4165 that might lead to ICE on 32bit target. The sequence unlikely combine
4168 [(set (match_operand:SF 0 "register_operand" "")
4170 (match_operand:DF 1 "nonimmediate_operand" "")))]
4171 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4172 && reload_completed && SSE_REG_P (operands[0])"
4175 (float_truncate:V2SF
4179 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4180 operands[3] = CONST0_RTX (V2SFmode);
4181 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4182 /* Use movsd for loading from memory, unpcklpd for registers.
4183 Try to avoid move when unpacking can be done in source, or SSE3
4184 movddup is available. */
4185 if (REG_P (operands[1]))
4188 && true_regnum (operands[0]) != true_regnum (operands[1])
4189 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4190 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4192 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4193 emit_move_insn (tmp, operands[1]);
4196 else if (!TARGET_SSE3)
4197 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4198 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4201 emit_insn (gen_sse2_loadlpd (operands[4],
4202 CONST0_RTX (V2DFmode), operands[1]));
4205 (define_expand "truncdfsf2_with_temp"
4206 [(parallel [(set (match_operand:SF 0 "" "")
4207 (float_truncate:SF (match_operand:DF 1 "" "")))
4208 (clobber (match_operand:SF 2 "" ""))])]
4211 (define_insn "*truncdfsf_fast_mixed"
4212 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4214 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4215 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4217 switch (which_alternative)
4220 return output_387_reg_move (insn, operands);
4222 return "cvtsd2ss\t{%1, %0|%0, %1}";
4227 [(set_attr "type" "fmov,ssecvt")
4228 (set_attr "mode" "SF")])
4230 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4231 ;; because nothing we do here is unsafe.
4232 (define_insn "*truncdfsf_fast_sse"
4233 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4235 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4236 "TARGET_SSE2 && TARGET_SSE_MATH"
4237 "cvtsd2ss\t{%1, %0|%0, %1}"
4238 [(set_attr "type" "ssecvt")
4239 (set_attr "mode" "SF")])
4241 (define_insn "*truncdfsf_fast_i387"
4242 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4244 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4245 "TARGET_80387 && flag_unsafe_math_optimizations"
4246 "* return output_387_reg_move (insn, operands);"
4247 [(set_attr "type" "fmov")
4248 (set_attr "mode" "SF")])
4250 (define_insn "*truncdfsf_mixed"
4251 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4253 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4254 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4255 "TARGET_MIX_SSE_I387"
4257 switch (which_alternative)
4260 return output_387_reg_move (insn, operands);
4265 return "cvtsd2ss\t{%1, %0|%0, %1}";
4270 [(set_attr "type" "fmov,multi,ssecvt")
4271 (set_attr "unit" "*,i387,*")
4272 (set_attr "mode" "SF")])
4274 (define_insn "*truncdfsf_i387"
4275 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4277 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4278 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4281 switch (which_alternative)
4284 return output_387_reg_move (insn, operands);
4292 [(set_attr "type" "fmov,multi")
4293 (set_attr "unit" "*,i387")
4294 (set_attr "mode" "SF")])
4296 (define_insn "*truncdfsf2_i387_1"
4297 [(set (match_operand:SF 0 "memory_operand" "=m")
4299 (match_operand:DF 1 "register_operand" "f")))]
4301 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4302 && !TARGET_MIX_SSE_I387"
4303 "* return output_387_reg_move (insn, operands);"
4304 [(set_attr "type" "fmov")
4305 (set_attr "mode" "SF")])
4308 [(set (match_operand:SF 0 "register_operand" "")
4310 (match_operand:DF 1 "fp_register_operand" "")))
4311 (clobber (match_operand 2 "" ""))]
4313 [(set (match_dup 2) (match_dup 1))
4314 (set (match_dup 0) (match_dup 2))]
4316 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4319 ;; Conversion from XFmode to {SF,DF}mode
4321 (define_expand "truncxf<mode>2"
4322 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4323 (float_truncate:MODEF
4324 (match_operand:XF 1 "register_operand" "")))
4325 (clobber (match_dup 2))])]
4328 if (flag_unsafe_math_optimizations)
4330 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4331 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4332 if (reg != operands[0])
4333 emit_move_insn (operands[0], reg);
4338 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4339 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4343 (define_insn "*truncxfsf2_mixed"
4344 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4346 (match_operand:XF 1 "register_operand" "f,f")))
4347 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4350 gcc_assert (!which_alternative);
4351 return output_387_reg_move (insn, operands);
4353 [(set_attr "type" "fmov,multi")
4354 (set_attr "unit" "*,i387")
4355 (set_attr "mode" "SF")])
4357 (define_insn "*truncxfdf2_mixed"
4358 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4360 (match_operand:XF 1 "register_operand" "f,f")))
4361 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4364 gcc_assert (!which_alternative);
4365 return output_387_reg_move (insn, operands);
4367 [(set_attr "type" "fmov,multi")
4368 (set_attr "unit" "*,i387")
4369 (set_attr "mode" "DF")])
4371 (define_insn "truncxf<mode>2_i387_noop"
4372 [(set (match_operand:MODEF 0 "register_operand" "=f")
4373 (float_truncate:MODEF
4374 (match_operand:XF 1 "register_operand" "f")))]
4375 "TARGET_80387 && flag_unsafe_math_optimizations"
4376 "* return output_387_reg_move (insn, operands);"
4377 [(set_attr "type" "fmov")
4378 (set_attr "mode" "<MODE>")])
4380 (define_insn "*truncxf<mode>2_i387"
4381 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4382 (float_truncate:MODEF
4383 (match_operand:XF 1 "register_operand" "f")))]
4385 "* return output_387_reg_move (insn, operands);"
4386 [(set_attr "type" "fmov")
4387 (set_attr "mode" "<MODE>")])
4390 [(set (match_operand:MODEF 0 "register_operand" "")
4391 (float_truncate:MODEF
4392 (match_operand:XF 1 "register_operand" "")))
4393 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4394 "TARGET_80387 && reload_completed"
4395 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4396 (set (match_dup 0) (match_dup 2))]
4400 [(set (match_operand:MODEF 0 "memory_operand" "")
4401 (float_truncate:MODEF
4402 (match_operand:XF 1 "register_operand" "")))
4403 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4405 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4408 ;; Signed conversion to DImode.
4410 (define_expand "fix_truncxfdi2"
4411 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4412 (fix:DI (match_operand:XF 1 "register_operand" "")))
4413 (clobber (reg:CC FLAGS_REG))])]
4418 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4423 (define_expand "fix_trunc<mode>di2"
4424 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4425 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4426 (clobber (reg:CC FLAGS_REG))])]
4427 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4430 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4432 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4435 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4437 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4438 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4439 if (out != operands[0])
4440 emit_move_insn (operands[0], out);
4445 ;; Signed conversion to SImode.
4447 (define_expand "fix_truncxfsi2"
4448 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4449 (fix:SI (match_operand:XF 1 "register_operand" "")))
4450 (clobber (reg:CC FLAGS_REG))])]
4455 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4460 (define_expand "fix_trunc<mode>si2"
4461 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4462 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4463 (clobber (reg:CC FLAGS_REG))])]
4464 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4467 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4469 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4472 if (SSE_FLOAT_MODE_P (<MODE>mode))
4474 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4475 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4476 if (out != operands[0])
4477 emit_move_insn (operands[0], out);
4482 ;; Signed conversion to HImode.
4484 (define_expand "fix_trunc<mode>hi2"
4485 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4486 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4487 (clobber (reg:CC FLAGS_REG))])]
4489 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4493 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4498 ;; Unsigned conversion to SImode.
4500 (define_expand "fixuns_trunc<mode>si2"
4502 [(set (match_operand:SI 0 "register_operand" "")
4504 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4506 (clobber (match_scratch:<ssevecmode> 3 ""))
4507 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4508 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4510 enum machine_mode mode = <MODE>mode;
4511 enum machine_mode vecmode = <ssevecmode>mode;
4512 REAL_VALUE_TYPE TWO31r;
4515 real_ldexp (&TWO31r, &dconst1, 31);
4516 two31 = const_double_from_real_value (TWO31r, mode);
4517 two31 = ix86_build_const_vector (mode, true, two31);
4518 operands[2] = force_reg (vecmode, two31);
4521 (define_insn_and_split "*fixuns_trunc<mode>_1"
4522 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4524 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4525 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4526 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4527 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4528 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4530 "&& reload_completed"
4533 ix86_split_convert_uns_si_sse (operands);
4537 ;; Unsigned conversion to HImode.
4538 ;; Without these patterns, we'll try the unsigned SI conversion which
4539 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4541 (define_expand "fixuns_trunc<mode>hi2"
4543 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4544 (set (match_operand:HI 0 "nonimmediate_operand" "")
4545 (subreg:HI (match_dup 2) 0))]
4546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4547 "operands[2] = gen_reg_rtx (SImode);")
4549 ;; When SSE is available, it is always faster to use it!
4550 (define_insn "fix_trunc<mode>di_sse"
4551 [(set (match_operand:DI 0 "register_operand" "=r,r")
4552 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4553 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4554 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4555 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4556 [(set_attr "type" "sseicvt")
4557 (set_attr "mode" "<MODE>")
4558 (set_attr "athlon_decode" "double,vector")
4559 (set_attr "amdfam10_decode" "double,double")])
4561 (define_insn "fix_trunc<mode>si_sse"
4562 [(set (match_operand:SI 0 "register_operand" "=r,r")
4563 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4564 "SSE_FLOAT_MODE_P (<MODE>mode)
4565 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4566 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4567 [(set_attr "type" "sseicvt")
4568 (set_attr "mode" "<MODE>")
4569 (set_attr "athlon_decode" "double,vector")
4570 (set_attr "amdfam10_decode" "double,double")])
4572 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4574 [(set (match_operand:MODEF 0 "register_operand" "")
4575 (match_operand:MODEF 1 "memory_operand" ""))
4576 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4577 (fix:SSEMODEI24 (match_dup 0)))]
4578 "TARGET_SHORTEN_X87_SSE
4579 && peep2_reg_dead_p (2, operands[0])"
4580 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4583 ;; Avoid vector decoded forms of the instruction.
4585 [(match_scratch:DF 2 "Y2")
4586 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4587 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4588 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4589 [(set (match_dup 2) (match_dup 1))
4590 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4594 [(match_scratch:SF 2 "x")
4595 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4596 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4597 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4598 [(set (match_dup 2) (match_dup 1))
4599 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4602 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4603 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4604 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4605 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4607 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4608 && (TARGET_64BIT || <MODE>mode != DImode))
4610 && !(reload_completed || reload_in_progress)"
4615 if (memory_operand (operands[0], VOIDmode))
4616 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4619 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4620 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4626 [(set_attr "type" "fisttp")
4627 (set_attr "mode" "<MODE>")])
4629 (define_insn "fix_trunc<mode>_i387_fisttp"
4630 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4631 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4632 (clobber (match_scratch:XF 2 "=&1f"))]
4633 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4635 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4636 && (TARGET_64BIT || <MODE>mode != DImode))
4637 && TARGET_SSE_MATH)"
4638 "* return output_fix_trunc (insn, operands, 1);"
4639 [(set_attr "type" "fisttp")
4640 (set_attr "mode" "<MODE>")])
4642 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4643 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4644 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4645 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4646 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4647 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4649 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4650 && (TARGET_64BIT || <MODE>mode != DImode))
4651 && TARGET_SSE_MATH)"
4653 [(set_attr "type" "fisttp")
4654 (set_attr "mode" "<MODE>")])
4657 [(set (match_operand:X87MODEI 0 "register_operand" "")
4658 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4659 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4660 (clobber (match_scratch 3 ""))]
4662 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4663 (clobber (match_dup 3))])
4664 (set (match_dup 0) (match_dup 2))]
4668 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4669 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4670 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4671 (clobber (match_scratch 3 ""))]
4673 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4674 (clobber (match_dup 3))])]
4677 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4678 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4679 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4680 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4681 ;; function in i386.c.
4682 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4683 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4684 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4685 (clobber (reg:CC FLAGS_REG))]
4686 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4688 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4689 && (TARGET_64BIT || <MODE>mode != DImode))
4690 && !(reload_completed || reload_in_progress)"
4695 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4697 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4698 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4699 if (memory_operand (operands[0], VOIDmode))
4700 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4701 operands[2], operands[3]));
4704 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4705 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4706 operands[2], operands[3],
4711 [(set_attr "type" "fistp")
4712 (set_attr "i387_cw" "trunc")
4713 (set_attr "mode" "<MODE>")])
4715 (define_insn "fix_truncdi_i387"
4716 [(set (match_operand:DI 0 "memory_operand" "=m")
4717 (fix:DI (match_operand 1 "register_operand" "f")))
4718 (use (match_operand:HI 2 "memory_operand" "m"))
4719 (use (match_operand:HI 3 "memory_operand" "m"))
4720 (clobber (match_scratch:XF 4 "=&1f"))]
4721 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4723 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4724 "* return output_fix_trunc (insn, operands, 0);"
4725 [(set_attr "type" "fistp")
4726 (set_attr "i387_cw" "trunc")
4727 (set_attr "mode" "DI")])
4729 (define_insn "fix_truncdi_i387_with_temp"
4730 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4731 (fix:DI (match_operand 1 "register_operand" "f,f")))
4732 (use (match_operand:HI 2 "memory_operand" "m,m"))
4733 (use (match_operand:HI 3 "memory_operand" "m,m"))
4734 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4735 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4736 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4738 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4740 [(set_attr "type" "fistp")
4741 (set_attr "i387_cw" "trunc")
4742 (set_attr "mode" "DI")])
4745 [(set (match_operand:DI 0 "register_operand" "")
4746 (fix:DI (match_operand 1 "register_operand" "")))
4747 (use (match_operand:HI 2 "memory_operand" ""))
4748 (use (match_operand:HI 3 "memory_operand" ""))
4749 (clobber (match_operand:DI 4 "memory_operand" ""))
4750 (clobber (match_scratch 5 ""))]
4752 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4755 (clobber (match_dup 5))])
4756 (set (match_dup 0) (match_dup 4))]
4760 [(set (match_operand:DI 0 "memory_operand" "")
4761 (fix:DI (match_operand 1 "register_operand" "")))
4762 (use (match_operand:HI 2 "memory_operand" ""))
4763 (use (match_operand:HI 3 "memory_operand" ""))
4764 (clobber (match_operand:DI 4 "memory_operand" ""))
4765 (clobber (match_scratch 5 ""))]
4767 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4770 (clobber (match_dup 5))])]
4773 (define_insn "fix_trunc<mode>_i387"
4774 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4775 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4776 (use (match_operand:HI 2 "memory_operand" "m"))
4777 (use (match_operand:HI 3 "memory_operand" "m"))]
4778 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4780 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4781 "* return output_fix_trunc (insn, operands, 0);"
4782 [(set_attr "type" "fistp")
4783 (set_attr "i387_cw" "trunc")
4784 (set_attr "mode" "<MODE>")])
4786 (define_insn "fix_trunc<mode>_i387_with_temp"
4787 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4788 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4789 (use (match_operand:HI 2 "memory_operand" "m,m"))
4790 (use (match_operand:HI 3 "memory_operand" "m,m"))
4791 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4792 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4794 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4796 [(set_attr "type" "fistp")
4797 (set_attr "i387_cw" "trunc")
4798 (set_attr "mode" "<MODE>")])
4801 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4802 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4803 (use (match_operand:HI 2 "memory_operand" ""))
4804 (use (match_operand:HI 3 "memory_operand" ""))
4805 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4807 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4809 (use (match_dup 3))])
4810 (set (match_dup 0) (match_dup 4))]
4814 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4815 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4816 (use (match_operand:HI 2 "memory_operand" ""))
4817 (use (match_operand:HI 3 "memory_operand" ""))
4818 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4820 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4822 (use (match_dup 3))])]
4825 (define_insn "x86_fnstcw_1"
4826 [(set (match_operand:HI 0 "memory_operand" "=m")
4827 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4830 [(set_attr "length" "2")
4831 (set_attr "mode" "HI")
4832 (set_attr "unit" "i387")])
4834 (define_insn "x86_fldcw_1"
4835 [(set (reg:HI FPCR_REG)
4836 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4839 [(set_attr "length" "2")
4840 (set_attr "mode" "HI")
4841 (set_attr "unit" "i387")
4842 (set_attr "athlon_decode" "vector")
4843 (set_attr "amdfam10_decode" "vector")])
4845 ;; Conversion between fixed point and floating point.
4847 ;; Even though we only accept memory inputs, the backend _really_
4848 ;; wants to be able to do this between registers.
4850 (define_expand "floathi<mode>2"
4851 [(set (match_operand:X87MODEF 0 "register_operand" "")
4852 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4854 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4855 || TARGET_MIX_SSE_I387)"
4858 ;; Pre-reload splitter to add memory clobber to the pattern.
4859 (define_insn_and_split "*floathi<mode>2_1"
4860 [(set (match_operand:X87MODEF 0 "register_operand" "")
4861 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4864 || TARGET_MIX_SSE_I387)
4865 && !(reload_completed || reload_in_progress)"
4868 [(parallel [(set (match_dup 0)
4869 (float:X87MODEF (match_dup 1)))
4870 (clobber (match_dup 2))])]
4871 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4873 (define_insn "*floathi<mode>2_i387_with_temp"
4874 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4875 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4876 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4878 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4879 || TARGET_MIX_SSE_I387)"
4881 [(set_attr "type" "fmov,multi")
4882 (set_attr "mode" "<MODE>")
4883 (set_attr "unit" "*,i387")
4884 (set_attr "fp_int_src" "true")])
4886 (define_insn "*floathi<mode>2_i387"
4887 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4888 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4891 || TARGET_MIX_SSE_I387)"
4893 [(set_attr "type" "fmov")
4894 (set_attr "mode" "<MODE>")
4895 (set_attr "fp_int_src" "true")])
4898 [(set (match_operand:X87MODEF 0 "register_operand" "")
4899 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4900 (clobber (match_operand:HI 2 "memory_operand" ""))]
4902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4903 || TARGET_MIX_SSE_I387)
4904 && reload_completed"
4905 [(set (match_dup 2) (match_dup 1))
4906 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4910 [(set (match_operand:X87MODEF 0 "register_operand" "")
4911 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4912 (clobber (match_operand:HI 2 "memory_operand" ""))]
4914 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4915 || TARGET_MIX_SSE_I387)
4916 && reload_completed"
4917 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4920 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4921 [(set (match_operand:X87MODEF 0 "register_operand" "")
4923 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4925 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4926 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4929 ;; Pre-reload splitter to add memory clobber to the pattern.
4930 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4931 [(set (match_operand:X87MODEF 0 "register_operand" "")
4932 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4934 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4935 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4936 || TARGET_MIX_SSE_I387))
4937 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4938 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4939 && ((<SSEMODEI24:MODE>mode == SImode
4940 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4941 && flag_trapping_math)
4942 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4943 && !(reload_completed || reload_in_progress)"
4946 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4947 (clobber (match_dup 2))])]
4949 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4951 /* Avoid store forwarding (partial memory) stall penalty
4952 by passing DImode value through XMM registers. */
4953 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4954 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4957 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4964 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4965 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4967 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4968 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4969 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4970 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4972 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4973 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4974 (set_attr "unit" "*,i387,*,*,*")
4975 (set_attr "athlon_decode" "*,*,double,direct,double")
4976 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4977 (set_attr "fp_int_src" "true")])
4979 (define_insn "*floatsi<mode>2_vector_mixed"
4980 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4981 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4982 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4983 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4987 [(set_attr "type" "fmov,sseicvt")
4988 (set_attr "mode" "<MODE>,<ssevecmode>")
4989 (set_attr "unit" "i387,*")
4990 (set_attr "athlon_decode" "*,direct")
4991 (set_attr "amdfam10_decode" "*,double")
4992 (set_attr "fp_int_src" "true")])
4994 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4995 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4997 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4998 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4999 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5000 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5002 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5003 (set_attr "mode" "<MODEF:MODE>")
5004 (set_attr "unit" "*,i387,*,*")
5005 (set_attr "athlon_decode" "*,*,double,direct")
5006 (set_attr "amdfam10_decode" "*,*,vector,double")
5007 (set_attr "fp_int_src" "true")])
5010 [(set (match_operand:MODEF 0 "register_operand" "")
5011 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5012 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5013 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5014 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5015 && TARGET_INTER_UNIT_CONVERSIONS
5017 && (SSE_REG_P (operands[0])
5018 || (GET_CODE (operands[0]) == SUBREG
5019 && SSE_REG_P (operands[0])))"
5020 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5024 [(set (match_operand:MODEF 0 "register_operand" "")
5025 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5026 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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)
5031 && (SSE_REG_P (operands[0])
5032 || (GET_CODE (operands[0]) == SUBREG
5033 && SSE_REG_P (operands[0])))"
5034 [(set (match_dup 2) (match_dup 1))
5035 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5038 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5039 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5041 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5042 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5043 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5044 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5047 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5048 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5049 [(set_attr "type" "fmov,sseicvt,sseicvt")
5050 (set_attr "mode" "<MODEF:MODE>")
5051 (set_attr "unit" "i387,*,*")
5052 (set_attr "athlon_decode" "*,double,direct")
5053 (set_attr "amdfam10_decode" "*,vector,double")
5054 (set_attr "fp_int_src" "true")])
5056 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5057 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5059 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5060 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5061 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5062 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5065 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5066 [(set_attr "type" "fmov,sseicvt")
5067 (set_attr "mode" "<MODEF:MODE>")
5068 (set_attr "athlon_decode" "*,direct")
5069 (set_attr "amdfam10_decode" "*,double")
5070 (set_attr "fp_int_src" "true")])
5072 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5073 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5075 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5076 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5077 "TARGET_SSE2 && TARGET_SSE_MATH
5078 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5080 [(set_attr "type" "sseicvt")
5081 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5082 (set_attr "athlon_decode" "double,direct,double")
5083 (set_attr "amdfam10_decode" "vector,double,double")
5084 (set_attr "fp_int_src" "true")])
5086 (define_insn "*floatsi<mode>2_vector_sse"
5087 [(set (match_operand:MODEF 0 "register_operand" "=x")
5088 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5089 "TARGET_SSE2 && TARGET_SSE_MATH
5090 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5092 [(set_attr "type" "sseicvt")
5093 (set_attr "mode" "<MODE>")
5094 (set_attr "athlon_decode" "direct")
5095 (set_attr "amdfam10_decode" "double")
5096 (set_attr "fp_int_src" "true")])
5099 [(set (match_operand:MODEF 0 "register_operand" "")
5100 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5101 (clobber (match_operand:SI 2 "memory_operand" ""))]
5102 "TARGET_SSE2 && TARGET_SSE_MATH
5103 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5105 && (SSE_REG_P (operands[0])
5106 || (GET_CODE (operands[0]) == SUBREG
5107 && SSE_REG_P (operands[0])))"
5110 rtx op1 = operands[1];
5112 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5114 if (GET_CODE (op1) == SUBREG)
5115 op1 = SUBREG_REG (op1);
5117 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5119 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5120 emit_insn (gen_sse2_loadld (operands[4],
5121 CONST0_RTX (V4SImode), operands[1]));
5123 /* We can ignore possible trapping value in the
5124 high part of SSE register for non-trapping math. */
5125 else if (SSE_REG_P (op1) && !flag_trapping_math)
5126 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5129 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5130 emit_move_insn (operands[2], operands[1]);
5131 emit_insn (gen_sse2_loadld (operands[4],
5132 CONST0_RTX (V4SImode), operands[2]));
5135 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5140 [(set (match_operand:MODEF 0 "register_operand" "")
5141 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5142 (clobber (match_operand:SI 2 "memory_operand" ""))]
5143 "TARGET_SSE2 && TARGET_SSE_MATH
5144 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5146 && (SSE_REG_P (operands[0])
5147 || (GET_CODE (operands[0]) == SUBREG
5148 && SSE_REG_P (operands[0])))"
5151 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5153 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5155 emit_insn (gen_sse2_loadld (operands[4],
5156 CONST0_RTX (V4SImode), operands[1]));
5158 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5163 [(set (match_operand:MODEF 0 "register_operand" "")
5164 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5165 "TARGET_SSE2 && TARGET_SSE_MATH
5166 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5168 && (SSE_REG_P (operands[0])
5169 || (GET_CODE (operands[0]) == SUBREG
5170 && SSE_REG_P (operands[0])))"
5173 rtx op1 = operands[1];
5175 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5177 if (GET_CODE (op1) == SUBREG)
5178 op1 = SUBREG_REG (op1);
5180 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5182 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5183 emit_insn (gen_sse2_loadld (operands[4],
5184 CONST0_RTX (V4SImode), operands[1]));
5186 /* We can ignore possible trapping value in the
5187 high part of SSE register for non-trapping math. */
5188 else if (SSE_REG_P (op1) && !flag_trapping_math)
5189 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5195 [(set (match_operand:MODEF 0 "register_operand" "")
5196 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5197 "TARGET_SSE2 && TARGET_SSE_MATH
5198 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5200 && (SSE_REG_P (operands[0])
5201 || (GET_CODE (operands[0]) == SUBREG
5202 && SSE_REG_P (operands[0])))"
5205 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5207 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5209 emit_insn (gen_sse2_loadld (operands[4],
5210 CONST0_RTX (V4SImode), operands[1]));
5212 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5216 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5217 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5219 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5220 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5221 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5222 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5224 [(set_attr "type" "sseicvt")
5225 (set_attr "mode" "<MODEF:MODE>")
5226 (set_attr "athlon_decode" "double,direct")
5227 (set_attr "amdfam10_decode" "vector,double")
5228 (set_attr "fp_int_src" "true")])
5230 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5231 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5233 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5234 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5235 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5236 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5237 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5238 [(set_attr "type" "sseicvt")
5239 (set_attr "mode" "<MODEF:MODE>")
5240 (set_attr "athlon_decode" "double,direct")
5241 (set_attr "amdfam10_decode" "vector,double")
5242 (set_attr "fp_int_src" "true")])
5245 [(set (match_operand:MODEF 0 "register_operand" "")
5246 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5247 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5248 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5249 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5250 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5252 && (SSE_REG_P (operands[0])
5253 || (GET_CODE (operands[0]) == SUBREG
5254 && SSE_REG_P (operands[0])))"
5255 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5258 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5259 [(set (match_operand:MODEF 0 "register_operand" "=x")
5261 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5262 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5263 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5264 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5265 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5266 [(set_attr "type" "sseicvt")
5267 (set_attr "mode" "<MODEF:MODE>")
5268 (set_attr "athlon_decode" "direct")
5269 (set_attr "amdfam10_decode" "double")
5270 (set_attr "fp_int_src" "true")])
5273 [(set (match_operand:MODEF 0 "register_operand" "")
5274 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5275 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5276 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5277 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5278 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5280 && (SSE_REG_P (operands[0])
5281 || (GET_CODE (operands[0]) == SUBREG
5282 && SSE_REG_P (operands[0])))"
5283 [(set (match_dup 2) (match_dup 1))
5284 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5288 [(set (match_operand:MODEF 0 "register_operand" "")
5289 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5290 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5291 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5292 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5294 && (SSE_REG_P (operands[0])
5295 || (GET_CODE (operands[0]) == SUBREG
5296 && SSE_REG_P (operands[0])))"
5297 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5300 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5301 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5303 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5304 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5309 [(set_attr "type" "fmov,multi")
5310 (set_attr "mode" "<X87MODEF:MODE>")
5311 (set_attr "unit" "*,i387")
5312 (set_attr "fp_int_src" "true")])
5314 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5315 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5317 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5320 [(set_attr "type" "fmov")
5321 (set_attr "mode" "<X87MODEF:MODE>")
5322 (set_attr "fp_int_src" "true")])
5325 [(set (match_operand:X87MODEF 0 "register_operand" "")
5326 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5327 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5330 && FP_REG_P (operands[0])"
5331 [(set (match_dup 2) (match_dup 1))
5332 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5336 [(set (match_operand:X87MODEF 0 "register_operand" "")
5337 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5338 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5341 && FP_REG_P (operands[0])"
5342 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5345 ;; Avoid store forwarding (partial memory) stall penalty
5346 ;; by passing DImode value through XMM registers. */
5348 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5349 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5351 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5352 (clobber (match_scratch:V4SI 3 "=X,x"))
5353 (clobber (match_scratch:V4SI 4 "=X,x"))
5354 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5355 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5356 && !TARGET_64BIT && !optimize_size"
5358 [(set_attr "type" "multi")
5359 (set_attr "mode" "<X87MODEF:MODE>")
5360 (set_attr "unit" "i387")
5361 (set_attr "fp_int_src" "true")])
5364 [(set (match_operand:X87MODEF 0 "register_operand" "")
5365 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5366 (clobber (match_scratch:V4SI 3 ""))
5367 (clobber (match_scratch:V4SI 4 ""))
5368 (clobber (match_operand:DI 2 "memory_operand" ""))]
5369 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5370 && !TARGET_64BIT && !optimize_size
5372 && FP_REG_P (operands[0])"
5373 [(set (match_dup 2) (match_dup 3))
5374 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5376 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5377 Assemble the 64-bit DImode value in an xmm register. */
5378 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5379 gen_rtx_SUBREG (SImode, operands[1], 0)));
5380 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5381 gen_rtx_SUBREG (SImode, operands[1], 4)));
5382 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5384 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5388 [(set (match_operand:X87MODEF 0 "register_operand" "")
5389 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5390 (clobber (match_scratch:V4SI 3 ""))
5391 (clobber (match_scratch:V4SI 4 ""))
5392 (clobber (match_operand:DI 2 "memory_operand" ""))]
5393 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5394 && !TARGET_64BIT && !optimize_size
5396 && FP_REG_P (operands[0])"
5397 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5400 ;; Avoid store forwarding (partial memory) stall penalty by extending
5401 ;; SImode value to DImode through XMM register instead of pushing two
5402 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5403 ;; targets benefit from this optimization. Also note that fild
5404 ;; loads from memory only.
5406 (define_insn "*floatunssi<mode>2_1"
5407 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5408 (unsigned_float:X87MODEF
5409 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5410 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5411 (clobber (match_scratch:SI 3 "=X,x"))]
5413 && TARGET_80387 && TARGET_SSE"
5415 [(set_attr "type" "multi")
5416 (set_attr "mode" "<MODE>")])
5419 [(set (match_operand:X87MODEF 0 "register_operand" "")
5420 (unsigned_float:X87MODEF
5421 (match_operand:SI 1 "register_operand" "")))
5422 (clobber (match_operand:DI 2 "memory_operand" ""))
5423 (clobber (match_scratch:SI 3 ""))]
5425 && TARGET_80387 && TARGET_SSE
5426 && reload_completed"
5427 [(set (match_dup 2) (match_dup 1))
5429 (float:X87MODEF (match_dup 2)))]
5430 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5433 [(set (match_operand:X87MODEF 0 "register_operand" "")
5434 (unsigned_float:X87MODEF
5435 (match_operand:SI 1 "memory_operand" "")))
5436 (clobber (match_operand:DI 2 "memory_operand" ""))
5437 (clobber (match_scratch:SI 3 ""))]
5439 && TARGET_80387 && TARGET_SSE
5440 && reload_completed"
5441 [(set (match_dup 2) (match_dup 3))
5443 (float:X87MODEF (match_dup 2)))]
5445 emit_move_insn (operands[3], operands[1]);
5446 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5449 (define_expand "floatunssi<mode>2"
5451 [(set (match_operand:X87MODEF 0 "register_operand" "")
5452 (unsigned_float:X87MODEF
5453 (match_operand:SI 1 "nonimmediate_operand" "")))
5454 (clobber (match_dup 2))
5455 (clobber (match_scratch:SI 3 ""))])]
5457 && ((TARGET_80387 && TARGET_SSE)
5458 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5460 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5462 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5467 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5468 operands[2] = assign_386_stack_local (DImode, slot);
5472 (define_expand "floatunsdisf2"
5473 [(use (match_operand:SF 0 "register_operand" ""))
5474 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5475 "TARGET_64BIT && TARGET_SSE_MATH"
5476 "x86_emit_floatuns (operands); DONE;")
5478 (define_expand "floatunsdidf2"
5479 [(use (match_operand:DF 0 "register_operand" ""))
5480 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5481 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5482 && TARGET_SSE2 && TARGET_SSE_MATH"
5485 x86_emit_floatuns (operands);
5487 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5493 ;; %%% splits for addditi3
5495 (define_expand "addti3"
5496 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5497 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5498 (match_operand:TI 2 "x86_64_general_operand" "")))
5499 (clobber (reg:CC FLAGS_REG))]
5501 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5503 (define_insn "*addti3_1"
5504 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5505 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5506 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5507 (clobber (reg:CC FLAGS_REG))]
5508 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5512 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5513 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5514 (match_operand:TI 2 "x86_64_general_operand" "")))
5515 (clobber (reg:CC FLAGS_REG))]
5516 "TARGET_64BIT && reload_completed"
5517 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5519 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5520 (parallel [(set (match_dup 3)
5521 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5524 (clobber (reg:CC FLAGS_REG))])]
5525 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5527 ;; %%% splits for addsidi3
5528 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5529 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5530 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5532 (define_expand "adddi3"
5533 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5534 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5535 (match_operand:DI 2 "x86_64_general_operand" "")))
5536 (clobber (reg:CC FLAGS_REG))]
5538 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5540 (define_insn "*adddi3_1"
5541 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5542 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5543 (match_operand:DI 2 "general_operand" "roiF,riF")))
5544 (clobber (reg:CC FLAGS_REG))]
5545 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5549 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5550 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5551 (match_operand:DI 2 "general_operand" "")))
5552 (clobber (reg:CC FLAGS_REG))]
5553 "!TARGET_64BIT && reload_completed"
5554 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5556 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5557 (parallel [(set (match_dup 3)
5558 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5561 (clobber (reg:CC FLAGS_REG))])]
5562 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5564 (define_insn "adddi3_carry_rex64"
5565 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5566 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5567 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5568 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5569 (clobber (reg:CC FLAGS_REG))]
5570 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5571 "adc{q}\t{%2, %0|%0, %2}"
5572 [(set_attr "type" "alu")
5573 (set_attr "pent_pair" "pu")
5574 (set_attr "mode" "DI")])
5576 (define_insn "*adddi3_cc_rex64"
5577 [(set (reg:CC FLAGS_REG)
5578 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5579 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5581 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5582 (plus:DI (match_dup 1) (match_dup 2)))]
5583 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5584 "add{q}\t{%2, %0|%0, %2}"
5585 [(set_attr "type" "alu")
5586 (set_attr "mode" "DI")])
5588 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5589 [(set (reg:CCC FLAGS_REG)
5592 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5593 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5595 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5596 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5597 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5598 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5599 [(set_attr "type" "alu")
5600 (set_attr "mode" "<MODE>")])
5602 (define_insn "*add<mode>3_cconly_overflow"
5603 [(set (reg:CCC FLAGS_REG)
5605 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5606 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5608 (clobber (match_scratch:SWI 0 "=<r>"))]
5609 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5610 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5611 [(set_attr "type" "alu")
5612 (set_attr "mode" "<MODE>")])
5614 (define_insn "*sub<mode>3_cconly_overflow"
5615 [(set (reg:CCC FLAGS_REG)
5617 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5618 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5621 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5622 [(set_attr "type" "icmp")
5623 (set_attr "mode" "<MODE>")])
5625 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5626 [(set (reg:CCC FLAGS_REG)
5628 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5629 (match_operand:SI 2 "general_operand" "g"))
5631 (set (match_operand:DI 0 "register_operand" "=r")
5632 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5633 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5634 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5635 [(set_attr "type" "alu")
5636 (set_attr "mode" "SI")])
5638 (define_insn "addqi3_carry"
5639 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5640 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5641 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5642 (match_operand:QI 2 "general_operand" "qi,qm")))
5643 (clobber (reg:CC FLAGS_REG))]
5644 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5645 "adc{b}\t{%2, %0|%0, %2}"
5646 [(set_attr "type" "alu")
5647 (set_attr "pent_pair" "pu")
5648 (set_attr "mode" "QI")])
5650 (define_insn "addhi3_carry"
5651 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5652 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5653 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5654 (match_operand:HI 2 "general_operand" "ri,rm")))
5655 (clobber (reg:CC FLAGS_REG))]
5656 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5657 "adc{w}\t{%2, %0|%0, %2}"
5658 [(set_attr "type" "alu")
5659 (set_attr "pent_pair" "pu")
5660 (set_attr "mode" "HI")])
5662 (define_insn "addsi3_carry"
5663 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5664 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5665 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5666 (match_operand:SI 2 "general_operand" "ri,rm")))
5667 (clobber (reg:CC FLAGS_REG))]
5668 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5669 "adc{l}\t{%2, %0|%0, %2}"
5670 [(set_attr "type" "alu")
5671 (set_attr "pent_pair" "pu")
5672 (set_attr "mode" "SI")])
5674 (define_insn "*addsi3_carry_zext"
5675 [(set (match_operand:DI 0 "register_operand" "=r")
5677 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5678 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5679 (match_operand:SI 2 "general_operand" "g"))))
5680 (clobber (reg:CC FLAGS_REG))]
5681 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5682 "adc{l}\t{%2, %k0|%k0, %2}"
5683 [(set_attr "type" "alu")
5684 (set_attr "pent_pair" "pu")
5685 (set_attr "mode" "SI")])
5687 (define_insn "*addsi3_cc"
5688 [(set (reg:CC FLAGS_REG)
5689 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5690 (match_operand:SI 2 "general_operand" "ri,rm")]
5692 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5693 (plus:SI (match_dup 1) (match_dup 2)))]
5694 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5695 "add{l}\t{%2, %0|%0, %2}"
5696 [(set_attr "type" "alu")
5697 (set_attr "mode" "SI")])
5699 (define_insn "addqi3_cc"
5700 [(set (reg:CC FLAGS_REG)
5701 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5702 (match_operand:QI 2 "general_operand" "qi,qm")]
5704 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5705 (plus:QI (match_dup 1) (match_dup 2)))]
5706 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5707 "add{b}\t{%2, %0|%0, %2}"
5708 [(set_attr "type" "alu")
5709 (set_attr "mode" "QI")])
5711 (define_expand "addsi3"
5712 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5713 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5714 (match_operand:SI 2 "general_operand" "")))
5715 (clobber (reg:CC FLAGS_REG))])]
5717 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5719 (define_insn "*lea_1"
5720 [(set (match_operand:SI 0 "register_operand" "=r")
5721 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5723 "lea{l}\t{%a1, %0|%0, %a1}"
5724 [(set_attr "type" "lea")
5725 (set_attr "mode" "SI")])
5727 (define_insn "*lea_1_rex64"
5728 [(set (match_operand:SI 0 "register_operand" "=r")
5729 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5731 "lea{l}\t{%a1, %0|%0, %a1}"
5732 [(set_attr "type" "lea")
5733 (set_attr "mode" "SI")])
5735 (define_insn "*lea_1_zext"
5736 [(set (match_operand:DI 0 "register_operand" "=r")
5738 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5740 "lea{l}\t{%a1, %k0|%k0, %a1}"
5741 [(set_attr "type" "lea")
5742 (set_attr "mode" "SI")])
5744 (define_insn "*lea_2_rex64"
5745 [(set (match_operand:DI 0 "register_operand" "=r")
5746 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5748 "lea{q}\t{%a1, %0|%0, %a1}"
5749 [(set_attr "type" "lea")
5750 (set_attr "mode" "DI")])
5752 ;; The lea patterns for non-Pmodes needs to be matched by several
5753 ;; insns converted to real lea by splitters.
5755 (define_insn_and_split "*lea_general_1"
5756 [(set (match_operand 0 "register_operand" "=r")
5757 (plus (plus (match_operand 1 "index_register_operand" "l")
5758 (match_operand 2 "register_operand" "r"))
5759 (match_operand 3 "immediate_operand" "i")))]
5760 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5761 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5762 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5763 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5764 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5765 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5766 || GET_MODE (operands[3]) == VOIDmode)"
5768 "&& reload_completed"
5772 operands[0] = gen_lowpart (SImode, operands[0]);
5773 operands[1] = gen_lowpart (Pmode, operands[1]);
5774 operands[2] = gen_lowpart (Pmode, operands[2]);
5775 operands[3] = gen_lowpart (Pmode, operands[3]);
5776 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5778 if (Pmode != SImode)
5779 pat = gen_rtx_SUBREG (SImode, pat, 0);
5780 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5783 [(set_attr "type" "lea")
5784 (set_attr "mode" "SI")])
5786 (define_insn_and_split "*lea_general_1_zext"
5787 [(set (match_operand:DI 0 "register_operand" "=r")
5789 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5790 (match_operand:SI 2 "register_operand" "r"))
5791 (match_operand:SI 3 "immediate_operand" "i"))))]
5794 "&& reload_completed"
5796 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5798 (match_dup 3)) 0)))]
5800 operands[1] = gen_lowpart (Pmode, operands[1]);
5801 operands[2] = gen_lowpart (Pmode, operands[2]);
5802 operands[3] = gen_lowpart (Pmode, operands[3]);
5804 [(set_attr "type" "lea")
5805 (set_attr "mode" "SI")])
5807 (define_insn_and_split "*lea_general_2"
5808 [(set (match_operand 0 "register_operand" "=r")
5809 (plus (mult (match_operand 1 "index_register_operand" "l")
5810 (match_operand 2 "const248_operand" "i"))
5811 (match_operand 3 "nonmemory_operand" "ri")))]
5812 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5813 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5814 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5815 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5816 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5817 || GET_MODE (operands[3]) == VOIDmode)"
5819 "&& reload_completed"
5823 operands[0] = gen_lowpart (SImode, operands[0]);
5824 operands[1] = gen_lowpart (Pmode, operands[1]);
5825 operands[3] = gen_lowpart (Pmode, operands[3]);
5826 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5828 if (Pmode != SImode)
5829 pat = gen_rtx_SUBREG (SImode, pat, 0);
5830 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5833 [(set_attr "type" "lea")
5834 (set_attr "mode" "SI")])
5836 (define_insn_and_split "*lea_general_2_zext"
5837 [(set (match_operand:DI 0 "register_operand" "=r")
5839 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5840 (match_operand:SI 2 "const248_operand" "n"))
5841 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5844 "&& reload_completed"
5846 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5848 (match_dup 3)) 0)))]
5850 operands[1] = gen_lowpart (Pmode, operands[1]);
5851 operands[3] = gen_lowpart (Pmode, operands[3]);
5853 [(set_attr "type" "lea")
5854 (set_attr "mode" "SI")])
5856 (define_insn_and_split "*lea_general_3"
5857 [(set (match_operand 0 "register_operand" "=r")
5858 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5859 (match_operand 2 "const248_operand" "i"))
5860 (match_operand 3 "register_operand" "r"))
5861 (match_operand 4 "immediate_operand" "i")))]
5862 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5863 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5864 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5865 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5866 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5868 "&& reload_completed"
5872 operands[0] = gen_lowpart (SImode, operands[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]);
5876 pat = gen_rtx_PLUS (Pmode,
5877 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5881 if (Pmode != SImode)
5882 pat = gen_rtx_SUBREG (SImode, pat, 0);
5883 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5886 [(set_attr "type" "lea")
5887 (set_attr "mode" "SI")])
5889 (define_insn_and_split "*lea_general_3_zext"
5890 [(set (match_operand:DI 0 "register_operand" "=r")
5892 (plus:SI (plus:SI (mult:SI
5893 (match_operand:SI 1 "index_register_operand" "l")
5894 (match_operand:SI 2 "const248_operand" "n"))
5895 (match_operand:SI 3 "register_operand" "r"))
5896 (match_operand:SI 4 "immediate_operand" "i"))))]
5899 "&& reload_completed"
5901 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5904 (match_dup 4)) 0)))]
5906 operands[1] = gen_lowpart (Pmode, operands[1]);
5907 operands[3] = gen_lowpart (Pmode, operands[3]);
5908 operands[4] = gen_lowpart (Pmode, operands[4]);
5910 [(set_attr "type" "lea")
5911 (set_attr "mode" "SI")])
5913 (define_insn "*adddi_1_rex64"
5914 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5915 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5916 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5917 (clobber (reg:CC FLAGS_REG))]
5918 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5920 switch (get_attr_type (insn))
5923 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5924 return "lea{q}\t{%a2, %0|%0, %a2}";
5927 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5928 if (operands[2] == const1_rtx)
5929 return "inc{q}\t%0";
5932 gcc_assert (operands[2] == constm1_rtx);
5933 return "dec{q}\t%0";
5937 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5939 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5940 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5941 if (CONST_INT_P (operands[2])
5942 /* Avoid overflows. */
5943 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5944 && (INTVAL (operands[2]) == 128
5945 || (INTVAL (operands[2]) < 0
5946 && INTVAL (operands[2]) != -128)))
5948 operands[2] = GEN_INT (-INTVAL (operands[2]));
5949 return "sub{q}\t{%2, %0|%0, %2}";
5951 return "add{q}\t{%2, %0|%0, %2}";
5955 (cond [(eq_attr "alternative" "2")
5956 (const_string "lea")
5957 ; Current assemblers are broken and do not allow @GOTOFF in
5958 ; ought but a memory context.
5959 (match_operand:DI 2 "pic_symbolic_operand" "")
5960 (const_string "lea")
5961 (match_operand:DI 2 "incdec_operand" "")
5962 (const_string "incdec")
5964 (const_string "alu")))
5965 (set_attr "mode" "DI")])
5967 ;; Convert lea to the lea pattern to avoid flags dependency.
5969 [(set (match_operand:DI 0 "register_operand" "")
5970 (plus:DI (match_operand:DI 1 "register_operand" "")
5971 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5972 (clobber (reg:CC FLAGS_REG))]
5973 "TARGET_64BIT && reload_completed
5974 && true_regnum (operands[0]) != true_regnum (operands[1])"
5976 (plus:DI (match_dup 1)
5980 (define_insn "*adddi_2_rex64"
5981 [(set (reg FLAGS_REG)
5983 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5984 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5986 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5987 (plus:DI (match_dup 1) (match_dup 2)))]
5988 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5989 && ix86_binary_operator_ok (PLUS, DImode, operands)
5990 /* Current assemblers are broken and do not allow @GOTOFF in
5991 ought but a memory context. */
5992 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5994 switch (get_attr_type (insn))
5997 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5998 if (operands[2] == const1_rtx)
5999 return "inc{q}\t%0";
6002 gcc_assert (operands[2] == constm1_rtx);
6003 return "dec{q}\t%0";
6007 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6008 /* ???? We ought to handle there the 32bit case too
6009 - do we need new constraint? */
6010 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6012 if (CONST_INT_P (operands[2])
6013 /* Avoid overflows. */
6014 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6015 && (INTVAL (operands[2]) == 128
6016 || (INTVAL (operands[2]) < 0
6017 && INTVAL (operands[2]) != -128)))
6019 operands[2] = GEN_INT (-INTVAL (operands[2]));
6020 return "sub{q}\t{%2, %0|%0, %2}";
6022 return "add{q}\t{%2, %0|%0, %2}";
6026 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6027 (const_string "incdec")
6028 (const_string "alu")))
6029 (set_attr "mode" "DI")])
6031 (define_insn "*adddi_3_rex64"
6032 [(set (reg FLAGS_REG)
6033 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6034 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6035 (clobber (match_scratch:DI 0 "=r"))]
6037 && ix86_match_ccmode (insn, CCZmode)
6038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6039 /* Current assemblers are broken and do not allow @GOTOFF in
6040 ought but a memory context. */
6041 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6043 switch (get_attr_type (insn))
6046 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6047 if (operands[2] == const1_rtx)
6048 return "inc{q}\t%0";
6051 gcc_assert (operands[2] == constm1_rtx);
6052 return "dec{q}\t%0";
6056 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6057 /* ???? We ought to handle there the 32bit case too
6058 - do we need new constraint? */
6059 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6060 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6061 if (CONST_INT_P (operands[2])
6062 /* Avoid overflows. */
6063 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6064 && (INTVAL (operands[2]) == 128
6065 || (INTVAL (operands[2]) < 0
6066 && INTVAL (operands[2]) != -128)))
6068 operands[2] = GEN_INT (-INTVAL (operands[2]));
6069 return "sub{q}\t{%2, %0|%0, %2}";
6071 return "add{q}\t{%2, %0|%0, %2}";
6075 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6076 (const_string "incdec")
6077 (const_string "alu")))
6078 (set_attr "mode" "DI")])
6080 ; For comparisons against 1, -1 and 128, we may generate better code
6081 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6082 ; is matched then. We can't accept general immediate, because for
6083 ; case of overflows, the result is messed up.
6084 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6086 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6087 ; only for comparisons not depending on it.
6088 (define_insn "*adddi_4_rex64"
6089 [(set (reg FLAGS_REG)
6090 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6091 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6092 (clobber (match_scratch:DI 0 "=rm"))]
6094 && ix86_match_ccmode (insn, CCGCmode)"
6096 switch (get_attr_type (insn))
6099 if (operands[2] == constm1_rtx)
6100 return "inc{q}\t%0";
6103 gcc_assert (operands[2] == const1_rtx);
6104 return "dec{q}\t%0";
6108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6109 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6110 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6111 if ((INTVAL (operands[2]) == -128
6112 || (INTVAL (operands[2]) > 0
6113 && INTVAL (operands[2]) != 128))
6114 /* Avoid overflows. */
6115 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6116 return "sub{q}\t{%2, %0|%0, %2}";
6117 operands[2] = GEN_INT (-INTVAL (operands[2]));
6118 return "add{q}\t{%2, %0|%0, %2}";
6122 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6123 (const_string "incdec")
6124 (const_string "alu")))
6125 (set_attr "mode" "DI")])
6127 (define_insn "*adddi_5_rex64"
6128 [(set (reg FLAGS_REG)
6130 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6131 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6133 (clobber (match_scratch:DI 0 "=r"))]
6135 && ix86_match_ccmode (insn, CCGOCmode)
6136 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6137 /* Current assemblers are broken and do not allow @GOTOFF in
6138 ought but a memory context. */
6139 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6141 switch (get_attr_type (insn))
6144 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6145 if (operands[2] == const1_rtx)
6146 return "inc{q}\t%0";
6149 gcc_assert (operands[2] == constm1_rtx);
6150 return "dec{q}\t%0";
6154 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6155 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6156 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6157 if (CONST_INT_P (operands[2])
6158 /* Avoid overflows. */
6159 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6160 && (INTVAL (operands[2]) == 128
6161 || (INTVAL (operands[2]) < 0
6162 && INTVAL (operands[2]) != -128)))
6164 operands[2] = GEN_INT (-INTVAL (operands[2]));
6165 return "sub{q}\t{%2, %0|%0, %2}";
6167 return "add{q}\t{%2, %0|%0, %2}";
6171 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6172 (const_string "incdec")
6173 (const_string "alu")))
6174 (set_attr "mode" "DI")])
6177 (define_insn "*addsi_1"
6178 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6179 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6180 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6181 (clobber (reg:CC FLAGS_REG))]
6182 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6184 switch (get_attr_type (insn))
6187 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6188 return "lea{l}\t{%a2, %0|%0, %a2}";
6191 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6192 if (operands[2] == const1_rtx)
6193 return "inc{l}\t%0";
6196 gcc_assert (operands[2] == constm1_rtx);
6197 return "dec{l}\t%0";
6201 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6203 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6204 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6205 if (CONST_INT_P (operands[2])
6206 && (INTVAL (operands[2]) == 128
6207 || (INTVAL (operands[2]) < 0
6208 && INTVAL (operands[2]) != -128)))
6210 operands[2] = GEN_INT (-INTVAL (operands[2]));
6211 return "sub{l}\t{%2, %0|%0, %2}";
6213 return "add{l}\t{%2, %0|%0, %2}";
6217 (cond [(eq_attr "alternative" "2")
6218 (const_string "lea")
6219 ; Current assemblers are broken and do not allow @GOTOFF in
6220 ; ought but a memory context.
6221 (match_operand:SI 2 "pic_symbolic_operand" "")
6222 (const_string "lea")
6223 (match_operand:SI 2 "incdec_operand" "")
6224 (const_string "incdec")
6226 (const_string "alu")))
6227 (set_attr "mode" "SI")])
6229 ;; Convert lea to the lea pattern to avoid flags dependency.
6231 [(set (match_operand 0 "register_operand" "")
6232 (plus (match_operand 1 "register_operand" "")
6233 (match_operand 2 "nonmemory_operand" "")))
6234 (clobber (reg:CC FLAGS_REG))]
6236 && true_regnum (operands[0]) != true_regnum (operands[1])"
6240 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6241 may confuse gen_lowpart. */
6242 if (GET_MODE (operands[0]) != Pmode)
6244 operands[1] = gen_lowpart (Pmode, operands[1]);
6245 operands[2] = gen_lowpart (Pmode, operands[2]);
6247 operands[0] = gen_lowpart (SImode, operands[0]);
6248 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6249 if (Pmode != SImode)
6250 pat = gen_rtx_SUBREG (SImode, pat, 0);
6251 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6255 ;; It may seem that nonimmediate operand is proper one for operand 1.
6256 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6257 ;; we take care in ix86_binary_operator_ok to not allow two memory
6258 ;; operands so proper swapping will be done in reload. This allow
6259 ;; patterns constructed from addsi_1 to match.
6260 (define_insn "addsi_1_zext"
6261 [(set (match_operand:DI 0 "register_operand" "=r,r")
6263 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6264 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6265 (clobber (reg:CC FLAGS_REG))]
6266 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6268 switch (get_attr_type (insn))
6271 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6272 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6275 if (operands[2] == const1_rtx)
6276 return "inc{l}\t%k0";
6279 gcc_assert (operands[2] == constm1_rtx);
6280 return "dec{l}\t%k0";
6284 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6285 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6286 if (CONST_INT_P (operands[2])
6287 && (INTVAL (operands[2]) == 128
6288 || (INTVAL (operands[2]) < 0
6289 && INTVAL (operands[2]) != -128)))
6291 operands[2] = GEN_INT (-INTVAL (operands[2]));
6292 return "sub{l}\t{%2, %k0|%k0, %2}";
6294 return "add{l}\t{%2, %k0|%k0, %2}";
6298 (cond [(eq_attr "alternative" "1")
6299 (const_string "lea")
6300 ; Current assemblers are broken and do not allow @GOTOFF in
6301 ; ought but a memory context.
6302 (match_operand:SI 2 "pic_symbolic_operand" "")
6303 (const_string "lea")
6304 (match_operand:SI 2 "incdec_operand" "")
6305 (const_string "incdec")
6307 (const_string "alu")))
6308 (set_attr "mode" "SI")])
6310 ;; Convert lea to the lea pattern to avoid flags dependency.
6312 [(set (match_operand:DI 0 "register_operand" "")
6314 (plus:SI (match_operand:SI 1 "register_operand" "")
6315 (match_operand:SI 2 "nonmemory_operand" ""))))
6316 (clobber (reg:CC FLAGS_REG))]
6317 "TARGET_64BIT && reload_completed
6318 && true_regnum (operands[0]) != true_regnum (operands[1])"
6320 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6322 operands[1] = gen_lowpart (Pmode, operands[1]);
6323 operands[2] = gen_lowpart (Pmode, operands[2]);
6326 (define_insn "*addsi_2"
6327 [(set (reg FLAGS_REG)
6329 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6330 (match_operand:SI 2 "general_operand" "rmni,rni"))
6332 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6333 (plus:SI (match_dup 1) (match_dup 2)))]
6334 "ix86_match_ccmode (insn, CCGOCmode)
6335 && ix86_binary_operator_ok (PLUS, SImode, operands)
6336 /* Current assemblers are broken and do not allow @GOTOFF in
6337 ought but a memory context. */
6338 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6340 switch (get_attr_type (insn))
6343 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6344 if (operands[2] == const1_rtx)
6345 return "inc{l}\t%0";
6348 gcc_assert (operands[2] == constm1_rtx);
6349 return "dec{l}\t%0";
6353 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6354 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6355 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6356 if (CONST_INT_P (operands[2])
6357 && (INTVAL (operands[2]) == 128
6358 || (INTVAL (operands[2]) < 0
6359 && INTVAL (operands[2]) != -128)))
6361 operands[2] = GEN_INT (-INTVAL (operands[2]));
6362 return "sub{l}\t{%2, %0|%0, %2}";
6364 return "add{l}\t{%2, %0|%0, %2}";
6368 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6369 (const_string "incdec")
6370 (const_string "alu")))
6371 (set_attr "mode" "SI")])
6373 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6374 (define_insn "*addsi_2_zext"
6375 [(set (reg FLAGS_REG)
6377 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6378 (match_operand:SI 2 "general_operand" "rmni"))
6380 (set (match_operand:DI 0 "register_operand" "=r")
6381 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6382 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6383 && ix86_binary_operator_ok (PLUS, SImode, operands)
6384 /* Current assemblers are broken and do not allow @GOTOFF in
6385 ought but a memory context. */
6386 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6388 switch (get_attr_type (insn))
6391 if (operands[2] == const1_rtx)
6392 return "inc{l}\t%k0";
6395 gcc_assert (operands[2] == constm1_rtx);
6396 return "dec{l}\t%k0";
6400 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6401 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6402 if (CONST_INT_P (operands[2])
6403 && (INTVAL (operands[2]) == 128
6404 || (INTVAL (operands[2]) < 0
6405 && INTVAL (operands[2]) != -128)))
6407 operands[2] = GEN_INT (-INTVAL (operands[2]));
6408 return "sub{l}\t{%2, %k0|%k0, %2}";
6410 return "add{l}\t{%2, %k0|%k0, %2}";
6414 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6415 (const_string "incdec")
6416 (const_string "alu")))
6417 (set_attr "mode" "SI")])
6419 (define_insn "*addsi_3"
6420 [(set (reg FLAGS_REG)
6421 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6422 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6423 (clobber (match_scratch:SI 0 "=r"))]
6424 "ix86_match_ccmode (insn, CCZmode)
6425 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6426 /* Current assemblers are broken and do not allow @GOTOFF in
6427 ought but a memory context. */
6428 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6430 switch (get_attr_type (insn))
6433 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6434 if (operands[2] == const1_rtx)
6435 return "inc{l}\t%0";
6438 gcc_assert (operands[2] == constm1_rtx);
6439 return "dec{l}\t%0";
6443 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6444 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6445 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6446 if (CONST_INT_P (operands[2])
6447 && (INTVAL (operands[2]) == 128
6448 || (INTVAL (operands[2]) < 0
6449 && INTVAL (operands[2]) != -128)))
6451 operands[2] = GEN_INT (-INTVAL (operands[2]));
6452 return "sub{l}\t{%2, %0|%0, %2}";
6454 return "add{l}\t{%2, %0|%0, %2}";
6458 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6459 (const_string "incdec")
6460 (const_string "alu")))
6461 (set_attr "mode" "SI")])
6463 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6464 (define_insn "*addsi_3_zext"
6465 [(set (reg FLAGS_REG)
6466 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6467 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6468 (set (match_operand:DI 0 "register_operand" "=r")
6469 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6470 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6471 && ix86_binary_operator_ok (PLUS, SImode, operands)
6472 /* Current assemblers are broken and do not allow @GOTOFF in
6473 ought but a memory context. */
6474 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6476 switch (get_attr_type (insn))
6479 if (operands[2] == const1_rtx)
6480 return "inc{l}\t%k0";
6483 gcc_assert (operands[2] == constm1_rtx);
6484 return "dec{l}\t%k0";
6488 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6490 if (CONST_INT_P (operands[2])
6491 && (INTVAL (operands[2]) == 128
6492 || (INTVAL (operands[2]) < 0
6493 && INTVAL (operands[2]) != -128)))
6495 operands[2] = GEN_INT (-INTVAL (operands[2]));
6496 return "sub{l}\t{%2, %k0|%k0, %2}";
6498 return "add{l}\t{%2, %k0|%k0, %2}";
6502 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6503 (const_string "incdec")
6504 (const_string "alu")))
6505 (set_attr "mode" "SI")])
6507 ; For comparisons against 1, -1 and 128, we may generate better code
6508 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6509 ; is matched then. We can't accept general immediate, because for
6510 ; case of overflows, the result is messed up.
6511 ; This pattern also don't hold of 0x80000000, since the value overflows
6513 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6514 ; only for comparisons not depending on it.
6515 (define_insn "*addsi_4"
6516 [(set (reg FLAGS_REG)
6517 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6518 (match_operand:SI 2 "const_int_operand" "n")))
6519 (clobber (match_scratch:SI 0 "=rm"))]
6520 "ix86_match_ccmode (insn, CCGCmode)
6521 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6523 switch (get_attr_type (insn))
6526 if (operands[2] == constm1_rtx)
6527 return "inc{l}\t%0";
6530 gcc_assert (operands[2] == const1_rtx);
6531 return "dec{l}\t%0";
6535 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6536 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6537 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6538 if ((INTVAL (operands[2]) == -128
6539 || (INTVAL (operands[2]) > 0
6540 && INTVAL (operands[2]) != 128)))
6541 return "sub{l}\t{%2, %0|%0, %2}";
6542 operands[2] = GEN_INT (-INTVAL (operands[2]));
6543 return "add{l}\t{%2, %0|%0, %2}";
6547 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6548 (const_string "incdec")
6549 (const_string "alu")))
6550 (set_attr "mode" "SI")])
6552 (define_insn "*addsi_5"
6553 [(set (reg FLAGS_REG)
6555 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6556 (match_operand:SI 2 "general_operand" "rmni"))
6558 (clobber (match_scratch:SI 0 "=r"))]
6559 "ix86_match_ccmode (insn, CCGOCmode)
6560 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6561 /* Current assemblers are broken and do not allow @GOTOFF in
6562 ought but a memory context. */
6563 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6565 switch (get_attr_type (insn))
6568 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6569 if (operands[2] == const1_rtx)
6570 return "inc{l}\t%0";
6573 gcc_assert (operands[2] == constm1_rtx);
6574 return "dec{l}\t%0";
6578 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6579 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6580 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6581 if (CONST_INT_P (operands[2])
6582 && (INTVAL (operands[2]) == 128
6583 || (INTVAL (operands[2]) < 0
6584 && INTVAL (operands[2]) != -128)))
6586 operands[2] = GEN_INT (-INTVAL (operands[2]));
6587 return "sub{l}\t{%2, %0|%0, %2}";
6589 return "add{l}\t{%2, %0|%0, %2}";
6593 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6594 (const_string "incdec")
6595 (const_string "alu")))
6596 (set_attr "mode" "SI")])
6598 (define_expand "addhi3"
6599 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6600 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6601 (match_operand:HI 2 "general_operand" "")))
6602 (clobber (reg:CC FLAGS_REG))])]
6603 "TARGET_HIMODE_MATH"
6604 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6606 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6607 ;; type optimizations enabled by define-splits. This is not important
6608 ;; for PII, and in fact harmful because of partial register stalls.
6610 (define_insn "*addhi_1_lea"
6611 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6612 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6613 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "!TARGET_PARTIAL_REG_STALL
6616 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6618 switch (get_attr_type (insn))
6623 if (operands[2] == const1_rtx)
6624 return "inc{w}\t%0";
6627 gcc_assert (operands[2] == constm1_rtx);
6628 return "dec{w}\t%0";
6632 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6633 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6634 if (CONST_INT_P (operands[2])
6635 && (INTVAL (operands[2]) == 128
6636 || (INTVAL (operands[2]) < 0
6637 && INTVAL (operands[2]) != -128)))
6639 operands[2] = GEN_INT (-INTVAL (operands[2]));
6640 return "sub{w}\t{%2, %0|%0, %2}";
6642 return "add{w}\t{%2, %0|%0, %2}";
6646 (if_then_else (eq_attr "alternative" "2")
6647 (const_string "lea")
6648 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6649 (const_string "incdec")
6650 (const_string "alu"))))
6651 (set_attr "mode" "HI,HI,SI")])
6653 (define_insn "*addhi_1"
6654 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6655 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6656 (match_operand:HI 2 "general_operand" "ri,rm")))
6657 (clobber (reg:CC FLAGS_REG))]
6658 "TARGET_PARTIAL_REG_STALL
6659 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6661 switch (get_attr_type (insn))
6664 if (operands[2] == const1_rtx)
6665 return "inc{w}\t%0";
6668 gcc_assert (operands[2] == constm1_rtx);
6669 return "dec{w}\t%0";
6673 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6674 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6675 if (CONST_INT_P (operands[2])
6676 && (INTVAL (operands[2]) == 128
6677 || (INTVAL (operands[2]) < 0
6678 && INTVAL (operands[2]) != -128)))
6680 operands[2] = GEN_INT (-INTVAL (operands[2]));
6681 return "sub{w}\t{%2, %0|%0, %2}";
6683 return "add{w}\t{%2, %0|%0, %2}";
6687 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6688 (const_string "incdec")
6689 (const_string "alu")))
6690 (set_attr "mode" "HI")])
6692 (define_insn "*addhi_2"
6693 [(set (reg FLAGS_REG)
6695 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6696 (match_operand:HI 2 "general_operand" "rmni,rni"))
6698 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6699 (plus:HI (match_dup 1) (match_dup 2)))]
6700 "ix86_match_ccmode (insn, CCGOCmode)
6701 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6703 switch (get_attr_type (insn))
6706 if (operands[2] == const1_rtx)
6707 return "inc{w}\t%0";
6710 gcc_assert (operands[2] == constm1_rtx);
6711 return "dec{w}\t%0";
6715 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6716 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6717 if (CONST_INT_P (operands[2])
6718 && (INTVAL (operands[2]) == 128
6719 || (INTVAL (operands[2]) < 0
6720 && INTVAL (operands[2]) != -128)))
6722 operands[2] = GEN_INT (-INTVAL (operands[2]));
6723 return "sub{w}\t{%2, %0|%0, %2}";
6725 return "add{w}\t{%2, %0|%0, %2}";
6729 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6730 (const_string "incdec")
6731 (const_string "alu")))
6732 (set_attr "mode" "HI")])
6734 (define_insn "*addhi_3"
6735 [(set (reg FLAGS_REG)
6736 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6737 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6738 (clobber (match_scratch:HI 0 "=r"))]
6739 "ix86_match_ccmode (insn, CCZmode)
6740 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6742 switch (get_attr_type (insn))
6745 if (operands[2] == const1_rtx)
6746 return "inc{w}\t%0";
6749 gcc_assert (operands[2] == constm1_rtx);
6750 return "dec{w}\t%0";
6754 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6755 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6756 if (CONST_INT_P (operands[2])
6757 && (INTVAL (operands[2]) == 128
6758 || (INTVAL (operands[2]) < 0
6759 && INTVAL (operands[2]) != -128)))
6761 operands[2] = GEN_INT (-INTVAL (operands[2]));
6762 return "sub{w}\t{%2, %0|%0, %2}";
6764 return "add{w}\t{%2, %0|%0, %2}";
6768 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6769 (const_string "incdec")
6770 (const_string "alu")))
6771 (set_attr "mode" "HI")])
6773 ; See comments above addsi_4 for details.
6774 (define_insn "*addhi_4"
6775 [(set (reg FLAGS_REG)
6776 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6777 (match_operand:HI 2 "const_int_operand" "n")))
6778 (clobber (match_scratch:HI 0 "=rm"))]
6779 "ix86_match_ccmode (insn, CCGCmode)
6780 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6782 switch (get_attr_type (insn))
6785 if (operands[2] == constm1_rtx)
6786 return "inc{w}\t%0";
6789 gcc_assert (operands[2] == const1_rtx);
6790 return "dec{w}\t%0";
6794 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6795 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6796 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6797 if ((INTVAL (operands[2]) == -128
6798 || (INTVAL (operands[2]) > 0
6799 && INTVAL (operands[2]) != 128)))
6800 return "sub{w}\t{%2, %0|%0, %2}";
6801 operands[2] = GEN_INT (-INTVAL (operands[2]));
6802 return "add{w}\t{%2, %0|%0, %2}";
6806 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6807 (const_string "incdec")
6808 (const_string "alu")))
6809 (set_attr "mode" "SI")])
6812 (define_insn "*addhi_5"
6813 [(set (reg FLAGS_REG)
6815 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6816 (match_operand:HI 2 "general_operand" "rmni"))
6818 (clobber (match_scratch:HI 0 "=r"))]
6819 "ix86_match_ccmode (insn, CCGOCmode)
6820 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6822 switch (get_attr_type (insn))
6825 if (operands[2] == const1_rtx)
6826 return "inc{w}\t%0";
6829 gcc_assert (operands[2] == constm1_rtx);
6830 return "dec{w}\t%0";
6834 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6835 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6836 if (CONST_INT_P (operands[2])
6837 && (INTVAL (operands[2]) == 128
6838 || (INTVAL (operands[2]) < 0
6839 && INTVAL (operands[2]) != -128)))
6841 operands[2] = GEN_INT (-INTVAL (operands[2]));
6842 return "sub{w}\t{%2, %0|%0, %2}";
6844 return "add{w}\t{%2, %0|%0, %2}";
6848 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6849 (const_string "incdec")
6850 (const_string "alu")))
6851 (set_attr "mode" "HI")])
6853 (define_expand "addqi3"
6854 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6855 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6856 (match_operand:QI 2 "general_operand" "")))
6857 (clobber (reg:CC FLAGS_REG))])]
6858 "TARGET_QIMODE_MATH"
6859 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6861 ;; %%% Potential partial reg stall on alternative 2. What to do?
6862 (define_insn "*addqi_1_lea"
6863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6864 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6865 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6866 (clobber (reg:CC FLAGS_REG))]
6867 "!TARGET_PARTIAL_REG_STALL
6868 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6870 int widen = (which_alternative == 2);
6871 switch (get_attr_type (insn))
6876 if (operands[2] == const1_rtx)
6877 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6880 gcc_assert (operands[2] == constm1_rtx);
6881 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6885 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6886 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6887 if (CONST_INT_P (operands[2])
6888 && (INTVAL (operands[2]) == 128
6889 || (INTVAL (operands[2]) < 0
6890 && INTVAL (operands[2]) != -128)))
6892 operands[2] = GEN_INT (-INTVAL (operands[2]));
6894 return "sub{l}\t{%2, %k0|%k0, %2}";
6896 return "sub{b}\t{%2, %0|%0, %2}";
6899 return "add{l}\t{%k2, %k0|%k0, %k2}";
6901 return "add{b}\t{%2, %0|%0, %2}";
6905 (if_then_else (eq_attr "alternative" "3")
6906 (const_string "lea")
6907 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6908 (const_string "incdec")
6909 (const_string "alu"))))
6910 (set_attr "mode" "QI,QI,SI,SI")])
6912 (define_insn "*addqi_1"
6913 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6914 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6915 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6916 (clobber (reg:CC FLAGS_REG))]
6917 "TARGET_PARTIAL_REG_STALL
6918 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6920 int widen = (which_alternative == 2);
6921 switch (get_attr_type (insn))
6924 if (operands[2] == const1_rtx)
6925 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6928 gcc_assert (operands[2] == constm1_rtx);
6929 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6933 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6934 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6935 if (CONST_INT_P (operands[2])
6936 && (INTVAL (operands[2]) == 128
6937 || (INTVAL (operands[2]) < 0
6938 && INTVAL (operands[2]) != -128)))
6940 operands[2] = GEN_INT (-INTVAL (operands[2]));
6942 return "sub{l}\t{%2, %k0|%k0, %2}";
6944 return "sub{b}\t{%2, %0|%0, %2}";
6947 return "add{l}\t{%k2, %k0|%k0, %k2}";
6949 return "add{b}\t{%2, %0|%0, %2}";
6953 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6954 (const_string "incdec")
6955 (const_string "alu")))
6956 (set_attr "mode" "QI,QI,SI")])
6958 (define_insn "*addqi_1_slp"
6959 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6960 (plus:QI (match_dup 0)
6961 (match_operand:QI 1 "general_operand" "qn,qnm")))
6962 (clobber (reg:CC FLAGS_REG))]
6963 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6964 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6966 switch (get_attr_type (insn))
6969 if (operands[1] == const1_rtx)
6970 return "inc{b}\t%0";
6973 gcc_assert (operands[1] == constm1_rtx);
6974 return "dec{b}\t%0";
6978 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6979 if (CONST_INT_P (operands[1])
6980 && INTVAL (operands[1]) < 0)
6982 operands[1] = GEN_INT (-INTVAL (operands[1]));
6983 return "sub{b}\t{%1, %0|%0, %1}";
6985 return "add{b}\t{%1, %0|%0, %1}";
6989 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6990 (const_string "incdec")
6991 (const_string "alu1")))
6992 (set (attr "memory")
6993 (if_then_else (match_operand 1 "memory_operand" "")
6994 (const_string "load")
6995 (const_string "none")))
6996 (set_attr "mode" "QI")])
6998 (define_insn "*addqi_2"
6999 [(set (reg FLAGS_REG)
7001 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7002 (match_operand:QI 2 "general_operand" "qmni,qni"))
7004 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7005 (plus:QI (match_dup 1) (match_dup 2)))]
7006 "ix86_match_ccmode (insn, CCGOCmode)
7007 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7009 switch (get_attr_type (insn))
7012 if (operands[2] == const1_rtx)
7013 return "inc{b}\t%0";
7016 gcc_assert (operands[2] == constm1_rtx
7017 || (CONST_INT_P (operands[2])
7018 && INTVAL (operands[2]) == 255));
7019 return "dec{b}\t%0";
7023 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7024 if (CONST_INT_P (operands[2])
7025 && INTVAL (operands[2]) < 0)
7027 operands[2] = GEN_INT (-INTVAL (operands[2]));
7028 return "sub{b}\t{%2, %0|%0, %2}";
7030 return "add{b}\t{%2, %0|%0, %2}";
7034 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7035 (const_string "incdec")
7036 (const_string "alu")))
7037 (set_attr "mode" "QI")])
7039 (define_insn "*addqi_3"
7040 [(set (reg FLAGS_REG)
7041 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7042 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7043 (clobber (match_scratch:QI 0 "=q"))]
7044 "ix86_match_ccmode (insn, CCZmode)
7045 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7047 switch (get_attr_type (insn))
7050 if (operands[2] == const1_rtx)
7051 return "inc{b}\t%0";
7054 gcc_assert (operands[2] == constm1_rtx
7055 || (CONST_INT_P (operands[2])
7056 && INTVAL (operands[2]) == 255));
7057 return "dec{b}\t%0";
7061 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7062 if (CONST_INT_P (operands[2])
7063 && INTVAL (operands[2]) < 0)
7065 operands[2] = GEN_INT (-INTVAL (operands[2]));
7066 return "sub{b}\t{%2, %0|%0, %2}";
7068 return "add{b}\t{%2, %0|%0, %2}";
7072 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7073 (const_string "incdec")
7074 (const_string "alu")))
7075 (set_attr "mode" "QI")])
7077 ; See comments above addsi_4 for details.
7078 (define_insn "*addqi_4"
7079 [(set (reg FLAGS_REG)
7080 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7081 (match_operand:QI 2 "const_int_operand" "n")))
7082 (clobber (match_scratch:QI 0 "=qm"))]
7083 "ix86_match_ccmode (insn, CCGCmode)
7084 && (INTVAL (operands[2]) & 0xff) != 0x80"
7086 switch (get_attr_type (insn))
7089 if (operands[2] == constm1_rtx
7090 || (CONST_INT_P (operands[2])
7091 && INTVAL (operands[2]) == 255))
7092 return "inc{b}\t%0";
7095 gcc_assert (operands[2] == const1_rtx);
7096 return "dec{b}\t%0";
7100 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7101 if (INTVAL (operands[2]) < 0)
7103 operands[2] = GEN_INT (-INTVAL (operands[2]));
7104 return "add{b}\t{%2, %0|%0, %2}";
7106 return "sub{b}\t{%2, %0|%0, %2}";
7110 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7111 (const_string "incdec")
7112 (const_string "alu")))
7113 (set_attr "mode" "QI")])
7116 (define_insn "*addqi_5"
7117 [(set (reg FLAGS_REG)
7119 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7120 (match_operand:QI 2 "general_operand" "qmni"))
7122 (clobber (match_scratch:QI 0 "=q"))]
7123 "ix86_match_ccmode (insn, CCGOCmode)
7124 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7126 switch (get_attr_type (insn))
7129 if (operands[2] == const1_rtx)
7130 return "inc{b}\t%0";
7133 gcc_assert (operands[2] == constm1_rtx
7134 || (CONST_INT_P (operands[2])
7135 && INTVAL (operands[2]) == 255));
7136 return "dec{b}\t%0";
7140 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7141 if (CONST_INT_P (operands[2])
7142 && INTVAL (operands[2]) < 0)
7144 operands[2] = GEN_INT (-INTVAL (operands[2]));
7145 return "sub{b}\t{%2, %0|%0, %2}";
7147 return "add{b}\t{%2, %0|%0, %2}";
7151 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7152 (const_string "incdec")
7153 (const_string "alu")))
7154 (set_attr "mode" "QI")])
7157 (define_insn "addqi_ext_1"
7158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7163 (match_operand 1 "ext_register_operand" "0")
7166 (match_operand:QI 2 "general_operand" "Qmn")))
7167 (clobber (reg:CC FLAGS_REG))]
7170 switch (get_attr_type (insn))
7173 if (operands[2] == const1_rtx)
7174 return "inc{b}\t%h0";
7177 gcc_assert (operands[2] == constm1_rtx
7178 || (CONST_INT_P (operands[2])
7179 && INTVAL (operands[2]) == 255));
7180 return "dec{b}\t%h0";
7184 return "add{b}\t{%2, %h0|%h0, %2}";
7188 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7189 (const_string "incdec")
7190 (const_string "alu")))
7191 (set_attr "mode" "QI")])
7193 (define_insn "*addqi_ext_1_rex64"
7194 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7199 (match_operand 1 "ext_register_operand" "0")
7202 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7203 (clobber (reg:CC FLAGS_REG))]
7206 switch (get_attr_type (insn))
7209 if (operands[2] == const1_rtx)
7210 return "inc{b}\t%h0";
7213 gcc_assert (operands[2] == constm1_rtx
7214 || (CONST_INT_P (operands[2])
7215 && INTVAL (operands[2]) == 255));
7216 return "dec{b}\t%h0";
7220 return "add{b}\t{%2, %h0|%h0, %2}";
7224 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7225 (const_string "incdec")
7226 (const_string "alu")))
7227 (set_attr "mode" "QI")])
7229 (define_insn "*addqi_ext_2"
7230 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7235 (match_operand 1 "ext_register_operand" "%0")
7239 (match_operand 2 "ext_register_operand" "Q")
7242 (clobber (reg:CC FLAGS_REG))]
7244 "add{b}\t{%h2, %h0|%h0, %h2}"
7245 [(set_attr "type" "alu")
7246 (set_attr "mode" "QI")])
7248 ;; The patterns that match these are at the end of this file.
7250 (define_expand "addxf3"
7251 [(set (match_operand:XF 0 "register_operand" "")
7252 (plus:XF (match_operand:XF 1 "register_operand" "")
7253 (match_operand:XF 2 "register_operand" "")))]
7257 (define_expand "add<mode>3"
7258 [(set (match_operand:MODEF 0 "register_operand" "")
7259 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7260 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7261 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7264 ;; Subtract instructions
7266 ;; %%% splits for subditi3
7268 (define_expand "subti3"
7269 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7270 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7271 (match_operand:TI 2 "x86_64_general_operand" "")))
7272 (clobber (reg:CC FLAGS_REG))])]
7274 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7276 (define_insn "*subti3_1"
7277 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7278 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7279 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7280 (clobber (reg:CC FLAGS_REG))]
7281 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7285 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7286 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7287 (match_operand:TI 2 "x86_64_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:DI (match_dup 1) (match_dup 2)))])
7292 (parallel [(set (match_dup 3)
7293 (minus:DI (match_dup 4)
7294 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7296 (clobber (reg:CC FLAGS_REG))])]
7297 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7299 ;; %%% splits for subsidi3
7301 (define_expand "subdi3"
7302 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7303 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7304 (match_operand:DI 2 "x86_64_general_operand" "")))
7305 (clobber (reg:CC FLAGS_REG))])]
7307 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7309 (define_insn "*subdi3_1"
7310 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7311 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7312 (match_operand:DI 2 "general_operand" "roiF,riF")))
7313 (clobber (reg:CC FLAGS_REG))]
7314 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7318 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7319 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7320 (match_operand:DI 2 "general_operand" "")))
7321 (clobber (reg:CC FLAGS_REG))]
7322 "!TARGET_64BIT && reload_completed"
7323 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7324 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7325 (parallel [(set (match_dup 3)
7326 (minus:SI (match_dup 4)
7327 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7329 (clobber (reg:CC FLAGS_REG))])]
7330 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7332 (define_insn "subdi3_carry_rex64"
7333 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7334 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7335 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7336 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7337 (clobber (reg:CC FLAGS_REG))]
7338 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7339 "sbb{q}\t{%2, %0|%0, %2}"
7340 [(set_attr "type" "alu")
7341 (set_attr "pent_pair" "pu")
7342 (set_attr "mode" "DI")])
7344 (define_insn "*subdi_1_rex64"
7345 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7346 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7347 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7348 (clobber (reg:CC FLAGS_REG))]
7349 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7350 "sub{q}\t{%2, %0|%0, %2}"
7351 [(set_attr "type" "alu")
7352 (set_attr "mode" "DI")])
7354 (define_insn "*subdi_2_rex64"
7355 [(set (reg FLAGS_REG)
7357 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7358 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7360 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7361 (minus:DI (match_dup 1) (match_dup 2)))]
7362 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7363 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7364 "sub{q}\t{%2, %0|%0, %2}"
7365 [(set_attr "type" "alu")
7366 (set_attr "mode" "DI")])
7368 (define_insn "*subdi_3_rex63"
7369 [(set (reg FLAGS_REG)
7370 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7371 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7372 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7373 (minus:DI (match_dup 1) (match_dup 2)))]
7374 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7375 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7376 "sub{q}\t{%2, %0|%0, %2}"
7377 [(set_attr "type" "alu")
7378 (set_attr "mode" "DI")])
7380 (define_insn "subqi3_carry"
7381 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7382 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7383 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7384 (match_operand:QI 2 "general_operand" "qi,qm"))))
7385 (clobber (reg:CC FLAGS_REG))]
7386 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7387 "sbb{b}\t{%2, %0|%0, %2}"
7388 [(set_attr "type" "alu")
7389 (set_attr "pent_pair" "pu")
7390 (set_attr "mode" "QI")])
7392 (define_insn "subhi3_carry"
7393 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7394 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7395 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7396 (match_operand:HI 2 "general_operand" "ri,rm"))))
7397 (clobber (reg:CC FLAGS_REG))]
7398 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7399 "sbb{w}\t{%2, %0|%0, %2}"
7400 [(set_attr "type" "alu")
7401 (set_attr "pent_pair" "pu")
7402 (set_attr "mode" "HI")])
7404 (define_insn "subsi3_carry"
7405 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7406 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7407 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7408 (match_operand:SI 2 "general_operand" "ri,rm"))))
7409 (clobber (reg:CC FLAGS_REG))]
7410 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7411 "sbb{l}\t{%2, %0|%0, %2}"
7412 [(set_attr "type" "alu")
7413 (set_attr "pent_pair" "pu")
7414 (set_attr "mode" "SI")])
7416 (define_insn "subsi3_carry_zext"
7417 [(set (match_operand:DI 0 "register_operand" "=r")
7419 (minus:SI (match_operand:SI 1 "register_operand" "0")
7420 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7421 (match_operand:SI 2 "general_operand" "g")))))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7424 "sbb{l}\t{%2, %k0|%k0, %2}"
7425 [(set_attr "type" "alu")
7426 (set_attr "pent_pair" "pu")
7427 (set_attr "mode" "SI")])
7429 (define_expand "subsi3"
7430 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7431 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7432 (match_operand:SI 2 "general_operand" "")))
7433 (clobber (reg:CC FLAGS_REG))])]
7435 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7437 (define_insn "*subsi_1"
7438 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7439 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7440 (match_operand:SI 2 "general_operand" "ri,rm")))
7441 (clobber (reg:CC FLAGS_REG))]
7442 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7443 "sub{l}\t{%2, %0|%0, %2}"
7444 [(set_attr "type" "alu")
7445 (set_attr "mode" "SI")])
7447 (define_insn "*subsi_1_zext"
7448 [(set (match_operand:DI 0 "register_operand" "=r")
7450 (minus:SI (match_operand:SI 1 "register_operand" "0")
7451 (match_operand:SI 2 "general_operand" "g"))))
7452 (clobber (reg:CC FLAGS_REG))]
7453 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7454 "sub{l}\t{%2, %k0|%k0, %2}"
7455 [(set_attr "type" "alu")
7456 (set_attr "mode" "SI")])
7458 (define_insn "*subsi_2"
7459 [(set (reg FLAGS_REG)
7461 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7462 (match_operand:SI 2 "general_operand" "ri,rm"))
7464 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7465 (minus:SI (match_dup 1) (match_dup 2)))]
7466 "ix86_match_ccmode (insn, CCGOCmode)
7467 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7468 "sub{l}\t{%2, %0|%0, %2}"
7469 [(set_attr "type" "alu")
7470 (set_attr "mode" "SI")])
7472 (define_insn "*subsi_2_zext"
7473 [(set (reg FLAGS_REG)
7475 (minus:SI (match_operand:SI 1 "register_operand" "0")
7476 (match_operand:SI 2 "general_operand" "g"))
7478 (set (match_operand:DI 0 "register_operand" "=r")
7480 (minus:SI (match_dup 1)
7482 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7483 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7484 "sub{l}\t{%2, %k0|%k0, %2}"
7485 [(set_attr "type" "alu")
7486 (set_attr "mode" "SI")])
7488 (define_insn "*subsi_3"
7489 [(set (reg FLAGS_REG)
7490 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7491 (match_operand:SI 2 "general_operand" "ri,rm")))
7492 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7493 (minus:SI (match_dup 1) (match_dup 2)))]
7494 "ix86_match_ccmode (insn, CCmode)
7495 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7496 "sub{l}\t{%2, %0|%0, %2}"
7497 [(set_attr "type" "alu")
7498 (set_attr "mode" "SI")])
7500 (define_insn "*subsi_3_zext"
7501 [(set (reg FLAGS_REG)
7502 (compare (match_operand:SI 1 "register_operand" "0")
7503 (match_operand:SI 2 "general_operand" "g")))
7504 (set (match_operand:DI 0 "register_operand" "=r")
7506 (minus:SI (match_dup 1)
7508 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7509 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7510 "sub{l}\t{%2, %1|%1, %2}"
7511 [(set_attr "type" "alu")
7512 (set_attr "mode" "DI")])
7514 (define_expand "subhi3"
7515 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7516 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7517 (match_operand:HI 2 "general_operand" "")))
7518 (clobber (reg:CC FLAGS_REG))])]
7519 "TARGET_HIMODE_MATH"
7520 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7522 (define_insn "*subhi_1"
7523 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7524 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7525 (match_operand:HI 2 "general_operand" "ri,rm")))
7526 (clobber (reg:CC FLAGS_REG))]
7527 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7528 "sub{w}\t{%2, %0|%0, %2}"
7529 [(set_attr "type" "alu")
7530 (set_attr "mode" "HI")])
7532 (define_insn "*subhi_2"
7533 [(set (reg FLAGS_REG)
7535 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7536 (match_operand:HI 2 "general_operand" "ri,rm"))
7538 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7539 (minus:HI (match_dup 1) (match_dup 2)))]
7540 "ix86_match_ccmode (insn, CCGOCmode)
7541 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7542 "sub{w}\t{%2, %0|%0, %2}"
7543 [(set_attr "type" "alu")
7544 (set_attr "mode" "HI")])
7546 (define_insn "*subhi_3"
7547 [(set (reg FLAGS_REG)
7548 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7549 (match_operand:HI 2 "general_operand" "ri,rm")))
7550 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7551 (minus:HI (match_dup 1) (match_dup 2)))]
7552 "ix86_match_ccmode (insn, CCmode)
7553 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7554 "sub{w}\t{%2, %0|%0, %2}"
7555 [(set_attr "type" "alu")
7556 (set_attr "mode" "HI")])
7558 (define_expand "subqi3"
7559 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7560 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7561 (match_operand:QI 2 "general_operand" "")))
7562 (clobber (reg:CC FLAGS_REG))])]
7563 "TARGET_QIMODE_MATH"
7564 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7566 (define_insn "*subqi_1"
7567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7568 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7569 (match_operand:QI 2 "general_operand" "qn,qmn")))
7570 (clobber (reg:CC FLAGS_REG))]
7571 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7572 "sub{b}\t{%2, %0|%0, %2}"
7573 [(set_attr "type" "alu")
7574 (set_attr "mode" "QI")])
7576 (define_insn "*subqi_1_slp"
7577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7578 (minus:QI (match_dup 0)
7579 (match_operand:QI 1 "general_operand" "qn,qmn")))
7580 (clobber (reg:CC FLAGS_REG))]
7581 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7582 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7583 "sub{b}\t{%1, %0|%0, %1}"
7584 [(set_attr "type" "alu1")
7585 (set_attr "mode" "QI")])
7587 (define_insn "*subqi_2"
7588 [(set (reg FLAGS_REG)
7590 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7591 (match_operand:QI 2 "general_operand" "qi,qm"))
7593 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7594 (minus:HI (match_dup 1) (match_dup 2)))]
7595 "ix86_match_ccmode (insn, CCGOCmode)
7596 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7597 "sub{b}\t{%2, %0|%0, %2}"
7598 [(set_attr "type" "alu")
7599 (set_attr "mode" "QI")])
7601 (define_insn "*subqi_3"
7602 [(set (reg FLAGS_REG)
7603 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7604 (match_operand:QI 2 "general_operand" "qi,qm")))
7605 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7606 (minus:HI (match_dup 1) (match_dup 2)))]
7607 "ix86_match_ccmode (insn, CCmode)
7608 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7609 "sub{b}\t{%2, %0|%0, %2}"
7610 [(set_attr "type" "alu")
7611 (set_attr "mode" "QI")])
7613 ;; The patterns that match these are at the end of this file.
7615 (define_expand "subxf3"
7616 [(set (match_operand:XF 0 "register_operand" "")
7617 (minus:XF (match_operand:XF 1 "register_operand" "")
7618 (match_operand:XF 2 "register_operand" "")))]
7622 (define_expand "sub<mode>3"
7623 [(set (match_operand:MODEF 0 "register_operand" "")
7624 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7625 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7626 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7629 ;; Multiply instructions
7631 (define_expand "muldi3"
7632 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7633 (mult:DI (match_operand:DI 1 "register_operand" "")
7634 (match_operand:DI 2 "x86_64_general_operand" "")))
7635 (clobber (reg:CC FLAGS_REG))])]
7640 ;; IMUL reg64, reg64, imm8 Direct
7641 ;; IMUL reg64, mem64, imm8 VectorPath
7642 ;; IMUL reg64, reg64, imm32 Direct
7643 ;; IMUL reg64, mem64, imm32 VectorPath
7644 ;; IMUL reg64, reg64 Direct
7645 ;; IMUL reg64, mem64 Direct
7647 (define_insn "*muldi3_1_rex64"
7648 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7649 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7650 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7651 (clobber (reg:CC FLAGS_REG))]
7653 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7655 imul{q}\t{%2, %1, %0|%0, %1, %2}
7656 imul{q}\t{%2, %1, %0|%0, %1, %2}
7657 imul{q}\t{%2, %0|%0, %2}"
7658 [(set_attr "type" "imul")
7659 (set_attr "prefix_0f" "0,0,1")
7660 (set (attr "athlon_decode")
7661 (cond [(eq_attr "cpu" "athlon")
7662 (const_string "vector")
7663 (eq_attr "alternative" "1")
7664 (const_string "vector")
7665 (and (eq_attr "alternative" "2")
7666 (match_operand 1 "memory_operand" ""))
7667 (const_string "vector")]
7668 (const_string "direct")))
7669 (set (attr "amdfam10_decode")
7670 (cond [(and (eq_attr "alternative" "0,1")
7671 (match_operand 1 "memory_operand" ""))
7672 (const_string "vector")]
7673 (const_string "direct")))
7674 (set_attr "mode" "DI")])
7676 (define_expand "mulsi3"
7677 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7678 (mult:SI (match_operand:SI 1 "register_operand" "")
7679 (match_operand:SI 2 "general_operand" "")))
7680 (clobber (reg:CC FLAGS_REG))])]
7685 ;; IMUL reg32, reg32, imm8 Direct
7686 ;; IMUL reg32, mem32, imm8 VectorPath
7687 ;; IMUL reg32, reg32, imm32 Direct
7688 ;; IMUL reg32, mem32, imm32 VectorPath
7689 ;; IMUL reg32, reg32 Direct
7690 ;; IMUL reg32, mem32 Direct
7692 (define_insn "*mulsi3_1"
7693 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7694 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7695 (match_operand:SI 2 "general_operand" "K,i,mr")))
7696 (clobber (reg:CC FLAGS_REG))]
7697 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7699 imul{l}\t{%2, %1, %0|%0, %1, %2}
7700 imul{l}\t{%2, %1, %0|%0, %1, %2}
7701 imul{l}\t{%2, %0|%0, %2}"
7702 [(set_attr "type" "imul")
7703 (set_attr "prefix_0f" "0,0,1")
7704 (set (attr "athlon_decode")
7705 (cond [(eq_attr "cpu" "athlon")
7706 (const_string "vector")
7707 (eq_attr "alternative" "1")
7708 (const_string "vector")
7709 (and (eq_attr "alternative" "2")
7710 (match_operand 1 "memory_operand" ""))
7711 (const_string "vector")]
7712 (const_string "direct")))
7713 (set (attr "amdfam10_decode")
7714 (cond [(and (eq_attr "alternative" "0,1")
7715 (match_operand 1 "memory_operand" ""))
7716 (const_string "vector")]
7717 (const_string "direct")))
7718 (set_attr "mode" "SI")])
7720 (define_insn "*mulsi3_1_zext"
7721 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7723 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7724 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7725 (clobber (reg:CC FLAGS_REG))]
7727 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7729 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7730 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7731 imul{l}\t{%2, %k0|%k0, %2}"
7732 [(set_attr "type" "imul")
7733 (set_attr "prefix_0f" "0,0,1")
7734 (set (attr "athlon_decode")
7735 (cond [(eq_attr "cpu" "athlon")
7736 (const_string "vector")
7737 (eq_attr "alternative" "1")
7738 (const_string "vector")
7739 (and (eq_attr "alternative" "2")
7740 (match_operand 1 "memory_operand" ""))
7741 (const_string "vector")]
7742 (const_string "direct")))
7743 (set (attr "amdfam10_decode")
7744 (cond [(and (eq_attr "alternative" "0,1")
7745 (match_operand 1 "memory_operand" ""))
7746 (const_string "vector")]
7747 (const_string "direct")))
7748 (set_attr "mode" "SI")])
7750 (define_expand "mulhi3"
7751 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7752 (mult:HI (match_operand:HI 1 "register_operand" "")
7753 (match_operand:HI 2 "general_operand" "")))
7754 (clobber (reg:CC FLAGS_REG))])]
7755 "TARGET_HIMODE_MATH"
7759 ;; IMUL reg16, reg16, imm8 VectorPath
7760 ;; IMUL reg16, mem16, imm8 VectorPath
7761 ;; IMUL reg16, reg16, imm16 VectorPath
7762 ;; IMUL reg16, mem16, imm16 VectorPath
7763 ;; IMUL reg16, reg16 Direct
7764 ;; IMUL reg16, mem16 Direct
7765 (define_insn "*mulhi3_1"
7766 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7767 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7768 (match_operand:HI 2 "general_operand" "K,i,mr")))
7769 (clobber (reg:CC FLAGS_REG))]
7770 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7772 imul{w}\t{%2, %1, %0|%0, %1, %2}
7773 imul{w}\t{%2, %1, %0|%0, %1, %2}
7774 imul{w}\t{%2, %0|%0, %2}"
7775 [(set_attr "type" "imul")
7776 (set_attr "prefix_0f" "0,0,1")
7777 (set (attr "athlon_decode")
7778 (cond [(eq_attr "cpu" "athlon")
7779 (const_string "vector")
7780 (eq_attr "alternative" "1,2")
7781 (const_string "vector")]
7782 (const_string "direct")))
7783 (set (attr "amdfam10_decode")
7784 (cond [(eq_attr "alternative" "0,1")
7785 (const_string "vector")]
7786 (const_string "direct")))
7787 (set_attr "mode" "HI")])
7789 (define_expand "mulqi3"
7790 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7791 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7792 (match_operand:QI 2 "register_operand" "")))
7793 (clobber (reg:CC FLAGS_REG))])]
7794 "TARGET_QIMODE_MATH"
7801 (define_insn "*mulqi3_1"
7802 [(set (match_operand:QI 0 "register_operand" "=a")
7803 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7804 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7805 (clobber (reg:CC FLAGS_REG))]
7807 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7809 [(set_attr "type" "imul")
7810 (set_attr "length_immediate" "0")
7811 (set (attr "athlon_decode")
7812 (if_then_else (eq_attr "cpu" "athlon")
7813 (const_string "vector")
7814 (const_string "direct")))
7815 (set_attr "amdfam10_decode" "direct")
7816 (set_attr "mode" "QI")])
7818 (define_expand "umulqihi3"
7819 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7820 (mult:HI (zero_extend:HI
7821 (match_operand:QI 1 "nonimmediate_operand" ""))
7823 (match_operand:QI 2 "register_operand" ""))))
7824 (clobber (reg:CC FLAGS_REG))])]
7825 "TARGET_QIMODE_MATH"
7828 (define_insn "*umulqihi3_1"
7829 [(set (match_operand:HI 0 "register_operand" "=a")
7830 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7831 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7832 (clobber (reg:CC FLAGS_REG))]
7834 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7836 [(set_attr "type" "imul")
7837 (set_attr "length_immediate" "0")
7838 (set (attr "athlon_decode")
7839 (if_then_else (eq_attr "cpu" "athlon")
7840 (const_string "vector")
7841 (const_string "direct")))
7842 (set_attr "amdfam10_decode" "direct")
7843 (set_attr "mode" "QI")])
7845 (define_expand "mulqihi3"
7846 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7847 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7848 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7849 (clobber (reg:CC FLAGS_REG))])]
7850 "TARGET_QIMODE_MATH"
7853 (define_insn "*mulqihi3_insn"
7854 [(set (match_operand:HI 0 "register_operand" "=a")
7855 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7856 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7857 (clobber (reg:CC FLAGS_REG))]
7859 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7861 [(set_attr "type" "imul")
7862 (set_attr "length_immediate" "0")
7863 (set (attr "athlon_decode")
7864 (if_then_else (eq_attr "cpu" "athlon")
7865 (const_string "vector")
7866 (const_string "direct")))
7867 (set_attr "amdfam10_decode" "direct")
7868 (set_attr "mode" "QI")])
7870 (define_expand "umulditi3"
7871 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7872 (mult:TI (zero_extend:TI
7873 (match_operand:DI 1 "nonimmediate_operand" ""))
7875 (match_operand:DI 2 "register_operand" ""))))
7876 (clobber (reg:CC FLAGS_REG))])]
7880 (define_insn "*umulditi3_insn"
7881 [(set (match_operand:TI 0 "register_operand" "=A")
7882 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7883 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7884 (clobber (reg:CC FLAGS_REG))]
7886 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7888 [(set_attr "type" "imul")
7889 (set_attr "length_immediate" "0")
7890 (set (attr "athlon_decode")
7891 (if_then_else (eq_attr "cpu" "athlon")
7892 (const_string "vector")
7893 (const_string "double")))
7894 (set_attr "amdfam10_decode" "double")
7895 (set_attr "mode" "DI")])
7897 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7898 (define_expand "umulsidi3"
7899 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7900 (mult:DI (zero_extend:DI
7901 (match_operand:SI 1 "nonimmediate_operand" ""))
7903 (match_operand:SI 2 "register_operand" ""))))
7904 (clobber (reg:CC FLAGS_REG))])]
7908 (define_insn "*umulsidi3_insn"
7909 [(set (match_operand:DI 0 "register_operand" "=A")
7910 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7911 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7912 (clobber (reg:CC FLAGS_REG))]
7914 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7916 [(set_attr "type" "imul")
7917 (set_attr "length_immediate" "0")
7918 (set (attr "athlon_decode")
7919 (if_then_else (eq_attr "cpu" "athlon")
7920 (const_string "vector")
7921 (const_string "double")))
7922 (set_attr "amdfam10_decode" "double")
7923 (set_attr "mode" "SI")])
7925 (define_expand "mulditi3"
7926 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7927 (mult:TI (sign_extend:TI
7928 (match_operand:DI 1 "nonimmediate_operand" ""))
7930 (match_operand:DI 2 "register_operand" ""))))
7931 (clobber (reg:CC FLAGS_REG))])]
7935 (define_insn "*mulditi3_insn"
7936 [(set (match_operand:TI 0 "register_operand" "=A")
7937 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7938 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7939 (clobber (reg:CC FLAGS_REG))]
7941 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7943 [(set_attr "type" "imul")
7944 (set_attr "length_immediate" "0")
7945 (set (attr "athlon_decode")
7946 (if_then_else (eq_attr "cpu" "athlon")
7947 (const_string "vector")
7948 (const_string "double")))
7949 (set_attr "amdfam10_decode" "double")
7950 (set_attr "mode" "DI")])
7952 (define_expand "mulsidi3"
7953 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7954 (mult:DI (sign_extend:DI
7955 (match_operand:SI 1 "nonimmediate_operand" ""))
7957 (match_operand:SI 2 "register_operand" ""))))
7958 (clobber (reg:CC FLAGS_REG))])]
7962 (define_insn "*mulsidi3_insn"
7963 [(set (match_operand:DI 0 "register_operand" "=A")
7964 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7965 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7966 (clobber (reg:CC FLAGS_REG))]
7968 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7970 [(set_attr "type" "imul")
7971 (set_attr "length_immediate" "0")
7972 (set (attr "athlon_decode")
7973 (if_then_else (eq_attr "cpu" "athlon")
7974 (const_string "vector")
7975 (const_string "double")))
7976 (set_attr "amdfam10_decode" "double")
7977 (set_attr "mode" "SI")])
7979 (define_expand "umuldi3_highpart"
7980 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7983 (mult:TI (zero_extend:TI
7984 (match_operand:DI 1 "nonimmediate_operand" ""))
7986 (match_operand:DI 2 "register_operand" "")))
7988 (clobber (match_scratch:DI 3 ""))
7989 (clobber (reg:CC FLAGS_REG))])]
7993 (define_insn "*umuldi3_highpart_rex64"
7994 [(set (match_operand:DI 0 "register_operand" "=d")
7997 (mult:TI (zero_extend:TI
7998 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8000 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8002 (clobber (match_scratch:DI 3 "=1"))
8003 (clobber (reg:CC FLAGS_REG))]
8005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8007 [(set_attr "type" "imul")
8008 (set_attr "length_immediate" "0")
8009 (set (attr "athlon_decode")
8010 (if_then_else (eq_attr "cpu" "athlon")
8011 (const_string "vector")
8012 (const_string "double")))
8013 (set_attr "amdfam10_decode" "double")
8014 (set_attr "mode" "DI")])
8016 (define_expand "umulsi3_highpart"
8017 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8020 (mult:DI (zero_extend:DI
8021 (match_operand:SI 1 "nonimmediate_operand" ""))
8023 (match_operand:SI 2 "register_operand" "")))
8025 (clobber (match_scratch:SI 3 ""))
8026 (clobber (reg:CC FLAGS_REG))])]
8030 (define_insn "*umulsi3_highpart_insn"
8031 [(set (match_operand:SI 0 "register_operand" "=d")
8034 (mult:DI (zero_extend:DI
8035 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8037 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8039 (clobber (match_scratch:SI 3 "=1"))
8040 (clobber (reg:CC FLAGS_REG))]
8041 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8043 [(set_attr "type" "imul")
8044 (set_attr "length_immediate" "0")
8045 (set (attr "athlon_decode")
8046 (if_then_else (eq_attr "cpu" "athlon")
8047 (const_string "vector")
8048 (const_string "double")))
8049 (set_attr "amdfam10_decode" "double")
8050 (set_attr "mode" "SI")])
8052 (define_insn "*umulsi3_highpart_zext"
8053 [(set (match_operand:DI 0 "register_operand" "=d")
8054 (zero_extend:DI (truncate:SI
8056 (mult:DI (zero_extend:DI
8057 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8059 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8061 (clobber (match_scratch:SI 3 "=1"))
8062 (clobber (reg:CC FLAGS_REG))]
8064 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8066 [(set_attr "type" "imul")
8067 (set_attr "length_immediate" "0")
8068 (set (attr "athlon_decode")
8069 (if_then_else (eq_attr "cpu" "athlon")
8070 (const_string "vector")
8071 (const_string "double")))
8072 (set_attr "amdfam10_decode" "double")
8073 (set_attr "mode" "SI")])
8075 (define_expand "smuldi3_highpart"
8076 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8079 (mult:TI (sign_extend:TI
8080 (match_operand:DI 1 "nonimmediate_operand" ""))
8082 (match_operand:DI 2 "register_operand" "")))
8084 (clobber (match_scratch:DI 3 ""))
8085 (clobber (reg:CC FLAGS_REG))])]
8089 (define_insn "*smuldi3_highpart_rex64"
8090 [(set (match_operand:DI 0 "register_operand" "=d")
8093 (mult:TI (sign_extend:TI
8094 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8096 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8098 (clobber (match_scratch:DI 3 "=1"))
8099 (clobber (reg:CC FLAGS_REG))]
8101 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8103 [(set_attr "type" "imul")
8104 (set (attr "athlon_decode")
8105 (if_then_else (eq_attr "cpu" "athlon")
8106 (const_string "vector")
8107 (const_string "double")))
8108 (set_attr "amdfam10_decode" "double")
8109 (set_attr "mode" "DI")])
8111 (define_expand "smulsi3_highpart"
8112 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8115 (mult:DI (sign_extend:DI
8116 (match_operand:SI 1 "nonimmediate_operand" ""))
8118 (match_operand:SI 2 "register_operand" "")))
8120 (clobber (match_scratch:SI 3 ""))
8121 (clobber (reg:CC FLAGS_REG))])]
8125 (define_insn "*smulsi3_highpart_insn"
8126 [(set (match_operand:SI 0 "register_operand" "=d")
8129 (mult:DI (sign_extend:DI
8130 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8132 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8134 (clobber (match_scratch:SI 3 "=1"))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8138 [(set_attr "type" "imul")
8139 (set (attr "athlon_decode")
8140 (if_then_else (eq_attr "cpu" "athlon")
8141 (const_string "vector")
8142 (const_string "double")))
8143 (set_attr "amdfam10_decode" "double")
8144 (set_attr "mode" "SI")])
8146 (define_insn "*smulsi3_highpart_zext"
8147 [(set (match_operand:DI 0 "register_operand" "=d")
8148 (zero_extend:DI (truncate:SI
8150 (mult:DI (sign_extend:DI
8151 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8153 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8155 (clobber (match_scratch:SI 3 "=1"))
8156 (clobber (reg:CC FLAGS_REG))]
8158 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8160 [(set_attr "type" "imul")
8161 (set (attr "athlon_decode")
8162 (if_then_else (eq_attr "cpu" "athlon")
8163 (const_string "vector")
8164 (const_string "double")))
8165 (set_attr "amdfam10_decode" "double")
8166 (set_attr "mode" "SI")])
8168 ;; The patterns that match these are at the end of this file.
8170 (define_expand "mulxf3"
8171 [(set (match_operand:XF 0 "register_operand" "")
8172 (mult:XF (match_operand:XF 1 "register_operand" "")
8173 (match_operand:XF 2 "register_operand" "")))]
8177 (define_expand "mul<mode>3"
8178 [(set (match_operand:MODEF 0 "register_operand" "")
8179 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8180 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8181 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8184 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8187 ;; Divide instructions
8189 (define_insn "divqi3"
8190 [(set (match_operand:QI 0 "register_operand" "=a")
8191 (div:QI (match_operand:HI 1 "register_operand" "0")
8192 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8193 (clobber (reg:CC FLAGS_REG))]
8194 "TARGET_QIMODE_MATH"
8196 [(set_attr "type" "idiv")
8197 (set_attr "mode" "QI")])
8199 (define_insn "udivqi3"
8200 [(set (match_operand:QI 0 "register_operand" "=a")
8201 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8202 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8203 (clobber (reg:CC FLAGS_REG))]
8204 "TARGET_QIMODE_MATH"
8206 [(set_attr "type" "idiv")
8207 (set_attr "mode" "QI")])
8209 ;; The patterns that match these are at the end of this file.
8211 (define_expand "divxf3"
8212 [(set (match_operand:XF 0 "register_operand" "")
8213 (div:XF (match_operand:XF 1 "register_operand" "")
8214 (match_operand:XF 2 "register_operand" "")))]
8218 (define_expand "divdf3"
8219 [(set (match_operand:DF 0 "register_operand" "")
8220 (div:DF (match_operand:DF 1 "register_operand" "")
8221 (match_operand:DF 2 "nonimmediate_operand" "")))]
8222 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8225 (define_expand "divsf3"
8226 [(set (match_operand:SF 0 "register_operand" "")
8227 (div:SF (match_operand:SF 1 "register_operand" "")
8228 (match_operand:SF 2 "nonimmediate_operand" "")))]
8229 "TARGET_80387 || TARGET_SSE_MATH"
8231 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8232 && flag_finite_math_only && !flag_trapping_math
8233 && flag_unsafe_math_optimizations)
8235 ix86_emit_swdivsf (operands[0], operands[1],
8236 operands[2], SFmode);
8241 ;; Remainder instructions.
8243 (define_expand "divmoddi4"
8244 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8245 (div:DI (match_operand:DI 1 "register_operand" "")
8246 (match_operand:DI 2 "nonimmediate_operand" "")))
8247 (set (match_operand:DI 3 "register_operand" "")
8248 (mod:DI (match_dup 1) (match_dup 2)))
8249 (clobber (reg:CC FLAGS_REG))])]
8253 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8254 ;; Penalize eax case slightly because it results in worse scheduling
8256 (define_insn "*divmoddi4_nocltd_rex64"
8257 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8258 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8259 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8260 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8261 (mod:DI (match_dup 2) (match_dup 3)))
8262 (clobber (reg:CC FLAGS_REG))]
8263 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8265 [(set_attr "type" "multi")])
8267 (define_insn "*divmoddi4_cltd_rex64"
8268 [(set (match_operand:DI 0 "register_operand" "=a")
8269 (div:DI (match_operand:DI 2 "register_operand" "a")
8270 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8271 (set (match_operand:DI 1 "register_operand" "=&d")
8272 (mod:DI (match_dup 2) (match_dup 3)))
8273 (clobber (reg:CC FLAGS_REG))]
8274 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8276 [(set_attr "type" "multi")])
8278 (define_insn "*divmoddi_noext_rex64"
8279 [(set (match_operand:DI 0 "register_operand" "=a")
8280 (div:DI (match_operand:DI 1 "register_operand" "0")
8281 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8282 (set (match_operand:DI 3 "register_operand" "=d")
8283 (mod:DI (match_dup 1) (match_dup 2)))
8284 (use (match_operand:DI 4 "register_operand" "3"))
8285 (clobber (reg:CC FLAGS_REG))]
8288 [(set_attr "type" "idiv")
8289 (set_attr "mode" "DI")])
8292 [(set (match_operand:DI 0 "register_operand" "")
8293 (div:DI (match_operand:DI 1 "register_operand" "")
8294 (match_operand:DI 2 "nonimmediate_operand" "")))
8295 (set (match_operand:DI 3 "register_operand" "")
8296 (mod:DI (match_dup 1) (match_dup 2)))
8297 (clobber (reg:CC FLAGS_REG))]
8298 "TARGET_64BIT && reload_completed"
8299 [(parallel [(set (match_dup 3)
8300 (ashiftrt:DI (match_dup 4) (const_int 63)))
8301 (clobber (reg:CC FLAGS_REG))])
8302 (parallel [(set (match_dup 0)
8303 (div:DI (reg:DI 0) (match_dup 2)))
8305 (mod:DI (reg:DI 0) (match_dup 2)))
8307 (clobber (reg:CC FLAGS_REG))])]
8309 /* Avoid use of cltd in favor of a mov+shift. */
8310 if (!TARGET_USE_CLTD && !optimize_size)
8312 if (true_regnum (operands[1]))
8313 emit_move_insn (operands[0], operands[1]);
8315 emit_move_insn (operands[3], operands[1]);
8316 operands[4] = operands[3];
8320 gcc_assert (!true_regnum (operands[1]));
8321 operands[4] = operands[1];
8326 (define_expand "divmodsi4"
8327 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8328 (div:SI (match_operand:SI 1 "register_operand" "")
8329 (match_operand:SI 2 "nonimmediate_operand" "")))
8330 (set (match_operand:SI 3 "register_operand" "")
8331 (mod:SI (match_dup 1) (match_dup 2)))
8332 (clobber (reg:CC FLAGS_REG))])]
8336 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8337 ;; Penalize eax case slightly because it results in worse scheduling
8339 (define_insn "*divmodsi4_nocltd"
8340 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8341 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8342 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8343 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8344 (mod:SI (match_dup 2) (match_dup 3)))
8345 (clobber (reg:CC FLAGS_REG))]
8346 "!optimize_size && !TARGET_USE_CLTD"
8348 [(set_attr "type" "multi")])
8350 (define_insn "*divmodsi4_cltd"
8351 [(set (match_operand:SI 0 "register_operand" "=a")
8352 (div:SI (match_operand:SI 2 "register_operand" "a")
8353 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8354 (set (match_operand:SI 1 "register_operand" "=&d")
8355 (mod:SI (match_dup 2) (match_dup 3)))
8356 (clobber (reg:CC FLAGS_REG))]
8357 "optimize_size || TARGET_USE_CLTD"
8359 [(set_attr "type" "multi")])
8361 (define_insn "*divmodsi_noext"
8362 [(set (match_operand:SI 0 "register_operand" "=a")
8363 (div:SI (match_operand:SI 1 "register_operand" "0")
8364 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8365 (set (match_operand:SI 3 "register_operand" "=d")
8366 (mod:SI (match_dup 1) (match_dup 2)))
8367 (use (match_operand:SI 4 "register_operand" "3"))
8368 (clobber (reg:CC FLAGS_REG))]
8371 [(set_attr "type" "idiv")
8372 (set_attr "mode" "SI")])
8375 [(set (match_operand:SI 0 "register_operand" "")
8376 (div:SI (match_operand:SI 1 "register_operand" "")
8377 (match_operand:SI 2 "nonimmediate_operand" "")))
8378 (set (match_operand:SI 3 "register_operand" "")
8379 (mod:SI (match_dup 1) (match_dup 2)))
8380 (clobber (reg:CC FLAGS_REG))]
8382 [(parallel [(set (match_dup 3)
8383 (ashiftrt:SI (match_dup 4) (const_int 31)))
8384 (clobber (reg:CC FLAGS_REG))])
8385 (parallel [(set (match_dup 0)
8386 (div:SI (reg:SI 0) (match_dup 2)))
8388 (mod:SI (reg:SI 0) (match_dup 2)))
8390 (clobber (reg:CC FLAGS_REG))])]
8392 /* Avoid use of cltd in favor of a mov+shift. */
8393 if (!TARGET_USE_CLTD && !optimize_size)
8395 if (true_regnum (operands[1]))
8396 emit_move_insn (operands[0], operands[1]);
8398 emit_move_insn (operands[3], operands[1]);
8399 operands[4] = operands[3];
8403 gcc_assert (!true_regnum (operands[1]));
8404 operands[4] = operands[1];
8408 (define_insn "divmodhi4"
8409 [(set (match_operand:HI 0 "register_operand" "=a")
8410 (div:HI (match_operand:HI 1 "register_operand" "0")
8411 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8412 (set (match_operand:HI 3 "register_operand" "=&d")
8413 (mod:HI (match_dup 1) (match_dup 2)))
8414 (clobber (reg:CC FLAGS_REG))]
8415 "TARGET_HIMODE_MATH"
8417 [(set_attr "type" "multi")
8418 (set_attr "length_immediate" "0")
8419 (set_attr "mode" "SI")])
8421 (define_insn "udivmoddi4"
8422 [(set (match_operand:DI 0 "register_operand" "=a")
8423 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8424 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8425 (set (match_operand:DI 3 "register_operand" "=&d")
8426 (umod:DI (match_dup 1) (match_dup 2)))
8427 (clobber (reg:CC FLAGS_REG))]
8429 "xor{q}\t%3, %3\;div{q}\t%2"
8430 [(set_attr "type" "multi")
8431 (set_attr "length_immediate" "0")
8432 (set_attr "mode" "DI")])
8434 (define_insn "*udivmoddi4_noext"
8435 [(set (match_operand:DI 0 "register_operand" "=a")
8436 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8437 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8438 (set (match_operand:DI 3 "register_operand" "=d")
8439 (umod:DI (match_dup 1) (match_dup 2)))
8441 (clobber (reg:CC FLAGS_REG))]
8444 [(set_attr "type" "idiv")
8445 (set_attr "mode" "DI")])
8448 [(set (match_operand:DI 0 "register_operand" "")
8449 (udiv:DI (match_operand:DI 1 "register_operand" "")
8450 (match_operand:DI 2 "nonimmediate_operand" "")))
8451 (set (match_operand:DI 3 "register_operand" "")
8452 (umod:DI (match_dup 1) (match_dup 2)))
8453 (clobber (reg:CC FLAGS_REG))]
8454 "TARGET_64BIT && reload_completed"
8455 [(set (match_dup 3) (const_int 0))
8456 (parallel [(set (match_dup 0)
8457 (udiv:DI (match_dup 1) (match_dup 2)))
8459 (umod:DI (match_dup 1) (match_dup 2)))
8461 (clobber (reg:CC FLAGS_REG))])]
8464 (define_insn "udivmodsi4"
8465 [(set (match_operand:SI 0 "register_operand" "=a")
8466 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8467 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8468 (set (match_operand:SI 3 "register_operand" "=&d")
8469 (umod:SI (match_dup 1) (match_dup 2)))
8470 (clobber (reg:CC FLAGS_REG))]
8472 "xor{l}\t%3, %3\;div{l}\t%2"
8473 [(set_attr "type" "multi")
8474 (set_attr "length_immediate" "0")
8475 (set_attr "mode" "SI")])
8477 (define_insn "*udivmodsi4_noext"
8478 [(set (match_operand:SI 0 "register_operand" "=a")
8479 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8480 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8481 (set (match_operand:SI 3 "register_operand" "=d")
8482 (umod:SI (match_dup 1) (match_dup 2)))
8484 (clobber (reg:CC FLAGS_REG))]
8487 [(set_attr "type" "idiv")
8488 (set_attr "mode" "SI")])
8491 [(set (match_operand:SI 0 "register_operand" "")
8492 (udiv:SI (match_operand:SI 1 "register_operand" "")
8493 (match_operand:SI 2 "nonimmediate_operand" "")))
8494 (set (match_operand:SI 3 "register_operand" "")
8495 (umod:SI (match_dup 1) (match_dup 2)))
8496 (clobber (reg:CC FLAGS_REG))]
8498 [(set (match_dup 3) (const_int 0))
8499 (parallel [(set (match_dup 0)
8500 (udiv:SI (match_dup 1) (match_dup 2)))
8502 (umod:SI (match_dup 1) (match_dup 2)))
8504 (clobber (reg:CC FLAGS_REG))])]
8507 (define_expand "udivmodhi4"
8508 [(set (match_dup 4) (const_int 0))
8509 (parallel [(set (match_operand:HI 0 "register_operand" "")
8510 (udiv:HI (match_operand:HI 1 "register_operand" "")
8511 (match_operand:HI 2 "nonimmediate_operand" "")))
8512 (set (match_operand:HI 3 "register_operand" "")
8513 (umod:HI (match_dup 1) (match_dup 2)))
8515 (clobber (reg:CC FLAGS_REG))])]
8516 "TARGET_HIMODE_MATH"
8517 "operands[4] = gen_reg_rtx (HImode);")
8519 (define_insn "*udivmodhi_noext"
8520 [(set (match_operand:HI 0 "register_operand" "=a")
8521 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8522 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8523 (set (match_operand:HI 3 "register_operand" "=d")
8524 (umod:HI (match_dup 1) (match_dup 2)))
8525 (use (match_operand:HI 4 "register_operand" "3"))
8526 (clobber (reg:CC FLAGS_REG))]
8529 [(set_attr "type" "idiv")
8530 (set_attr "mode" "HI")])
8532 ;; We cannot use div/idiv for double division, because it causes
8533 ;; "division by zero" on the overflow and that's not what we expect
8534 ;; from truncate. Because true (non truncating) double division is
8535 ;; never generated, we can't create this insn anyway.
8538 ; [(set (match_operand:SI 0 "register_operand" "=a")
8540 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8542 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8543 ; (set (match_operand:SI 3 "register_operand" "=d")
8545 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8546 ; (clobber (reg:CC FLAGS_REG))]
8548 ; "div{l}\t{%2, %0|%0, %2}"
8549 ; [(set_attr "type" "idiv")])
8551 ;;- Logical AND instructions
8553 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8554 ;; Note that this excludes ah.
8556 (define_insn "*testdi_1_rex64"
8557 [(set (reg FLAGS_REG)
8559 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8560 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8562 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8563 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8565 test{l}\t{%k1, %k0|%k0, %k1}
8566 test{l}\t{%k1, %k0|%k0, %k1}
8567 test{q}\t{%1, %0|%0, %1}
8568 test{q}\t{%1, %0|%0, %1}
8569 test{q}\t{%1, %0|%0, %1}"
8570 [(set_attr "type" "test")
8571 (set_attr "modrm" "0,1,0,1,1")
8572 (set_attr "mode" "SI,SI,DI,DI,DI")
8573 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8575 (define_insn "testsi_1"
8576 [(set (reg FLAGS_REG)
8578 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8579 (match_operand:SI 1 "general_operand" "in,in,rin"))
8581 "ix86_match_ccmode (insn, CCNOmode)
8582 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8583 "test{l}\t{%1, %0|%0, %1}"
8584 [(set_attr "type" "test")
8585 (set_attr "modrm" "0,1,1")
8586 (set_attr "mode" "SI")
8587 (set_attr "pent_pair" "uv,np,uv")])
8589 (define_expand "testsi_ccno_1"
8590 [(set (reg:CCNO FLAGS_REG)
8592 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8593 (match_operand:SI 1 "nonmemory_operand" ""))
8598 (define_insn "*testhi_1"
8599 [(set (reg FLAGS_REG)
8600 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8601 (match_operand:HI 1 "general_operand" "n,n,rn"))
8603 "ix86_match_ccmode (insn, CCNOmode)
8604 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8605 "test{w}\t{%1, %0|%0, %1}"
8606 [(set_attr "type" "test")
8607 (set_attr "modrm" "0,1,1")
8608 (set_attr "mode" "HI")
8609 (set_attr "pent_pair" "uv,np,uv")])
8611 (define_expand "testqi_ccz_1"
8612 [(set (reg:CCZ FLAGS_REG)
8613 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8614 (match_operand:QI 1 "nonmemory_operand" ""))
8619 (define_insn "*testqi_1_maybe_si"
8620 [(set (reg FLAGS_REG)
8623 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8624 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8626 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8627 && ix86_match_ccmode (insn,
8628 CONST_INT_P (operands[1])
8629 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8631 if (which_alternative == 3)
8633 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8634 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8635 return "test{l}\t{%1, %k0|%k0, %1}";
8637 return "test{b}\t{%1, %0|%0, %1}";
8639 [(set_attr "type" "test")
8640 (set_attr "modrm" "0,1,1,1")
8641 (set_attr "mode" "QI,QI,QI,SI")
8642 (set_attr "pent_pair" "uv,np,uv,np")])
8644 (define_insn "*testqi_1"
8645 [(set (reg FLAGS_REG)
8648 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8649 (match_operand:QI 1 "general_operand" "n,n,qn"))
8651 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8652 && ix86_match_ccmode (insn, CCNOmode)"
8653 "test{b}\t{%1, %0|%0, %1}"
8654 [(set_attr "type" "test")
8655 (set_attr "modrm" "0,1,1")
8656 (set_attr "mode" "QI")
8657 (set_attr "pent_pair" "uv,np,uv")])
8659 (define_expand "testqi_ext_ccno_0"
8660 [(set (reg:CCNO FLAGS_REG)
8664 (match_operand 0 "ext_register_operand" "")
8667 (match_operand 1 "const_int_operand" ""))
8672 (define_insn "*testqi_ext_0"
8673 [(set (reg FLAGS_REG)
8677 (match_operand 0 "ext_register_operand" "Q")
8680 (match_operand 1 "const_int_operand" "n"))
8682 "ix86_match_ccmode (insn, CCNOmode)"
8683 "test{b}\t{%1, %h0|%h0, %1}"
8684 [(set_attr "type" "test")
8685 (set_attr "mode" "QI")
8686 (set_attr "length_immediate" "1")
8687 (set_attr "pent_pair" "np")])
8689 (define_insn "*testqi_ext_1"
8690 [(set (reg FLAGS_REG)
8694 (match_operand 0 "ext_register_operand" "Q")
8698 (match_operand:QI 1 "general_operand" "Qm")))
8700 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8701 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8702 "test{b}\t{%1, %h0|%h0, %1}"
8703 [(set_attr "type" "test")
8704 (set_attr "mode" "QI")])
8706 (define_insn "*testqi_ext_1_rex64"
8707 [(set (reg FLAGS_REG)
8711 (match_operand 0 "ext_register_operand" "Q")
8715 (match_operand:QI 1 "register_operand" "Q")))
8717 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8718 "test{b}\t{%1, %h0|%h0, %1}"
8719 [(set_attr "type" "test")
8720 (set_attr "mode" "QI")])
8722 (define_insn "*testqi_ext_2"
8723 [(set (reg FLAGS_REG)
8727 (match_operand 0 "ext_register_operand" "Q")
8731 (match_operand 1 "ext_register_operand" "Q")
8735 "ix86_match_ccmode (insn, CCNOmode)"
8736 "test{b}\t{%h1, %h0|%h0, %h1}"
8737 [(set_attr "type" "test")
8738 (set_attr "mode" "QI")])
8740 ;; Combine likes to form bit extractions for some tests. Humor it.
8741 (define_insn "*testqi_ext_3"
8742 [(set (reg FLAGS_REG)
8743 (compare (zero_extract:SI
8744 (match_operand 0 "nonimmediate_operand" "rm")
8745 (match_operand:SI 1 "const_int_operand" "")
8746 (match_operand:SI 2 "const_int_operand" ""))
8748 "ix86_match_ccmode (insn, CCNOmode)
8749 && INTVAL (operands[1]) > 0
8750 && INTVAL (operands[2]) >= 0
8751 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8752 && (GET_MODE (operands[0]) == SImode
8753 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8754 || GET_MODE (operands[0]) == HImode
8755 || GET_MODE (operands[0]) == QImode)"
8758 (define_insn "*testqi_ext_3_rex64"
8759 [(set (reg FLAGS_REG)
8760 (compare (zero_extract:DI
8761 (match_operand 0 "nonimmediate_operand" "rm")
8762 (match_operand:DI 1 "const_int_operand" "")
8763 (match_operand:DI 2 "const_int_operand" ""))
8766 && ix86_match_ccmode (insn, CCNOmode)
8767 && INTVAL (operands[1]) > 0
8768 && INTVAL (operands[2]) >= 0
8769 /* Ensure that resulting mask is zero or sign extended operand. */
8770 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8771 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8772 && INTVAL (operands[1]) > 32))
8773 && (GET_MODE (operands[0]) == SImode
8774 || GET_MODE (operands[0]) == DImode
8775 || GET_MODE (operands[0]) == HImode
8776 || GET_MODE (operands[0]) == QImode)"
8780 [(set (match_operand 0 "flags_reg_operand" "")
8781 (match_operator 1 "compare_operator"
8783 (match_operand 2 "nonimmediate_operand" "")
8784 (match_operand 3 "const_int_operand" "")
8785 (match_operand 4 "const_int_operand" ""))
8787 "ix86_match_ccmode (insn, CCNOmode)"
8788 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8790 rtx val = operands[2];
8791 HOST_WIDE_INT len = INTVAL (operands[3]);
8792 HOST_WIDE_INT pos = INTVAL (operands[4]);
8794 enum machine_mode mode, submode;
8796 mode = GET_MODE (val);
8799 /* ??? Combine likes to put non-volatile mem extractions in QImode
8800 no matter the size of the test. So find a mode that works. */
8801 if (! MEM_VOLATILE_P (val))
8803 mode = smallest_mode_for_size (pos + len, MODE_INT);
8804 val = adjust_address (val, mode, 0);
8807 else if (GET_CODE (val) == SUBREG
8808 && (submode = GET_MODE (SUBREG_REG (val)),
8809 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8810 && pos + len <= GET_MODE_BITSIZE (submode))
8812 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8814 val = SUBREG_REG (val);
8816 else if (mode == HImode && pos + len <= 8)
8818 /* Small HImode tests can be converted to QImode. */
8820 val = gen_lowpart (QImode, val);
8823 if (len == HOST_BITS_PER_WIDE_INT)
8826 mask = ((HOST_WIDE_INT)1 << len) - 1;
8829 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8832 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8833 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8834 ;; this is relatively important trick.
8835 ;; Do the conversion only post-reload to avoid limiting of the register class
8838 [(set (match_operand 0 "flags_reg_operand" "")
8839 (match_operator 1 "compare_operator"
8840 [(and (match_operand 2 "register_operand" "")
8841 (match_operand 3 "const_int_operand" ""))
8844 && QI_REG_P (operands[2])
8845 && GET_MODE (operands[2]) != QImode
8846 && ((ix86_match_ccmode (insn, CCZmode)
8847 && !(INTVAL (operands[3]) & ~(255 << 8)))
8848 || (ix86_match_ccmode (insn, CCNOmode)
8849 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8852 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8855 "operands[2] = gen_lowpart (SImode, operands[2]);
8856 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8859 [(set (match_operand 0 "flags_reg_operand" "")
8860 (match_operator 1 "compare_operator"
8861 [(and (match_operand 2 "nonimmediate_operand" "")
8862 (match_operand 3 "const_int_operand" ""))
8865 && GET_MODE (operands[2]) != QImode
8866 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8867 && ((ix86_match_ccmode (insn, CCZmode)
8868 && !(INTVAL (operands[3]) & ~255))
8869 || (ix86_match_ccmode (insn, CCNOmode)
8870 && !(INTVAL (operands[3]) & ~127)))"
8872 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8874 "operands[2] = gen_lowpart (QImode, operands[2]);
8875 operands[3] = gen_lowpart (QImode, operands[3]);")
8878 ;; %%% This used to optimize known byte-wide and operations to memory,
8879 ;; and sometimes to QImode registers. If this is considered useful,
8880 ;; it should be done with splitters.
8882 (define_expand "anddi3"
8883 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8884 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8885 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8886 (clobber (reg:CC FLAGS_REG))]
8888 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8890 (define_insn "*anddi_1_rex64"
8891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8892 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8893 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8894 (clobber (reg:CC FLAGS_REG))]
8895 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8897 switch (get_attr_type (insn))
8901 enum machine_mode mode;
8903 gcc_assert (CONST_INT_P (operands[2]));
8904 if (INTVAL (operands[2]) == 0xff)
8908 gcc_assert (INTVAL (operands[2]) == 0xffff);
8912 operands[1] = gen_lowpart (mode, operands[1]);
8914 return "movz{bq|x}\t{%1,%0|%0, %1}";
8916 return "movz{wq|x}\t{%1,%0|%0, %1}";
8920 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8921 if (get_attr_mode (insn) == MODE_SI)
8922 return "and{l}\t{%k2, %k0|%k0, %k2}";
8924 return "and{q}\t{%2, %0|%0, %2}";
8927 [(set_attr "type" "alu,alu,alu,imovx")
8928 (set_attr "length_immediate" "*,*,*,0")
8929 (set_attr "mode" "SI,DI,DI,DI")])
8931 (define_insn "*anddi_2"
8932 [(set (reg FLAGS_REG)
8933 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8934 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8936 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8937 (and:DI (match_dup 1) (match_dup 2)))]
8938 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8939 && ix86_binary_operator_ok (AND, DImode, operands)"
8941 and{l}\t{%k2, %k0|%k0, %k2}
8942 and{q}\t{%2, %0|%0, %2}
8943 and{q}\t{%2, %0|%0, %2}"
8944 [(set_attr "type" "alu")
8945 (set_attr "mode" "SI,DI,DI")])
8947 (define_expand "andsi3"
8948 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8949 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8950 (match_operand:SI 2 "general_operand" "")))
8951 (clobber (reg:CC FLAGS_REG))]
8953 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8955 (define_insn "*andsi_1"
8956 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8957 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8958 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8959 (clobber (reg:CC FLAGS_REG))]
8960 "ix86_binary_operator_ok (AND, SImode, operands)"
8962 switch (get_attr_type (insn))
8966 enum machine_mode mode;
8968 gcc_assert (CONST_INT_P (operands[2]));
8969 if (INTVAL (operands[2]) == 0xff)
8973 gcc_assert (INTVAL (operands[2]) == 0xffff);
8977 operands[1] = gen_lowpart (mode, operands[1]);
8979 return "movz{bl|x}\t{%1,%0|%0, %1}";
8981 return "movz{wl|x}\t{%1,%0|%0, %1}";
8985 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8986 return "and{l}\t{%2, %0|%0, %2}";
8989 [(set_attr "type" "alu,alu,imovx")
8990 (set_attr "length_immediate" "*,*,0")
8991 (set_attr "mode" "SI")])
8994 [(set (match_operand 0 "register_operand" "")
8996 (const_int -65536)))
8997 (clobber (reg:CC FLAGS_REG))]
8998 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8999 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9000 "operands[1] = gen_lowpart (HImode, operands[0]);")
9003 [(set (match_operand 0 "ext_register_operand" "")
9006 (clobber (reg:CC FLAGS_REG))]
9007 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9008 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9009 "operands[1] = gen_lowpart (QImode, operands[0]);")
9012 [(set (match_operand 0 "ext_register_operand" "")
9014 (const_int -65281)))
9015 (clobber (reg:CC FLAGS_REG))]
9016 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9017 [(parallel [(set (zero_extract:SI (match_dup 0)
9021 (zero_extract:SI (match_dup 0)
9024 (zero_extract:SI (match_dup 0)
9027 (clobber (reg:CC FLAGS_REG))])]
9028 "operands[0] = gen_lowpart (SImode, operands[0]);")
9030 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9031 (define_insn "*andsi_1_zext"
9032 [(set (match_operand:DI 0 "register_operand" "=r")
9034 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9035 (match_operand:SI 2 "general_operand" "g"))))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9038 "and{l}\t{%2, %k0|%k0, %2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "SI")])
9042 (define_insn "*andsi_2"
9043 [(set (reg FLAGS_REG)
9044 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9045 (match_operand:SI 2 "general_operand" "g,ri"))
9047 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9048 (and:SI (match_dup 1) (match_dup 2)))]
9049 "ix86_match_ccmode (insn, CCNOmode)
9050 && ix86_binary_operator_ok (AND, SImode, operands)"
9051 "and{l}\t{%2, %0|%0, %2}"
9052 [(set_attr "type" "alu")
9053 (set_attr "mode" "SI")])
9055 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9056 (define_insn "*andsi_2_zext"
9057 [(set (reg FLAGS_REG)
9058 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059 (match_operand:SI 2 "general_operand" "g"))
9061 (set (match_operand:DI 0 "register_operand" "=r")
9062 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9063 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_binary_operator_ok (AND, SImode, operands)"
9065 "and{l}\t{%2, %k0|%k0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "SI")])
9069 (define_expand "andhi3"
9070 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9071 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9072 (match_operand:HI 2 "general_operand" "")))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "TARGET_HIMODE_MATH"
9075 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9077 (define_insn "*andhi_1"
9078 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9079 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9080 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9081 (clobber (reg:CC FLAGS_REG))]
9082 "ix86_binary_operator_ok (AND, HImode, operands)"
9084 switch (get_attr_type (insn))
9087 gcc_assert (CONST_INT_P (operands[2]));
9088 gcc_assert (INTVAL (operands[2]) == 0xff);
9089 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9092 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9094 return "and{w}\t{%2, %0|%0, %2}";
9097 [(set_attr "type" "alu,alu,imovx")
9098 (set_attr "length_immediate" "*,*,0")
9099 (set_attr "mode" "HI,HI,SI")])
9101 (define_insn "*andhi_2"
9102 [(set (reg FLAGS_REG)
9103 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9104 (match_operand:HI 2 "general_operand" "g,ri"))
9106 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9107 (and:HI (match_dup 1) (match_dup 2)))]
9108 "ix86_match_ccmode (insn, CCNOmode)
9109 && ix86_binary_operator_ok (AND, HImode, operands)"
9110 "and{w}\t{%2, %0|%0, %2}"
9111 [(set_attr "type" "alu")
9112 (set_attr "mode" "HI")])
9114 (define_expand "andqi3"
9115 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9116 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9117 (match_operand:QI 2 "general_operand" "")))
9118 (clobber (reg:CC FLAGS_REG))]
9119 "TARGET_QIMODE_MATH"
9120 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9122 ;; %%% Potential partial reg stall on alternative 2. What to do?
9123 (define_insn "*andqi_1"
9124 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9125 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9126 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9127 (clobber (reg:CC FLAGS_REG))]
9128 "ix86_binary_operator_ok (AND, QImode, operands)"
9130 and{b}\t{%2, %0|%0, %2}
9131 and{b}\t{%2, %0|%0, %2}
9132 and{l}\t{%k2, %k0|%k0, %k2}"
9133 [(set_attr "type" "alu")
9134 (set_attr "mode" "QI,QI,SI")])
9136 (define_insn "*andqi_1_slp"
9137 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9138 (and:QI (match_dup 0)
9139 (match_operand:QI 1 "general_operand" "qi,qmi")))
9140 (clobber (reg:CC FLAGS_REG))]
9141 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9142 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9143 "and{b}\t{%1, %0|%0, %1}"
9144 [(set_attr "type" "alu1")
9145 (set_attr "mode" "QI")])
9147 (define_insn "*andqi_2_maybe_si"
9148 [(set (reg FLAGS_REG)
9150 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9151 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9153 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9154 (and:QI (match_dup 1) (match_dup 2)))]
9155 "ix86_binary_operator_ok (AND, QImode, operands)
9156 && ix86_match_ccmode (insn,
9157 CONST_INT_P (operands[2])
9158 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9160 if (which_alternative == 2)
9162 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9163 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9164 return "and{l}\t{%2, %k0|%k0, %2}";
9166 return "and{b}\t{%2, %0|%0, %2}";
9168 [(set_attr "type" "alu")
9169 (set_attr "mode" "QI,QI,SI")])
9171 (define_insn "*andqi_2"
9172 [(set (reg FLAGS_REG)
9174 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9175 (match_operand:QI 2 "general_operand" "qim,qi"))
9177 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9178 (and:QI (match_dup 1) (match_dup 2)))]
9179 "ix86_match_ccmode (insn, CCNOmode)
9180 && ix86_binary_operator_ok (AND, QImode, operands)"
9181 "and{b}\t{%2, %0|%0, %2}"
9182 [(set_attr "type" "alu")
9183 (set_attr "mode" "QI")])
9185 (define_insn "*andqi_2_slp"
9186 [(set (reg FLAGS_REG)
9188 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9189 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9191 (set (strict_low_part (match_dup 0))
9192 (and:QI (match_dup 0) (match_dup 1)))]
9193 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9194 && ix86_match_ccmode (insn, CCNOmode)
9195 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9196 "and{b}\t{%1, %0|%0, %1}"
9197 [(set_attr "type" "alu1")
9198 (set_attr "mode" "QI")])
9200 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9201 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9202 ;; for a QImode operand, which of course failed.
9204 (define_insn "andqi_ext_0"
9205 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9210 (match_operand 1 "ext_register_operand" "0")
9213 (match_operand 2 "const_int_operand" "n")))
9214 (clobber (reg:CC FLAGS_REG))]
9216 "and{b}\t{%2, %h0|%h0, %2}"
9217 [(set_attr "type" "alu")
9218 (set_attr "length_immediate" "1")
9219 (set_attr "mode" "QI")])
9221 ;; Generated by peephole translating test to and. This shows up
9222 ;; often in fp comparisons.
9224 (define_insn "*andqi_ext_0_cc"
9225 [(set (reg FLAGS_REG)
9229 (match_operand 1 "ext_register_operand" "0")
9232 (match_operand 2 "const_int_operand" "n"))
9234 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9243 "ix86_match_ccmode (insn, CCNOmode)"
9244 "and{b}\t{%2, %h0|%h0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "length_immediate" "1")
9247 (set_attr "mode" "QI")])
9249 (define_insn "*andqi_ext_1"
9250 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9255 (match_operand 1 "ext_register_operand" "0")
9259 (match_operand:QI 2 "general_operand" "Qm"))))
9260 (clobber (reg:CC FLAGS_REG))]
9262 "and{b}\t{%2, %h0|%h0, %2}"
9263 [(set_attr "type" "alu")
9264 (set_attr "length_immediate" "0")
9265 (set_attr "mode" "QI")])
9267 (define_insn "*andqi_ext_1_rex64"
9268 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9273 (match_operand 1 "ext_register_operand" "0")
9277 (match_operand 2 "ext_register_operand" "Q"))))
9278 (clobber (reg:CC FLAGS_REG))]
9280 "and{b}\t{%2, %h0|%h0, %2}"
9281 [(set_attr "type" "alu")
9282 (set_attr "length_immediate" "0")
9283 (set_attr "mode" "QI")])
9285 (define_insn "*andqi_ext_2"
9286 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9291 (match_operand 1 "ext_register_operand" "%0")
9295 (match_operand 2 "ext_register_operand" "Q")
9298 (clobber (reg:CC FLAGS_REG))]
9300 "and{b}\t{%h2, %h0|%h0, %h2}"
9301 [(set_attr "type" "alu")
9302 (set_attr "length_immediate" "0")
9303 (set_attr "mode" "QI")])
9305 ;; Convert wide AND instructions with immediate operand to shorter QImode
9306 ;; equivalents when possible.
9307 ;; Don't do the splitting with memory operands, since it introduces risk
9308 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9309 ;; for size, but that can (should?) be handled by generic code instead.
9311 [(set (match_operand 0 "register_operand" "")
9312 (and (match_operand 1 "register_operand" "")
9313 (match_operand 2 "const_int_operand" "")))
9314 (clobber (reg:CC FLAGS_REG))]
9316 && QI_REG_P (operands[0])
9317 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9318 && !(~INTVAL (operands[2]) & ~(255 << 8))
9319 && GET_MODE (operands[0]) != QImode"
9320 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9321 (and:SI (zero_extract:SI (match_dup 1)
9322 (const_int 8) (const_int 8))
9324 (clobber (reg:CC FLAGS_REG))])]
9325 "operands[0] = gen_lowpart (SImode, operands[0]);
9326 operands[1] = gen_lowpart (SImode, operands[1]);
9327 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9329 ;; Since AND can be encoded with sign extended immediate, this is only
9330 ;; profitable when 7th bit is not set.
9332 [(set (match_operand 0 "register_operand" "")
9333 (and (match_operand 1 "general_operand" "")
9334 (match_operand 2 "const_int_operand" "")))
9335 (clobber (reg:CC FLAGS_REG))]
9337 && ANY_QI_REG_P (operands[0])
9338 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9339 && !(~INTVAL (operands[2]) & ~255)
9340 && !(INTVAL (operands[2]) & 128)
9341 && GET_MODE (operands[0]) != QImode"
9342 [(parallel [(set (strict_low_part (match_dup 0))
9343 (and:QI (match_dup 1)
9345 (clobber (reg:CC FLAGS_REG))])]
9346 "operands[0] = gen_lowpart (QImode, operands[0]);
9347 operands[1] = gen_lowpart (QImode, operands[1]);
9348 operands[2] = gen_lowpart (QImode, operands[2]);")
9350 ;; Logical inclusive OR instructions
9352 ;; %%% This used to optimize known byte-wide and operations to memory.
9353 ;; If this is considered useful, it should be done with splitters.
9355 (define_expand "iordi3"
9356 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9357 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9358 (match_operand:DI 2 "x86_64_general_operand" "")))
9359 (clobber (reg:CC FLAGS_REG))]
9361 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9363 (define_insn "*iordi_1_rex64"
9364 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9365 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9366 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9367 (clobber (reg:CC FLAGS_REG))]
9369 && ix86_binary_operator_ok (IOR, DImode, operands)"
9370 "or{q}\t{%2, %0|%0, %2}"
9371 [(set_attr "type" "alu")
9372 (set_attr "mode" "DI")])
9374 (define_insn "*iordi_2_rex64"
9375 [(set (reg FLAGS_REG)
9376 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9377 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9379 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9380 (ior:DI (match_dup 1) (match_dup 2)))]
9382 && ix86_match_ccmode (insn, CCNOmode)
9383 && ix86_binary_operator_ok (IOR, DImode, operands)"
9384 "or{q}\t{%2, %0|%0, %2}"
9385 [(set_attr "type" "alu")
9386 (set_attr "mode" "DI")])
9388 (define_insn "*iordi_3_rex64"
9389 [(set (reg FLAGS_REG)
9390 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9391 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9393 (clobber (match_scratch:DI 0 "=r"))]
9395 && ix86_match_ccmode (insn, CCNOmode)
9396 && ix86_binary_operator_ok (IOR, DImode, operands)"
9397 "or{q}\t{%2, %0|%0, %2}"
9398 [(set_attr "type" "alu")
9399 (set_attr "mode" "DI")])
9402 (define_expand "iorsi3"
9403 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9404 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9405 (match_operand:SI 2 "general_operand" "")))
9406 (clobber (reg:CC FLAGS_REG))]
9408 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9410 (define_insn "*iorsi_1"
9411 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9412 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9413 (match_operand:SI 2 "general_operand" "ri,g")))
9414 (clobber (reg:CC FLAGS_REG))]
9415 "ix86_binary_operator_ok (IOR, SImode, operands)"
9416 "or{l}\t{%2, %0|%0, %2}"
9417 [(set_attr "type" "alu")
9418 (set_attr "mode" "SI")])
9420 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9421 (define_insn "*iorsi_1_zext"
9422 [(set (match_operand:DI 0 "register_operand" "=r")
9424 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9425 (match_operand:SI 2 "general_operand" "g"))))
9426 (clobber (reg:CC FLAGS_REG))]
9427 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9428 "or{l}\t{%2, %k0|%k0, %2}"
9429 [(set_attr "type" "alu")
9430 (set_attr "mode" "SI")])
9432 (define_insn "*iorsi_1_zext_imm"
9433 [(set (match_operand:DI 0 "register_operand" "=r")
9434 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9435 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9436 (clobber (reg:CC FLAGS_REG))]
9438 "or{l}\t{%2, %k0|%k0, %2}"
9439 [(set_attr "type" "alu")
9440 (set_attr "mode" "SI")])
9442 (define_insn "*iorsi_2"
9443 [(set (reg FLAGS_REG)
9444 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9445 (match_operand:SI 2 "general_operand" "g,ri"))
9447 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9448 (ior:SI (match_dup 1) (match_dup 2)))]
9449 "ix86_match_ccmode (insn, CCNOmode)
9450 && ix86_binary_operator_ok (IOR, SImode, operands)"
9451 "or{l}\t{%2, %0|%0, %2}"
9452 [(set_attr "type" "alu")
9453 (set_attr "mode" "SI")])
9455 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9456 ;; ??? Special case for immediate operand is missing - it is tricky.
9457 (define_insn "*iorsi_2_zext"
9458 [(set (reg FLAGS_REG)
9459 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9460 (match_operand:SI 2 "general_operand" "g"))
9462 (set (match_operand:DI 0 "register_operand" "=r")
9463 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9464 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9465 && ix86_binary_operator_ok (IOR, SImode, operands)"
9466 "or{l}\t{%2, %k0|%k0, %2}"
9467 [(set_attr "type" "alu")
9468 (set_attr "mode" "SI")])
9470 (define_insn "*iorsi_2_zext_imm"
9471 [(set (reg FLAGS_REG)
9472 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9473 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9475 (set (match_operand:DI 0 "register_operand" "=r")
9476 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9477 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9478 && ix86_binary_operator_ok (IOR, SImode, operands)"
9479 "or{l}\t{%2, %k0|%k0, %2}"
9480 [(set_attr "type" "alu")
9481 (set_attr "mode" "SI")])
9483 (define_insn "*iorsi_3"
9484 [(set (reg FLAGS_REG)
9485 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9486 (match_operand:SI 2 "general_operand" "g"))
9488 (clobber (match_scratch:SI 0 "=r"))]
9489 "ix86_match_ccmode (insn, CCNOmode)
9490 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9491 "or{l}\t{%2, %0|%0, %2}"
9492 [(set_attr "type" "alu")
9493 (set_attr "mode" "SI")])
9495 (define_expand "iorhi3"
9496 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9497 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9498 (match_operand:HI 2 "general_operand" "")))
9499 (clobber (reg:CC FLAGS_REG))]
9500 "TARGET_HIMODE_MATH"
9501 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9503 (define_insn "*iorhi_1"
9504 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9505 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9506 (match_operand:HI 2 "general_operand" "g,ri")))
9507 (clobber (reg:CC FLAGS_REG))]
9508 "ix86_binary_operator_ok (IOR, HImode, operands)"
9509 "or{w}\t{%2, %0|%0, %2}"
9510 [(set_attr "type" "alu")
9511 (set_attr "mode" "HI")])
9513 (define_insn "*iorhi_2"
9514 [(set (reg FLAGS_REG)
9515 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9516 (match_operand:HI 2 "general_operand" "g,ri"))
9518 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9519 (ior:HI (match_dup 1) (match_dup 2)))]
9520 "ix86_match_ccmode (insn, CCNOmode)
9521 && ix86_binary_operator_ok (IOR, HImode, operands)"
9522 "or{w}\t{%2, %0|%0, %2}"
9523 [(set_attr "type" "alu")
9524 (set_attr "mode" "HI")])
9526 (define_insn "*iorhi_3"
9527 [(set (reg FLAGS_REG)
9528 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9529 (match_operand:HI 2 "general_operand" "g"))
9531 (clobber (match_scratch:HI 0 "=r"))]
9532 "ix86_match_ccmode (insn, CCNOmode)
9533 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9534 "or{w}\t{%2, %0|%0, %2}"
9535 [(set_attr "type" "alu")
9536 (set_attr "mode" "HI")])
9538 (define_expand "iorqi3"
9539 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9540 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9541 (match_operand:QI 2 "general_operand" "")))
9542 (clobber (reg:CC FLAGS_REG))]
9543 "TARGET_QIMODE_MATH"
9544 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9546 ;; %%% Potential partial reg stall on alternative 2. What to do?
9547 (define_insn "*iorqi_1"
9548 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9549 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9550 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9551 (clobber (reg:CC FLAGS_REG))]
9552 "ix86_binary_operator_ok (IOR, QImode, operands)"
9554 or{b}\t{%2, %0|%0, %2}
9555 or{b}\t{%2, %0|%0, %2}
9556 or{l}\t{%k2, %k0|%k0, %k2}"
9557 [(set_attr "type" "alu")
9558 (set_attr "mode" "QI,QI,SI")])
9560 (define_insn "*iorqi_1_slp"
9561 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9562 (ior:QI (match_dup 0)
9563 (match_operand:QI 1 "general_operand" "qmi,qi")))
9564 (clobber (reg:CC FLAGS_REG))]
9565 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9566 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9567 "or{b}\t{%1, %0|%0, %1}"
9568 [(set_attr "type" "alu1")
9569 (set_attr "mode" "QI")])
9571 (define_insn "*iorqi_2"
9572 [(set (reg FLAGS_REG)
9573 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9574 (match_operand:QI 2 "general_operand" "qim,qi"))
9576 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9577 (ior:QI (match_dup 1) (match_dup 2)))]
9578 "ix86_match_ccmode (insn, CCNOmode)
9579 && ix86_binary_operator_ok (IOR, QImode, operands)"
9580 "or{b}\t{%2, %0|%0, %2}"
9581 [(set_attr "type" "alu")
9582 (set_attr "mode" "QI")])
9584 (define_insn "*iorqi_2_slp"
9585 [(set (reg FLAGS_REG)
9586 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9587 (match_operand:QI 1 "general_operand" "qim,qi"))
9589 (set (strict_low_part (match_dup 0))
9590 (ior:QI (match_dup 0) (match_dup 1)))]
9591 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9592 && ix86_match_ccmode (insn, CCNOmode)
9593 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9594 "or{b}\t{%1, %0|%0, %1}"
9595 [(set_attr "type" "alu1")
9596 (set_attr "mode" "QI")])
9598 (define_insn "*iorqi_3"
9599 [(set (reg FLAGS_REG)
9600 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9601 (match_operand:QI 2 "general_operand" "qim"))
9603 (clobber (match_scratch:QI 0 "=q"))]
9604 "ix86_match_ccmode (insn, CCNOmode)
9605 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9606 "or{b}\t{%2, %0|%0, %2}"
9607 [(set_attr "type" "alu")
9608 (set_attr "mode" "QI")])
9610 (define_insn "iorqi_ext_0"
9611 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9616 (match_operand 1 "ext_register_operand" "0")
9619 (match_operand 2 "const_int_operand" "n")))
9620 (clobber (reg:CC FLAGS_REG))]
9621 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9622 "or{b}\t{%2, %h0|%h0, %2}"
9623 [(set_attr "type" "alu")
9624 (set_attr "length_immediate" "1")
9625 (set_attr "mode" "QI")])
9627 (define_insn "*iorqi_ext_1"
9628 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9633 (match_operand 1 "ext_register_operand" "0")
9637 (match_operand:QI 2 "general_operand" "Qm"))))
9638 (clobber (reg:CC FLAGS_REG))]
9640 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9641 "or{b}\t{%2, %h0|%h0, %2}"
9642 [(set_attr "type" "alu")
9643 (set_attr "length_immediate" "0")
9644 (set_attr "mode" "QI")])
9646 (define_insn "*iorqi_ext_1_rex64"
9647 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9652 (match_operand 1 "ext_register_operand" "0")
9656 (match_operand 2 "ext_register_operand" "Q"))))
9657 (clobber (reg:CC FLAGS_REG))]
9659 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9660 "or{b}\t{%2, %h0|%h0, %2}"
9661 [(set_attr "type" "alu")
9662 (set_attr "length_immediate" "0")
9663 (set_attr "mode" "QI")])
9665 (define_insn "*iorqi_ext_2"
9666 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9670 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9673 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9676 (clobber (reg:CC FLAGS_REG))]
9677 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9678 "ior{b}\t{%h2, %h0|%h0, %h2}"
9679 [(set_attr "type" "alu")
9680 (set_attr "length_immediate" "0")
9681 (set_attr "mode" "QI")])
9684 [(set (match_operand 0 "register_operand" "")
9685 (ior (match_operand 1 "register_operand" "")
9686 (match_operand 2 "const_int_operand" "")))
9687 (clobber (reg:CC FLAGS_REG))]
9689 && QI_REG_P (operands[0])
9690 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9691 && !(INTVAL (operands[2]) & ~(255 << 8))
9692 && GET_MODE (operands[0]) != QImode"
9693 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9694 (ior:SI (zero_extract:SI (match_dup 1)
9695 (const_int 8) (const_int 8))
9697 (clobber (reg:CC FLAGS_REG))])]
9698 "operands[0] = gen_lowpart (SImode, operands[0]);
9699 operands[1] = gen_lowpart (SImode, operands[1]);
9700 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9702 ;; Since OR can be encoded with sign extended immediate, this is only
9703 ;; profitable when 7th bit is set.
9705 [(set (match_operand 0 "register_operand" "")
9706 (ior (match_operand 1 "general_operand" "")
9707 (match_operand 2 "const_int_operand" "")))
9708 (clobber (reg:CC FLAGS_REG))]
9710 && ANY_QI_REG_P (operands[0])
9711 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9712 && !(INTVAL (operands[2]) & ~255)
9713 && (INTVAL (operands[2]) & 128)
9714 && GET_MODE (operands[0]) != QImode"
9715 [(parallel [(set (strict_low_part (match_dup 0))
9716 (ior:QI (match_dup 1)
9718 (clobber (reg:CC FLAGS_REG))])]
9719 "operands[0] = gen_lowpart (QImode, operands[0]);
9720 operands[1] = gen_lowpart (QImode, operands[1]);
9721 operands[2] = gen_lowpart (QImode, operands[2]);")
9723 ;; Logical XOR instructions
9725 ;; %%% This used to optimize known byte-wide and operations to memory.
9726 ;; If this is considered useful, it should be done with splitters.
9728 (define_expand "xordi3"
9729 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9730 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9731 (match_operand:DI 2 "x86_64_general_operand" "")))
9732 (clobber (reg:CC FLAGS_REG))]
9734 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9736 (define_insn "*xordi_1_rex64"
9737 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9738 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9739 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9740 (clobber (reg:CC FLAGS_REG))]
9742 && ix86_binary_operator_ok (XOR, DImode, operands)"
9743 "xor{q}\t{%2, %0|%0, %2}"
9744 [(set_attr "type" "alu")
9745 (set_attr "mode" "DI")])
9747 (define_insn "*xordi_2_rex64"
9748 [(set (reg FLAGS_REG)
9749 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9750 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9752 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9753 (xor:DI (match_dup 1) (match_dup 2)))]
9755 && ix86_match_ccmode (insn, CCNOmode)
9756 && ix86_binary_operator_ok (XOR, DImode, operands)"
9757 "xor{q}\t{%2, %0|%0, %2}"
9758 [(set_attr "type" "alu")
9759 (set_attr "mode" "DI")])
9761 (define_insn "*xordi_3_rex64"
9762 [(set (reg FLAGS_REG)
9763 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9764 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9766 (clobber (match_scratch:DI 0 "=r"))]
9768 && ix86_match_ccmode (insn, CCNOmode)
9769 && ix86_binary_operator_ok (XOR, DImode, operands)"
9770 "xor{q}\t{%2, %0|%0, %2}"
9771 [(set_attr "type" "alu")
9772 (set_attr "mode" "DI")])
9774 (define_expand "xorsi3"
9775 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9776 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9777 (match_operand:SI 2 "general_operand" "")))
9778 (clobber (reg:CC FLAGS_REG))]
9780 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9782 (define_insn "*xorsi_1"
9783 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9784 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9785 (match_operand:SI 2 "general_operand" "ri,rm")))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "ix86_binary_operator_ok (XOR, SImode, operands)"
9788 "xor{l}\t{%2, %0|%0, %2}"
9789 [(set_attr "type" "alu")
9790 (set_attr "mode" "SI")])
9792 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9793 ;; Add speccase for immediates
9794 (define_insn "*xorsi_1_zext"
9795 [(set (match_operand:DI 0 "register_operand" "=r")
9797 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9798 (match_operand:SI 2 "general_operand" "g"))))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9801 "xor{l}\t{%2, %k0|%k0, %2}"
9802 [(set_attr "type" "alu")
9803 (set_attr "mode" "SI")])
9805 (define_insn "*xorsi_1_zext_imm"
9806 [(set (match_operand:DI 0 "register_operand" "=r")
9807 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9808 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9809 (clobber (reg:CC FLAGS_REG))]
9810 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9811 "xor{l}\t{%2, %k0|%k0, %2}"
9812 [(set_attr "type" "alu")
9813 (set_attr "mode" "SI")])
9815 (define_insn "*xorsi_2"
9816 [(set (reg FLAGS_REG)
9817 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9818 (match_operand:SI 2 "general_operand" "g,ri"))
9820 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9821 (xor:SI (match_dup 1) (match_dup 2)))]
9822 "ix86_match_ccmode (insn, CCNOmode)
9823 && ix86_binary_operator_ok (XOR, SImode, operands)"
9824 "xor{l}\t{%2, %0|%0, %2}"
9825 [(set_attr "type" "alu")
9826 (set_attr "mode" "SI")])
9828 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9829 ;; ??? Special case for immediate operand is missing - it is tricky.
9830 (define_insn "*xorsi_2_zext"
9831 [(set (reg FLAGS_REG)
9832 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9833 (match_operand:SI 2 "general_operand" "g"))
9835 (set (match_operand:DI 0 "register_operand" "=r")
9836 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9837 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9838 && ix86_binary_operator_ok (XOR, SImode, operands)"
9839 "xor{l}\t{%2, %k0|%k0, %2}"
9840 [(set_attr "type" "alu")
9841 (set_attr "mode" "SI")])
9843 (define_insn "*xorsi_2_zext_imm"
9844 [(set (reg FLAGS_REG)
9845 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9846 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9848 (set (match_operand:DI 0 "register_operand" "=r")
9849 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9850 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9851 && ix86_binary_operator_ok (XOR, SImode, operands)"
9852 "xor{l}\t{%2, %k0|%k0, %2}"
9853 [(set_attr "type" "alu")
9854 (set_attr "mode" "SI")])
9856 (define_insn "*xorsi_3"
9857 [(set (reg FLAGS_REG)
9858 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9859 (match_operand:SI 2 "general_operand" "g"))
9861 (clobber (match_scratch:SI 0 "=r"))]
9862 "ix86_match_ccmode (insn, CCNOmode)
9863 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9864 "xor{l}\t{%2, %0|%0, %2}"
9865 [(set_attr "type" "alu")
9866 (set_attr "mode" "SI")])
9868 (define_expand "xorhi3"
9869 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9870 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9871 (match_operand:HI 2 "general_operand" "")))
9872 (clobber (reg:CC FLAGS_REG))]
9873 "TARGET_HIMODE_MATH"
9874 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9876 (define_insn "*xorhi_1"
9877 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9878 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9879 (match_operand:HI 2 "general_operand" "g,ri")))
9880 (clobber (reg:CC FLAGS_REG))]
9881 "ix86_binary_operator_ok (XOR, HImode, operands)"
9882 "xor{w}\t{%2, %0|%0, %2}"
9883 [(set_attr "type" "alu")
9884 (set_attr "mode" "HI")])
9886 (define_insn "*xorhi_2"
9887 [(set (reg FLAGS_REG)
9888 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9889 (match_operand:HI 2 "general_operand" "g,ri"))
9891 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9892 (xor:HI (match_dup 1) (match_dup 2)))]
9893 "ix86_match_ccmode (insn, CCNOmode)
9894 && ix86_binary_operator_ok (XOR, HImode, operands)"
9895 "xor{w}\t{%2, %0|%0, %2}"
9896 [(set_attr "type" "alu")
9897 (set_attr "mode" "HI")])
9899 (define_insn "*xorhi_3"
9900 [(set (reg FLAGS_REG)
9901 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9902 (match_operand:HI 2 "general_operand" "g"))
9904 (clobber (match_scratch:HI 0 "=r"))]
9905 "ix86_match_ccmode (insn, CCNOmode)
9906 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9907 "xor{w}\t{%2, %0|%0, %2}"
9908 [(set_attr "type" "alu")
9909 (set_attr "mode" "HI")])
9911 (define_expand "xorqi3"
9912 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9913 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9914 (match_operand:QI 2 "general_operand" "")))
9915 (clobber (reg:CC FLAGS_REG))]
9916 "TARGET_QIMODE_MATH"
9917 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9919 ;; %%% Potential partial reg stall on alternative 2. What to do?
9920 (define_insn "*xorqi_1"
9921 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9922 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9923 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9924 (clobber (reg:CC FLAGS_REG))]
9925 "ix86_binary_operator_ok (XOR, QImode, operands)"
9927 xor{b}\t{%2, %0|%0, %2}
9928 xor{b}\t{%2, %0|%0, %2}
9929 xor{l}\t{%k2, %k0|%k0, %k2}"
9930 [(set_attr "type" "alu")
9931 (set_attr "mode" "QI,QI,SI")])
9933 (define_insn "*xorqi_1_slp"
9934 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9935 (xor:QI (match_dup 0)
9936 (match_operand:QI 1 "general_operand" "qi,qmi")))
9937 (clobber (reg:CC FLAGS_REG))]
9938 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9939 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9940 "xor{b}\t{%1, %0|%0, %1}"
9941 [(set_attr "type" "alu1")
9942 (set_attr "mode" "QI")])
9944 (define_insn "xorqi_ext_0"
9945 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9950 (match_operand 1 "ext_register_operand" "0")
9953 (match_operand 2 "const_int_operand" "n")))
9954 (clobber (reg:CC FLAGS_REG))]
9955 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9956 "xor{b}\t{%2, %h0|%h0, %2}"
9957 [(set_attr "type" "alu")
9958 (set_attr "length_immediate" "1")
9959 (set_attr "mode" "QI")])
9961 (define_insn "*xorqi_ext_1"
9962 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9967 (match_operand 1 "ext_register_operand" "0")
9971 (match_operand:QI 2 "general_operand" "Qm"))))
9972 (clobber (reg:CC FLAGS_REG))]
9974 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9975 "xor{b}\t{%2, %h0|%h0, %2}"
9976 [(set_attr "type" "alu")
9977 (set_attr "length_immediate" "0")
9978 (set_attr "mode" "QI")])
9980 (define_insn "*xorqi_ext_1_rex64"
9981 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9986 (match_operand 1 "ext_register_operand" "0")
9990 (match_operand 2 "ext_register_operand" "Q"))))
9991 (clobber (reg:CC FLAGS_REG))]
9993 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9994 "xor{b}\t{%2, %h0|%h0, %2}"
9995 [(set_attr "type" "alu")
9996 (set_attr "length_immediate" "0")
9997 (set_attr "mode" "QI")])
9999 (define_insn "*xorqi_ext_2"
10000 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10004 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10007 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10010 (clobber (reg:CC FLAGS_REG))]
10011 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10012 "xor{b}\t{%h2, %h0|%h0, %h2}"
10013 [(set_attr "type" "alu")
10014 (set_attr "length_immediate" "0")
10015 (set_attr "mode" "QI")])
10017 (define_insn "*xorqi_cc_1"
10018 [(set (reg FLAGS_REG)
10020 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10021 (match_operand:QI 2 "general_operand" "qim,qi"))
10023 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10024 (xor:QI (match_dup 1) (match_dup 2)))]
10025 "ix86_match_ccmode (insn, CCNOmode)
10026 && ix86_binary_operator_ok (XOR, QImode, operands)"
10027 "xor{b}\t{%2, %0|%0, %2}"
10028 [(set_attr "type" "alu")
10029 (set_attr "mode" "QI")])
10031 (define_insn "*xorqi_2_slp"
10032 [(set (reg FLAGS_REG)
10033 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10034 (match_operand:QI 1 "general_operand" "qim,qi"))
10036 (set (strict_low_part (match_dup 0))
10037 (xor:QI (match_dup 0) (match_dup 1)))]
10038 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10039 && ix86_match_ccmode (insn, CCNOmode)
10040 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10041 "xor{b}\t{%1, %0|%0, %1}"
10042 [(set_attr "type" "alu1")
10043 (set_attr "mode" "QI")])
10045 (define_insn "*xorqi_cc_2"
10046 [(set (reg FLAGS_REG)
10048 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10049 (match_operand:QI 2 "general_operand" "qim"))
10051 (clobber (match_scratch:QI 0 "=q"))]
10052 "ix86_match_ccmode (insn, CCNOmode)
10053 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10054 "xor{b}\t{%2, %0|%0, %2}"
10055 [(set_attr "type" "alu")
10056 (set_attr "mode" "QI")])
10058 (define_insn "*xorqi_cc_ext_1"
10059 [(set (reg FLAGS_REG)
10063 (match_operand 1 "ext_register_operand" "0")
10066 (match_operand:QI 2 "general_operand" "qmn"))
10068 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10072 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10074 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10075 "xor{b}\t{%2, %h0|%h0, %2}"
10076 [(set_attr "type" "alu")
10077 (set_attr "mode" "QI")])
10079 (define_insn "*xorqi_cc_ext_1_rex64"
10080 [(set (reg FLAGS_REG)
10084 (match_operand 1 "ext_register_operand" "0")
10087 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10089 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10093 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10095 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10096 "xor{b}\t{%2, %h0|%h0, %2}"
10097 [(set_attr "type" "alu")
10098 (set_attr "mode" "QI")])
10100 (define_expand "xorqi_cc_ext_1"
10102 (set (reg:CCNO FLAGS_REG)
10106 (match_operand 1 "ext_register_operand" "")
10109 (match_operand:QI 2 "general_operand" ""))
10111 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10115 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10121 [(set (match_operand 0 "register_operand" "")
10122 (xor (match_operand 1 "register_operand" "")
10123 (match_operand 2 "const_int_operand" "")))
10124 (clobber (reg:CC FLAGS_REG))]
10126 && QI_REG_P (operands[0])
10127 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10128 && !(INTVAL (operands[2]) & ~(255 << 8))
10129 && GET_MODE (operands[0]) != QImode"
10130 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10131 (xor:SI (zero_extract:SI (match_dup 1)
10132 (const_int 8) (const_int 8))
10134 (clobber (reg:CC FLAGS_REG))])]
10135 "operands[0] = gen_lowpart (SImode, operands[0]);
10136 operands[1] = gen_lowpart (SImode, operands[1]);
10137 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10139 ;; Since XOR can be encoded with sign extended immediate, this is only
10140 ;; profitable when 7th bit is set.
10142 [(set (match_operand 0 "register_operand" "")
10143 (xor (match_operand 1 "general_operand" "")
10144 (match_operand 2 "const_int_operand" "")))
10145 (clobber (reg:CC FLAGS_REG))]
10147 && ANY_QI_REG_P (operands[0])
10148 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10149 && !(INTVAL (operands[2]) & ~255)
10150 && (INTVAL (operands[2]) & 128)
10151 && GET_MODE (operands[0]) != QImode"
10152 [(parallel [(set (strict_low_part (match_dup 0))
10153 (xor:QI (match_dup 1)
10155 (clobber (reg:CC FLAGS_REG))])]
10156 "operands[0] = gen_lowpart (QImode, operands[0]);
10157 operands[1] = gen_lowpart (QImode, operands[1]);
10158 operands[2] = gen_lowpart (QImode, operands[2]);")
10160 ;; Negation instructions
10162 (define_expand "negti2"
10163 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10164 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10165 (clobber (reg:CC FLAGS_REG))])]
10167 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10169 (define_insn "*negti2_1"
10170 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10171 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10172 (clobber (reg:CC FLAGS_REG))]
10174 && ix86_unary_operator_ok (NEG, TImode, operands)"
10178 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10179 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "TARGET_64BIT && reload_completed"
10183 [(set (reg:CCZ FLAGS_REG)
10184 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10185 (set (match_dup 0) (neg:DI (match_dup 1)))])
10187 [(set (match_dup 2)
10188 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10191 (clobber (reg:CC FLAGS_REG))])
10193 [(set (match_dup 2)
10194 (neg:DI (match_dup 2)))
10195 (clobber (reg:CC FLAGS_REG))])]
10196 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10198 (define_expand "negdi2"
10199 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10200 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10201 (clobber (reg:CC FLAGS_REG))])]
10203 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10205 (define_insn "*negdi2_1"
10206 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10207 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10208 (clobber (reg:CC FLAGS_REG))]
10210 && ix86_unary_operator_ok (NEG, DImode, operands)"
10214 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10215 (neg:DI (match_operand:DI 1 "general_operand" "")))
10216 (clobber (reg:CC FLAGS_REG))]
10217 "!TARGET_64BIT && reload_completed"
10219 [(set (reg:CCZ FLAGS_REG)
10220 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10221 (set (match_dup 0) (neg:SI (match_dup 1)))])
10223 [(set (match_dup 2)
10224 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10227 (clobber (reg:CC FLAGS_REG))])
10229 [(set (match_dup 2)
10230 (neg:SI (match_dup 2)))
10231 (clobber (reg:CC FLAGS_REG))])]
10232 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10234 (define_insn "*negdi2_1_rex64"
10235 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10236 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10237 (clobber (reg:CC FLAGS_REG))]
10238 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10240 [(set_attr "type" "negnot")
10241 (set_attr "mode" "DI")])
10243 ;; The problem with neg is that it does not perform (compare x 0),
10244 ;; it really performs (compare 0 x), which leaves us with the zero
10245 ;; flag being the only useful item.
10247 (define_insn "*negdi2_cmpz_rex64"
10248 [(set (reg:CCZ FLAGS_REG)
10249 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10251 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10252 (neg:DI (match_dup 1)))]
10253 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10255 [(set_attr "type" "negnot")
10256 (set_attr "mode" "DI")])
10259 (define_expand "negsi2"
10260 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10261 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10262 (clobber (reg:CC FLAGS_REG))])]
10264 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10266 (define_insn "*negsi2_1"
10267 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10268 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10269 (clobber (reg:CC FLAGS_REG))]
10270 "ix86_unary_operator_ok (NEG, SImode, operands)"
10272 [(set_attr "type" "negnot")
10273 (set_attr "mode" "SI")])
10275 ;; Combine is quite creative about this pattern.
10276 (define_insn "*negsi2_1_zext"
10277 [(set (match_operand:DI 0 "register_operand" "=r")
10278 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10281 (clobber (reg:CC FLAGS_REG))]
10282 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10284 [(set_attr "type" "negnot")
10285 (set_attr "mode" "SI")])
10287 ;; The problem with neg is that it does not perform (compare x 0),
10288 ;; it really performs (compare 0 x), which leaves us with the zero
10289 ;; flag being the only useful item.
10291 (define_insn "*negsi2_cmpz"
10292 [(set (reg:CCZ FLAGS_REG)
10293 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10295 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10296 (neg:SI (match_dup 1)))]
10297 "ix86_unary_operator_ok (NEG, SImode, operands)"
10299 [(set_attr "type" "negnot")
10300 (set_attr "mode" "SI")])
10302 (define_insn "*negsi2_cmpz_zext"
10303 [(set (reg:CCZ FLAGS_REG)
10304 (compare:CCZ (lshiftrt:DI
10306 (match_operand:DI 1 "register_operand" "0")
10310 (set (match_operand:DI 0 "register_operand" "=r")
10311 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10314 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10316 [(set_attr "type" "negnot")
10317 (set_attr "mode" "SI")])
10319 (define_expand "neghi2"
10320 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10321 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10322 (clobber (reg:CC FLAGS_REG))])]
10323 "TARGET_HIMODE_MATH"
10324 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10326 (define_insn "*neghi2_1"
10327 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10328 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10329 (clobber (reg:CC FLAGS_REG))]
10330 "ix86_unary_operator_ok (NEG, HImode, operands)"
10332 [(set_attr "type" "negnot")
10333 (set_attr "mode" "HI")])
10335 (define_insn "*neghi2_cmpz"
10336 [(set (reg:CCZ FLAGS_REG)
10337 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10339 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10340 (neg:HI (match_dup 1)))]
10341 "ix86_unary_operator_ok (NEG, HImode, operands)"
10343 [(set_attr "type" "negnot")
10344 (set_attr "mode" "HI")])
10346 (define_expand "negqi2"
10347 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10348 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10349 (clobber (reg:CC FLAGS_REG))])]
10350 "TARGET_QIMODE_MATH"
10351 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10353 (define_insn "*negqi2_1"
10354 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10355 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10356 (clobber (reg:CC FLAGS_REG))]
10357 "ix86_unary_operator_ok (NEG, QImode, operands)"
10359 [(set_attr "type" "negnot")
10360 (set_attr "mode" "QI")])
10362 (define_insn "*negqi2_cmpz"
10363 [(set (reg:CCZ FLAGS_REG)
10364 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10366 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10367 (neg:QI (match_dup 1)))]
10368 "ix86_unary_operator_ok (NEG, QImode, operands)"
10370 [(set_attr "type" "negnot")
10371 (set_attr "mode" "QI")])
10373 ;; Changing of sign for FP values is doable using integer unit too.
10375 (define_expand "<code><mode>2"
10376 [(set (match_operand:X87MODEF 0 "register_operand" "")
10377 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10378 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10379 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10381 (define_insn "*absneg<mode>2_mixed"
10382 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10383 (match_operator:MODEF 3 "absneg_operator"
10384 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10385 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10386 (clobber (reg:CC FLAGS_REG))]
10387 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10390 (define_insn "*absneg<mode>2_sse"
10391 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10392 (match_operator:MODEF 3 "absneg_operator"
10393 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10394 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10395 (clobber (reg:CC FLAGS_REG))]
10396 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10399 (define_insn "*absneg<mode>2_i387"
10400 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10401 (match_operator:X87MODEF 3 "absneg_operator"
10402 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10403 (use (match_operand 2 "" ""))
10404 (clobber (reg:CC FLAGS_REG))]
10405 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10408 (define_expand "<code>tf2"
10409 [(set (match_operand:TF 0 "register_operand" "")
10410 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10412 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10414 (define_insn "*absnegtf2_sse"
10415 [(set (match_operand:TF 0 "register_operand" "=x,x")
10416 (match_operator:TF 3 "absneg_operator"
10417 [(match_operand:TF 1 "register_operand" "0,x")]))
10418 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10419 (clobber (reg:CC FLAGS_REG))]
10423 ;; Splitters for fp abs and neg.
10426 [(set (match_operand 0 "fp_register_operand" "")
10427 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10428 (use (match_operand 2 "" ""))
10429 (clobber (reg:CC FLAGS_REG))]
10431 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10434 [(set (match_operand 0 "register_operand" "")
10435 (match_operator 3 "absneg_operator"
10436 [(match_operand 1 "register_operand" "")]))
10437 (use (match_operand 2 "nonimmediate_operand" ""))
10438 (clobber (reg:CC FLAGS_REG))]
10439 "reload_completed && SSE_REG_P (operands[0])"
10440 [(set (match_dup 0) (match_dup 3))]
10442 enum machine_mode mode = GET_MODE (operands[0]);
10443 enum machine_mode vmode = GET_MODE (operands[2]);
10446 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10447 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10448 if (operands_match_p (operands[0], operands[2]))
10451 operands[1] = operands[2];
10454 if (GET_CODE (operands[3]) == ABS)
10455 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10457 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10462 [(set (match_operand:SF 0 "register_operand" "")
10463 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10464 (use (match_operand:V4SF 2 "" ""))
10465 (clobber (reg:CC FLAGS_REG))]
10467 [(parallel [(set (match_dup 0) (match_dup 1))
10468 (clobber (reg:CC FLAGS_REG))])]
10471 operands[0] = gen_lowpart (SImode, operands[0]);
10472 if (GET_CODE (operands[1]) == ABS)
10474 tmp = gen_int_mode (0x7fffffff, SImode);
10475 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10479 tmp = gen_int_mode (0x80000000, SImode);
10480 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10486 [(set (match_operand:DF 0 "register_operand" "")
10487 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10488 (use (match_operand 2 "" ""))
10489 (clobber (reg:CC FLAGS_REG))]
10491 [(parallel [(set (match_dup 0) (match_dup 1))
10492 (clobber (reg:CC FLAGS_REG))])]
10497 tmp = gen_lowpart (DImode, operands[0]);
10498 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10501 if (GET_CODE (operands[1]) == ABS)
10504 tmp = gen_rtx_NOT (DImode, tmp);
10508 operands[0] = gen_highpart (SImode, operands[0]);
10509 if (GET_CODE (operands[1]) == ABS)
10511 tmp = gen_int_mode (0x7fffffff, SImode);
10512 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10516 tmp = gen_int_mode (0x80000000, SImode);
10517 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10524 [(set (match_operand:XF 0 "register_operand" "")
10525 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10526 (use (match_operand 2 "" ""))
10527 (clobber (reg:CC FLAGS_REG))]
10529 [(parallel [(set (match_dup 0) (match_dup 1))
10530 (clobber (reg:CC FLAGS_REG))])]
10533 operands[0] = gen_rtx_REG (SImode,
10534 true_regnum (operands[0])
10535 + (TARGET_64BIT ? 1 : 2));
10536 if (GET_CODE (operands[1]) == ABS)
10538 tmp = GEN_INT (0x7fff);
10539 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10543 tmp = GEN_INT (0x8000);
10544 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10549 ;; Conditionalize these after reload. If they match before reload, we
10550 ;; lose the clobber and ability to use integer instructions.
10552 (define_insn "*<code><mode>2_1"
10553 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10554 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10556 && (reload_completed
10557 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10559 [(set_attr "type" "fsgn")
10560 (set_attr "mode" "<MODE>")])
10562 (define_insn "*<code>extendsfdf2"
10563 [(set (match_operand:DF 0 "register_operand" "=f")
10564 (absneg:DF (float_extend:DF
10565 (match_operand:SF 1 "register_operand" "0"))))]
10566 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10568 [(set_attr "type" "fsgn")
10569 (set_attr "mode" "DF")])
10571 (define_insn "*<code>extendsfxf2"
10572 [(set (match_operand:XF 0 "register_operand" "=f")
10573 (absneg:XF (float_extend:XF
10574 (match_operand:SF 1 "register_operand" "0"))))]
10577 [(set_attr "type" "fsgn")
10578 (set_attr "mode" "XF")])
10580 (define_insn "*<code>extenddfxf2"
10581 [(set (match_operand:XF 0 "register_operand" "=f")
10582 (absneg:XF (float_extend:XF
10583 (match_operand:DF 1 "register_operand" "0"))))]
10586 [(set_attr "type" "fsgn")
10587 (set_attr "mode" "XF")])
10589 ;; Copysign instructions
10591 (define_mode_iterator CSGNMODE [SF DF TF])
10592 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10594 (define_expand "copysign<mode>3"
10595 [(match_operand:CSGNMODE 0 "register_operand" "")
10596 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10597 (match_operand:CSGNMODE 2 "register_operand" "")]
10598 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10599 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10601 ix86_expand_copysign (operands);
10605 (define_insn_and_split "copysign<mode>3_const"
10606 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10608 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10609 (match_operand:CSGNMODE 2 "register_operand" "0")
10610 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10612 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10613 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10615 "&& reload_completed"
10618 ix86_split_copysign_const (operands);
10622 (define_insn "copysign<mode>3_var"
10623 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10625 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10626 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10627 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10628 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10630 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10631 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10632 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10636 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10638 [(match_operand:CSGNMODE 2 "register_operand" "")
10639 (match_operand:CSGNMODE 3 "register_operand" "")
10640 (match_operand:<CSGNVMODE> 4 "" "")
10641 (match_operand:<CSGNVMODE> 5 "" "")]
10643 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10644 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10645 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10646 && reload_completed"
10649 ix86_split_copysign_var (operands);
10653 ;; One complement instructions
10655 (define_expand "one_cmpldi2"
10656 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10657 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10659 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10661 (define_insn "*one_cmpldi2_1_rex64"
10662 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10663 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10664 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10666 [(set_attr "type" "negnot")
10667 (set_attr "mode" "DI")])
10669 (define_insn "*one_cmpldi2_2_rex64"
10670 [(set (reg FLAGS_REG)
10671 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10673 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10674 (not:DI (match_dup 1)))]
10675 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10676 && ix86_unary_operator_ok (NOT, DImode, operands)"
10678 [(set_attr "type" "alu1")
10679 (set_attr "mode" "DI")])
10682 [(set (match_operand 0 "flags_reg_operand" "")
10683 (match_operator 2 "compare_operator"
10684 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10686 (set (match_operand:DI 1 "nonimmediate_operand" "")
10687 (not:DI (match_dup 3)))]
10688 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10689 [(parallel [(set (match_dup 0)
10691 [(xor:DI (match_dup 3) (const_int -1))
10694 (xor:DI (match_dup 3) (const_int -1)))])]
10697 (define_expand "one_cmplsi2"
10698 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10699 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10701 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10703 (define_insn "*one_cmplsi2_1"
10704 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10705 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10706 "ix86_unary_operator_ok (NOT, SImode, operands)"
10708 [(set_attr "type" "negnot")
10709 (set_attr "mode" "SI")])
10711 ;; ??? Currently never generated - xor is used instead.
10712 (define_insn "*one_cmplsi2_1_zext"
10713 [(set (match_operand:DI 0 "register_operand" "=r")
10714 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10715 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10717 [(set_attr "type" "negnot")
10718 (set_attr "mode" "SI")])
10720 (define_insn "*one_cmplsi2_2"
10721 [(set (reg FLAGS_REG)
10722 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10724 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10725 (not:SI (match_dup 1)))]
10726 "ix86_match_ccmode (insn, CCNOmode)
10727 && ix86_unary_operator_ok (NOT, SImode, operands)"
10729 [(set_attr "type" "alu1")
10730 (set_attr "mode" "SI")])
10733 [(set (match_operand 0 "flags_reg_operand" "")
10734 (match_operator 2 "compare_operator"
10735 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10737 (set (match_operand:SI 1 "nonimmediate_operand" "")
10738 (not:SI (match_dup 3)))]
10739 "ix86_match_ccmode (insn, CCNOmode)"
10740 [(parallel [(set (match_dup 0)
10741 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10744 (xor:SI (match_dup 3) (const_int -1)))])]
10747 ;; ??? Currently never generated - xor is used instead.
10748 (define_insn "*one_cmplsi2_2_zext"
10749 [(set (reg FLAGS_REG)
10750 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10752 (set (match_operand:DI 0 "register_operand" "=r")
10753 (zero_extend:DI (not:SI (match_dup 1))))]
10754 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10755 && ix86_unary_operator_ok (NOT, SImode, operands)"
10757 [(set_attr "type" "alu1")
10758 (set_attr "mode" "SI")])
10761 [(set (match_operand 0 "flags_reg_operand" "")
10762 (match_operator 2 "compare_operator"
10763 [(not:SI (match_operand:SI 3 "register_operand" ""))
10765 (set (match_operand:DI 1 "register_operand" "")
10766 (zero_extend:DI (not:SI (match_dup 3))))]
10767 "ix86_match_ccmode (insn, CCNOmode)"
10768 [(parallel [(set (match_dup 0)
10769 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10772 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10775 (define_expand "one_cmplhi2"
10776 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10777 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10778 "TARGET_HIMODE_MATH"
10779 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10781 (define_insn "*one_cmplhi2_1"
10782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10783 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10784 "ix86_unary_operator_ok (NOT, HImode, operands)"
10786 [(set_attr "type" "negnot")
10787 (set_attr "mode" "HI")])
10789 (define_insn "*one_cmplhi2_2"
10790 [(set (reg FLAGS_REG)
10791 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10793 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10794 (not:HI (match_dup 1)))]
10795 "ix86_match_ccmode (insn, CCNOmode)
10796 && ix86_unary_operator_ok (NEG, HImode, operands)"
10798 [(set_attr "type" "alu1")
10799 (set_attr "mode" "HI")])
10802 [(set (match_operand 0 "flags_reg_operand" "")
10803 (match_operator 2 "compare_operator"
10804 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10806 (set (match_operand:HI 1 "nonimmediate_operand" "")
10807 (not:HI (match_dup 3)))]
10808 "ix86_match_ccmode (insn, CCNOmode)"
10809 [(parallel [(set (match_dup 0)
10810 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10813 (xor:HI (match_dup 3) (const_int -1)))])]
10816 ;; %%% Potential partial reg stall on alternative 1. What to do?
10817 (define_expand "one_cmplqi2"
10818 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10819 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10820 "TARGET_QIMODE_MATH"
10821 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10823 (define_insn "*one_cmplqi2_1"
10824 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10825 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10826 "ix86_unary_operator_ok (NOT, QImode, operands)"
10830 [(set_attr "type" "negnot")
10831 (set_attr "mode" "QI,SI")])
10833 (define_insn "*one_cmplqi2_2"
10834 [(set (reg FLAGS_REG)
10835 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10837 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10838 (not:QI (match_dup 1)))]
10839 "ix86_match_ccmode (insn, CCNOmode)
10840 && ix86_unary_operator_ok (NOT, QImode, operands)"
10842 [(set_attr "type" "alu1")
10843 (set_attr "mode" "QI")])
10846 [(set (match_operand 0 "flags_reg_operand" "")
10847 (match_operator 2 "compare_operator"
10848 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10850 (set (match_operand:QI 1 "nonimmediate_operand" "")
10851 (not:QI (match_dup 3)))]
10852 "ix86_match_ccmode (insn, CCNOmode)"
10853 [(parallel [(set (match_dup 0)
10854 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10857 (xor:QI (match_dup 3) (const_int -1)))])]
10860 ;; Arithmetic shift instructions
10862 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10863 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10864 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10865 ;; from the assembler input.
10867 ;; This instruction shifts the target reg/mem as usual, but instead of
10868 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10869 ;; is a left shift double, bits are taken from the high order bits of
10870 ;; reg, else if the insn is a shift right double, bits are taken from the
10871 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10872 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10874 ;; Since sh[lr]d does not change the `reg' operand, that is done
10875 ;; separately, making all shifts emit pairs of shift double and normal
10876 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10877 ;; support a 63 bit shift, each shift where the count is in a reg expands
10878 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10880 ;; If the shift count is a constant, we need never emit more than one
10881 ;; shift pair, instead using moves and sign extension for counts greater
10884 (define_expand "ashlti3"
10885 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10886 (ashift:TI (match_operand:TI 1 "register_operand" "")
10887 (match_operand:QI 2 "nonmemory_operand" "")))
10888 (clobber (reg:CC FLAGS_REG))])]
10891 if (! immediate_operand (operands[2], QImode))
10893 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10896 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10900 (define_insn "ashlti3_1"
10901 [(set (match_operand:TI 0 "register_operand" "=r")
10902 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10903 (match_operand:QI 2 "register_operand" "c")))
10904 (clobber (match_scratch:DI 3 "=&r"))
10905 (clobber (reg:CC FLAGS_REG))]
10908 [(set_attr "type" "multi")])
10910 ;; This pattern must be defined before *ashlti3_2 to prevent
10911 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10913 (define_insn "sse2_ashlti3"
10914 [(set (match_operand:TI 0 "register_operand" "=x")
10915 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10916 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10919 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10920 return "pslldq\t{%2, %0|%0, %2}";
10922 [(set_attr "type" "sseishft")
10923 (set_attr "prefix_data16" "1")
10924 (set_attr "mode" "TI")])
10926 (define_insn "*ashlti3_2"
10927 [(set (match_operand:TI 0 "register_operand" "=r")
10928 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10929 (match_operand:QI 2 "immediate_operand" "O")))
10930 (clobber (reg:CC FLAGS_REG))]
10933 [(set_attr "type" "multi")])
10936 [(set (match_operand:TI 0 "register_operand" "")
10937 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10938 (match_operand:QI 2 "register_operand" "")))
10939 (clobber (match_scratch:DI 3 ""))
10940 (clobber (reg:CC FLAGS_REG))]
10941 "TARGET_64BIT && reload_completed"
10943 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10946 [(set (match_operand:TI 0 "register_operand" "")
10947 (ashift:TI (match_operand:TI 1 "register_operand" "")
10948 (match_operand:QI 2 "immediate_operand" "")))
10949 (clobber (reg:CC FLAGS_REG))]
10950 "TARGET_64BIT && reload_completed"
10952 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10954 (define_insn "x86_64_shld"
10955 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10956 (ior:DI (ashift:DI (match_dup 0)
10957 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10958 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10959 (minus:QI (const_int 64) (match_dup 2)))))
10960 (clobber (reg:CC FLAGS_REG))]
10963 shld{q}\t{%2, %1, %0|%0, %1, %2}
10964 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10965 [(set_attr "type" "ishift")
10966 (set_attr "prefix_0f" "1")
10967 (set_attr "mode" "DI")
10968 (set_attr "athlon_decode" "vector")
10969 (set_attr "amdfam10_decode" "vector")])
10971 (define_expand "x86_64_shift_adj"
10972 [(set (reg:CCZ FLAGS_REG)
10973 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10976 (set (match_operand:DI 0 "register_operand" "")
10977 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10978 (match_operand:DI 1 "register_operand" "")
10981 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10982 (match_operand:DI 3 "register_operand" "r")
10987 (define_expand "ashldi3"
10988 [(set (match_operand:DI 0 "shiftdi_operand" "")
10989 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10990 (match_operand:QI 2 "nonmemory_operand" "")))]
10992 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10994 (define_insn "*ashldi3_1_rex64"
10995 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10996 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10997 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10998 (clobber (reg:CC FLAGS_REG))]
10999 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11001 switch (get_attr_type (insn))
11004 gcc_assert (operands[2] == const1_rtx);
11005 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11006 return "add{q}\t%0, %0";
11009 gcc_assert (CONST_INT_P (operands[2]));
11010 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11011 operands[1] = gen_rtx_MULT (DImode, operands[1],
11012 GEN_INT (1 << INTVAL (operands[2])));
11013 return "lea{q}\t{%a1, %0|%0, %a1}";
11016 if (REG_P (operands[2]))
11017 return "sal{q}\t{%b2, %0|%0, %b2}";
11018 else if (operands[2] == const1_rtx
11019 && (TARGET_SHIFT1 || optimize_size))
11020 return "sal{q}\t%0";
11022 return "sal{q}\t{%2, %0|%0, %2}";
11025 [(set (attr "type")
11026 (cond [(eq_attr "alternative" "1")
11027 (const_string "lea")
11028 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11030 (match_operand 0 "register_operand" ""))
11031 (match_operand 2 "const1_operand" ""))
11032 (const_string "alu")
11034 (const_string "ishift")))
11035 (set_attr "mode" "DI")])
11037 ;; Convert lea to the lea pattern to avoid flags dependency.
11039 [(set (match_operand:DI 0 "register_operand" "")
11040 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11041 (match_operand:QI 2 "immediate_operand" "")))
11042 (clobber (reg:CC FLAGS_REG))]
11043 "TARGET_64BIT && reload_completed
11044 && true_regnum (operands[0]) != true_regnum (operands[1])"
11045 [(set (match_dup 0)
11046 (mult:DI (match_dup 1)
11048 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11050 ;; This pattern can't accept a variable shift count, since shifts by
11051 ;; zero don't affect the flags. We assume that shifts by constant
11052 ;; zero are optimized away.
11053 (define_insn "*ashldi3_cmp_rex64"
11054 [(set (reg FLAGS_REG)
11056 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11057 (match_operand:QI 2 "immediate_operand" "e"))
11059 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11060 (ashift:DI (match_dup 1) (match_dup 2)))]
11063 || !TARGET_PARTIAL_FLAG_REG_STALL
11064 || (operands[2] == const1_rtx
11066 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11067 && ix86_match_ccmode (insn, CCGOCmode)
11068 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11070 switch (get_attr_type (insn))
11073 gcc_assert (operands[2] == const1_rtx);
11074 return "add{q}\t%0, %0";
11077 if (REG_P (operands[2]))
11078 return "sal{q}\t{%b2, %0|%0, %b2}";
11079 else if (operands[2] == const1_rtx
11080 && (TARGET_SHIFT1 || optimize_size))
11081 return "sal{q}\t%0";
11083 return "sal{q}\t{%2, %0|%0, %2}";
11086 [(set (attr "type")
11087 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11089 (match_operand 0 "register_operand" ""))
11090 (match_operand 2 "const1_operand" ""))
11091 (const_string "alu")
11093 (const_string "ishift")))
11094 (set_attr "mode" "DI")])
11096 (define_insn "*ashldi3_cconly_rex64"
11097 [(set (reg FLAGS_REG)
11099 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11100 (match_operand:QI 2 "immediate_operand" "e"))
11102 (clobber (match_scratch:DI 0 "=r"))]
11105 || !TARGET_PARTIAL_FLAG_REG_STALL
11106 || (operands[2] == const1_rtx
11108 || TARGET_DOUBLE_WITH_ADD)))
11109 && ix86_match_ccmode (insn, CCGOCmode)
11110 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11112 switch (get_attr_type (insn))
11115 gcc_assert (operands[2] == const1_rtx);
11116 return "add{q}\t%0, %0";
11119 if (REG_P (operands[2]))
11120 return "sal{q}\t{%b2, %0|%0, %b2}";
11121 else if (operands[2] == const1_rtx
11122 && (TARGET_SHIFT1 || optimize_size))
11123 return "sal{q}\t%0";
11125 return "sal{q}\t{%2, %0|%0, %2}";
11128 [(set (attr "type")
11129 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11131 (match_operand 0 "register_operand" ""))
11132 (match_operand 2 "const1_operand" ""))
11133 (const_string "alu")
11135 (const_string "ishift")))
11136 (set_attr "mode" "DI")])
11138 (define_insn "*ashldi3_1"
11139 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11140 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11141 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11142 (clobber (reg:CC FLAGS_REG))]
11145 [(set_attr "type" "multi")])
11147 ;; By default we don't ask for a scratch register, because when DImode
11148 ;; values are manipulated, registers are already at a premium. But if
11149 ;; we have one handy, we won't turn it away.
11151 [(match_scratch:SI 3 "r")
11152 (parallel [(set (match_operand:DI 0 "register_operand" "")
11153 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11154 (match_operand:QI 2 "nonmemory_operand" "")))
11155 (clobber (reg:CC FLAGS_REG))])
11157 "!TARGET_64BIT && TARGET_CMOVE"
11159 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11162 [(set (match_operand:DI 0 "register_operand" "")
11163 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11164 (match_operand:QI 2 "nonmemory_operand" "")))
11165 (clobber (reg:CC FLAGS_REG))]
11166 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11167 ? epilogue_completed : reload_completed)"
11169 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11171 (define_insn "x86_shld_1"
11172 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11173 (ior:SI (ashift:SI (match_dup 0)
11174 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11175 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11176 (minus:QI (const_int 32) (match_dup 2)))))
11177 (clobber (reg:CC FLAGS_REG))]
11180 shld{l}\t{%2, %1, %0|%0, %1, %2}
11181 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11182 [(set_attr "type" "ishift")
11183 (set_attr "prefix_0f" "1")
11184 (set_attr "mode" "SI")
11185 (set_attr "pent_pair" "np")
11186 (set_attr "athlon_decode" "vector")
11187 (set_attr "amdfam10_decode" "vector")])
11189 (define_expand "x86_shift_adj_1"
11190 [(set (reg:CCZ FLAGS_REG)
11191 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11194 (set (match_operand:SI 0 "register_operand" "")
11195 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11196 (match_operand:SI 1 "register_operand" "")
11199 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11200 (match_operand:SI 3 "register_operand" "r")
11205 (define_expand "x86_shift_adj_2"
11206 [(use (match_operand:SI 0 "register_operand" ""))
11207 (use (match_operand:SI 1 "register_operand" ""))
11208 (use (match_operand:QI 2 "register_operand" ""))]
11211 rtx label = gen_label_rtx ();
11214 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11216 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11217 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11218 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11219 gen_rtx_LABEL_REF (VOIDmode, label),
11221 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11222 JUMP_LABEL (tmp) = label;
11224 emit_move_insn (operands[0], operands[1]);
11225 ix86_expand_clear (operands[1]);
11227 emit_label (label);
11228 LABEL_NUSES (label) = 1;
11233 (define_expand "ashlsi3"
11234 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11235 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11236 (match_operand:QI 2 "nonmemory_operand" "")))
11237 (clobber (reg:CC FLAGS_REG))]
11239 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11241 (define_insn "*ashlsi3_1"
11242 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11243 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11244 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11245 (clobber (reg:CC FLAGS_REG))]
11246 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11248 switch (get_attr_type (insn))
11251 gcc_assert (operands[2] == const1_rtx);
11252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11253 return "add{l}\t%0, %0";
11259 if (REG_P (operands[2]))
11260 return "sal{l}\t{%b2, %0|%0, %b2}";
11261 else if (operands[2] == const1_rtx
11262 && (TARGET_SHIFT1 || optimize_size))
11263 return "sal{l}\t%0";
11265 return "sal{l}\t{%2, %0|%0, %2}";
11268 [(set (attr "type")
11269 (cond [(eq_attr "alternative" "1")
11270 (const_string "lea")
11271 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11273 (match_operand 0 "register_operand" ""))
11274 (match_operand 2 "const1_operand" ""))
11275 (const_string "alu")
11277 (const_string "ishift")))
11278 (set_attr "mode" "SI")])
11280 ;; Convert lea to the lea pattern to avoid flags dependency.
11282 [(set (match_operand 0 "register_operand" "")
11283 (ashift (match_operand 1 "index_register_operand" "")
11284 (match_operand:QI 2 "const_int_operand" "")))
11285 (clobber (reg:CC FLAGS_REG))]
11287 && true_regnum (operands[0]) != true_regnum (operands[1])
11288 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11292 enum machine_mode mode = GET_MODE (operands[0]);
11294 if (GET_MODE_SIZE (mode) < 4)
11295 operands[0] = gen_lowpart (SImode, operands[0]);
11297 operands[1] = gen_lowpart (Pmode, operands[1]);
11298 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11300 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11301 if (Pmode != SImode)
11302 pat = gen_rtx_SUBREG (SImode, pat, 0);
11303 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11307 ;; Rare case of shifting RSP is handled by generating move and shift
11309 [(set (match_operand 0 "register_operand" "")
11310 (ashift (match_operand 1 "register_operand" "")
11311 (match_operand:QI 2 "const_int_operand" "")))
11312 (clobber (reg:CC FLAGS_REG))]
11314 && true_regnum (operands[0]) != true_regnum (operands[1])"
11318 emit_move_insn (operands[0], operands[1]);
11319 pat = gen_rtx_SET (VOIDmode, operands[0],
11320 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11321 operands[0], operands[2]));
11322 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11323 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11327 (define_insn "*ashlsi3_1_zext"
11328 [(set (match_operand:DI 0 "register_operand" "=r,r")
11329 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11330 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11331 (clobber (reg:CC FLAGS_REG))]
11332 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11334 switch (get_attr_type (insn))
11337 gcc_assert (operands[2] == const1_rtx);
11338 return "add{l}\t%k0, %k0";
11344 if (REG_P (operands[2]))
11345 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11346 else if (operands[2] == const1_rtx
11347 && (TARGET_SHIFT1 || optimize_size))
11348 return "sal{l}\t%k0";
11350 return "sal{l}\t{%2, %k0|%k0, %2}";
11353 [(set (attr "type")
11354 (cond [(eq_attr "alternative" "1")
11355 (const_string "lea")
11356 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11358 (match_operand 2 "const1_operand" ""))
11359 (const_string "alu")
11361 (const_string "ishift")))
11362 (set_attr "mode" "SI")])
11364 ;; Convert lea to the lea pattern to avoid flags dependency.
11366 [(set (match_operand:DI 0 "register_operand" "")
11367 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11368 (match_operand:QI 2 "const_int_operand" ""))))
11369 (clobber (reg:CC FLAGS_REG))]
11370 "TARGET_64BIT && reload_completed
11371 && true_regnum (operands[0]) != true_regnum (operands[1])"
11372 [(set (match_dup 0) (zero_extend:DI
11373 (subreg:SI (mult:SI (match_dup 1)
11374 (match_dup 2)) 0)))]
11376 operands[1] = gen_lowpart (Pmode, operands[1]);
11377 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11380 ;; This pattern can't accept a variable shift count, since shifts by
11381 ;; zero don't affect the flags. We assume that shifts by constant
11382 ;; zero are optimized away.
11383 (define_insn "*ashlsi3_cmp"
11384 [(set (reg FLAGS_REG)
11386 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11387 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11389 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11390 (ashift:SI (match_dup 1) (match_dup 2)))]
11392 || !TARGET_PARTIAL_FLAG_REG_STALL
11393 || (operands[2] == const1_rtx
11395 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11396 && ix86_match_ccmode (insn, CCGOCmode)
11397 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11399 switch (get_attr_type (insn))
11402 gcc_assert (operands[2] == const1_rtx);
11403 return "add{l}\t%0, %0";
11406 if (REG_P (operands[2]))
11407 return "sal{l}\t{%b2, %0|%0, %b2}";
11408 else if (operands[2] == const1_rtx
11409 && (TARGET_SHIFT1 || optimize_size))
11410 return "sal{l}\t%0";
11412 return "sal{l}\t{%2, %0|%0, %2}";
11415 [(set (attr "type")
11416 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11418 (match_operand 0 "register_operand" ""))
11419 (match_operand 2 "const1_operand" ""))
11420 (const_string "alu")
11422 (const_string "ishift")))
11423 (set_attr "mode" "SI")])
11425 (define_insn "*ashlsi3_cconly"
11426 [(set (reg FLAGS_REG)
11428 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11429 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11431 (clobber (match_scratch:SI 0 "=r"))]
11433 || !TARGET_PARTIAL_FLAG_REG_STALL
11434 || (operands[2] == const1_rtx
11436 || TARGET_DOUBLE_WITH_ADD)))
11437 && ix86_match_ccmode (insn, CCGOCmode)
11438 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11440 switch (get_attr_type (insn))
11443 gcc_assert (operands[2] == const1_rtx);
11444 return "add{l}\t%0, %0";
11447 if (REG_P (operands[2]))
11448 return "sal{l}\t{%b2, %0|%0, %b2}";
11449 else if (operands[2] == const1_rtx
11450 && (TARGET_SHIFT1 || optimize_size))
11451 return "sal{l}\t%0";
11453 return "sal{l}\t{%2, %0|%0, %2}";
11456 [(set (attr "type")
11457 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11459 (match_operand 0 "register_operand" ""))
11460 (match_operand 2 "const1_operand" ""))
11461 (const_string "alu")
11463 (const_string "ishift")))
11464 (set_attr "mode" "SI")])
11466 (define_insn "*ashlsi3_cmp_zext"
11467 [(set (reg FLAGS_REG)
11469 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11470 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11472 (set (match_operand:DI 0 "register_operand" "=r")
11473 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11476 || !TARGET_PARTIAL_FLAG_REG_STALL
11477 || (operands[2] == const1_rtx
11479 || TARGET_DOUBLE_WITH_ADD)))
11480 && ix86_match_ccmode (insn, CCGOCmode)
11481 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11483 switch (get_attr_type (insn))
11486 gcc_assert (operands[2] == const1_rtx);
11487 return "add{l}\t%k0, %k0";
11490 if (REG_P (operands[2]))
11491 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11492 else if (operands[2] == const1_rtx
11493 && (TARGET_SHIFT1 || optimize_size))
11494 return "sal{l}\t%k0";
11496 return "sal{l}\t{%2, %k0|%k0, %2}";
11499 [(set (attr "type")
11500 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11502 (match_operand 2 "const1_operand" ""))
11503 (const_string "alu")
11505 (const_string "ishift")))
11506 (set_attr "mode" "SI")])
11508 (define_expand "ashlhi3"
11509 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11510 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11511 (match_operand:QI 2 "nonmemory_operand" "")))
11512 (clobber (reg:CC FLAGS_REG))]
11513 "TARGET_HIMODE_MATH"
11514 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11516 (define_insn "*ashlhi3_1_lea"
11517 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11518 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11519 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11520 (clobber (reg:CC FLAGS_REG))]
11521 "!TARGET_PARTIAL_REG_STALL
11522 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11524 switch (get_attr_type (insn))
11529 gcc_assert (operands[2] == const1_rtx);
11530 return "add{w}\t%0, %0";
11533 if (REG_P (operands[2]))
11534 return "sal{w}\t{%b2, %0|%0, %b2}";
11535 else if (operands[2] == const1_rtx
11536 && (TARGET_SHIFT1 || optimize_size))
11537 return "sal{w}\t%0";
11539 return "sal{w}\t{%2, %0|%0, %2}";
11542 [(set (attr "type")
11543 (cond [(eq_attr "alternative" "1")
11544 (const_string "lea")
11545 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11547 (match_operand 0 "register_operand" ""))
11548 (match_operand 2 "const1_operand" ""))
11549 (const_string "alu")
11551 (const_string "ishift")))
11552 (set_attr "mode" "HI,SI")])
11554 (define_insn "*ashlhi3_1"
11555 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11556 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11557 (match_operand:QI 2 "nonmemory_operand" "cI")))
11558 (clobber (reg:CC FLAGS_REG))]
11559 "TARGET_PARTIAL_REG_STALL
11560 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11562 switch (get_attr_type (insn))
11565 gcc_assert (operands[2] == const1_rtx);
11566 return "add{w}\t%0, %0";
11569 if (REG_P (operands[2]))
11570 return "sal{w}\t{%b2, %0|%0, %b2}";
11571 else if (operands[2] == const1_rtx
11572 && (TARGET_SHIFT1 || optimize_size))
11573 return "sal{w}\t%0";
11575 return "sal{w}\t{%2, %0|%0, %2}";
11578 [(set (attr "type")
11579 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11581 (match_operand 0 "register_operand" ""))
11582 (match_operand 2 "const1_operand" ""))
11583 (const_string "alu")
11585 (const_string "ishift")))
11586 (set_attr "mode" "HI")])
11588 ;; This pattern can't accept a variable shift count, since shifts by
11589 ;; zero don't affect the flags. We assume that shifts by constant
11590 ;; zero are optimized away.
11591 (define_insn "*ashlhi3_cmp"
11592 [(set (reg FLAGS_REG)
11594 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11595 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11597 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11598 (ashift:HI (match_dup 1) (match_dup 2)))]
11600 || !TARGET_PARTIAL_FLAG_REG_STALL
11601 || (operands[2] == const1_rtx
11603 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11604 && ix86_match_ccmode (insn, CCGOCmode)
11605 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11607 switch (get_attr_type (insn))
11610 gcc_assert (operands[2] == const1_rtx);
11611 return "add{w}\t%0, %0";
11614 if (REG_P (operands[2]))
11615 return "sal{w}\t{%b2, %0|%0, %b2}";
11616 else if (operands[2] == const1_rtx
11617 && (TARGET_SHIFT1 || optimize_size))
11618 return "sal{w}\t%0";
11620 return "sal{w}\t{%2, %0|%0, %2}";
11623 [(set (attr "type")
11624 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11626 (match_operand 0 "register_operand" ""))
11627 (match_operand 2 "const1_operand" ""))
11628 (const_string "alu")
11630 (const_string "ishift")))
11631 (set_attr "mode" "HI")])
11633 (define_insn "*ashlhi3_cconly"
11634 [(set (reg FLAGS_REG)
11636 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11637 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11639 (clobber (match_scratch:HI 0 "=r"))]
11641 || !TARGET_PARTIAL_FLAG_REG_STALL
11642 || (operands[2] == const1_rtx
11644 || TARGET_DOUBLE_WITH_ADD)))
11645 && ix86_match_ccmode (insn, CCGOCmode)
11646 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11648 switch (get_attr_type (insn))
11651 gcc_assert (operands[2] == const1_rtx);
11652 return "add{w}\t%0, %0";
11655 if (REG_P (operands[2]))
11656 return "sal{w}\t{%b2, %0|%0, %b2}";
11657 else if (operands[2] == const1_rtx
11658 && (TARGET_SHIFT1 || optimize_size))
11659 return "sal{w}\t%0";
11661 return "sal{w}\t{%2, %0|%0, %2}";
11664 [(set (attr "type")
11665 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11667 (match_operand 0 "register_operand" ""))
11668 (match_operand 2 "const1_operand" ""))
11669 (const_string "alu")
11671 (const_string "ishift")))
11672 (set_attr "mode" "HI")])
11674 (define_expand "ashlqi3"
11675 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11676 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11677 (match_operand:QI 2 "nonmemory_operand" "")))
11678 (clobber (reg:CC FLAGS_REG))]
11679 "TARGET_QIMODE_MATH"
11680 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11682 ;; %%% Potential partial reg stall on alternative 2. What to do?
11684 (define_insn "*ashlqi3_1_lea"
11685 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11686 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11687 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11688 (clobber (reg:CC FLAGS_REG))]
11689 "!TARGET_PARTIAL_REG_STALL
11690 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11692 switch (get_attr_type (insn))
11697 gcc_assert (operands[2] == const1_rtx);
11698 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11699 return "add{l}\t%k0, %k0";
11701 return "add{b}\t%0, %0";
11704 if (REG_P (operands[2]))
11706 if (get_attr_mode (insn) == MODE_SI)
11707 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11709 return "sal{b}\t{%b2, %0|%0, %b2}";
11711 else if (operands[2] == const1_rtx
11712 && (TARGET_SHIFT1 || optimize_size))
11714 if (get_attr_mode (insn) == MODE_SI)
11715 return "sal{l}\t%0";
11717 return "sal{b}\t%0";
11721 if (get_attr_mode (insn) == MODE_SI)
11722 return "sal{l}\t{%2, %k0|%k0, %2}";
11724 return "sal{b}\t{%2, %0|%0, %2}";
11728 [(set (attr "type")
11729 (cond [(eq_attr "alternative" "2")
11730 (const_string "lea")
11731 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11733 (match_operand 0 "register_operand" ""))
11734 (match_operand 2 "const1_operand" ""))
11735 (const_string "alu")
11737 (const_string "ishift")))
11738 (set_attr "mode" "QI,SI,SI")])
11740 (define_insn "*ashlqi3_1"
11741 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11742 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11743 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11744 (clobber (reg:CC FLAGS_REG))]
11745 "TARGET_PARTIAL_REG_STALL
11746 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11748 switch (get_attr_type (insn))
11751 gcc_assert (operands[2] == const1_rtx);
11752 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11753 return "add{l}\t%k0, %k0";
11755 return "add{b}\t%0, %0";
11758 if (REG_P (operands[2]))
11760 if (get_attr_mode (insn) == MODE_SI)
11761 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11763 return "sal{b}\t{%b2, %0|%0, %b2}";
11765 else if (operands[2] == const1_rtx
11766 && (TARGET_SHIFT1 || optimize_size))
11768 if (get_attr_mode (insn) == MODE_SI)
11769 return "sal{l}\t%0";
11771 return "sal{b}\t%0";
11775 if (get_attr_mode (insn) == MODE_SI)
11776 return "sal{l}\t{%2, %k0|%k0, %2}";
11778 return "sal{b}\t{%2, %0|%0, %2}";
11782 [(set (attr "type")
11783 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11785 (match_operand 0 "register_operand" ""))
11786 (match_operand 2 "const1_operand" ""))
11787 (const_string "alu")
11789 (const_string "ishift")))
11790 (set_attr "mode" "QI,SI")])
11792 ;; This pattern can't accept a variable shift count, since shifts by
11793 ;; zero don't affect the flags. We assume that shifts by constant
11794 ;; zero are optimized away.
11795 (define_insn "*ashlqi3_cmp"
11796 [(set (reg FLAGS_REG)
11798 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11799 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11802 (ashift:QI (match_dup 1) (match_dup 2)))]
11804 || !TARGET_PARTIAL_FLAG_REG_STALL
11805 || (operands[2] == const1_rtx
11807 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11808 && ix86_match_ccmode (insn, CCGOCmode)
11809 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11811 switch (get_attr_type (insn))
11814 gcc_assert (operands[2] == const1_rtx);
11815 return "add{b}\t%0, %0";
11818 if (REG_P (operands[2]))
11819 return "sal{b}\t{%b2, %0|%0, %b2}";
11820 else if (operands[2] == const1_rtx
11821 && (TARGET_SHIFT1 || optimize_size))
11822 return "sal{b}\t%0";
11824 return "sal{b}\t{%2, %0|%0, %2}";
11827 [(set (attr "type")
11828 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11830 (match_operand 0 "register_operand" ""))
11831 (match_operand 2 "const1_operand" ""))
11832 (const_string "alu")
11834 (const_string "ishift")))
11835 (set_attr "mode" "QI")])
11837 (define_insn "*ashlqi3_cconly"
11838 [(set (reg FLAGS_REG)
11840 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11841 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11843 (clobber (match_scratch:QI 0 "=q"))]
11845 || !TARGET_PARTIAL_FLAG_REG_STALL
11846 || (operands[2] == const1_rtx
11848 || TARGET_DOUBLE_WITH_ADD)))
11849 && ix86_match_ccmode (insn, CCGOCmode)
11850 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11852 switch (get_attr_type (insn))
11855 gcc_assert (operands[2] == const1_rtx);
11856 return "add{b}\t%0, %0";
11859 if (REG_P (operands[2]))
11860 return "sal{b}\t{%b2, %0|%0, %b2}";
11861 else if (operands[2] == const1_rtx
11862 && (TARGET_SHIFT1 || optimize_size))
11863 return "sal{b}\t%0";
11865 return "sal{b}\t{%2, %0|%0, %2}";
11868 [(set (attr "type")
11869 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11871 (match_operand 0 "register_operand" ""))
11872 (match_operand 2 "const1_operand" ""))
11873 (const_string "alu")
11875 (const_string "ishift")))
11876 (set_attr "mode" "QI")])
11878 ;; See comment above `ashldi3' about how this works.
11880 (define_expand "ashrti3"
11881 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11882 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11883 (match_operand:QI 2 "nonmemory_operand" "")))
11884 (clobber (reg:CC FLAGS_REG))])]
11887 if (! immediate_operand (operands[2], QImode))
11889 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11892 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11896 (define_insn "ashrti3_1"
11897 [(set (match_operand:TI 0 "register_operand" "=r")
11898 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11899 (match_operand:QI 2 "register_operand" "c")))
11900 (clobber (match_scratch:DI 3 "=&r"))
11901 (clobber (reg:CC FLAGS_REG))]
11904 [(set_attr "type" "multi")])
11906 (define_insn "*ashrti3_2"
11907 [(set (match_operand:TI 0 "register_operand" "=r")
11908 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11909 (match_operand:QI 2 "immediate_operand" "O")))
11910 (clobber (reg:CC FLAGS_REG))]
11913 [(set_attr "type" "multi")])
11916 [(set (match_operand:TI 0 "register_operand" "")
11917 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11918 (match_operand:QI 2 "register_operand" "")))
11919 (clobber (match_scratch:DI 3 ""))
11920 (clobber (reg:CC FLAGS_REG))]
11921 "TARGET_64BIT && reload_completed"
11923 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11926 [(set (match_operand:TI 0 "register_operand" "")
11927 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11928 (match_operand:QI 2 "immediate_operand" "")))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "TARGET_64BIT && reload_completed"
11932 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11934 (define_insn "x86_64_shrd"
11935 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11936 (ior:DI (ashiftrt:DI (match_dup 0)
11937 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11938 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11939 (minus:QI (const_int 64) (match_dup 2)))))
11940 (clobber (reg:CC FLAGS_REG))]
11943 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11944 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11945 [(set_attr "type" "ishift")
11946 (set_attr "prefix_0f" "1")
11947 (set_attr "mode" "DI")
11948 (set_attr "athlon_decode" "vector")
11949 (set_attr "amdfam10_decode" "vector")])
11951 (define_expand "ashrdi3"
11952 [(set (match_operand:DI 0 "shiftdi_operand" "")
11953 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11954 (match_operand:QI 2 "nonmemory_operand" "")))]
11956 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11958 (define_insn "*ashrdi3_63_rex64"
11959 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11960 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11961 (match_operand:DI 2 "const_int_operand" "i,i")))
11962 (clobber (reg:CC FLAGS_REG))]
11963 "TARGET_64BIT && INTVAL (operands[2]) == 63
11964 && (TARGET_USE_CLTD || optimize_size)
11965 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11968 sar{q}\t{%2, %0|%0, %2}"
11969 [(set_attr "type" "imovx,ishift")
11970 (set_attr "prefix_0f" "0,*")
11971 (set_attr "length_immediate" "0,*")
11972 (set_attr "modrm" "0,1")
11973 (set_attr "mode" "DI")])
11975 (define_insn "*ashrdi3_1_one_bit_rex64"
11976 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11977 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11978 (match_operand:QI 2 "const1_operand" "")))
11979 (clobber (reg:CC FLAGS_REG))]
11981 && (TARGET_SHIFT1 || optimize_size)
11982 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11984 [(set_attr "type" "ishift")
11985 (set (attr "length")
11986 (if_then_else (match_operand:DI 0 "register_operand" "")
11988 (const_string "*")))])
11990 (define_insn "*ashrdi3_1_rex64"
11991 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11992 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11993 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11994 (clobber (reg:CC FLAGS_REG))]
11995 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11997 sar{q}\t{%2, %0|%0, %2}
11998 sar{q}\t{%b2, %0|%0, %b2}"
11999 [(set_attr "type" "ishift")
12000 (set_attr "mode" "DI")])
12002 ;; This pattern can't accept a variable shift count, since shifts by
12003 ;; zero don't affect the flags. We assume that shifts by constant
12004 ;; zero are optimized away.
12005 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12006 [(set (reg FLAGS_REG)
12008 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12009 (match_operand:QI 2 "const1_operand" ""))
12011 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12012 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12014 && (TARGET_SHIFT1 || optimize_size)
12015 && ix86_match_ccmode (insn, CCGOCmode)
12016 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12018 [(set_attr "type" "ishift")
12019 (set (attr "length")
12020 (if_then_else (match_operand:DI 0 "register_operand" "")
12022 (const_string "*")))])
12024 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12025 [(set (reg FLAGS_REG)
12027 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const1_operand" ""))
12030 (clobber (match_scratch:DI 0 "=r"))]
12032 && (TARGET_SHIFT1 || optimize_size)
12033 && ix86_match_ccmode (insn, CCGOCmode)
12034 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12036 [(set_attr "type" "ishift")
12037 (set_attr "length" "2")])
12039 ;; This pattern can't accept a variable shift count, since shifts by
12040 ;; zero don't affect the flags. We assume that shifts by constant
12041 ;; zero are optimized away.
12042 (define_insn "*ashrdi3_cmp_rex64"
12043 [(set (reg FLAGS_REG)
12045 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12046 (match_operand:QI 2 "const_int_operand" "n"))
12048 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12049 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12051 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12052 && ix86_match_ccmode (insn, CCGOCmode)
12053 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12054 "sar{q}\t{%2, %0|%0, %2}"
12055 [(set_attr "type" "ishift")
12056 (set_attr "mode" "DI")])
12058 (define_insn "*ashrdi3_cconly_rex64"
12059 [(set (reg FLAGS_REG)
12061 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12062 (match_operand:QI 2 "const_int_operand" "n"))
12064 (clobber (match_scratch:DI 0 "=r"))]
12066 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12067 && ix86_match_ccmode (insn, CCGOCmode)
12068 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12069 "sar{q}\t{%2, %0|%0, %2}"
12070 [(set_attr "type" "ishift")
12071 (set_attr "mode" "DI")])
12073 (define_insn "*ashrdi3_1"
12074 [(set (match_operand:DI 0 "register_operand" "=r")
12075 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12076 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12077 (clobber (reg:CC FLAGS_REG))]
12080 [(set_attr "type" "multi")])
12082 ;; By default we don't ask for a scratch register, because when DImode
12083 ;; values are manipulated, registers are already at a premium. But if
12084 ;; we have one handy, we won't turn it away.
12086 [(match_scratch:SI 3 "r")
12087 (parallel [(set (match_operand:DI 0 "register_operand" "")
12088 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12089 (match_operand:QI 2 "nonmemory_operand" "")))
12090 (clobber (reg:CC FLAGS_REG))])
12092 "!TARGET_64BIT && TARGET_CMOVE"
12094 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12097 [(set (match_operand:DI 0 "register_operand" "")
12098 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12099 (match_operand:QI 2 "nonmemory_operand" "")))
12100 (clobber (reg:CC FLAGS_REG))]
12101 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12102 ? epilogue_completed : reload_completed)"
12104 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12106 (define_insn "x86_shrd_1"
12107 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12108 (ior:SI (ashiftrt:SI (match_dup 0)
12109 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12110 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12111 (minus:QI (const_int 32) (match_dup 2)))))
12112 (clobber (reg:CC FLAGS_REG))]
12115 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12116 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12117 [(set_attr "type" "ishift")
12118 (set_attr "prefix_0f" "1")
12119 (set_attr "pent_pair" "np")
12120 (set_attr "mode" "SI")])
12122 (define_expand "x86_shift_adj_3"
12123 [(use (match_operand:SI 0 "register_operand" ""))
12124 (use (match_operand:SI 1 "register_operand" ""))
12125 (use (match_operand:QI 2 "register_operand" ""))]
12128 rtx label = gen_label_rtx ();
12131 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12133 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12134 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12135 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12136 gen_rtx_LABEL_REF (VOIDmode, label),
12138 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12139 JUMP_LABEL (tmp) = label;
12141 emit_move_insn (operands[0], operands[1]);
12142 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12144 emit_label (label);
12145 LABEL_NUSES (label) = 1;
12150 (define_insn "ashrsi3_31"
12151 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12152 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12153 (match_operand:SI 2 "const_int_operand" "i,i")))
12154 (clobber (reg:CC FLAGS_REG))]
12155 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12156 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12159 sar{l}\t{%2, %0|%0, %2}"
12160 [(set_attr "type" "imovx,ishift")
12161 (set_attr "prefix_0f" "0,*")
12162 (set_attr "length_immediate" "0,*")
12163 (set_attr "modrm" "0,1")
12164 (set_attr "mode" "SI")])
12166 (define_insn "*ashrsi3_31_zext"
12167 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12168 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12169 (match_operand:SI 2 "const_int_operand" "i,i"))))
12170 (clobber (reg:CC FLAGS_REG))]
12171 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12172 && INTVAL (operands[2]) == 31
12173 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12176 sar{l}\t{%2, %k0|%k0, %2}"
12177 [(set_attr "type" "imovx,ishift")
12178 (set_attr "prefix_0f" "0,*")
12179 (set_attr "length_immediate" "0,*")
12180 (set_attr "modrm" "0,1")
12181 (set_attr "mode" "SI")])
12183 (define_expand "ashrsi3"
12184 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12185 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12186 (match_operand:QI 2 "nonmemory_operand" "")))
12187 (clobber (reg:CC FLAGS_REG))]
12189 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12191 (define_insn "*ashrsi3_1_one_bit"
12192 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12193 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12194 (match_operand:QI 2 "const1_operand" "")))
12195 (clobber (reg:CC FLAGS_REG))]
12196 "(TARGET_SHIFT1 || optimize_size)
12197 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12199 [(set_attr "type" "ishift")
12200 (set (attr "length")
12201 (if_then_else (match_operand:SI 0 "register_operand" "")
12203 (const_string "*")))])
12205 (define_insn "*ashrsi3_1_one_bit_zext"
12206 [(set (match_operand:DI 0 "register_operand" "=r")
12207 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12208 (match_operand:QI 2 "const1_operand" ""))))
12209 (clobber (reg:CC FLAGS_REG))]
12211 && (TARGET_SHIFT1 || optimize_size)
12212 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12214 [(set_attr "type" "ishift")
12215 (set_attr "length" "2")])
12217 (define_insn "*ashrsi3_1"
12218 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12219 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12220 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12221 (clobber (reg:CC FLAGS_REG))]
12222 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12224 sar{l}\t{%2, %0|%0, %2}
12225 sar{l}\t{%b2, %0|%0, %b2}"
12226 [(set_attr "type" "ishift")
12227 (set_attr "mode" "SI")])
12229 (define_insn "*ashrsi3_1_zext"
12230 [(set (match_operand:DI 0 "register_operand" "=r,r")
12231 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12232 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12233 (clobber (reg:CC FLAGS_REG))]
12234 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12236 sar{l}\t{%2, %k0|%k0, %2}
12237 sar{l}\t{%b2, %k0|%k0, %b2}"
12238 [(set_attr "type" "ishift")
12239 (set_attr "mode" "SI")])
12241 ;; This pattern can't accept a variable shift count, since shifts by
12242 ;; zero don't affect the flags. We assume that shifts by constant
12243 ;; zero are optimized away.
12244 (define_insn "*ashrsi3_one_bit_cmp"
12245 [(set (reg FLAGS_REG)
12247 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12248 (match_operand:QI 2 "const1_operand" ""))
12250 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12251 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12252 "(TARGET_SHIFT1 || optimize_size)
12253 && ix86_match_ccmode (insn, CCGOCmode)
12254 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12256 [(set_attr "type" "ishift")
12257 (set (attr "length")
12258 (if_then_else (match_operand:SI 0 "register_operand" "")
12260 (const_string "*")))])
12262 (define_insn "*ashrsi3_one_bit_cconly"
12263 [(set (reg FLAGS_REG)
12265 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12266 (match_operand:QI 2 "const1_operand" ""))
12268 (clobber (match_scratch:SI 0 "=r"))]
12269 "(TARGET_SHIFT1 || optimize_size)
12270 && ix86_match_ccmode (insn, CCGOCmode)
12271 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12273 [(set_attr "type" "ishift")
12274 (set_attr "length" "2")])
12276 (define_insn "*ashrsi3_one_bit_cmp_zext"
12277 [(set (reg FLAGS_REG)
12279 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12280 (match_operand:QI 2 "const1_operand" ""))
12282 (set (match_operand:DI 0 "register_operand" "=r")
12283 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12285 && (TARGET_SHIFT1 || optimize_size)
12286 && ix86_match_ccmode (insn, CCmode)
12287 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12289 [(set_attr "type" "ishift")
12290 (set_attr "length" "2")])
12292 ;; This pattern can't accept a variable shift count, since shifts by
12293 ;; zero don't affect the flags. We assume that shifts by constant
12294 ;; zero are optimized away.
12295 (define_insn "*ashrsi3_cmp"
12296 [(set (reg FLAGS_REG)
12298 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12299 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12301 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12302 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12303 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12304 && ix86_match_ccmode (insn, CCGOCmode)
12305 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12306 "sar{l}\t{%2, %0|%0, %2}"
12307 [(set_attr "type" "ishift")
12308 (set_attr "mode" "SI")])
12310 (define_insn "*ashrsi3_cconly"
12311 [(set (reg FLAGS_REG)
12313 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12316 (clobber (match_scratch:SI 0 "=r"))]
12317 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12318 && ix86_match_ccmode (insn, CCGOCmode)
12319 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12320 "sar{l}\t{%2, %0|%0, %2}"
12321 [(set_attr "type" "ishift")
12322 (set_attr "mode" "SI")])
12324 (define_insn "*ashrsi3_cmp_zext"
12325 [(set (reg FLAGS_REG)
12327 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12328 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12330 (set (match_operand:DI 0 "register_operand" "=r")
12331 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12333 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12334 && ix86_match_ccmode (insn, CCGOCmode)
12335 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12336 "sar{l}\t{%2, %k0|%k0, %2}"
12337 [(set_attr "type" "ishift")
12338 (set_attr "mode" "SI")])
12340 (define_expand "ashrhi3"
12341 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12342 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12343 (match_operand:QI 2 "nonmemory_operand" "")))
12344 (clobber (reg:CC FLAGS_REG))]
12345 "TARGET_HIMODE_MATH"
12346 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12348 (define_insn "*ashrhi3_1_one_bit"
12349 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12350 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351 (match_operand:QI 2 "const1_operand" "")))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "(TARGET_SHIFT1 || optimize_size)
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_1"
12363 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12364 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12365 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12366 (clobber (reg:CC FLAGS_REG))]
12367 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12369 sar{w}\t{%2, %0|%0, %2}
12370 sar{w}\t{%b2, %0|%0, %b2}"
12371 [(set_attr "type" "ishift")
12372 (set_attr "mode" "HI")])
12374 ;; This pattern can't accept a variable shift count, since shifts by
12375 ;; zero don't affect the flags. We assume that shifts by constant
12376 ;; zero are optimized away.
12377 (define_insn "*ashrhi3_one_bit_cmp"
12378 [(set (reg FLAGS_REG)
12380 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12381 (match_operand:QI 2 "const1_operand" ""))
12383 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12384 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12385 "(TARGET_SHIFT1 || optimize_size)
12386 && ix86_match_ccmode (insn, CCGOCmode)
12387 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12389 [(set_attr "type" "ishift")
12390 (set (attr "length")
12391 (if_then_else (match_operand 0 "register_operand" "")
12393 (const_string "*")))])
12395 (define_insn "*ashrhi3_one_bit_cconly"
12396 [(set (reg FLAGS_REG)
12398 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12399 (match_operand:QI 2 "const1_operand" ""))
12401 (clobber (match_scratch:HI 0 "=r"))]
12402 "(TARGET_SHIFT1 || optimize_size)
12403 && ix86_match_ccmode (insn, CCGOCmode)
12404 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12406 [(set_attr "type" "ishift")
12407 (set_attr "length" "2")])
12409 ;; This pattern can't accept a variable shift count, since shifts by
12410 ;; zero don't affect the flags. We assume that shifts by constant
12411 ;; zero are optimized away.
12412 (define_insn "*ashrhi3_cmp"
12413 [(set (reg FLAGS_REG)
12415 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12416 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12418 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12419 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12420 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12421 && ix86_match_ccmode (insn, CCGOCmode)
12422 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12423 "sar{w}\t{%2, %0|%0, %2}"
12424 [(set_attr "type" "ishift")
12425 (set_attr "mode" "HI")])
12427 (define_insn "*ashrhi3_cconly"
12428 [(set (reg FLAGS_REG)
12430 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12431 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12433 (clobber (match_scratch:HI 0 "=r"))]
12434 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12435 && ix86_match_ccmode (insn, CCGOCmode)
12436 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12437 "sar{w}\t{%2, %0|%0, %2}"
12438 [(set_attr "type" "ishift")
12439 (set_attr "mode" "HI")])
12441 (define_expand "ashrqi3"
12442 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12443 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12444 (match_operand:QI 2 "nonmemory_operand" "")))
12445 (clobber (reg:CC FLAGS_REG))]
12446 "TARGET_QIMODE_MATH"
12447 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12449 (define_insn "*ashrqi3_1_one_bit"
12450 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12451 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12452 (match_operand:QI 2 "const1_operand" "")))
12453 (clobber (reg:CC FLAGS_REG))]
12454 "(TARGET_SHIFT1 || optimize_size)
12455 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12457 [(set_attr "type" "ishift")
12458 (set (attr "length")
12459 (if_then_else (match_operand 0 "register_operand" "")
12461 (const_string "*")))])
12463 (define_insn "*ashrqi3_1_one_bit_slp"
12464 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12465 (ashiftrt:QI (match_dup 0)
12466 (match_operand:QI 1 "const1_operand" "")))
12467 (clobber (reg:CC FLAGS_REG))]
12468 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12469 && (TARGET_SHIFT1 || optimize_size)
12470 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12472 [(set_attr "type" "ishift1")
12473 (set (attr "length")
12474 (if_then_else (match_operand 0 "register_operand" "")
12476 (const_string "*")))])
12478 (define_insn "*ashrqi3_1"
12479 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12480 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12481 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12482 (clobber (reg:CC FLAGS_REG))]
12483 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12485 sar{b}\t{%2, %0|%0, %2}
12486 sar{b}\t{%b2, %0|%0, %b2}"
12487 [(set_attr "type" "ishift")
12488 (set_attr "mode" "QI")])
12490 (define_insn "*ashrqi3_1_slp"
12491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12492 (ashiftrt:QI (match_dup 0)
12493 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12494 (clobber (reg:CC FLAGS_REG))]
12495 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12496 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12498 sar{b}\t{%1, %0|%0, %1}
12499 sar{b}\t{%b1, %0|%0, %b1}"
12500 [(set_attr "type" "ishift1")
12501 (set_attr "mode" "QI")])
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags. We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*ashrqi3_one_bit_cmp"
12507 [(set (reg FLAGS_REG)
12509 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12510 (match_operand:QI 2 "const1_operand" "I"))
12512 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12513 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12514 "(TARGET_SHIFT1 || optimize_size)
12515 && ix86_match_ccmode (insn, CCGOCmode)
12516 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12518 [(set_attr "type" "ishift")
12519 (set (attr "length")
12520 (if_then_else (match_operand 0 "register_operand" "")
12522 (const_string "*")))])
12524 (define_insn "*ashrqi3_one_bit_cconly"
12525 [(set (reg FLAGS_REG)
12527 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const1_operand" "I"))
12530 (clobber (match_scratch:QI 0 "=q"))]
12531 "(TARGET_SHIFT1 || optimize_size)
12532 && ix86_match_ccmode (insn, CCGOCmode)
12533 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12535 [(set_attr "type" "ishift")
12536 (set_attr "length" "2")])
12538 ;; This pattern can't accept a variable shift count, since shifts by
12539 ;; zero don't affect the flags. We assume that shifts by constant
12540 ;; zero are optimized away.
12541 (define_insn "*ashrqi3_cmp"
12542 [(set (reg FLAGS_REG)
12544 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12545 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12547 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12548 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12549 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12550 && ix86_match_ccmode (insn, CCGOCmode)
12551 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12552 "sar{b}\t{%2, %0|%0, %2}"
12553 [(set_attr "type" "ishift")
12554 (set_attr "mode" "QI")])
12556 (define_insn "*ashrqi3_cconly"
12557 [(set (reg FLAGS_REG)
12559 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12560 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12562 (clobber (match_scratch:QI 0 "=q"))]
12563 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12564 && ix86_match_ccmode (insn, CCGOCmode)
12565 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12566 "sar{b}\t{%2, %0|%0, %2}"
12567 [(set_attr "type" "ishift")
12568 (set_attr "mode" "QI")])
12571 ;; Logical shift instructions
12573 ;; See comment above `ashldi3' about how this works.
12575 (define_expand "lshrti3"
12576 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12577 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12578 (match_operand:QI 2 "nonmemory_operand" "")))
12579 (clobber (reg:CC FLAGS_REG))])]
12582 if (! immediate_operand (operands[2], QImode))
12584 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12587 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12591 (define_insn "lshrti3_1"
12592 [(set (match_operand:TI 0 "register_operand" "=r")
12593 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12594 (match_operand:QI 2 "register_operand" "c")))
12595 (clobber (match_scratch:DI 3 "=&r"))
12596 (clobber (reg:CC FLAGS_REG))]
12599 [(set_attr "type" "multi")])
12601 ;; This pattern must be defined before *lshrti3_2 to prevent
12602 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12604 (define_insn "sse2_lshrti3"
12605 [(set (match_operand:TI 0 "register_operand" "=x")
12606 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12607 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12610 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12611 return "psrldq\t{%2, %0|%0, %2}";
12613 [(set_attr "type" "sseishft")
12614 (set_attr "prefix_data16" "1")
12615 (set_attr "mode" "TI")])
12617 (define_insn "*lshrti3_2"
12618 [(set (match_operand:TI 0 "register_operand" "=r")
12619 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12620 (match_operand:QI 2 "immediate_operand" "O")))
12621 (clobber (reg:CC FLAGS_REG))]
12624 [(set_attr "type" "multi")])
12627 [(set (match_operand:TI 0 "register_operand" "")
12628 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12629 (match_operand:QI 2 "register_operand" "")))
12630 (clobber (match_scratch:DI 3 ""))
12631 (clobber (reg:CC FLAGS_REG))]
12632 "TARGET_64BIT && reload_completed"
12634 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12637 [(set (match_operand:TI 0 "register_operand" "")
12638 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12639 (match_operand:QI 2 "immediate_operand" "")))
12640 (clobber (reg:CC FLAGS_REG))]
12641 "TARGET_64BIT && reload_completed"
12643 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12645 (define_expand "lshrdi3"
12646 [(set (match_operand:DI 0 "shiftdi_operand" "")
12647 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12648 (match_operand:QI 2 "nonmemory_operand" "")))]
12650 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12652 (define_insn "*lshrdi3_1_one_bit_rex64"
12653 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12654 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12655 (match_operand:QI 2 "const1_operand" "")))
12656 (clobber (reg:CC FLAGS_REG))]
12658 && (TARGET_SHIFT1 || optimize_size)
12659 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12661 [(set_attr "type" "ishift")
12662 (set (attr "length")
12663 (if_then_else (match_operand:DI 0 "register_operand" "")
12665 (const_string "*")))])
12667 (define_insn "*lshrdi3_1_rex64"
12668 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12669 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12670 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12671 (clobber (reg:CC FLAGS_REG))]
12672 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12674 shr{q}\t{%2, %0|%0, %2}
12675 shr{q}\t{%b2, %0|%0, %b2}"
12676 [(set_attr "type" "ishift")
12677 (set_attr "mode" "DI")])
12679 ;; This pattern can't accept a variable shift count, since shifts by
12680 ;; zero don't affect the flags. We assume that shifts by constant
12681 ;; zero are optimized away.
12682 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12683 [(set (reg FLAGS_REG)
12685 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12686 (match_operand:QI 2 "const1_operand" ""))
12688 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12689 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12691 && (TARGET_SHIFT1 || optimize_size)
12692 && ix86_match_ccmode (insn, CCGOCmode)
12693 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12695 [(set_attr "type" "ishift")
12696 (set (attr "length")
12697 (if_then_else (match_operand:DI 0 "register_operand" "")
12699 (const_string "*")))])
12701 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12702 [(set (reg FLAGS_REG)
12704 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12705 (match_operand:QI 2 "const1_operand" ""))
12707 (clobber (match_scratch:DI 0 "=r"))]
12709 && (TARGET_SHIFT1 || optimize_size)
12710 && ix86_match_ccmode (insn, CCGOCmode)
12711 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12713 [(set_attr "type" "ishift")
12714 (set_attr "length" "2")])
12716 ;; This pattern can't accept a variable shift count, since shifts by
12717 ;; zero don't affect the flags. We assume that shifts by constant
12718 ;; zero are optimized away.
12719 (define_insn "*lshrdi3_cmp_rex64"
12720 [(set (reg FLAGS_REG)
12722 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12723 (match_operand:QI 2 "const_int_operand" "e"))
12725 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12726 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12728 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12729 && ix86_match_ccmode (insn, CCGOCmode)
12730 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12731 "shr{q}\t{%2, %0|%0, %2}"
12732 [(set_attr "type" "ishift")
12733 (set_attr "mode" "DI")])
12735 (define_insn "*lshrdi3_cconly_rex64"
12736 [(set (reg FLAGS_REG)
12738 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12739 (match_operand:QI 2 "const_int_operand" "e"))
12741 (clobber (match_scratch:DI 0 "=r"))]
12743 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12744 && ix86_match_ccmode (insn, CCGOCmode)
12745 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12746 "shr{q}\t{%2, %0|%0, %2}"
12747 [(set_attr "type" "ishift")
12748 (set_attr "mode" "DI")])
12750 (define_insn "*lshrdi3_1"
12751 [(set (match_operand:DI 0 "register_operand" "=r")
12752 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12753 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12754 (clobber (reg:CC FLAGS_REG))]
12757 [(set_attr "type" "multi")])
12759 ;; By default we don't ask for a scratch register, because when DImode
12760 ;; values are manipulated, registers are already at a premium. But if
12761 ;; we have one handy, we won't turn it away.
12763 [(match_scratch:SI 3 "r")
12764 (parallel [(set (match_operand:DI 0 "register_operand" "")
12765 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12766 (match_operand:QI 2 "nonmemory_operand" "")))
12767 (clobber (reg:CC FLAGS_REG))])
12769 "!TARGET_64BIT && TARGET_CMOVE"
12771 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12774 [(set (match_operand:DI 0 "register_operand" "")
12775 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12776 (match_operand:QI 2 "nonmemory_operand" "")))
12777 (clobber (reg:CC FLAGS_REG))]
12778 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12779 ? epilogue_completed : reload_completed)"
12781 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12783 (define_expand "lshrsi3"
12784 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12785 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12786 (match_operand:QI 2 "nonmemory_operand" "")))
12787 (clobber (reg:CC FLAGS_REG))]
12789 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12791 (define_insn "*lshrsi3_1_one_bit"
12792 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12793 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12794 (match_operand:QI 2 "const1_operand" "")))
12795 (clobber (reg:CC FLAGS_REG))]
12796 "(TARGET_SHIFT1 || optimize_size)
12797 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12799 [(set_attr "type" "ishift")
12800 (set (attr "length")
12801 (if_then_else (match_operand:SI 0 "register_operand" "")
12803 (const_string "*")))])
12805 (define_insn "*lshrsi3_1_one_bit_zext"
12806 [(set (match_operand:DI 0 "register_operand" "=r")
12807 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12808 (match_operand:QI 2 "const1_operand" "")))
12809 (clobber (reg:CC FLAGS_REG))]
12811 && (TARGET_SHIFT1 || optimize_size)
12812 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12814 [(set_attr "type" "ishift")
12815 (set_attr "length" "2")])
12817 (define_insn "*lshrsi3_1"
12818 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12819 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12820 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12821 (clobber (reg:CC FLAGS_REG))]
12822 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12824 shr{l}\t{%2, %0|%0, %2}
12825 shr{l}\t{%b2, %0|%0, %b2}"
12826 [(set_attr "type" "ishift")
12827 (set_attr "mode" "SI")])
12829 (define_insn "*lshrsi3_1_zext"
12830 [(set (match_operand:DI 0 "register_operand" "=r,r")
12832 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12833 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12834 (clobber (reg:CC FLAGS_REG))]
12835 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12837 shr{l}\t{%2, %k0|%k0, %2}
12838 shr{l}\t{%b2, %k0|%k0, %b2}"
12839 [(set_attr "type" "ishift")
12840 (set_attr "mode" "SI")])
12842 ;; This pattern can't accept a variable shift count, since shifts by
12843 ;; zero don't affect the flags. We assume that shifts by constant
12844 ;; zero are optimized away.
12845 (define_insn "*lshrsi3_one_bit_cmp"
12846 [(set (reg FLAGS_REG)
12848 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12849 (match_operand:QI 2 "const1_operand" ""))
12851 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12852 (lshiftrt:SI (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")
12859 (if_then_else (match_operand:SI 0 "register_operand" "")
12861 (const_string "*")))])
12863 (define_insn "*lshrsi3_one_bit_cconly"
12864 [(set (reg FLAGS_REG)
12866 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12867 (match_operand:QI 2 "const1_operand" ""))
12869 (clobber (match_scratch:SI 0 "=r"))]
12870 "(TARGET_SHIFT1 || optimize_size)
12871 && ix86_match_ccmode (insn, CCGOCmode)
12872 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12874 [(set_attr "type" "ishift")
12875 (set_attr "length" "2")])
12877 (define_insn "*lshrsi3_cmp_one_bit_zext"
12878 [(set (reg FLAGS_REG)
12880 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12881 (match_operand:QI 2 "const1_operand" ""))
12883 (set (match_operand:DI 0 "register_operand" "=r")
12884 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12886 && (TARGET_SHIFT1 || optimize_size)
12887 && ix86_match_ccmode (insn, CCGOCmode)
12888 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12890 [(set_attr "type" "ishift")
12891 (set_attr "length" "2")])
12893 ;; This pattern can't accept a variable shift count, since shifts by
12894 ;; zero don't affect the flags. We assume that shifts by constant
12895 ;; zero are optimized away.
12896 (define_insn "*lshrsi3_cmp"
12897 [(set (reg FLAGS_REG)
12899 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12900 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12902 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12903 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12904 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12905 && ix86_match_ccmode (insn, CCGOCmode)
12906 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12907 "shr{l}\t{%2, %0|%0, %2}"
12908 [(set_attr "type" "ishift")
12909 (set_attr "mode" "SI")])
12911 (define_insn "*lshrsi3_cconly"
12912 [(set (reg FLAGS_REG)
12914 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12915 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12917 (clobber (match_scratch:SI 0 "=r"))]
12918 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12919 && ix86_match_ccmode (insn, CCGOCmode)
12920 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12921 "shr{l}\t{%2, %0|%0, %2}"
12922 [(set_attr "type" "ishift")
12923 (set_attr "mode" "SI")])
12925 (define_insn "*lshrsi3_cmp_zext"
12926 [(set (reg FLAGS_REG)
12928 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12929 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12931 (set (match_operand:DI 0 "register_operand" "=r")
12932 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12934 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12935 && ix86_match_ccmode (insn, CCGOCmode)
12936 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12937 "shr{l}\t{%2, %k0|%k0, %2}"
12938 [(set_attr "type" "ishift")
12939 (set_attr "mode" "SI")])
12941 (define_expand "lshrhi3"
12942 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12943 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12944 (match_operand:QI 2 "nonmemory_operand" "")))
12945 (clobber (reg:CC FLAGS_REG))]
12946 "TARGET_HIMODE_MATH"
12947 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12949 (define_insn "*lshrhi3_1_one_bit"
12950 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12951 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12952 (match_operand:QI 2 "const1_operand" "")))
12953 (clobber (reg:CC FLAGS_REG))]
12954 "(TARGET_SHIFT1 || optimize_size)
12955 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12957 [(set_attr "type" "ishift")
12958 (set (attr "length")
12959 (if_then_else (match_operand 0 "register_operand" "")
12961 (const_string "*")))])
12963 (define_insn "*lshrhi3_1"
12964 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12965 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12966 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12967 (clobber (reg:CC FLAGS_REG))]
12968 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12970 shr{w}\t{%2, %0|%0, %2}
12971 shr{w}\t{%b2, %0|%0, %b2}"
12972 [(set_attr "type" "ishift")
12973 (set_attr "mode" "HI")])
12975 ;; This pattern can't accept a variable shift count, since shifts by
12976 ;; zero don't affect the flags. We assume that shifts by constant
12977 ;; zero are optimized away.
12978 (define_insn "*lshrhi3_one_bit_cmp"
12979 [(set (reg FLAGS_REG)
12981 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12982 (match_operand:QI 2 "const1_operand" ""))
12984 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12985 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12986 "(TARGET_SHIFT1 || optimize_size)
12987 && ix86_match_ccmode (insn, CCGOCmode)
12988 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12990 [(set_attr "type" "ishift")
12991 (set (attr "length")
12992 (if_then_else (match_operand:SI 0 "register_operand" "")
12994 (const_string "*")))])
12996 (define_insn "*lshrhi3_one_bit_cconly"
12997 [(set (reg FLAGS_REG)
12999 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13000 (match_operand:QI 2 "const1_operand" ""))
13002 (clobber (match_scratch:HI 0 "=r"))]
13003 "(TARGET_SHIFT1 || optimize_size)
13004 && ix86_match_ccmode (insn, CCGOCmode)
13005 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13007 [(set_attr "type" "ishift")
13008 (set_attr "length" "2")])
13010 ;; This pattern can't accept a variable shift count, since shifts by
13011 ;; zero don't affect the flags. We assume that shifts by constant
13012 ;; zero are optimized away.
13013 (define_insn "*lshrhi3_cmp"
13014 [(set (reg FLAGS_REG)
13016 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13017 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13019 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13020 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13021 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13022 && ix86_match_ccmode (insn, CCGOCmode)
13023 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13024 "shr{w}\t{%2, %0|%0, %2}"
13025 [(set_attr "type" "ishift")
13026 (set_attr "mode" "HI")])
13028 (define_insn "*lshrhi3_cconly"
13029 [(set (reg FLAGS_REG)
13031 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13032 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13034 (clobber (match_scratch:HI 0 "=r"))]
13035 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13036 && ix86_match_ccmode (insn, CCGOCmode)
13037 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13038 "shr{w}\t{%2, %0|%0, %2}"
13039 [(set_attr "type" "ishift")
13040 (set_attr "mode" "HI")])
13042 (define_expand "lshrqi3"
13043 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13044 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13045 (match_operand:QI 2 "nonmemory_operand" "")))
13046 (clobber (reg:CC FLAGS_REG))]
13047 "TARGET_QIMODE_MATH"
13048 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13050 (define_insn "*lshrqi3_1_one_bit"
13051 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13052 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13053 (match_operand:QI 2 "const1_operand" "")))
13054 (clobber (reg:CC FLAGS_REG))]
13055 "(TARGET_SHIFT1 || optimize_size)
13056 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13058 [(set_attr "type" "ishift")
13059 (set (attr "length")
13060 (if_then_else (match_operand 0 "register_operand" "")
13062 (const_string "*")))])
13064 (define_insn "*lshrqi3_1_one_bit_slp"
13065 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13066 (lshiftrt:QI (match_dup 0)
13067 (match_operand:QI 1 "const1_operand" "")))
13068 (clobber (reg:CC FLAGS_REG))]
13069 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13070 && (TARGET_SHIFT1 || optimize_size)"
13072 [(set_attr "type" "ishift1")
13073 (set (attr "length")
13074 (if_then_else (match_operand 0 "register_operand" "")
13076 (const_string "*")))])
13078 (define_insn "*lshrqi3_1"
13079 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13080 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13081 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13082 (clobber (reg:CC FLAGS_REG))]
13083 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13085 shr{b}\t{%2, %0|%0, %2}
13086 shr{b}\t{%b2, %0|%0, %b2}"
13087 [(set_attr "type" "ishift")
13088 (set_attr "mode" "QI")])
13090 (define_insn "*lshrqi3_1_slp"
13091 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13092 (lshiftrt:QI (match_dup 0)
13093 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13094 (clobber (reg:CC FLAGS_REG))]
13095 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13096 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13098 shr{b}\t{%1, %0|%0, %1}
13099 shr{b}\t{%b1, %0|%0, %b1}"
13100 [(set_attr "type" "ishift1")
13101 (set_attr "mode" "QI")])
13103 ;; This pattern can't accept a variable shift count, since shifts by
13104 ;; zero don't affect the flags. We assume that shifts by constant
13105 ;; zero are optimized away.
13106 (define_insn "*lshrqi2_one_bit_cmp"
13107 [(set (reg FLAGS_REG)
13109 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13110 (match_operand:QI 2 "const1_operand" ""))
13112 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13113 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13114 "(TARGET_SHIFT1 || optimize_size)
13115 && ix86_match_ccmode (insn, CCGOCmode)
13116 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13118 [(set_attr "type" "ishift")
13119 (set (attr "length")
13120 (if_then_else (match_operand:SI 0 "register_operand" "")
13122 (const_string "*")))])
13124 (define_insn "*lshrqi2_one_bit_cconly"
13125 [(set (reg FLAGS_REG)
13127 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13128 (match_operand:QI 2 "const1_operand" ""))
13130 (clobber (match_scratch:QI 0 "=q"))]
13131 "(TARGET_SHIFT1 || optimize_size)
13132 && ix86_match_ccmode (insn, CCGOCmode)
13133 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13135 [(set_attr "type" "ishift")
13136 (set_attr "length" "2")])
13138 ;; This pattern can't accept a variable shift count, since shifts by
13139 ;; zero don't affect the flags. We assume that shifts by constant
13140 ;; zero are optimized away.
13141 (define_insn "*lshrqi2_cmp"
13142 [(set (reg FLAGS_REG)
13144 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13145 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13147 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13148 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13149 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13150 && ix86_match_ccmode (insn, CCGOCmode)
13151 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13152 "shr{b}\t{%2, %0|%0, %2}"
13153 [(set_attr "type" "ishift")
13154 (set_attr "mode" "QI")])
13156 (define_insn "*lshrqi2_cconly"
13157 [(set (reg FLAGS_REG)
13159 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13160 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13162 (clobber (match_scratch:QI 0 "=q"))]
13163 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13164 && ix86_match_ccmode (insn, CCGOCmode)
13165 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13166 "shr{b}\t{%2, %0|%0, %2}"
13167 [(set_attr "type" "ishift")
13168 (set_attr "mode" "QI")])
13170 ;; Rotate instructions
13172 (define_expand "rotldi3"
13173 [(set (match_operand:DI 0 "shiftdi_operand" "")
13174 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13175 (match_operand:QI 2 "nonmemory_operand" "")))
13176 (clobber (reg:CC FLAGS_REG))]
13181 ix86_expand_binary_operator (ROTATE, DImode, operands);
13184 if (!const_1_to_31_operand (operands[2], VOIDmode))
13186 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13190 ;; Implement rotation using two double-precision shift instructions
13191 ;; and a scratch register.
13192 (define_insn_and_split "ix86_rotldi3"
13193 [(set (match_operand:DI 0 "register_operand" "=r")
13194 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13195 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13196 (clobber (reg:CC FLAGS_REG))
13197 (clobber (match_scratch:SI 3 "=&r"))]
13200 "&& reload_completed"
13201 [(set (match_dup 3) (match_dup 4))
13203 [(set (match_dup 4)
13204 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13205 (lshiftrt:SI (match_dup 5)
13206 (minus:QI (const_int 32) (match_dup 2)))))
13207 (clobber (reg:CC FLAGS_REG))])
13209 [(set (match_dup 5)
13210 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13211 (lshiftrt:SI (match_dup 3)
13212 (minus:QI (const_int 32) (match_dup 2)))))
13213 (clobber (reg:CC FLAGS_REG))])]
13214 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13216 (define_insn "*rotlsi3_1_one_bit_rex64"
13217 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13218 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13219 (match_operand:QI 2 "const1_operand" "")))
13220 (clobber (reg:CC FLAGS_REG))]
13222 && (TARGET_SHIFT1 || optimize_size)
13223 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13225 [(set_attr "type" "rotate")
13226 (set (attr "length")
13227 (if_then_else (match_operand:DI 0 "register_operand" "")
13229 (const_string "*")))])
13231 (define_insn "*rotldi3_1_rex64"
13232 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13233 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13234 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13235 (clobber (reg:CC FLAGS_REG))]
13236 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13238 rol{q}\t{%2, %0|%0, %2}
13239 rol{q}\t{%b2, %0|%0, %b2}"
13240 [(set_attr "type" "rotate")
13241 (set_attr "mode" "DI")])
13243 (define_expand "rotlsi3"
13244 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13245 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13246 (match_operand:QI 2 "nonmemory_operand" "")))
13247 (clobber (reg:CC FLAGS_REG))]
13249 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13251 (define_insn "*rotlsi3_1_one_bit"
13252 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13253 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13254 (match_operand:QI 2 "const1_operand" "")))
13255 (clobber (reg:CC FLAGS_REG))]
13256 "(TARGET_SHIFT1 || optimize_size)
13257 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13259 [(set_attr "type" "rotate")
13260 (set (attr "length")
13261 (if_then_else (match_operand:SI 0 "register_operand" "")
13263 (const_string "*")))])
13265 (define_insn "*rotlsi3_1_one_bit_zext"
13266 [(set (match_operand:DI 0 "register_operand" "=r")
13268 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13269 (match_operand:QI 2 "const1_operand" ""))))
13270 (clobber (reg:CC FLAGS_REG))]
13272 && (TARGET_SHIFT1 || optimize_size)
13273 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13275 [(set_attr "type" "rotate")
13276 (set_attr "length" "2")])
13278 (define_insn "*rotlsi3_1"
13279 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13280 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13281 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13282 (clobber (reg:CC FLAGS_REG))]
13283 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13285 rol{l}\t{%2, %0|%0, %2}
13286 rol{l}\t{%b2, %0|%0, %b2}"
13287 [(set_attr "type" "rotate")
13288 (set_attr "mode" "SI")])
13290 (define_insn "*rotlsi3_1_zext"
13291 [(set (match_operand:DI 0 "register_operand" "=r,r")
13293 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13294 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13295 (clobber (reg:CC FLAGS_REG))]
13296 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13298 rol{l}\t{%2, %k0|%k0, %2}
13299 rol{l}\t{%b2, %k0|%k0, %b2}"
13300 [(set_attr "type" "rotate")
13301 (set_attr "mode" "SI")])
13303 (define_expand "rotlhi3"
13304 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13305 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13306 (match_operand:QI 2 "nonmemory_operand" "")))
13307 (clobber (reg:CC FLAGS_REG))]
13308 "TARGET_HIMODE_MATH"
13309 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13311 (define_insn "*rotlhi3_1_one_bit"
13312 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13313 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13314 (match_operand:QI 2 "const1_operand" "")))
13315 (clobber (reg:CC FLAGS_REG))]
13316 "(TARGET_SHIFT1 || optimize_size)
13317 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13319 [(set_attr "type" "rotate")
13320 (set (attr "length")
13321 (if_then_else (match_operand 0 "register_operand" "")
13323 (const_string "*")))])
13325 (define_insn "*rotlhi3_1"
13326 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13327 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13328 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13329 (clobber (reg:CC FLAGS_REG))]
13330 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13332 rol{w}\t{%2, %0|%0, %2}
13333 rol{w}\t{%b2, %0|%0, %b2}"
13334 [(set_attr "type" "rotate")
13335 (set_attr "mode" "HI")])
13338 [(set (match_operand:HI 0 "register_operand" "")
13339 (rotate:HI (match_dup 0) (const_int 8)))
13340 (clobber (reg:CC FLAGS_REG))]
13342 [(parallel [(set (strict_low_part (match_dup 0))
13343 (bswap:HI (match_dup 0)))
13344 (clobber (reg:CC FLAGS_REG))])]
13347 (define_expand "rotlqi3"
13348 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13349 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13350 (match_operand:QI 2 "nonmemory_operand" "")))
13351 (clobber (reg:CC FLAGS_REG))]
13352 "TARGET_QIMODE_MATH"
13353 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13355 (define_insn "*rotlqi3_1_one_bit_slp"
13356 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13357 (rotate:QI (match_dup 0)
13358 (match_operand:QI 1 "const1_operand" "")))
13359 (clobber (reg:CC FLAGS_REG))]
13360 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13361 && (TARGET_SHIFT1 || optimize_size)"
13363 [(set_attr "type" "rotate1")
13364 (set (attr "length")
13365 (if_then_else (match_operand 0 "register_operand" "")
13367 (const_string "*")))])
13369 (define_insn "*rotlqi3_1_one_bit"
13370 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13371 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13372 (match_operand:QI 2 "const1_operand" "")))
13373 (clobber (reg:CC FLAGS_REG))]
13374 "(TARGET_SHIFT1 || optimize_size)
13375 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13377 [(set_attr "type" "rotate")
13378 (set (attr "length")
13379 (if_then_else (match_operand 0 "register_operand" "")
13381 (const_string "*")))])
13383 (define_insn "*rotlqi3_1_slp"
13384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13385 (rotate:QI (match_dup 0)
13386 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13387 (clobber (reg:CC FLAGS_REG))]
13388 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13389 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13391 rol{b}\t{%1, %0|%0, %1}
13392 rol{b}\t{%b1, %0|%0, %b1}"
13393 [(set_attr "type" "rotate1")
13394 (set_attr "mode" "QI")])
13396 (define_insn "*rotlqi3_1"
13397 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13398 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13399 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13400 (clobber (reg:CC FLAGS_REG))]
13401 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13403 rol{b}\t{%2, %0|%0, %2}
13404 rol{b}\t{%b2, %0|%0, %b2}"
13405 [(set_attr "type" "rotate")
13406 (set_attr "mode" "QI")])
13408 (define_expand "rotrdi3"
13409 [(set (match_operand:DI 0 "shiftdi_operand" "")
13410 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13411 (match_operand:QI 2 "nonmemory_operand" "")))
13412 (clobber (reg:CC FLAGS_REG))]
13417 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13420 if (!const_1_to_31_operand (operands[2], VOIDmode))
13422 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13426 ;; Implement rotation using two double-precision shift instructions
13427 ;; and a scratch register.
13428 (define_insn_and_split "ix86_rotrdi3"
13429 [(set (match_operand:DI 0 "register_operand" "=r")
13430 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13431 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13432 (clobber (reg:CC FLAGS_REG))
13433 (clobber (match_scratch:SI 3 "=&r"))]
13436 "&& reload_completed"
13437 [(set (match_dup 3) (match_dup 4))
13439 [(set (match_dup 4)
13440 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13441 (ashift:SI (match_dup 5)
13442 (minus:QI (const_int 32) (match_dup 2)))))
13443 (clobber (reg:CC FLAGS_REG))])
13445 [(set (match_dup 5)
13446 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13447 (ashift:SI (match_dup 3)
13448 (minus:QI (const_int 32) (match_dup 2)))))
13449 (clobber (reg:CC FLAGS_REG))])]
13450 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13452 (define_insn "*rotrdi3_1_one_bit_rex64"
13453 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13454 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13455 (match_operand:QI 2 "const1_operand" "")))
13456 (clobber (reg:CC FLAGS_REG))]
13458 && (TARGET_SHIFT1 || optimize_size)
13459 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13461 [(set_attr "type" "rotate")
13462 (set (attr "length")
13463 (if_then_else (match_operand:DI 0 "register_operand" "")
13465 (const_string "*")))])
13467 (define_insn "*rotrdi3_1_rex64"
13468 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13469 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13470 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13471 (clobber (reg:CC FLAGS_REG))]
13472 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13474 ror{q}\t{%2, %0|%0, %2}
13475 ror{q}\t{%b2, %0|%0, %b2}"
13476 [(set_attr "type" "rotate")
13477 (set_attr "mode" "DI")])
13479 (define_expand "rotrsi3"
13480 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13481 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13482 (match_operand:QI 2 "nonmemory_operand" "")))
13483 (clobber (reg:CC FLAGS_REG))]
13485 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13487 (define_insn "*rotrsi3_1_one_bit"
13488 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13489 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13490 (match_operand:QI 2 "const1_operand" "")))
13491 (clobber (reg:CC FLAGS_REG))]
13492 "(TARGET_SHIFT1 || optimize_size)
13493 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13495 [(set_attr "type" "rotate")
13496 (set (attr "length")
13497 (if_then_else (match_operand:SI 0 "register_operand" "")
13499 (const_string "*")))])
13501 (define_insn "*rotrsi3_1_one_bit_zext"
13502 [(set (match_operand:DI 0 "register_operand" "=r")
13504 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13505 (match_operand:QI 2 "const1_operand" ""))))
13506 (clobber (reg:CC FLAGS_REG))]
13508 && (TARGET_SHIFT1 || optimize_size)
13509 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13511 [(set_attr "type" "rotate")
13512 (set (attr "length")
13513 (if_then_else (match_operand:SI 0 "register_operand" "")
13515 (const_string "*")))])
13517 (define_insn "*rotrsi3_1"
13518 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13519 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13520 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13521 (clobber (reg:CC FLAGS_REG))]
13522 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13524 ror{l}\t{%2, %0|%0, %2}
13525 ror{l}\t{%b2, %0|%0, %b2}"
13526 [(set_attr "type" "rotate")
13527 (set_attr "mode" "SI")])
13529 (define_insn "*rotrsi3_1_zext"
13530 [(set (match_operand:DI 0 "register_operand" "=r,r")
13532 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13533 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13534 (clobber (reg:CC FLAGS_REG))]
13535 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13537 ror{l}\t{%2, %k0|%k0, %2}
13538 ror{l}\t{%b2, %k0|%k0, %b2}"
13539 [(set_attr "type" "rotate")
13540 (set_attr "mode" "SI")])
13542 (define_expand "rotrhi3"
13543 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13544 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13545 (match_operand:QI 2 "nonmemory_operand" "")))
13546 (clobber (reg:CC FLAGS_REG))]
13547 "TARGET_HIMODE_MATH"
13548 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13550 (define_insn "*rotrhi3_one_bit"
13551 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13552 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13553 (match_operand:QI 2 "const1_operand" "")))
13554 (clobber (reg:CC FLAGS_REG))]
13555 "(TARGET_SHIFT1 || optimize_size)
13556 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13558 [(set_attr "type" "rotate")
13559 (set (attr "length")
13560 (if_then_else (match_operand 0 "register_operand" "")
13562 (const_string "*")))])
13564 (define_insn "*rotrhi3_1"
13565 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13566 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13567 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13568 (clobber (reg:CC FLAGS_REG))]
13569 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13571 ror{w}\t{%2, %0|%0, %2}
13572 ror{w}\t{%b2, %0|%0, %b2}"
13573 [(set_attr "type" "rotate")
13574 (set_attr "mode" "HI")])
13577 [(set (match_operand:HI 0 "register_operand" "")
13578 (rotatert:HI (match_dup 0) (const_int 8)))
13579 (clobber (reg:CC FLAGS_REG))]
13581 [(parallel [(set (strict_low_part (match_dup 0))
13582 (bswap:HI (match_dup 0)))
13583 (clobber (reg:CC FLAGS_REG))])]
13586 (define_expand "rotrqi3"
13587 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13588 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13589 (match_operand:QI 2 "nonmemory_operand" "")))
13590 (clobber (reg:CC FLAGS_REG))]
13591 "TARGET_QIMODE_MATH"
13592 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13594 (define_insn "*rotrqi3_1_one_bit"
13595 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13596 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13597 (match_operand:QI 2 "const1_operand" "")))
13598 (clobber (reg:CC FLAGS_REG))]
13599 "(TARGET_SHIFT1 || optimize_size)
13600 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13602 [(set_attr "type" "rotate")
13603 (set (attr "length")
13604 (if_then_else (match_operand 0 "register_operand" "")
13606 (const_string "*")))])
13608 (define_insn "*rotrqi3_1_one_bit_slp"
13609 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13610 (rotatert:QI (match_dup 0)
13611 (match_operand:QI 1 "const1_operand" "")))
13612 (clobber (reg:CC FLAGS_REG))]
13613 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13614 && (TARGET_SHIFT1 || optimize_size)"
13616 [(set_attr "type" "rotate1")
13617 (set (attr "length")
13618 (if_then_else (match_operand 0 "register_operand" "")
13620 (const_string "*")))])
13622 (define_insn "*rotrqi3_1"
13623 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13624 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13625 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13626 (clobber (reg:CC FLAGS_REG))]
13627 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13629 ror{b}\t{%2, %0|%0, %2}
13630 ror{b}\t{%b2, %0|%0, %b2}"
13631 [(set_attr "type" "rotate")
13632 (set_attr "mode" "QI")])
13634 (define_insn "*rotrqi3_1_slp"
13635 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13636 (rotatert:QI (match_dup 0)
13637 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13638 (clobber (reg:CC FLAGS_REG))]
13639 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13640 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13642 ror{b}\t{%1, %0|%0, %1}
13643 ror{b}\t{%b1, %0|%0, %b1}"
13644 [(set_attr "type" "rotate1")
13645 (set_attr "mode" "QI")])
13647 ;; Bit set / bit test instructions
13649 (define_expand "extv"
13650 [(set (match_operand:SI 0 "register_operand" "")
13651 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13652 (match_operand:SI 2 "const8_operand" "")
13653 (match_operand:SI 3 "const8_operand" "")))]
13656 /* Handle extractions from %ah et al. */
13657 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13660 /* From mips.md: extract_bit_field doesn't verify that our source
13661 matches the predicate, so check it again here. */
13662 if (! ext_register_operand (operands[1], VOIDmode))
13666 (define_expand "extzv"
13667 [(set (match_operand:SI 0 "register_operand" "")
13668 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13669 (match_operand:SI 2 "const8_operand" "")
13670 (match_operand:SI 3 "const8_operand" "")))]
13673 /* Handle extractions from %ah et al. */
13674 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13677 /* From mips.md: extract_bit_field doesn't verify that our source
13678 matches the predicate, so check it again here. */
13679 if (! ext_register_operand (operands[1], VOIDmode))
13683 (define_expand "insv"
13684 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13685 (match_operand 1 "const8_operand" "")
13686 (match_operand 2 "const8_operand" ""))
13687 (match_operand 3 "register_operand" ""))]
13690 /* Handle insertions to %ah et al. */
13691 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13694 /* From mips.md: insert_bit_field doesn't verify that our source
13695 matches the predicate, so check it again here. */
13696 if (! ext_register_operand (operands[0], VOIDmode))
13700 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13702 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13707 ;; %%% bts, btr, btc, bt.
13708 ;; In general these instructions are *slow* when applied to memory,
13709 ;; since they enforce atomic operation. When applied to registers,
13710 ;; it depends on the cpu implementation. They're never faster than
13711 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13712 ;; no point. But in 64-bit, we can't hold the relevant immediates
13713 ;; within the instruction itself, so operating on bits in the high
13714 ;; 32-bits of a register becomes easier.
13716 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13717 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13718 ;; negdf respectively, so they can never be disabled entirely.
13720 (define_insn "*btsq"
13721 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13723 (match_operand:DI 1 "const_0_to_63_operand" ""))
13725 (clobber (reg:CC FLAGS_REG))]
13726 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13728 [(set_attr "type" "alu1")])
13730 (define_insn "*btrq"
13731 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13733 (match_operand:DI 1 "const_0_to_63_operand" ""))
13735 (clobber (reg:CC FLAGS_REG))]
13736 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13738 [(set_attr "type" "alu1")])
13740 (define_insn "*btcq"
13741 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13743 (match_operand:DI 1 "const_0_to_63_operand" ""))
13744 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13745 (clobber (reg:CC FLAGS_REG))]
13746 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13748 [(set_attr "type" "alu1")])
13750 ;; Allow Nocona to avoid these instructions if a register is available.
13753 [(match_scratch:DI 2 "r")
13754 (parallel [(set (zero_extract:DI
13755 (match_operand:DI 0 "register_operand" "")
13757 (match_operand:DI 1 "const_0_to_63_operand" ""))
13759 (clobber (reg:CC FLAGS_REG))])]
13760 "TARGET_64BIT && !TARGET_USE_BT"
13763 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13766 if (HOST_BITS_PER_WIDE_INT >= 64)
13767 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13768 else if (i < HOST_BITS_PER_WIDE_INT)
13769 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13771 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13773 op1 = immed_double_const (lo, hi, DImode);
13776 emit_move_insn (operands[2], op1);
13780 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13785 [(match_scratch:DI 2 "r")
13786 (parallel [(set (zero_extract:DI
13787 (match_operand:DI 0 "register_operand" "")
13789 (match_operand:DI 1 "const_0_to_63_operand" ""))
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_anddi3 (operands[0], operands[0], op1));
13817 [(match_scratch:DI 2 "r")
13818 (parallel [(set (zero_extract:DI
13819 (match_operand:DI 0 "register_operand" "")
13821 (match_operand:DI 1 "const_0_to_63_operand" ""))
13822 (not:DI (zero_extract:DI
13823 (match_dup 0) (const_int 1) (match_dup 1))))
13824 (clobber (reg:CC FLAGS_REG))])]
13825 "TARGET_64BIT && !TARGET_USE_BT"
13828 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13831 if (HOST_BITS_PER_WIDE_INT >= 64)
13832 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13833 else if (i < HOST_BITS_PER_WIDE_INT)
13834 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13836 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13838 op1 = immed_double_const (lo, hi, DImode);
13841 emit_move_insn (operands[2], op1);
13845 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13849 ;; Store-flag instructions.
13851 ;; For all sCOND expanders, also expand the compare or test insn that
13852 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13854 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13855 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13856 ;; way, which can later delete the movzx if only QImode is needed.
13858 (define_expand "s<code>"
13859 [(set (match_operand:QI 0 "register_operand" "")
13860 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13862 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13864 (define_expand "s<code>"
13865 [(set (match_operand:QI 0 "register_operand" "")
13866 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13867 "TARGET_80387 || TARGET_SSE"
13868 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13870 (define_insn "*setcc_1"
13871 [(set (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 (define_insn "*setcc_2"
13880 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13881 (match_operator:QI 1 "ix86_comparison_operator"
13882 [(reg FLAGS_REG) (const_int 0)]))]
13885 [(set_attr "type" "setcc")
13886 (set_attr "mode" "QI")])
13888 ;; In general it is not safe to assume too much about CCmode registers,
13889 ;; so simplify-rtx stops when it sees a second one. Under certain
13890 ;; conditions this is safe on x86, so help combine not create
13897 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13898 (ne:QI (match_operator 1 "ix86_comparison_operator"
13899 [(reg FLAGS_REG) (const_int 0)])
13902 [(set (match_dup 0) (match_dup 1))]
13904 PUT_MODE (operands[1], QImode);
13908 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13909 (ne:QI (match_operator 1 "ix86_comparison_operator"
13910 [(reg FLAGS_REG) (const_int 0)])
13913 [(set (match_dup 0) (match_dup 1))]
13915 PUT_MODE (operands[1], QImode);
13919 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13920 (eq:QI (match_operator 1 "ix86_comparison_operator"
13921 [(reg FLAGS_REG) (const_int 0)])
13924 [(set (match_dup 0) (match_dup 1))]
13926 rtx new_op1 = copy_rtx (operands[1]);
13927 operands[1] = new_op1;
13928 PUT_MODE (new_op1, QImode);
13929 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13930 GET_MODE (XEXP (new_op1, 0))));
13932 /* Make sure that (a) the CCmode we have for the flags is strong
13933 enough for the reversed compare or (b) we have a valid FP compare. */
13934 if (! ix86_comparison_operator (new_op1, VOIDmode))
13939 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13940 (eq:QI (match_operator 1 "ix86_comparison_operator"
13941 [(reg FLAGS_REG) (const_int 0)])
13944 [(set (match_dup 0) (match_dup 1))]
13946 rtx new_op1 = copy_rtx (operands[1]);
13947 operands[1] = new_op1;
13948 PUT_MODE (new_op1, QImode);
13949 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13950 GET_MODE (XEXP (new_op1, 0))));
13952 /* Make sure that (a) the CCmode we have for the flags is strong
13953 enough for the reversed compare or (b) we have a valid FP compare. */
13954 if (! ix86_comparison_operator (new_op1, VOIDmode))
13958 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13959 ;; subsequent logical operations are used to imitate conditional moves.
13960 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13963 (define_insn "*sse_setcc<mode>"
13964 [(set (match_operand:MODEF 0 "register_operand" "=x")
13965 (match_operator:MODEF 1 "sse_comparison_operator"
13966 [(match_operand:MODEF 2 "register_operand" "0")
13967 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13968 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13969 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13970 [(set_attr "type" "ssecmp")
13971 (set_attr "mode" "<MODE>")])
13973 (define_insn "*sse5_setcc<mode>"
13974 [(set (match_operand:MODEF 0 "register_operand" "=x")
13975 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13976 [(match_operand:MODEF 2 "register_operand" "x")
13977 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13979 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13980 [(set_attr "type" "sse4arg")
13981 (set_attr "mode" "<MODE>")])
13984 ;; Basic conditional jump instructions.
13985 ;; We ignore the overflow flag for signed branch instructions.
13987 ;; For all bCOND expanders, also expand the compare or test insn that
13988 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13990 (define_expand "b<code>"
13992 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13994 (label_ref (match_operand 0 ""))
13997 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13999 (define_expand "b<code>"
14001 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14003 (label_ref (match_operand 0 ""))
14005 "TARGET_80387 || TARGET_SSE_MATH"
14006 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14008 (define_insn "*jcc_1"
14010 (if_then_else (match_operator 1 "ix86_comparison_operator"
14011 [(reg FLAGS_REG) (const_int 0)])
14012 (label_ref (match_operand 0 "" ""))
14016 [(set_attr "type" "ibr")
14017 (set_attr "modrm" "0")
14018 (set (attr "length")
14019 (if_then_else (and (ge (minus (match_dup 0) (pc))
14021 (lt (minus (match_dup 0) (pc))
14026 (define_insn "*jcc_2"
14028 (if_then_else (match_operator 1 "ix86_comparison_operator"
14029 [(reg FLAGS_REG) (const_int 0)])
14031 (label_ref (match_operand 0 "" ""))))]
14034 [(set_attr "type" "ibr")
14035 (set_attr "modrm" "0")
14036 (set (attr "length")
14037 (if_then_else (and (ge (minus (match_dup 0) (pc))
14039 (lt (minus (match_dup 0) (pc))
14044 ;; In general it is not safe to assume too much about CCmode registers,
14045 ;; so simplify-rtx stops when it sees a second one. Under certain
14046 ;; conditions this is safe on x86, so help combine not create
14054 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14055 [(reg FLAGS_REG) (const_int 0)])
14057 (label_ref (match_operand 1 "" ""))
14061 (if_then_else (match_dup 0)
14062 (label_ref (match_dup 1))
14065 PUT_MODE (operands[0], VOIDmode);
14070 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14071 [(reg FLAGS_REG) (const_int 0)])
14073 (label_ref (match_operand 1 "" ""))
14077 (if_then_else (match_dup 0)
14078 (label_ref (match_dup 1))
14081 rtx new_op0 = copy_rtx (operands[0]);
14082 operands[0] = new_op0;
14083 PUT_MODE (new_op0, VOIDmode);
14084 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14085 GET_MODE (XEXP (new_op0, 0))));
14087 /* Make sure that (a) the CCmode we have for the flags is strong
14088 enough for the reversed compare or (b) we have a valid FP compare. */
14089 if (! ix86_comparison_operator (new_op0, VOIDmode))
14093 ;; Define combination compare-and-branch fp compare instructions to use
14094 ;; during early optimization. Splitting the operation apart early makes
14095 ;; for bad code when we want to reverse the operation.
14097 (define_insn "*fp_jcc_1_mixed"
14099 (if_then_else (match_operator 0 "comparison_operator"
14100 [(match_operand 1 "register_operand" "f,x")
14101 (match_operand 2 "nonimmediate_operand" "f,xm")])
14102 (label_ref (match_operand 3 "" ""))
14104 (clobber (reg:CCFP FPSR_REG))
14105 (clobber (reg:CCFP FLAGS_REG))]
14106 "TARGET_MIX_SSE_I387
14107 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14108 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14109 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14112 (define_insn "*fp_jcc_1_sse"
14114 (if_then_else (match_operator 0 "comparison_operator"
14115 [(match_operand 1 "register_operand" "x")
14116 (match_operand 2 "nonimmediate_operand" "xm")])
14117 (label_ref (match_operand 3 "" ""))
14119 (clobber (reg:CCFP FPSR_REG))
14120 (clobber (reg:CCFP FLAGS_REG))]
14122 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14123 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14124 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14127 (define_insn "*fp_jcc_1_387"
14129 (if_then_else (match_operator 0 "comparison_operator"
14130 [(match_operand 1 "register_operand" "f")
14131 (match_operand 2 "register_operand" "f")])
14132 (label_ref (match_operand 3 "" ""))
14134 (clobber (reg:CCFP FPSR_REG))
14135 (clobber (reg:CCFP FLAGS_REG))]
14136 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14138 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14139 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14142 (define_insn "*fp_jcc_2_mixed"
14144 (if_then_else (match_operator 0 "comparison_operator"
14145 [(match_operand 1 "register_operand" "f,x")
14146 (match_operand 2 "nonimmediate_operand" "f,xm")])
14148 (label_ref (match_operand 3 "" ""))))
14149 (clobber (reg:CCFP FPSR_REG))
14150 (clobber (reg:CCFP FLAGS_REG))]
14151 "TARGET_MIX_SSE_I387
14152 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14153 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14154 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14157 (define_insn "*fp_jcc_2_sse"
14159 (if_then_else (match_operator 0 "comparison_operator"
14160 [(match_operand 1 "register_operand" "x")
14161 (match_operand 2 "nonimmediate_operand" "xm")])
14163 (label_ref (match_operand 3 "" ""))))
14164 (clobber (reg:CCFP FPSR_REG))
14165 (clobber (reg:CCFP FLAGS_REG))]
14167 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14168 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14169 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14172 (define_insn "*fp_jcc_2_387"
14174 (if_then_else (match_operator 0 "comparison_operator"
14175 [(match_operand 1 "register_operand" "f")
14176 (match_operand 2 "register_operand" "f")])
14178 (label_ref (match_operand 3 "" ""))))
14179 (clobber (reg:CCFP FPSR_REG))
14180 (clobber (reg:CCFP FLAGS_REG))]
14181 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14183 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14184 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14187 (define_insn "*fp_jcc_3_387"
14189 (if_then_else (match_operator 0 "comparison_operator"
14190 [(match_operand 1 "register_operand" "f")
14191 (match_operand 2 "nonimmediate_operand" "fm")])
14192 (label_ref (match_operand 3 "" ""))
14194 (clobber (reg:CCFP FPSR_REG))
14195 (clobber (reg:CCFP FLAGS_REG))
14196 (clobber (match_scratch:HI 4 "=a"))]
14198 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14199 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14200 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14201 && SELECT_CC_MODE (GET_CODE (operands[0]),
14202 operands[1], operands[2]) == CCFPmode
14203 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14206 (define_insn "*fp_jcc_4_387"
14208 (if_then_else (match_operator 0 "comparison_operator"
14209 [(match_operand 1 "register_operand" "f")
14210 (match_operand 2 "nonimmediate_operand" "fm")])
14212 (label_ref (match_operand 3 "" ""))))
14213 (clobber (reg:CCFP FPSR_REG))
14214 (clobber (reg:CCFP FLAGS_REG))
14215 (clobber (match_scratch:HI 4 "=a"))]
14217 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14218 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14219 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14220 && SELECT_CC_MODE (GET_CODE (operands[0]),
14221 operands[1], operands[2]) == CCFPmode
14222 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14225 (define_insn "*fp_jcc_5_387"
14227 (if_then_else (match_operator 0 "comparison_operator"
14228 [(match_operand 1 "register_operand" "f")
14229 (match_operand 2 "register_operand" "f")])
14230 (label_ref (match_operand 3 "" ""))
14232 (clobber (reg:CCFP FPSR_REG))
14233 (clobber (reg:CCFP FLAGS_REG))
14234 (clobber (match_scratch:HI 4 "=a"))]
14235 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14236 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14237 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14240 (define_insn "*fp_jcc_6_387"
14242 (if_then_else (match_operator 0 "comparison_operator"
14243 [(match_operand 1 "register_operand" "f")
14244 (match_operand 2 "register_operand" "f")])
14246 (label_ref (match_operand 3 "" ""))))
14247 (clobber (reg:CCFP FPSR_REG))
14248 (clobber (reg:CCFP FLAGS_REG))
14249 (clobber (match_scratch:HI 4 "=a"))]
14250 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14251 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14252 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14255 (define_insn "*fp_jcc_7_387"
14257 (if_then_else (match_operator 0 "comparison_operator"
14258 [(match_operand 1 "register_operand" "f")
14259 (match_operand 2 "const0_operand" "X")])
14260 (label_ref (match_operand 3 "" ""))
14262 (clobber (reg:CCFP FPSR_REG))
14263 (clobber (reg:CCFP FLAGS_REG))
14264 (clobber (match_scratch:HI 4 "=a"))]
14265 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14266 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14267 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14268 && SELECT_CC_MODE (GET_CODE (operands[0]),
14269 operands[1], operands[2]) == CCFPmode
14270 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14273 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14274 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14275 ;; with a precedence over other operators and is always put in the first
14276 ;; place. Swap condition and operands to match ficom instruction.
14278 (define_insn "*fp_jcc_8<mode>_387"
14280 (if_then_else (match_operator 0 "comparison_operator"
14281 [(match_operator 1 "float_operator"
14282 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14283 (match_operand 3 "register_operand" "f,f")])
14284 (label_ref (match_operand 4 "" ""))
14286 (clobber (reg:CCFP FPSR_REG))
14287 (clobber (reg:CCFP FLAGS_REG))
14288 (clobber (match_scratch:HI 5 "=a,a"))]
14289 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14290 && TARGET_USE_<MODE>MODE_FIOP
14291 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14292 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14293 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14294 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14299 (if_then_else (match_operator 0 "comparison_operator"
14300 [(match_operand 1 "register_operand" "")
14301 (match_operand 2 "nonimmediate_operand" "")])
14302 (match_operand 3 "" "")
14303 (match_operand 4 "" "")))
14304 (clobber (reg:CCFP FPSR_REG))
14305 (clobber (reg:CCFP FLAGS_REG))]
14309 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14310 operands[3], operands[4], NULL_RTX, NULL_RTX);
14316 (if_then_else (match_operator 0 "comparison_operator"
14317 [(match_operand 1 "register_operand" "")
14318 (match_operand 2 "general_operand" "")])
14319 (match_operand 3 "" "")
14320 (match_operand 4 "" "")))
14321 (clobber (reg:CCFP FPSR_REG))
14322 (clobber (reg:CCFP FLAGS_REG))
14323 (clobber (match_scratch:HI 5 "=a"))]
14327 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14328 operands[3], operands[4], operands[5], NULL_RTX);
14334 (if_then_else (match_operator 0 "comparison_operator"
14335 [(match_operator 1 "float_operator"
14336 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14337 (match_operand 3 "register_operand" "")])
14338 (match_operand 4 "" "")
14339 (match_operand 5 "" "")))
14340 (clobber (reg:CCFP FPSR_REG))
14341 (clobber (reg:CCFP FLAGS_REG))
14342 (clobber (match_scratch:HI 6 "=a"))]
14346 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14347 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14348 operands[3], operands[7],
14349 operands[4], operands[5], operands[6], NULL_RTX);
14353 ;; %%% Kill this when reload knows how to do it.
14356 (if_then_else (match_operator 0 "comparison_operator"
14357 [(match_operator 1 "float_operator"
14358 [(match_operand:X87MODEI12 2 "register_operand" "")])
14359 (match_operand 3 "register_operand" "")])
14360 (match_operand 4 "" "")
14361 (match_operand 5 "" "")))
14362 (clobber (reg:CCFP FPSR_REG))
14363 (clobber (reg:CCFP FLAGS_REG))
14364 (clobber (match_scratch:HI 6 "=a"))]
14368 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14369 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14370 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14371 operands[3], operands[7],
14372 operands[4], operands[5], operands[6], operands[2]);
14376 ;; Unconditional and other jump instructions
14378 (define_insn "jump"
14380 (label_ref (match_operand 0 "" "")))]
14383 [(set_attr "type" "ibr")
14384 (set (attr "length")
14385 (if_then_else (and (ge (minus (match_dup 0) (pc))
14387 (lt (minus (match_dup 0) (pc))
14391 (set_attr "modrm" "0")])
14393 (define_expand "indirect_jump"
14394 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14398 (define_insn "*indirect_jump"
14399 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14402 [(set_attr "type" "ibr")
14403 (set_attr "length_immediate" "0")])
14405 (define_insn "*indirect_jump_rtx64"
14406 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14409 [(set_attr "type" "ibr")
14410 (set_attr "length_immediate" "0")])
14412 (define_expand "tablejump"
14413 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14414 (use (label_ref (match_operand 1 "" "")))])]
14417 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14418 relative. Convert the relative address to an absolute address. */
14422 enum rtx_code code;
14424 /* We can't use @GOTOFF for text labels on VxWorks;
14425 see gotoff_operand. */
14426 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14430 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14432 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14436 op1 = pic_offset_table_rtx;
14441 op0 = pic_offset_table_rtx;
14445 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14450 (define_insn "*tablejump_1"
14451 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14452 (use (label_ref (match_operand 1 "" "")))]
14455 [(set_attr "type" "ibr")
14456 (set_attr "length_immediate" "0")])
14458 (define_insn "*tablejump_1_rtx64"
14459 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14460 (use (label_ref (match_operand 1 "" "")))]
14463 [(set_attr "type" "ibr")
14464 (set_attr "length_immediate" "0")])
14466 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14469 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14470 (set (match_operand:QI 1 "register_operand" "")
14471 (match_operator:QI 2 "ix86_comparison_operator"
14472 [(reg FLAGS_REG) (const_int 0)]))
14473 (set (match_operand 3 "q_regs_operand" "")
14474 (zero_extend (match_dup 1)))]
14475 "(peep2_reg_dead_p (3, operands[1])
14476 || operands_match_p (operands[1], operands[3]))
14477 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14478 [(set (match_dup 4) (match_dup 0))
14479 (set (strict_low_part (match_dup 5))
14482 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14483 operands[5] = gen_lowpart (QImode, operands[3]);
14484 ix86_expand_clear (operands[3]);
14487 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14490 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14491 (set (match_operand:QI 1 "register_operand" "")
14492 (match_operator:QI 2 "ix86_comparison_operator"
14493 [(reg FLAGS_REG) (const_int 0)]))
14494 (parallel [(set (match_operand 3 "q_regs_operand" "")
14495 (zero_extend (match_dup 1)))
14496 (clobber (reg:CC FLAGS_REG))])]
14497 "(peep2_reg_dead_p (3, operands[1])
14498 || operands_match_p (operands[1], operands[3]))
14499 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14500 [(set (match_dup 4) (match_dup 0))
14501 (set (strict_low_part (match_dup 5))
14504 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14505 operands[5] = gen_lowpart (QImode, operands[3]);
14506 ix86_expand_clear (operands[3]);
14509 ;; Call instructions.
14511 ;; The predicates normally associated with named expanders are not properly
14512 ;; checked for calls. This is a bug in the generic code, but it isn't that
14513 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14515 ;; Call subroutine returning no value.
14517 (define_expand "call_pop"
14518 [(parallel [(call (match_operand:QI 0 "" "")
14519 (match_operand:SI 1 "" ""))
14520 (set (reg:SI SP_REG)
14521 (plus:SI (reg:SI SP_REG)
14522 (match_operand:SI 3 "" "")))])]
14525 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14529 (define_insn "*call_pop_0"
14530 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14531 (match_operand:SI 1 "" ""))
14532 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14533 (match_operand:SI 2 "immediate_operand" "")))]
14536 if (SIBLING_CALL_P (insn))
14539 return "call\t%P0";
14541 [(set_attr "type" "call")])
14543 (define_insn "*call_pop_1"
14544 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14545 (match_operand:SI 1 "" ""))
14546 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14547 (match_operand:SI 2 "immediate_operand" "i")))]
14550 if (constant_call_address_operand (operands[0], Pmode))
14552 if (SIBLING_CALL_P (insn))
14555 return "call\t%P0";
14557 if (SIBLING_CALL_P (insn))
14560 return "call\t%A0";
14562 [(set_attr "type" "call")])
14564 (define_expand "call"
14565 [(call (match_operand:QI 0 "" "")
14566 (match_operand 1 "" ""))
14567 (use (match_operand 2 "" ""))]
14570 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14574 (define_expand "sibcall"
14575 [(call (match_operand:QI 0 "" "")
14576 (match_operand 1 "" ""))
14577 (use (match_operand 2 "" ""))]
14580 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14584 (define_insn "*call_0"
14585 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14586 (match_operand 1 "" ""))]
14589 if (SIBLING_CALL_P (insn))
14592 return "call\t%P0";
14594 [(set_attr "type" "call")])
14596 (define_insn "*call_1"
14597 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14598 (match_operand 1 "" ""))]
14599 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14601 if (constant_call_address_operand (operands[0], Pmode))
14602 return "call\t%P0";
14603 return "call\t%A0";
14605 [(set_attr "type" "call")])
14607 (define_insn "*sibcall_1"
14608 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14609 (match_operand 1 "" ""))]
14610 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14612 if (constant_call_address_operand (operands[0], Pmode))
14616 [(set_attr "type" "call")])
14618 (define_insn "*call_1_rex64"
14619 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14620 (match_operand 1 "" ""))]
14621 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14622 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14624 if (constant_call_address_operand (operands[0], Pmode))
14625 return "call\t%P0";
14626 return "call\t%A0";
14628 [(set_attr "type" "call")])
14630 (define_insn "*call_1_rex64_large"
14631 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14632 (match_operand 1 "" ""))]
14633 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14635 [(set_attr "type" "call")])
14637 (define_insn "*sibcall_1_rex64"
14638 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14639 (match_operand 1 "" ""))]
14640 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14642 [(set_attr "type" "call")])
14644 (define_insn "*sibcall_1_rex64_v"
14645 [(call (mem:QI (reg:DI R11_REG))
14646 (match_operand 0 "" ""))]
14647 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14649 [(set_attr "type" "call")])
14652 ;; Call subroutine, returning value in operand 0
14654 (define_expand "call_value_pop"
14655 [(parallel [(set (match_operand 0 "" "")
14656 (call (match_operand:QI 1 "" "")
14657 (match_operand:SI 2 "" "")))
14658 (set (reg:SI SP_REG)
14659 (plus:SI (reg:SI SP_REG)
14660 (match_operand:SI 4 "" "")))])]
14663 ix86_expand_call (operands[0], operands[1], operands[2],
14664 operands[3], operands[4], 0);
14668 (define_expand "call_value"
14669 [(set (match_operand 0 "" "")
14670 (call (match_operand:QI 1 "" "")
14671 (match_operand:SI 2 "" "")))
14672 (use (match_operand:SI 3 "" ""))]
14673 ;; Operand 2 not used on the i386.
14676 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14680 (define_expand "sibcall_value"
14681 [(set (match_operand 0 "" "")
14682 (call (match_operand:QI 1 "" "")
14683 (match_operand:SI 2 "" "")))
14684 (use (match_operand:SI 3 "" ""))]
14685 ;; Operand 2 not used on the i386.
14688 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14692 ;; Call subroutine returning any type.
14694 (define_expand "untyped_call"
14695 [(parallel [(call (match_operand 0 "" "")
14697 (match_operand 1 "" "")
14698 (match_operand 2 "" "")])]
14703 /* In order to give reg-stack an easier job in validating two
14704 coprocessor registers as containing a possible return value,
14705 simply pretend the untyped call returns a complex long double
14708 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14709 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14710 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14713 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14715 rtx set = XVECEXP (operands[2], 0, i);
14716 emit_move_insn (SET_DEST (set), SET_SRC (set));
14719 /* The optimizer does not know that the call sets the function value
14720 registers we stored in the result block. We avoid problems by
14721 claiming that all hard registers are used and clobbered at this
14723 emit_insn (gen_blockage ());
14728 ;; Prologue and epilogue instructions
14730 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14731 ;; all of memory. This blocks insns from being moved across this point.
14733 (define_insn "blockage"
14734 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14737 [(set_attr "length" "0")])
14739 ;; As USE insns aren't meaningful after reload, this is used instead
14740 ;; to prevent deleting instructions setting registers for PIC code
14741 (define_insn "prologue_use"
14742 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14745 [(set_attr "length" "0")])
14747 ;; Insn emitted into the body of a function to return from a function.
14748 ;; This is only done if the function's epilogue is known to be simple.
14749 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14751 (define_expand "return"
14753 "ix86_can_use_return_insn_p ()"
14755 if (crtl->args.pops_args)
14757 rtx popc = GEN_INT (crtl->args.pops_args);
14758 emit_jump_insn (gen_return_pop_internal (popc));
14763 (define_insn "return_internal"
14767 [(set_attr "length" "1")
14768 (set_attr "length_immediate" "0")
14769 (set_attr "modrm" "0")])
14771 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14772 ;; instruction Athlon and K8 have.
14774 (define_insn "return_internal_long"
14776 (unspec [(const_int 0)] UNSPEC_REP)]
14779 [(set_attr "length" "1")
14780 (set_attr "length_immediate" "0")
14781 (set_attr "prefix_rep" "1")
14782 (set_attr "modrm" "0")])
14784 (define_insn "return_pop_internal"
14786 (use (match_operand:SI 0 "const_int_operand" ""))]
14789 [(set_attr "length" "3")
14790 (set_attr "length_immediate" "2")
14791 (set_attr "modrm" "0")])
14793 (define_insn "return_indirect_internal"
14795 (use (match_operand:SI 0 "register_operand" "r"))]
14798 [(set_attr "type" "ibr")
14799 (set_attr "length_immediate" "0")])
14805 [(set_attr "length" "1")
14806 (set_attr "length_immediate" "0")
14807 (set_attr "modrm" "0")])
14809 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14810 ;; branch prediction penalty for the third jump in a 16-byte
14813 (define_insn "align"
14814 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14817 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14818 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14820 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14821 The align insn is used to avoid 3 jump instructions in the row to improve
14822 branch prediction and the benefits hardly outweigh the cost of extra 8
14823 nops on the average inserted by full alignment pseudo operation. */
14827 [(set_attr "length" "16")])
14829 (define_expand "prologue"
14832 "ix86_expand_prologue (); DONE;")
14834 (define_insn "set_got"
14835 [(set (match_operand:SI 0 "register_operand" "=r")
14836 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14837 (clobber (reg:CC FLAGS_REG))]
14839 { return output_set_got (operands[0], NULL_RTX); }
14840 [(set_attr "type" "multi")
14841 (set_attr "length" "12")])
14843 (define_insn "set_got_labelled"
14844 [(set (match_operand:SI 0 "register_operand" "=r")
14845 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14847 (clobber (reg:CC FLAGS_REG))]
14849 { return output_set_got (operands[0], operands[1]); }
14850 [(set_attr "type" "multi")
14851 (set_attr "length" "12")])
14853 (define_insn "set_got_rex64"
14854 [(set (match_operand:DI 0 "register_operand" "=r")
14855 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14857 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14858 [(set_attr "type" "lea")
14859 (set_attr "length" "6")])
14861 (define_insn "set_rip_rex64"
14862 [(set (match_operand:DI 0 "register_operand" "=r")
14863 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14865 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14866 [(set_attr "type" "lea")
14867 (set_attr "length" "6")])
14869 (define_insn "set_got_offset_rex64"
14870 [(set (match_operand:DI 0 "register_operand" "=r")
14871 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14873 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14874 [(set_attr "type" "imov")
14875 (set_attr "length" "11")])
14877 (define_expand "epilogue"
14880 "ix86_expand_epilogue (1); DONE;")
14882 (define_expand "sibcall_epilogue"
14885 "ix86_expand_epilogue (0); DONE;")
14887 (define_expand "eh_return"
14888 [(use (match_operand 0 "register_operand" ""))]
14891 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14893 /* Tricky bit: we write the address of the handler to which we will
14894 be returning into someone else's stack frame, one word below the
14895 stack address we wish to restore. */
14896 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14897 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14898 tmp = gen_rtx_MEM (Pmode, tmp);
14899 emit_move_insn (tmp, ra);
14901 if (Pmode == SImode)
14902 emit_jump_insn (gen_eh_return_si (sa));
14904 emit_jump_insn (gen_eh_return_di (sa));
14909 (define_insn_and_split "eh_return_si"
14911 (unspec [(match_operand:SI 0 "register_operand" "c")]
14912 UNSPEC_EH_RETURN))]
14917 "ix86_expand_epilogue (2); DONE;")
14919 (define_insn_and_split "eh_return_di"
14921 (unspec [(match_operand:DI 0 "register_operand" "c")]
14922 UNSPEC_EH_RETURN))]
14927 "ix86_expand_epilogue (2); DONE;")
14929 (define_insn "leave"
14930 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14931 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14932 (clobber (mem:BLK (scratch)))]
14935 [(set_attr "type" "leave")])
14937 (define_insn "leave_rex64"
14938 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14939 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14940 (clobber (mem:BLK (scratch)))]
14943 [(set_attr "type" "leave")])
14945 (define_expand "ffssi2"
14947 [(set (match_operand:SI 0 "register_operand" "")
14948 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14949 (clobber (match_scratch:SI 2 ""))
14950 (clobber (reg:CC FLAGS_REG))])]
14955 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14960 (define_expand "ffs_cmove"
14961 [(set (match_dup 2) (const_int -1))
14962 (parallel [(set (reg:CCZ FLAGS_REG)
14963 (compare:CCZ (match_operand:SI 1 "register_operand" "")
14965 (set (match_operand:SI 0 "nonimmediate_operand" "")
14966 (ctz:SI (match_dup 1)))])
14967 (set (match_dup 0) (if_then_else:SI
14968 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14971 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14972 (clobber (reg:CC FLAGS_REG))])]
14974 "operands[2] = gen_reg_rtx (SImode);")
14976 (define_insn_and_split "*ffs_no_cmove"
14977 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14978 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14979 (clobber (match_scratch:SI 2 "=&q"))
14980 (clobber (reg:CC FLAGS_REG))]
14983 "&& reload_completed"
14984 [(parallel [(set (reg:CCZ FLAGS_REG)
14985 (compare:CCZ (match_dup 1) (const_int 0)))
14986 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14987 (set (strict_low_part (match_dup 3))
14988 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14989 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14990 (clobber (reg:CC FLAGS_REG))])
14991 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14992 (clobber (reg:CC FLAGS_REG))])
14993 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14994 (clobber (reg:CC FLAGS_REG))])]
14996 operands[3] = gen_lowpart (QImode, operands[2]);
14997 ix86_expand_clear (operands[2]);
15000 (define_insn "*ffssi_1"
15001 [(set (reg:CCZ FLAGS_REG)
15002 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15004 (set (match_operand:SI 0 "register_operand" "=r")
15005 (ctz:SI (match_dup 1)))]
15007 "bsf{l}\t{%1, %0|%0, %1}"
15008 [(set_attr "prefix_0f" "1")])
15010 (define_expand "ffsdi2"
15011 [(set (match_dup 2) (const_int -1))
15012 (parallel [(set (reg:CCZ FLAGS_REG)
15013 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15015 (set (match_operand:DI 0 "nonimmediate_operand" "")
15016 (ctz:DI (match_dup 1)))])
15017 (set (match_dup 0) (if_then_else:DI
15018 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15021 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15022 (clobber (reg:CC FLAGS_REG))])]
15024 "operands[2] = gen_reg_rtx (DImode);")
15026 (define_insn "*ffsdi_1"
15027 [(set (reg:CCZ FLAGS_REG)
15028 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15030 (set (match_operand:DI 0 "register_operand" "=r")
15031 (ctz:DI (match_dup 1)))]
15033 "bsf{q}\t{%1, %0|%0, %1}"
15034 [(set_attr "prefix_0f" "1")])
15036 (define_insn "ctzsi2"
15037 [(set (match_operand:SI 0 "register_operand" "=r")
15038 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15039 (clobber (reg:CC FLAGS_REG))]
15041 "bsf{l}\t{%1, %0|%0, %1}"
15042 [(set_attr "prefix_0f" "1")])
15044 (define_insn "ctzdi2"
15045 [(set (match_operand:DI 0 "register_operand" "=r")
15046 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15047 (clobber (reg:CC FLAGS_REG))]
15049 "bsf{q}\t{%1, %0|%0, %1}"
15050 [(set_attr "prefix_0f" "1")])
15052 (define_expand "clzsi2"
15054 [(set (match_operand:SI 0 "register_operand" "")
15055 (minus:SI (const_int 31)
15056 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15057 (clobber (reg:CC FLAGS_REG))])
15059 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15060 (clobber (reg:CC FLAGS_REG))])]
15065 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15070 (define_insn "clzsi2_abm"
15071 [(set (match_operand:SI 0 "register_operand" "=r")
15072 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15073 (clobber (reg:CC FLAGS_REG))]
15075 "lzcnt{l}\t{%1, %0|%0, %1}"
15076 [(set_attr "prefix_rep" "1")
15077 (set_attr "type" "bitmanip")
15078 (set_attr "mode" "SI")])
15080 (define_insn "*bsr"
15081 [(set (match_operand:SI 0 "register_operand" "=r")
15082 (minus:SI (const_int 31)
15083 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15084 (clobber (reg:CC FLAGS_REG))]
15086 "bsr{l}\t{%1, %0|%0, %1}"
15087 [(set_attr "prefix_0f" "1")
15088 (set_attr "mode" "SI")])
15090 (define_insn "popcountsi2"
15091 [(set (match_operand:SI 0 "register_operand" "=r")
15092 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15093 (clobber (reg:CC FLAGS_REG))]
15095 "popcnt{l}\t{%1, %0|%0, %1}"
15096 [(set_attr "prefix_rep" "1")
15097 (set_attr "type" "bitmanip")
15098 (set_attr "mode" "SI")])
15100 (define_insn "*popcountsi2_cmp"
15101 [(set (reg FLAGS_REG)
15103 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15105 (set (match_operand:SI 0 "register_operand" "=r")
15106 (popcount:SI (match_dup 1)))]
15107 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15108 "popcnt{l}\t{%1, %0|%0, %1}"
15109 [(set_attr "prefix_rep" "1")
15110 (set_attr "type" "bitmanip")
15111 (set_attr "mode" "SI")])
15113 (define_insn "*popcountsi2_cmp_zext"
15114 [(set (reg FLAGS_REG)
15116 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15118 (set (match_operand:DI 0 "register_operand" "=r")
15119 (zero_extend:DI(popcount:SI (match_dup 1))))]
15120 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15121 "popcnt{l}\t{%1, %0|%0, %1}"
15122 [(set_attr "prefix_rep" "1")
15123 (set_attr "type" "bitmanip")
15124 (set_attr "mode" "SI")])
15126 (define_expand "bswapsi2"
15127 [(set (match_operand:SI 0 "register_operand" "")
15128 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15133 rtx x = operands[0];
15135 emit_move_insn (x, operands[1]);
15136 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15137 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15138 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15143 (define_insn "*bswapsi_1"
15144 [(set (match_operand:SI 0 "register_operand" "=r")
15145 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15148 [(set_attr "prefix_0f" "1")
15149 (set_attr "length" "2")])
15151 (define_insn "*bswaphi_lowpart_1"
15152 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15153 (bswap:HI (match_dup 0)))
15154 (clobber (reg:CC FLAGS_REG))]
15155 "TARGET_USE_XCHGB || optimize_size"
15157 xchg{b}\t{%h0, %b0|%b0, %h0}
15158 rol{w}\t{$8, %0|%0, 8}"
15159 [(set_attr "length" "2,4")
15160 (set_attr "mode" "QI,HI")])
15162 (define_insn "bswaphi_lowpart"
15163 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15164 (bswap:HI (match_dup 0)))
15165 (clobber (reg:CC FLAGS_REG))]
15167 "rol{w}\t{$8, %0|%0, 8}"
15168 [(set_attr "length" "4")
15169 (set_attr "mode" "HI")])
15171 (define_insn "bswapdi2"
15172 [(set (match_operand:DI 0 "register_operand" "=r")
15173 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15176 [(set_attr "prefix_0f" "1")
15177 (set_attr "length" "3")])
15179 (define_expand "clzdi2"
15181 [(set (match_operand:DI 0 "register_operand" "")
15182 (minus:DI (const_int 63)
15183 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15184 (clobber (reg:CC FLAGS_REG))])
15186 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15187 (clobber (reg:CC FLAGS_REG))])]
15192 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15197 (define_insn "clzdi2_abm"
15198 [(set (match_operand:DI 0 "register_operand" "=r")
15199 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15200 (clobber (reg:CC FLAGS_REG))]
15201 "TARGET_64BIT && TARGET_ABM"
15202 "lzcnt{q}\t{%1, %0|%0, %1}"
15203 [(set_attr "prefix_rep" "1")
15204 (set_attr "type" "bitmanip")
15205 (set_attr "mode" "DI")])
15207 (define_insn "*bsr_rex64"
15208 [(set (match_operand:DI 0 "register_operand" "=r")
15209 (minus:DI (const_int 63)
15210 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15211 (clobber (reg:CC FLAGS_REG))]
15213 "bsr{q}\t{%1, %0|%0, %1}"
15214 [(set_attr "prefix_0f" "1")
15215 (set_attr "mode" "DI")])
15217 (define_insn "popcountdi2"
15218 [(set (match_operand:DI 0 "register_operand" "=r")
15219 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15220 (clobber (reg:CC FLAGS_REG))]
15221 "TARGET_64BIT && TARGET_POPCNT"
15222 "popcnt{q}\t{%1, %0|%0, %1}"
15223 [(set_attr "prefix_rep" "1")
15224 (set_attr "type" "bitmanip")
15225 (set_attr "mode" "DI")])
15227 (define_insn "*popcountdi2_cmp"
15228 [(set (reg FLAGS_REG)
15230 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15232 (set (match_operand:DI 0 "register_operand" "=r")
15233 (popcount:DI (match_dup 1)))]
15234 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15235 "popcnt{q}\t{%1, %0|%0, %1}"
15236 [(set_attr "prefix_rep" "1")
15237 (set_attr "type" "bitmanip")
15238 (set_attr "mode" "DI")])
15240 (define_expand "clzhi2"
15242 [(set (match_operand:HI 0 "register_operand" "")
15243 (minus:HI (const_int 15)
15244 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15245 (clobber (reg:CC FLAGS_REG))])
15247 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15248 (clobber (reg:CC FLAGS_REG))])]
15253 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15258 (define_insn "clzhi2_abm"
15259 [(set (match_operand:HI 0 "register_operand" "=r")
15260 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15261 (clobber (reg:CC FLAGS_REG))]
15263 "lzcnt{w}\t{%1, %0|%0, %1}"
15264 [(set_attr "prefix_rep" "1")
15265 (set_attr "type" "bitmanip")
15266 (set_attr "mode" "HI")])
15268 (define_insn "*bsrhi"
15269 [(set (match_operand:HI 0 "register_operand" "=r")
15270 (minus:HI (const_int 15)
15271 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15272 (clobber (reg:CC FLAGS_REG))]
15274 "bsr{w}\t{%1, %0|%0, %1}"
15275 [(set_attr "prefix_0f" "1")
15276 (set_attr "mode" "HI")])
15278 (define_insn "popcounthi2"
15279 [(set (match_operand:HI 0 "register_operand" "=r")
15280 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15281 (clobber (reg:CC FLAGS_REG))]
15283 "popcnt{w}\t{%1, %0|%0, %1}"
15284 [(set_attr "prefix_rep" "1")
15285 (set_attr "type" "bitmanip")
15286 (set_attr "mode" "HI")])
15288 (define_insn "*popcounthi2_cmp"
15289 [(set (reg FLAGS_REG)
15291 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15293 (set (match_operand:HI 0 "register_operand" "=r")
15294 (popcount:HI (match_dup 1)))]
15295 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15296 "popcnt{w}\t{%1, %0|%0, %1}"
15297 [(set_attr "prefix_rep" "1")
15298 (set_attr "type" "bitmanip")
15299 (set_attr "mode" "HI")])
15301 (define_expand "paritydi2"
15302 [(set (match_operand:DI 0 "register_operand" "")
15303 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15306 rtx scratch = gen_reg_rtx (QImode);
15309 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15310 NULL_RTX, operands[1]));
15312 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15313 gen_rtx_REG (CCmode, FLAGS_REG),
15315 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15318 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15321 rtx tmp = gen_reg_rtx (SImode);
15323 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15324 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15329 (define_insn_and_split "paritydi2_cmp"
15330 [(set (reg:CC FLAGS_REG)
15331 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15332 (clobber (match_scratch:DI 0 "=r"))
15333 (clobber (match_scratch:SI 1 "=&r"))
15334 (clobber (match_scratch:HI 2 "=Q"))]
15337 "&& reload_completed"
15339 [(set (match_dup 1)
15340 (xor:SI (match_dup 1) (match_dup 4)))
15341 (clobber (reg:CC FLAGS_REG))])
15343 [(set (reg:CC FLAGS_REG)
15344 (parity:CC (match_dup 1)))
15345 (clobber (match_dup 1))
15346 (clobber (match_dup 2))])]
15348 operands[4] = gen_lowpart (SImode, operands[3]);
15352 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15353 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15356 operands[1] = gen_highpart (SImode, operands[3]);
15359 (define_expand "paritysi2"
15360 [(set (match_operand:SI 0 "register_operand" "")
15361 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15364 rtx scratch = gen_reg_rtx (QImode);
15367 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15369 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15370 gen_rtx_REG (CCmode, FLAGS_REG),
15372 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15374 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15378 (define_insn_and_split "paritysi2_cmp"
15379 [(set (reg:CC FLAGS_REG)
15380 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15381 (clobber (match_scratch:SI 0 "=r"))
15382 (clobber (match_scratch:HI 1 "=&Q"))]
15385 "&& reload_completed"
15387 [(set (match_dup 1)
15388 (xor:HI (match_dup 1) (match_dup 3)))
15389 (clobber (reg:CC FLAGS_REG))])
15391 [(set (reg:CC FLAGS_REG)
15392 (parity:CC (match_dup 1)))
15393 (clobber (match_dup 1))])]
15395 operands[3] = gen_lowpart (HImode, operands[2]);
15397 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15398 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15401 (define_insn "*parityhi2_cmp"
15402 [(set (reg:CC FLAGS_REG)
15403 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15404 (clobber (match_scratch:HI 0 "=Q"))]
15406 "xor{b}\t{%h0, %b0|%b0, %h0}"
15407 [(set_attr "length" "2")
15408 (set_attr "mode" "HI")])
15410 (define_insn "*parityqi2_cmp"
15411 [(set (reg:CC FLAGS_REG)
15412 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15415 [(set_attr "length" "2")
15416 (set_attr "mode" "QI")])
15418 ;; Thread-local storage patterns for ELF.
15420 ;; Note that these code sequences must appear exactly as shown
15421 ;; in order to allow linker relaxation.
15423 (define_insn "*tls_global_dynamic_32_gnu"
15424 [(set (match_operand:SI 0 "register_operand" "=a")
15425 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15426 (match_operand:SI 2 "tls_symbolic_operand" "")
15427 (match_operand:SI 3 "call_insn_operand" "")]
15429 (clobber (match_scratch:SI 4 "=d"))
15430 (clobber (match_scratch:SI 5 "=c"))
15431 (clobber (reg:CC FLAGS_REG))]
15432 "!TARGET_64BIT && TARGET_GNU_TLS"
15433 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15434 [(set_attr "type" "multi")
15435 (set_attr "length" "12")])
15437 (define_insn "*tls_global_dynamic_32_sun"
15438 [(set (match_operand:SI 0 "register_operand" "=a")
15439 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15440 (match_operand:SI 2 "tls_symbolic_operand" "")
15441 (match_operand:SI 3 "call_insn_operand" "")]
15443 (clobber (match_scratch:SI 4 "=d"))
15444 (clobber (match_scratch:SI 5 "=c"))
15445 (clobber (reg:CC FLAGS_REG))]
15446 "!TARGET_64BIT && TARGET_SUN_TLS"
15447 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15448 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15449 [(set_attr "type" "multi")
15450 (set_attr "length" "14")])
15452 (define_expand "tls_global_dynamic_32"
15453 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15456 (match_operand:SI 1 "tls_symbolic_operand" "")
15459 (clobber (match_scratch:SI 4 ""))
15460 (clobber (match_scratch:SI 5 ""))
15461 (clobber (reg:CC FLAGS_REG))])]
15465 operands[2] = pic_offset_table_rtx;
15468 operands[2] = gen_reg_rtx (Pmode);
15469 emit_insn (gen_set_got (operands[2]));
15471 if (TARGET_GNU2_TLS)
15473 emit_insn (gen_tls_dynamic_gnu2_32
15474 (operands[0], operands[1], operands[2]));
15477 operands[3] = ix86_tls_get_addr ();
15480 (define_insn "*tls_global_dynamic_64"
15481 [(set (match_operand:DI 0 "register_operand" "=a")
15482 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15483 (match_operand:DI 3 "" "")))
15484 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15487 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15488 [(set_attr "type" "multi")
15489 (set_attr "length" "16")])
15491 (define_expand "tls_global_dynamic_64"
15492 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15493 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15494 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15498 if (TARGET_GNU2_TLS)
15500 emit_insn (gen_tls_dynamic_gnu2_64
15501 (operands[0], operands[1]));
15504 operands[2] = ix86_tls_get_addr ();
15507 (define_insn "*tls_local_dynamic_base_32_gnu"
15508 [(set (match_operand:SI 0 "register_operand" "=a")
15509 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15510 (match_operand:SI 2 "call_insn_operand" "")]
15511 UNSPEC_TLS_LD_BASE))
15512 (clobber (match_scratch:SI 3 "=d"))
15513 (clobber (match_scratch:SI 4 "=c"))
15514 (clobber (reg:CC FLAGS_REG))]
15515 "!TARGET_64BIT && TARGET_GNU_TLS"
15516 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15517 [(set_attr "type" "multi")
15518 (set_attr "length" "11")])
15520 (define_insn "*tls_local_dynamic_base_32_sun"
15521 [(set (match_operand:SI 0 "register_operand" "=a")
15522 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15523 (match_operand:SI 2 "call_insn_operand" "")]
15524 UNSPEC_TLS_LD_BASE))
15525 (clobber (match_scratch:SI 3 "=d"))
15526 (clobber (match_scratch:SI 4 "=c"))
15527 (clobber (reg:CC FLAGS_REG))]
15528 "!TARGET_64BIT && TARGET_SUN_TLS"
15529 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15530 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15531 [(set_attr "type" "multi")
15532 (set_attr "length" "13")])
15534 (define_expand "tls_local_dynamic_base_32"
15535 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15536 (unspec:SI [(match_dup 1) (match_dup 2)]
15537 UNSPEC_TLS_LD_BASE))
15538 (clobber (match_scratch:SI 3 ""))
15539 (clobber (match_scratch:SI 4 ""))
15540 (clobber (reg:CC FLAGS_REG))])]
15544 operands[1] = pic_offset_table_rtx;
15547 operands[1] = gen_reg_rtx (Pmode);
15548 emit_insn (gen_set_got (operands[1]));
15550 if (TARGET_GNU2_TLS)
15552 emit_insn (gen_tls_dynamic_gnu2_32
15553 (operands[0], ix86_tls_module_base (), operands[1]));
15556 operands[2] = ix86_tls_get_addr ();
15559 (define_insn "*tls_local_dynamic_base_64"
15560 [(set (match_operand:DI 0 "register_operand" "=a")
15561 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15562 (match_operand:DI 2 "" "")))
15563 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15565 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15566 [(set_attr "type" "multi")
15567 (set_attr "length" "12")])
15569 (define_expand "tls_local_dynamic_base_64"
15570 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15571 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15572 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15575 if (TARGET_GNU2_TLS)
15577 emit_insn (gen_tls_dynamic_gnu2_64
15578 (operands[0], ix86_tls_module_base ()));
15581 operands[1] = ix86_tls_get_addr ();
15584 ;; Local dynamic of a single variable is a lose. Show combine how
15585 ;; to convert that back to global dynamic.
15587 (define_insn_and_split "*tls_local_dynamic_32_once"
15588 [(set (match_operand:SI 0 "register_operand" "=a")
15589 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15590 (match_operand:SI 2 "call_insn_operand" "")]
15591 UNSPEC_TLS_LD_BASE)
15592 (const:SI (unspec:SI
15593 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15595 (clobber (match_scratch:SI 4 "=d"))
15596 (clobber (match_scratch:SI 5 "=c"))
15597 (clobber (reg:CC FLAGS_REG))]
15601 [(parallel [(set (match_dup 0)
15602 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15604 (clobber (match_dup 4))
15605 (clobber (match_dup 5))
15606 (clobber (reg:CC FLAGS_REG))])]
15609 ;; Load and add the thread base pointer from %gs:0.
15611 (define_insn "*load_tp_si"
15612 [(set (match_operand:SI 0 "register_operand" "=r")
15613 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15615 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15616 [(set_attr "type" "imov")
15617 (set_attr "modrm" "0")
15618 (set_attr "length" "7")
15619 (set_attr "memory" "load")
15620 (set_attr "imm_disp" "false")])
15622 (define_insn "*add_tp_si"
15623 [(set (match_operand:SI 0 "register_operand" "=r")
15624 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15625 (match_operand:SI 1 "register_operand" "0")))
15626 (clobber (reg:CC FLAGS_REG))]
15628 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15629 [(set_attr "type" "alu")
15630 (set_attr "modrm" "0")
15631 (set_attr "length" "7")
15632 (set_attr "memory" "load")
15633 (set_attr "imm_disp" "false")])
15635 (define_insn "*load_tp_di"
15636 [(set (match_operand:DI 0 "register_operand" "=r")
15637 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15639 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15640 [(set_attr "type" "imov")
15641 (set_attr "modrm" "0")
15642 (set_attr "length" "7")
15643 (set_attr "memory" "load")
15644 (set_attr "imm_disp" "false")])
15646 (define_insn "*add_tp_di"
15647 [(set (match_operand:DI 0 "register_operand" "=r")
15648 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15649 (match_operand:DI 1 "register_operand" "0")))
15650 (clobber (reg:CC FLAGS_REG))]
15652 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15653 [(set_attr "type" "alu")
15654 (set_attr "modrm" "0")
15655 (set_attr "length" "7")
15656 (set_attr "memory" "load")
15657 (set_attr "imm_disp" "false")])
15659 ;; GNU2 TLS patterns can be split.
15661 (define_expand "tls_dynamic_gnu2_32"
15662 [(set (match_dup 3)
15663 (plus:SI (match_operand:SI 2 "register_operand" "")
15665 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15668 [(set (match_operand:SI 0 "register_operand" "")
15669 (unspec:SI [(match_dup 1) (match_dup 3)
15670 (match_dup 2) (reg:SI SP_REG)]
15672 (clobber (reg:CC FLAGS_REG))])]
15673 "!TARGET_64BIT && TARGET_GNU2_TLS"
15675 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15676 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15679 (define_insn "*tls_dynamic_lea_32"
15680 [(set (match_operand:SI 0 "register_operand" "=r")
15681 (plus:SI (match_operand:SI 1 "register_operand" "b")
15683 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15684 UNSPEC_TLSDESC))))]
15685 "!TARGET_64BIT && TARGET_GNU2_TLS"
15686 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15687 [(set_attr "type" "lea")
15688 (set_attr "mode" "SI")
15689 (set_attr "length" "6")
15690 (set_attr "length_address" "4")])
15692 (define_insn "*tls_dynamic_call_32"
15693 [(set (match_operand:SI 0 "register_operand" "=a")
15694 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15695 (match_operand:SI 2 "register_operand" "0")
15696 ;; we have to make sure %ebx still points to the GOT
15697 (match_operand:SI 3 "register_operand" "b")
15700 (clobber (reg:CC FLAGS_REG))]
15701 "!TARGET_64BIT && TARGET_GNU2_TLS"
15702 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15703 [(set_attr "type" "call")
15704 (set_attr "length" "2")
15705 (set_attr "length_address" "0")])
15707 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15708 [(set (match_operand:SI 0 "register_operand" "=&a")
15710 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15711 (match_operand:SI 4 "" "")
15712 (match_operand:SI 2 "register_operand" "b")
15715 (const:SI (unspec:SI
15716 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15718 (clobber (reg:CC FLAGS_REG))]
15719 "!TARGET_64BIT && TARGET_GNU2_TLS"
15722 [(set (match_dup 0) (match_dup 5))]
15724 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15725 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15728 (define_expand "tls_dynamic_gnu2_64"
15729 [(set (match_dup 2)
15730 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15733 [(set (match_operand:DI 0 "register_operand" "")
15734 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15736 (clobber (reg:CC FLAGS_REG))])]
15737 "TARGET_64BIT && TARGET_GNU2_TLS"
15739 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15740 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15743 (define_insn "*tls_dynamic_lea_64"
15744 [(set (match_operand:DI 0 "register_operand" "=r")
15745 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15747 "TARGET_64BIT && TARGET_GNU2_TLS"
15748 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15749 [(set_attr "type" "lea")
15750 (set_attr "mode" "DI")
15751 (set_attr "length" "7")
15752 (set_attr "length_address" "4")])
15754 (define_insn "*tls_dynamic_call_64"
15755 [(set (match_operand:DI 0 "register_operand" "=a")
15756 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15757 (match_operand:DI 2 "register_operand" "0")
15760 (clobber (reg:CC FLAGS_REG))]
15761 "TARGET_64BIT && TARGET_GNU2_TLS"
15762 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15763 [(set_attr "type" "call")
15764 (set_attr "length" "2")
15765 (set_attr "length_address" "0")])
15767 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15768 [(set (match_operand:DI 0 "register_operand" "=&a")
15770 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15771 (match_operand:DI 3 "" "")
15774 (const:DI (unspec:DI
15775 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15777 (clobber (reg:CC FLAGS_REG))]
15778 "TARGET_64BIT && TARGET_GNU2_TLS"
15781 [(set (match_dup 0) (match_dup 4))]
15783 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15784 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15789 ;; These patterns match the binary 387 instructions for addM3, subM3,
15790 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15791 ;; SFmode. The first is the normal insn, the second the same insn but
15792 ;; with one operand a conversion, and the third the same insn but with
15793 ;; the other operand a conversion. The conversion may be SFmode or
15794 ;; SImode if the target mode DFmode, but only SImode if the target mode
15797 ;; Gcc is slightly more smart about handling normal two address instructions
15798 ;; so use special patterns for add and mull.
15800 (define_insn "*fop_sf_comm_mixed"
15801 [(set (match_operand:SF 0 "register_operand" "=f,x")
15802 (match_operator:SF 3 "binary_fp_operator"
15803 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15804 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15805 "TARGET_MIX_SSE_I387
15806 && COMMUTATIVE_ARITH_P (operands[3])
15807 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15808 "* return output_387_binary_op (insn, operands);"
15809 [(set (attr "type")
15810 (if_then_else (eq_attr "alternative" "1")
15811 (if_then_else (match_operand:SF 3 "mult_operator" "")
15812 (const_string "ssemul")
15813 (const_string "sseadd"))
15814 (if_then_else (match_operand:SF 3 "mult_operator" "")
15815 (const_string "fmul")
15816 (const_string "fop"))))
15817 (set_attr "mode" "SF")])
15819 (define_insn "*fop_sf_comm_sse"
15820 [(set (match_operand:SF 0 "register_operand" "=x")
15821 (match_operator:SF 3 "binary_fp_operator"
15822 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15823 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15825 && COMMUTATIVE_ARITH_P (operands[3])
15826 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15827 "* return output_387_binary_op (insn, operands);"
15828 [(set (attr "type")
15829 (if_then_else (match_operand:SF 3 "mult_operator" "")
15830 (const_string "ssemul")
15831 (const_string "sseadd")))
15832 (set_attr "mode" "SF")])
15834 (define_insn "*fop_sf_comm_i387"
15835 [(set (match_operand:SF 0 "register_operand" "=f")
15836 (match_operator:SF 3 "binary_fp_operator"
15837 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15838 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15840 && COMMUTATIVE_ARITH_P (operands[3])
15841 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15842 "* return output_387_binary_op (insn, operands);"
15843 [(set (attr "type")
15844 (if_then_else (match_operand:SF 3 "mult_operator" "")
15845 (const_string "fmul")
15846 (const_string "fop")))
15847 (set_attr "mode" "SF")])
15849 (define_insn "*fop_sf_1_mixed"
15850 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15851 (match_operator:SF 3 "binary_fp_operator"
15852 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15853 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15854 "TARGET_MIX_SSE_I387
15855 && !COMMUTATIVE_ARITH_P (operands[3])
15856 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15857 "* return output_387_binary_op (insn, operands);"
15858 [(set (attr "type")
15859 (cond [(and (eq_attr "alternative" "2")
15860 (match_operand:SF 3 "mult_operator" ""))
15861 (const_string "ssemul")
15862 (and (eq_attr "alternative" "2")
15863 (match_operand:SF 3 "div_operator" ""))
15864 (const_string "ssediv")
15865 (eq_attr "alternative" "2")
15866 (const_string "sseadd")
15867 (match_operand:SF 3 "mult_operator" "")
15868 (const_string "fmul")
15869 (match_operand:SF 3 "div_operator" "")
15870 (const_string "fdiv")
15872 (const_string "fop")))
15873 (set_attr "mode" "SF")])
15875 (define_insn "*rcpsf2_sse"
15876 [(set (match_operand:SF 0 "register_operand" "=x")
15877 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15880 "rcpss\t{%1, %0|%0, %1}"
15881 [(set_attr "type" "sse")
15882 (set_attr "mode" "SF")])
15884 (define_insn "*fop_sf_1_sse"
15885 [(set (match_operand:SF 0 "register_operand" "=x")
15886 (match_operator:SF 3 "binary_fp_operator"
15887 [(match_operand:SF 1 "register_operand" "0")
15888 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15890 && !COMMUTATIVE_ARITH_P (operands[3])"
15891 "* return output_387_binary_op (insn, operands);"
15892 [(set (attr "type")
15893 (cond [(match_operand:SF 3 "mult_operator" "")
15894 (const_string "ssemul")
15895 (match_operand:SF 3 "div_operator" "")
15896 (const_string "ssediv")
15898 (const_string "sseadd")))
15899 (set_attr "mode" "SF")])
15901 ;; This pattern is not fully shadowed by the pattern above.
15902 (define_insn "*fop_sf_1_i387"
15903 [(set (match_operand:SF 0 "register_operand" "=f,f")
15904 (match_operator:SF 3 "binary_fp_operator"
15905 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15906 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15907 "TARGET_80387 && !TARGET_SSE_MATH
15908 && !COMMUTATIVE_ARITH_P (operands[3])
15909 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15910 "* return output_387_binary_op (insn, operands);"
15911 [(set (attr "type")
15912 (cond [(match_operand:SF 3 "mult_operator" "")
15913 (const_string "fmul")
15914 (match_operand:SF 3 "div_operator" "")
15915 (const_string "fdiv")
15917 (const_string "fop")))
15918 (set_attr "mode" "SF")])
15920 ;; ??? Add SSE splitters for these!
15921 (define_insn "*fop_sf_2<mode>_i387"
15922 [(set (match_operand:SF 0 "register_operand" "=f,f")
15923 (match_operator:SF 3 "binary_fp_operator"
15924 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15925 (match_operand:SF 2 "register_operand" "0,0")]))]
15926 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15927 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15928 [(set (attr "type")
15929 (cond [(match_operand:SF 3 "mult_operator" "")
15930 (const_string "fmul")
15931 (match_operand:SF 3 "div_operator" "")
15932 (const_string "fdiv")
15934 (const_string "fop")))
15935 (set_attr "fp_int_src" "true")
15936 (set_attr "mode" "<MODE>")])
15938 (define_insn "*fop_sf_3<mode>_i387"
15939 [(set (match_operand:SF 0 "register_operand" "=f,f")
15940 (match_operator:SF 3 "binary_fp_operator"
15941 [(match_operand:SF 1 "register_operand" "0,0")
15942 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15943 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15944 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15945 [(set (attr "type")
15946 (cond [(match_operand:SF 3 "mult_operator" "")
15947 (const_string "fmul")
15948 (match_operand:SF 3 "div_operator" "")
15949 (const_string "fdiv")
15951 (const_string "fop")))
15952 (set_attr "fp_int_src" "true")
15953 (set_attr "mode" "<MODE>")])
15955 (define_insn "*fop_df_comm_mixed"
15956 [(set (match_operand:DF 0 "register_operand" "=f,x")
15957 (match_operator:DF 3 "binary_fp_operator"
15958 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15959 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15960 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15961 && COMMUTATIVE_ARITH_P (operands[3])
15962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15963 "* return output_387_binary_op (insn, operands);"
15964 [(set (attr "type")
15965 (if_then_else (eq_attr "alternative" "1")
15966 (if_then_else (match_operand:DF 3 "mult_operator" "")
15967 (const_string "ssemul")
15968 (const_string "sseadd"))
15969 (if_then_else (match_operand:DF 3 "mult_operator" "")
15970 (const_string "fmul")
15971 (const_string "fop"))))
15972 (set_attr "mode" "DF")])
15974 (define_insn "*fop_df_comm_sse"
15975 [(set (match_operand:DF 0 "register_operand" "=x")
15976 (match_operator:DF 3 "binary_fp_operator"
15977 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15978 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15979 "TARGET_SSE2 && TARGET_SSE_MATH
15980 && COMMUTATIVE_ARITH_P (operands[3])
15981 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15982 "* return output_387_binary_op (insn, operands);"
15983 [(set (attr "type")
15984 (if_then_else (match_operand:DF 3 "mult_operator" "")
15985 (const_string "ssemul")
15986 (const_string "sseadd")))
15987 (set_attr "mode" "DF")])
15989 (define_insn "*fop_df_comm_i387"
15990 [(set (match_operand:DF 0 "register_operand" "=f")
15991 (match_operator:DF 3 "binary_fp_operator"
15992 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15993 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15995 && COMMUTATIVE_ARITH_P (operands[3])
15996 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15997 "* return output_387_binary_op (insn, operands);"
15998 [(set (attr "type")
15999 (if_then_else (match_operand:DF 3 "mult_operator" "")
16000 (const_string "fmul")
16001 (const_string "fop")))
16002 (set_attr "mode" "DF")])
16004 (define_insn "*fop_df_1_mixed"
16005 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16006 (match_operator:DF 3 "binary_fp_operator"
16007 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16008 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16009 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16010 && !COMMUTATIVE_ARITH_P (operands[3])
16011 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16012 "* return output_387_binary_op (insn, operands);"
16013 [(set (attr "type")
16014 (cond [(and (eq_attr "alternative" "2")
16015 (match_operand:DF 3 "mult_operator" ""))
16016 (const_string "ssemul")
16017 (and (eq_attr "alternative" "2")
16018 (match_operand:DF 3 "div_operator" ""))
16019 (const_string "ssediv")
16020 (eq_attr "alternative" "2")
16021 (const_string "sseadd")
16022 (match_operand:DF 3 "mult_operator" "")
16023 (const_string "fmul")
16024 (match_operand:DF 3 "div_operator" "")
16025 (const_string "fdiv")
16027 (const_string "fop")))
16028 (set_attr "mode" "DF")])
16030 (define_insn "*fop_df_1_sse"
16031 [(set (match_operand:DF 0 "register_operand" "=x")
16032 (match_operator:DF 3 "binary_fp_operator"
16033 [(match_operand:DF 1 "register_operand" "0")
16034 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16035 "TARGET_SSE2 && TARGET_SSE_MATH
16036 && !COMMUTATIVE_ARITH_P (operands[3])"
16037 "* return output_387_binary_op (insn, operands);"
16038 [(set_attr "mode" "DF")
16040 (cond [(match_operand:DF 3 "mult_operator" "")
16041 (const_string "ssemul")
16042 (match_operand:DF 3 "div_operator" "")
16043 (const_string "ssediv")
16045 (const_string "sseadd")))])
16047 ;; This pattern is not fully shadowed by the pattern above.
16048 (define_insn "*fop_df_1_i387"
16049 [(set (match_operand:DF 0 "register_operand" "=f,f")
16050 (match_operator:DF 3 "binary_fp_operator"
16051 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16052 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16053 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16054 && !COMMUTATIVE_ARITH_P (operands[3])
16055 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16056 "* return output_387_binary_op (insn, operands);"
16057 [(set (attr "type")
16058 (cond [(match_operand:DF 3 "mult_operator" "")
16059 (const_string "fmul")
16060 (match_operand:DF 3 "div_operator" "")
16061 (const_string "fdiv")
16063 (const_string "fop")))
16064 (set_attr "mode" "DF")])
16066 ;; ??? Add SSE splitters for these!
16067 (define_insn "*fop_df_2<mode>_i387"
16068 [(set (match_operand:DF 0 "register_operand" "=f,f")
16069 (match_operator:DF 3 "binary_fp_operator"
16070 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16071 (match_operand:DF 2 "register_operand" "0,0")]))]
16072 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16073 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16074 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16075 [(set (attr "type")
16076 (cond [(match_operand:DF 3 "mult_operator" "")
16077 (const_string "fmul")
16078 (match_operand:DF 3 "div_operator" "")
16079 (const_string "fdiv")
16081 (const_string "fop")))
16082 (set_attr "fp_int_src" "true")
16083 (set_attr "mode" "<MODE>")])
16085 (define_insn "*fop_df_3<mode>_i387"
16086 [(set (match_operand:DF 0 "register_operand" "=f,f")
16087 (match_operator:DF 3 "binary_fp_operator"
16088 [(match_operand:DF 1 "register_operand" "0,0")
16089 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16090 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16091 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16092 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16093 [(set (attr "type")
16094 (cond [(match_operand:DF 3 "mult_operator" "")
16095 (const_string "fmul")
16096 (match_operand:DF 3 "div_operator" "")
16097 (const_string "fdiv")
16099 (const_string "fop")))
16100 (set_attr "fp_int_src" "true")
16101 (set_attr "mode" "<MODE>")])
16103 (define_insn "*fop_df_4_i387"
16104 [(set (match_operand:DF 0 "register_operand" "=f,f")
16105 (match_operator:DF 3 "binary_fp_operator"
16106 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16107 (match_operand:DF 2 "register_operand" "0,f")]))]
16108 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16109 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16110 "* return output_387_binary_op (insn, operands);"
16111 [(set (attr "type")
16112 (cond [(match_operand:DF 3 "mult_operator" "")
16113 (const_string "fmul")
16114 (match_operand:DF 3 "div_operator" "")
16115 (const_string "fdiv")
16117 (const_string "fop")))
16118 (set_attr "mode" "SF")])
16120 (define_insn "*fop_df_5_i387"
16121 [(set (match_operand:DF 0 "register_operand" "=f,f")
16122 (match_operator:DF 3 "binary_fp_operator"
16123 [(match_operand:DF 1 "register_operand" "0,f")
16125 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16126 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16127 "* return output_387_binary_op (insn, operands);"
16128 [(set (attr "type")
16129 (cond [(match_operand:DF 3 "mult_operator" "")
16130 (const_string "fmul")
16131 (match_operand:DF 3 "div_operator" "")
16132 (const_string "fdiv")
16134 (const_string "fop")))
16135 (set_attr "mode" "SF")])
16137 (define_insn "*fop_df_6_i387"
16138 [(set (match_operand:DF 0 "register_operand" "=f,f")
16139 (match_operator:DF 3 "binary_fp_operator"
16141 (match_operand:SF 1 "register_operand" "0,f"))
16143 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16144 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16145 "* return output_387_binary_op (insn, operands);"
16146 [(set (attr "type")
16147 (cond [(match_operand:DF 3 "mult_operator" "")
16148 (const_string "fmul")
16149 (match_operand:DF 3 "div_operator" "")
16150 (const_string "fdiv")
16152 (const_string "fop")))
16153 (set_attr "mode" "SF")])
16155 (define_insn "*fop_xf_comm_i387"
16156 [(set (match_operand:XF 0 "register_operand" "=f")
16157 (match_operator:XF 3 "binary_fp_operator"
16158 [(match_operand:XF 1 "register_operand" "%0")
16159 (match_operand:XF 2 "register_operand" "f")]))]
16161 && COMMUTATIVE_ARITH_P (operands[3])"
16162 "* return output_387_binary_op (insn, operands);"
16163 [(set (attr "type")
16164 (if_then_else (match_operand:XF 3 "mult_operator" "")
16165 (const_string "fmul")
16166 (const_string "fop")))
16167 (set_attr "mode" "XF")])
16169 (define_insn "*fop_xf_1_i387"
16170 [(set (match_operand:XF 0 "register_operand" "=f,f")
16171 (match_operator:XF 3 "binary_fp_operator"
16172 [(match_operand:XF 1 "register_operand" "0,f")
16173 (match_operand:XF 2 "register_operand" "f,0")]))]
16175 && !COMMUTATIVE_ARITH_P (operands[3])"
16176 "* return output_387_binary_op (insn, operands);"
16177 [(set (attr "type")
16178 (cond [(match_operand:XF 3 "mult_operator" "")
16179 (const_string "fmul")
16180 (match_operand:XF 3 "div_operator" "")
16181 (const_string "fdiv")
16183 (const_string "fop")))
16184 (set_attr "mode" "XF")])
16186 (define_insn "*fop_xf_2<mode>_i387"
16187 [(set (match_operand:XF 0 "register_operand" "=f,f")
16188 (match_operator:XF 3 "binary_fp_operator"
16189 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16190 (match_operand:XF 2 "register_operand" "0,0")]))]
16191 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16192 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16193 [(set (attr "type")
16194 (cond [(match_operand:XF 3 "mult_operator" "")
16195 (const_string "fmul")
16196 (match_operand:XF 3 "div_operator" "")
16197 (const_string "fdiv")
16199 (const_string "fop")))
16200 (set_attr "fp_int_src" "true")
16201 (set_attr "mode" "<MODE>")])
16203 (define_insn "*fop_xf_3<mode>_i387"
16204 [(set (match_operand:XF 0 "register_operand" "=f,f")
16205 (match_operator:XF 3 "binary_fp_operator"
16206 [(match_operand:XF 1 "register_operand" "0,0")
16207 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16208 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16209 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16210 [(set (attr "type")
16211 (cond [(match_operand:XF 3 "mult_operator" "")
16212 (const_string "fmul")
16213 (match_operand:XF 3 "div_operator" "")
16214 (const_string "fdiv")
16216 (const_string "fop")))
16217 (set_attr "fp_int_src" "true")
16218 (set_attr "mode" "<MODE>")])
16220 (define_insn "*fop_xf_4_i387"
16221 [(set (match_operand:XF 0 "register_operand" "=f,f")
16222 (match_operator:XF 3 "binary_fp_operator"
16224 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16225 (match_operand:XF 2 "register_operand" "0,f")]))]
16227 "* return output_387_binary_op (insn, operands);"
16228 [(set (attr "type")
16229 (cond [(match_operand:XF 3 "mult_operator" "")
16230 (const_string "fmul")
16231 (match_operand:XF 3 "div_operator" "")
16232 (const_string "fdiv")
16234 (const_string "fop")))
16235 (set_attr "mode" "SF")])
16237 (define_insn "*fop_xf_5_i387"
16238 [(set (match_operand:XF 0 "register_operand" "=f,f")
16239 (match_operator:XF 3 "binary_fp_operator"
16240 [(match_operand:XF 1 "register_operand" "0,f")
16242 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16244 "* return output_387_binary_op (insn, operands);"
16245 [(set (attr "type")
16246 (cond [(match_operand:XF 3 "mult_operator" "")
16247 (const_string "fmul")
16248 (match_operand:XF 3 "div_operator" "")
16249 (const_string "fdiv")
16251 (const_string "fop")))
16252 (set_attr "mode" "SF")])
16254 (define_insn "*fop_xf_6_i387"
16255 [(set (match_operand:XF 0 "register_operand" "=f,f")
16256 (match_operator:XF 3 "binary_fp_operator"
16258 (match_operand:MODEF 1 "register_operand" "0,f"))
16260 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16262 "* return output_387_binary_op (insn, operands);"
16263 [(set (attr "type")
16264 (cond [(match_operand:XF 3 "mult_operator" "")
16265 (const_string "fmul")
16266 (match_operand:XF 3 "div_operator" "")
16267 (const_string "fdiv")
16269 (const_string "fop")))
16270 (set_attr "mode" "SF")])
16273 [(set (match_operand 0 "register_operand" "")
16274 (match_operator 3 "binary_fp_operator"
16275 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16276 (match_operand 2 "register_operand" "")]))]
16278 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16281 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16282 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16283 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16284 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16285 GET_MODE (operands[3]),
16288 ix86_free_from_memory (GET_MODE (operands[1]));
16293 [(set (match_operand 0 "register_operand" "")
16294 (match_operator 3 "binary_fp_operator"
16295 [(match_operand 1 "register_operand" "")
16296 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16298 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16301 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16302 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16303 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16304 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16305 GET_MODE (operands[3]),
16308 ix86_free_from_memory (GET_MODE (operands[2]));
16312 ;; FPU special functions.
16314 ;; This pattern implements a no-op XFmode truncation for
16315 ;; all fancy i386 XFmode math functions.
16317 (define_insn "truncxf<mode>2_i387_noop_unspec"
16318 [(set (match_operand:MODEF 0 "register_operand" "=f")
16319 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16320 UNSPEC_TRUNC_NOOP))]
16321 "TARGET_USE_FANCY_MATH_387"
16322 "* return output_387_reg_move (insn, operands);"
16323 [(set_attr "type" "fmov")
16324 (set_attr "mode" "<MODE>")])
16326 (define_insn "sqrtxf2"
16327 [(set (match_operand:XF 0 "register_operand" "=f")
16328 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16329 "TARGET_USE_FANCY_MATH_387"
16331 [(set_attr "type" "fpspc")
16332 (set_attr "mode" "XF")
16333 (set_attr "athlon_decode" "direct")
16334 (set_attr "amdfam10_decode" "direct")])
16336 (define_insn "sqrt_extend<mode>xf2_i387"
16337 [(set (match_operand:XF 0 "register_operand" "=f")
16340 (match_operand:MODEF 1 "register_operand" "0"))))]
16341 "TARGET_USE_FANCY_MATH_387"
16343 [(set_attr "type" "fpspc")
16344 (set_attr "mode" "XF")
16345 (set_attr "athlon_decode" "direct")
16346 (set_attr "amdfam10_decode" "direct")])
16348 (define_insn "*rsqrtsf2_sse"
16349 [(set (match_operand:SF 0 "register_operand" "=x")
16350 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16353 "rsqrtss\t{%1, %0|%0, %1}"
16354 [(set_attr "type" "sse")
16355 (set_attr "mode" "SF")])
16357 (define_expand "rsqrtsf2"
16358 [(set (match_operand:SF 0 "register_operand" "")
16359 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16363 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16367 (define_insn "*sqrt<mode>2_sse"
16368 [(set (match_operand:MODEF 0 "register_operand" "=x")
16370 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16371 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16372 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16373 [(set_attr "type" "sse")
16374 (set_attr "mode" "<MODE>")
16375 (set_attr "athlon_decode" "*")
16376 (set_attr "amdfam10_decode" "*")])
16378 (define_expand "sqrt<mode>2"
16379 [(set (match_operand:MODEF 0 "register_operand" "")
16381 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16382 "TARGET_USE_FANCY_MATH_387
16383 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16385 if (<MODE>mode == SFmode
16386 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16387 && flag_finite_math_only && !flag_trapping_math
16388 && flag_unsafe_math_optimizations)
16390 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16394 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16396 rtx op0 = gen_reg_rtx (XFmode);
16397 rtx op1 = force_reg (<MODE>mode, operands[1]);
16399 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16400 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16405 (define_insn "fpremxf4_i387"
16406 [(set (match_operand:XF 0 "register_operand" "=f")
16407 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16408 (match_operand:XF 3 "register_operand" "1")]
16410 (set (match_operand:XF 1 "register_operand" "=u")
16411 (unspec:XF [(match_dup 2) (match_dup 3)]
16413 (set (reg:CCFP FPSR_REG)
16414 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16416 "TARGET_USE_FANCY_MATH_387"
16418 [(set_attr "type" "fpspc")
16419 (set_attr "mode" "XF")])
16421 (define_expand "fmodxf3"
16422 [(use (match_operand:XF 0 "register_operand" ""))
16423 (use (match_operand:XF 1 "general_operand" ""))
16424 (use (match_operand:XF 2 "general_operand" ""))]
16425 "TARGET_USE_FANCY_MATH_387"
16427 rtx label = gen_label_rtx ();
16429 rtx op1 = gen_reg_rtx (XFmode);
16430 rtx op2 = gen_reg_rtx (XFmode);
16432 emit_move_insn (op1, operands[1]);
16433 emit_move_insn (op2, operands[2]);
16435 emit_label (label);
16436 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16437 ix86_emit_fp_unordered_jump (label);
16438 LABEL_NUSES (label) = 1;
16440 emit_move_insn (operands[0], op1);
16444 (define_expand "fmod<mode>3"
16445 [(use (match_operand:MODEF 0 "register_operand" ""))
16446 (use (match_operand:MODEF 1 "general_operand" ""))
16447 (use (match_operand:MODEF 2 "general_operand" ""))]
16448 "TARGET_USE_FANCY_MATH_387"
16450 rtx label = gen_label_rtx ();
16452 rtx op1 = gen_reg_rtx (XFmode);
16453 rtx op2 = gen_reg_rtx (XFmode);
16455 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16456 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16458 emit_label (label);
16459 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16460 ix86_emit_fp_unordered_jump (label);
16461 LABEL_NUSES (label) = 1;
16463 /* Truncate the result properly for strict SSE math. */
16464 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16465 && !TARGET_MIX_SSE_I387)
16466 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16468 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16473 (define_insn "fprem1xf4_i387"
16474 [(set (match_operand:XF 0 "register_operand" "=f")
16475 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16476 (match_operand:XF 3 "register_operand" "1")]
16478 (set (match_operand:XF 1 "register_operand" "=u")
16479 (unspec:XF [(match_dup 2) (match_dup 3)]
16481 (set (reg:CCFP FPSR_REG)
16482 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16484 "TARGET_USE_FANCY_MATH_387"
16486 [(set_attr "type" "fpspc")
16487 (set_attr "mode" "XF")])
16489 (define_expand "remainderxf3"
16490 [(use (match_operand:XF 0 "register_operand" ""))
16491 (use (match_operand:XF 1 "general_operand" ""))
16492 (use (match_operand:XF 2 "general_operand" ""))]
16493 "TARGET_USE_FANCY_MATH_387"
16495 rtx label = gen_label_rtx ();
16497 rtx op1 = gen_reg_rtx (XFmode);
16498 rtx op2 = gen_reg_rtx (XFmode);
16500 emit_move_insn (op1, operands[1]);
16501 emit_move_insn (op2, operands[2]);
16503 emit_label (label);
16504 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16505 ix86_emit_fp_unordered_jump (label);
16506 LABEL_NUSES (label) = 1;
16508 emit_move_insn (operands[0], op1);
16512 (define_expand "remainder<mode>3"
16513 [(use (match_operand:MODEF 0 "register_operand" ""))
16514 (use (match_operand:MODEF 1 "general_operand" ""))
16515 (use (match_operand:MODEF 2 "general_operand" ""))]
16516 "TARGET_USE_FANCY_MATH_387"
16518 rtx label = gen_label_rtx ();
16520 rtx op1 = gen_reg_rtx (XFmode);
16521 rtx op2 = gen_reg_rtx (XFmode);
16523 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16524 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16526 emit_label (label);
16528 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16529 ix86_emit_fp_unordered_jump (label);
16530 LABEL_NUSES (label) = 1;
16532 /* Truncate the result properly for strict SSE math. */
16533 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16534 && !TARGET_MIX_SSE_I387)
16535 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16537 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16542 (define_insn "*sinxf2_i387"
16543 [(set (match_operand:XF 0 "register_operand" "=f")
16544 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16545 "TARGET_USE_FANCY_MATH_387
16546 && flag_unsafe_math_optimizations"
16548 [(set_attr "type" "fpspc")
16549 (set_attr "mode" "XF")])
16551 (define_insn "*sin_extend<mode>xf2_i387"
16552 [(set (match_operand:XF 0 "register_operand" "=f")
16553 (unspec:XF [(float_extend:XF
16554 (match_operand:MODEF 1 "register_operand" "0"))]
16556 "TARGET_USE_FANCY_MATH_387
16557 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16558 || TARGET_MIX_SSE_I387)
16559 && flag_unsafe_math_optimizations"
16561 [(set_attr "type" "fpspc")
16562 (set_attr "mode" "XF")])
16564 (define_insn "*cosxf2_i387"
16565 [(set (match_operand:XF 0 "register_operand" "=f")
16566 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16567 "TARGET_USE_FANCY_MATH_387
16568 && flag_unsafe_math_optimizations"
16570 [(set_attr "type" "fpspc")
16571 (set_attr "mode" "XF")])
16573 (define_insn "*cos_extend<mode>xf2_i387"
16574 [(set (match_operand:XF 0 "register_operand" "=f")
16575 (unspec:XF [(float_extend:XF
16576 (match_operand:MODEF 1 "register_operand" "0"))]
16578 "TARGET_USE_FANCY_MATH_387
16579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16580 || TARGET_MIX_SSE_I387)
16581 && flag_unsafe_math_optimizations"
16583 [(set_attr "type" "fpspc")
16584 (set_attr "mode" "XF")])
16586 ;; When sincos pattern is defined, sin and cos builtin functions will be
16587 ;; expanded to sincos pattern with one of its outputs left unused.
16588 ;; CSE pass will figure out if two sincos patterns can be combined,
16589 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16590 ;; depending on the unused output.
16592 (define_insn "sincosxf3"
16593 [(set (match_operand:XF 0 "register_operand" "=f")
16594 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16595 UNSPEC_SINCOS_COS))
16596 (set (match_operand:XF 1 "register_operand" "=u")
16597 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16598 "TARGET_USE_FANCY_MATH_387
16599 && flag_unsafe_math_optimizations"
16601 [(set_attr "type" "fpspc")
16602 (set_attr "mode" "XF")])
16605 [(set (match_operand:XF 0 "register_operand" "")
16606 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16607 UNSPEC_SINCOS_COS))
16608 (set (match_operand:XF 1 "register_operand" "")
16609 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16610 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16611 && !(reload_completed || reload_in_progress)"
16612 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16616 [(set (match_operand:XF 0 "register_operand" "")
16617 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16618 UNSPEC_SINCOS_COS))
16619 (set (match_operand:XF 1 "register_operand" "")
16620 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16621 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16622 && !(reload_completed || reload_in_progress)"
16623 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16626 (define_insn "sincos_extend<mode>xf3_i387"
16627 [(set (match_operand:XF 0 "register_operand" "=f")
16628 (unspec:XF [(float_extend:XF
16629 (match_operand:MODEF 2 "register_operand" "0"))]
16630 UNSPEC_SINCOS_COS))
16631 (set (match_operand:XF 1 "register_operand" "=u")
16632 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16633 "TARGET_USE_FANCY_MATH_387
16634 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16635 || TARGET_MIX_SSE_I387)
16636 && flag_unsafe_math_optimizations"
16638 [(set_attr "type" "fpspc")
16639 (set_attr "mode" "XF")])
16642 [(set (match_operand:XF 0 "register_operand" "")
16643 (unspec:XF [(float_extend:XF
16644 (match_operand:MODEF 2 "register_operand" ""))]
16645 UNSPEC_SINCOS_COS))
16646 (set (match_operand:XF 1 "register_operand" "")
16647 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16648 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16649 && !(reload_completed || reload_in_progress)"
16650 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16654 [(set (match_operand:XF 0 "register_operand" "")
16655 (unspec:XF [(float_extend:XF
16656 (match_operand:MODEF 2 "register_operand" ""))]
16657 UNSPEC_SINCOS_COS))
16658 (set (match_operand:XF 1 "register_operand" "")
16659 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16660 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16661 && !(reload_completed || reload_in_progress)"
16662 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16665 (define_expand "sincos<mode>3"
16666 [(use (match_operand:MODEF 0 "register_operand" ""))
16667 (use (match_operand:MODEF 1 "register_operand" ""))
16668 (use (match_operand:MODEF 2 "register_operand" ""))]
16669 "TARGET_USE_FANCY_MATH_387
16670 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671 || TARGET_MIX_SSE_I387)
16672 && flag_unsafe_math_optimizations"
16674 rtx op0 = gen_reg_rtx (XFmode);
16675 rtx op1 = gen_reg_rtx (XFmode);
16677 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16678 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16679 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16683 (define_insn "fptanxf4_i387"
16684 [(set (match_operand:XF 0 "register_operand" "=f")
16685 (match_operand:XF 3 "const_double_operand" "F"))
16686 (set (match_operand:XF 1 "register_operand" "=u")
16687 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16689 "TARGET_USE_FANCY_MATH_387
16690 && flag_unsafe_math_optimizations
16691 && standard_80387_constant_p (operands[3]) == 2"
16693 [(set_attr "type" "fpspc")
16694 (set_attr "mode" "XF")])
16696 (define_insn "fptan_extend<mode>xf4_i387"
16697 [(set (match_operand:MODEF 0 "register_operand" "=f")
16698 (match_operand:MODEF 3 "const_double_operand" "F"))
16699 (set (match_operand:XF 1 "register_operand" "=u")
16700 (unspec:XF [(float_extend:XF
16701 (match_operand:MODEF 2 "register_operand" "0"))]
16703 "TARGET_USE_FANCY_MATH_387
16704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16705 || TARGET_MIX_SSE_I387)
16706 && flag_unsafe_math_optimizations
16707 && standard_80387_constant_p (operands[3]) == 2"
16709 [(set_attr "type" "fpspc")
16710 (set_attr "mode" "XF")])
16712 (define_expand "tanxf2"
16713 [(use (match_operand:XF 0 "register_operand" ""))
16714 (use (match_operand:XF 1 "register_operand" ""))]
16715 "TARGET_USE_FANCY_MATH_387
16716 && flag_unsafe_math_optimizations"
16718 rtx one = gen_reg_rtx (XFmode);
16719 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16721 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16725 (define_expand "tan<mode>2"
16726 [(use (match_operand:MODEF 0 "register_operand" ""))
16727 (use (match_operand:MODEF 1 "register_operand" ""))]
16728 "TARGET_USE_FANCY_MATH_387
16729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16730 || TARGET_MIX_SSE_I387)
16731 && flag_unsafe_math_optimizations"
16733 rtx op0 = gen_reg_rtx (XFmode);
16735 rtx one = gen_reg_rtx (<MODE>mode);
16736 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16738 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16739 operands[1], op2));
16740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16744 (define_insn "*fpatanxf3_i387"
16745 [(set (match_operand:XF 0 "register_operand" "=f")
16746 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16747 (match_operand:XF 2 "register_operand" "u")]
16749 (clobber (match_scratch:XF 3 "=2"))]
16750 "TARGET_USE_FANCY_MATH_387
16751 && flag_unsafe_math_optimizations"
16753 [(set_attr "type" "fpspc")
16754 (set_attr "mode" "XF")])
16756 (define_insn "fpatan_extend<mode>xf3_i387"
16757 [(set (match_operand:XF 0 "register_operand" "=f")
16758 (unspec:XF [(float_extend:XF
16759 (match_operand:MODEF 1 "register_operand" "0"))
16761 (match_operand:MODEF 2 "register_operand" "u"))]
16763 (clobber (match_scratch:XF 3 "=2"))]
16764 "TARGET_USE_FANCY_MATH_387
16765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16766 || TARGET_MIX_SSE_I387)
16767 && flag_unsafe_math_optimizations"
16769 [(set_attr "type" "fpspc")
16770 (set_attr "mode" "XF")])
16772 (define_expand "atan2xf3"
16773 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16774 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16775 (match_operand:XF 1 "register_operand" "")]
16777 (clobber (match_scratch:XF 3 ""))])]
16778 "TARGET_USE_FANCY_MATH_387
16779 && flag_unsafe_math_optimizations"
16782 (define_expand "atan2<mode>3"
16783 [(use (match_operand:MODEF 0 "register_operand" ""))
16784 (use (match_operand:MODEF 1 "register_operand" ""))
16785 (use (match_operand:MODEF 2 "register_operand" ""))]
16786 "TARGET_USE_FANCY_MATH_387
16787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16788 || TARGET_MIX_SSE_I387)
16789 && flag_unsafe_math_optimizations"
16791 rtx op0 = gen_reg_rtx (XFmode);
16793 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16798 (define_expand "atanxf2"
16799 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16800 (unspec:XF [(match_dup 2)
16801 (match_operand:XF 1 "register_operand" "")]
16803 (clobber (match_scratch:XF 3 ""))])]
16804 "TARGET_USE_FANCY_MATH_387
16805 && flag_unsafe_math_optimizations"
16807 operands[2] = gen_reg_rtx (XFmode);
16808 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16811 (define_expand "atan<mode>2"
16812 [(use (match_operand:MODEF 0 "register_operand" ""))
16813 (use (match_operand:MODEF 1 "register_operand" ""))]
16814 "TARGET_USE_FANCY_MATH_387
16815 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16816 || TARGET_MIX_SSE_I387)
16817 && flag_unsafe_math_optimizations"
16819 rtx op0 = gen_reg_rtx (XFmode);
16821 rtx op2 = gen_reg_rtx (<MODE>mode);
16822 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16824 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16825 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16829 (define_expand "asinxf2"
16830 [(set (match_dup 2)
16831 (mult:XF (match_operand:XF 1 "register_operand" "")
16833 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16834 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16835 (parallel [(set (match_operand:XF 0 "register_operand" "")
16836 (unspec:XF [(match_dup 5) (match_dup 1)]
16838 (clobber (match_scratch:XF 6 ""))])]
16839 "TARGET_USE_FANCY_MATH_387
16840 && flag_unsafe_math_optimizations && !optimize_size"
16844 for (i = 2; i < 6; i++)
16845 operands[i] = gen_reg_rtx (XFmode);
16847 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16850 (define_expand "asin<mode>2"
16851 [(use (match_operand:MODEF 0 "register_operand" ""))
16852 (use (match_operand:MODEF 1 "general_operand" ""))]
16853 "TARGET_USE_FANCY_MATH_387
16854 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16855 || TARGET_MIX_SSE_I387)
16856 && flag_unsafe_math_optimizations && !optimize_size"
16858 rtx op0 = gen_reg_rtx (XFmode);
16859 rtx op1 = gen_reg_rtx (XFmode);
16861 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16862 emit_insn (gen_asinxf2 (op0, op1));
16863 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16867 (define_expand "acosxf2"
16868 [(set (match_dup 2)
16869 (mult:XF (match_operand:XF 1 "register_operand" "")
16871 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16872 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16873 (parallel [(set (match_operand:XF 0 "register_operand" "")
16874 (unspec:XF [(match_dup 1) (match_dup 5)]
16876 (clobber (match_scratch:XF 6 ""))])]
16877 "TARGET_USE_FANCY_MATH_387
16878 && flag_unsafe_math_optimizations && !optimize_size"
16882 for (i = 2; i < 6; i++)
16883 operands[i] = gen_reg_rtx (XFmode);
16885 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16888 (define_expand "acos<mode>2"
16889 [(use (match_operand:MODEF 0 "register_operand" ""))
16890 (use (match_operand:MODEF 1 "general_operand" ""))]
16891 "TARGET_USE_FANCY_MATH_387
16892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16893 || TARGET_MIX_SSE_I387)
16894 && flag_unsafe_math_optimizations && !optimize_size"
16896 rtx op0 = gen_reg_rtx (XFmode);
16897 rtx op1 = gen_reg_rtx (XFmode);
16899 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16900 emit_insn (gen_acosxf2 (op0, op1));
16901 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16905 (define_insn "fyl2xxf3_i387"
16906 [(set (match_operand:XF 0 "register_operand" "=f")
16907 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16908 (match_operand:XF 2 "register_operand" "u")]
16910 (clobber (match_scratch:XF 3 "=2"))]
16911 "TARGET_USE_FANCY_MATH_387
16912 && flag_unsafe_math_optimizations"
16914 [(set_attr "type" "fpspc")
16915 (set_attr "mode" "XF")])
16917 (define_insn "fyl2x_extend<mode>xf3_i387"
16918 [(set (match_operand:XF 0 "register_operand" "=f")
16919 (unspec:XF [(float_extend:XF
16920 (match_operand:MODEF 1 "register_operand" "0"))
16921 (match_operand:XF 2 "register_operand" "u")]
16923 (clobber (match_scratch:XF 3 "=2"))]
16924 "TARGET_USE_FANCY_MATH_387
16925 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16926 || TARGET_MIX_SSE_I387)
16927 && flag_unsafe_math_optimizations"
16929 [(set_attr "type" "fpspc")
16930 (set_attr "mode" "XF")])
16932 (define_expand "logxf2"
16933 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16934 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16935 (match_dup 2)] UNSPEC_FYL2X))
16936 (clobber (match_scratch:XF 3 ""))])]
16937 "TARGET_USE_FANCY_MATH_387
16938 && flag_unsafe_math_optimizations"
16940 operands[2] = gen_reg_rtx (XFmode);
16941 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16944 (define_expand "log<mode>2"
16945 [(use (match_operand:MODEF 0 "register_operand" ""))
16946 (use (match_operand:MODEF 1 "register_operand" ""))]
16947 "TARGET_USE_FANCY_MATH_387
16948 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16949 || TARGET_MIX_SSE_I387)
16950 && flag_unsafe_math_optimizations"
16952 rtx op0 = gen_reg_rtx (XFmode);
16954 rtx op2 = gen_reg_rtx (XFmode);
16955 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16957 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16958 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16962 (define_expand "log10xf2"
16963 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16964 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16965 (match_dup 2)] UNSPEC_FYL2X))
16966 (clobber (match_scratch:XF 3 ""))])]
16967 "TARGET_USE_FANCY_MATH_387
16968 && flag_unsafe_math_optimizations"
16970 operands[2] = gen_reg_rtx (XFmode);
16971 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16974 (define_expand "log10<mode>2"
16975 [(use (match_operand:MODEF 0 "register_operand" ""))
16976 (use (match_operand:MODEF 1 "register_operand" ""))]
16977 "TARGET_USE_FANCY_MATH_387
16978 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16979 || TARGET_MIX_SSE_I387)
16980 && flag_unsafe_math_optimizations"
16982 rtx op0 = gen_reg_rtx (XFmode);
16984 rtx op2 = gen_reg_rtx (XFmode);
16985 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16987 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16992 (define_expand "log2xf2"
16993 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16994 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16995 (match_dup 2)] UNSPEC_FYL2X))
16996 (clobber (match_scratch:XF 3 ""))])]
16997 "TARGET_USE_FANCY_MATH_387
16998 && flag_unsafe_math_optimizations"
17000 operands[2] = gen_reg_rtx (XFmode);
17001 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17004 (define_expand "log2<mode>2"
17005 [(use (match_operand:MODEF 0 "register_operand" ""))
17006 (use (match_operand:MODEF 1 "register_operand" ""))]
17007 "TARGET_USE_FANCY_MATH_387
17008 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17009 || TARGET_MIX_SSE_I387)
17010 && flag_unsafe_math_optimizations"
17012 rtx op0 = gen_reg_rtx (XFmode);
17014 rtx op2 = gen_reg_rtx (XFmode);
17015 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17017 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17018 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17022 (define_insn "fyl2xp1xf3_i387"
17023 [(set (match_operand:XF 0 "register_operand" "=f")
17024 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17025 (match_operand:XF 2 "register_operand" "u")]
17027 (clobber (match_scratch:XF 3 "=2"))]
17028 "TARGET_USE_FANCY_MATH_387
17029 && flag_unsafe_math_optimizations"
17031 [(set_attr "type" "fpspc")
17032 (set_attr "mode" "XF")])
17034 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17035 [(set (match_operand:XF 0 "register_operand" "=f")
17036 (unspec:XF [(float_extend:XF
17037 (match_operand:MODEF 1 "register_operand" "0"))
17038 (match_operand:XF 2 "register_operand" "u")]
17040 (clobber (match_scratch:XF 3 "=2"))]
17041 "TARGET_USE_FANCY_MATH_387
17042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17043 || TARGET_MIX_SSE_I387)
17044 && flag_unsafe_math_optimizations"
17046 [(set_attr "type" "fpspc")
17047 (set_attr "mode" "XF")])
17049 (define_expand "log1pxf2"
17050 [(use (match_operand:XF 0 "register_operand" ""))
17051 (use (match_operand:XF 1 "register_operand" ""))]
17052 "TARGET_USE_FANCY_MATH_387
17053 && flag_unsafe_math_optimizations && !optimize_size"
17055 ix86_emit_i387_log1p (operands[0], operands[1]);
17059 (define_expand "log1p<mode>2"
17060 [(use (match_operand:MODEF 0 "register_operand" ""))
17061 (use (match_operand:MODEF 1 "register_operand" ""))]
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 && !optimize_size"
17067 rtx op0 = gen_reg_rtx (XFmode);
17069 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17071 ix86_emit_i387_log1p (op0, operands[1]);
17072 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17076 (define_insn "fxtractxf3_i387"
17077 [(set (match_operand:XF 0 "register_operand" "=f")
17078 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17079 UNSPEC_XTRACT_FRACT))
17080 (set (match_operand:XF 1 "register_operand" "=u")
17081 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17082 "TARGET_USE_FANCY_MATH_387
17083 && flag_unsafe_math_optimizations"
17085 [(set_attr "type" "fpspc")
17086 (set_attr "mode" "XF")])
17088 (define_insn "fxtract_extend<mode>xf3_i387"
17089 [(set (match_operand:XF 0 "register_operand" "=f")
17090 (unspec:XF [(float_extend:XF
17091 (match_operand:MODEF 2 "register_operand" "0"))]
17092 UNSPEC_XTRACT_FRACT))
17093 (set (match_operand:XF 1 "register_operand" "=u")
17094 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17095 "TARGET_USE_FANCY_MATH_387
17096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17097 || TARGET_MIX_SSE_I387)
17098 && flag_unsafe_math_optimizations"
17100 [(set_attr "type" "fpspc")
17101 (set_attr "mode" "XF")])
17103 (define_expand "logbxf2"
17104 [(parallel [(set (match_dup 2)
17105 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17106 UNSPEC_XTRACT_FRACT))
17107 (set (match_operand:XF 0 "register_operand" "")
17108 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17109 "TARGET_USE_FANCY_MATH_387
17110 && flag_unsafe_math_optimizations"
17112 operands[2] = gen_reg_rtx (XFmode);
17115 (define_expand "logb<mode>2"
17116 [(use (match_operand:MODEF 0 "register_operand" ""))
17117 (use (match_operand:MODEF 1 "register_operand" ""))]
17118 "TARGET_USE_FANCY_MATH_387
17119 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17120 || TARGET_MIX_SSE_I387)
17121 && flag_unsafe_math_optimizations"
17123 rtx op0 = gen_reg_rtx (XFmode);
17124 rtx op1 = gen_reg_rtx (XFmode);
17126 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17127 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17131 (define_expand "ilogbxf2"
17132 [(use (match_operand:SI 0 "register_operand" ""))
17133 (use (match_operand:XF 1 "register_operand" ""))]
17134 "TARGET_USE_FANCY_MATH_387
17135 && flag_unsafe_math_optimizations && !optimize_size"
17137 rtx op0 = gen_reg_rtx (XFmode);
17138 rtx op1 = gen_reg_rtx (XFmode);
17140 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17141 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17145 (define_expand "ilogb<mode>2"
17146 [(use (match_operand:SI 0 "register_operand" ""))
17147 (use (match_operand:MODEF 1 "register_operand" ""))]
17148 "TARGET_USE_FANCY_MATH_387
17149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17150 || TARGET_MIX_SSE_I387)
17151 && flag_unsafe_math_optimizations && !optimize_size"
17153 rtx op0 = gen_reg_rtx (XFmode);
17154 rtx op1 = gen_reg_rtx (XFmode);
17156 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17157 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17161 (define_insn "*f2xm1xf2_i387"
17162 [(set (match_operand:XF 0 "register_operand" "=f")
17163 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17165 "TARGET_USE_FANCY_MATH_387
17166 && flag_unsafe_math_optimizations"
17168 [(set_attr "type" "fpspc")
17169 (set_attr "mode" "XF")])
17171 (define_insn "*fscalexf4_i387"
17172 [(set (match_operand:XF 0 "register_operand" "=f")
17173 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17174 (match_operand:XF 3 "register_operand" "1")]
17175 UNSPEC_FSCALE_FRACT))
17176 (set (match_operand:XF 1 "register_operand" "=u")
17177 (unspec:XF [(match_dup 2) (match_dup 3)]
17178 UNSPEC_FSCALE_EXP))]
17179 "TARGET_USE_FANCY_MATH_387
17180 && flag_unsafe_math_optimizations"
17182 [(set_attr "type" "fpspc")
17183 (set_attr "mode" "XF")])
17185 (define_expand "expNcorexf3"
17186 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17187 (match_operand:XF 2 "register_operand" "")))
17188 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17189 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17190 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17191 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17192 (parallel [(set (match_operand:XF 0 "register_operand" "")
17193 (unspec:XF [(match_dup 8) (match_dup 4)]
17194 UNSPEC_FSCALE_FRACT))
17196 (unspec:XF [(match_dup 8) (match_dup 4)]
17197 UNSPEC_FSCALE_EXP))])]
17198 "TARGET_USE_FANCY_MATH_387
17199 && flag_unsafe_math_optimizations && !optimize_size"
17203 for (i = 3; i < 10; i++)
17204 operands[i] = gen_reg_rtx (XFmode);
17206 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17209 (define_expand "expxf2"
17210 [(use (match_operand:XF 0 "register_operand" ""))
17211 (use (match_operand:XF 1 "register_operand" ""))]
17212 "TARGET_USE_FANCY_MATH_387
17213 && flag_unsafe_math_optimizations && !optimize_size"
17215 rtx op2 = gen_reg_rtx (XFmode);
17216 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17218 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17222 (define_expand "exp<mode>2"
17223 [(use (match_operand:MODEF 0 "register_operand" ""))
17224 (use (match_operand:MODEF 1 "general_operand" ""))]
17225 "TARGET_USE_FANCY_MATH_387
17226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17227 || TARGET_MIX_SSE_I387)
17228 && flag_unsafe_math_optimizations && !optimize_size"
17230 rtx op0 = gen_reg_rtx (XFmode);
17231 rtx op1 = gen_reg_rtx (XFmode);
17233 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17234 emit_insn (gen_expxf2 (op0, op1));
17235 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17239 (define_expand "exp10xf2"
17240 [(use (match_operand:XF 0 "register_operand" ""))
17241 (use (match_operand:XF 1 "register_operand" ""))]
17242 "TARGET_USE_FANCY_MATH_387
17243 && flag_unsafe_math_optimizations && !optimize_size"
17245 rtx op2 = gen_reg_rtx (XFmode);
17246 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17248 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17252 (define_expand "exp10<mode>2"
17253 [(use (match_operand:MODEF 0 "register_operand" ""))
17254 (use (match_operand:MODEF 1 "general_operand" ""))]
17255 "TARGET_USE_FANCY_MATH_387
17256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17257 || TARGET_MIX_SSE_I387)
17258 && flag_unsafe_math_optimizations && !optimize_size"
17260 rtx op0 = gen_reg_rtx (XFmode);
17261 rtx op1 = gen_reg_rtx (XFmode);
17263 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17264 emit_insn (gen_exp10xf2 (op0, op1));
17265 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17269 (define_expand "exp2xf2"
17270 [(use (match_operand:XF 0 "register_operand" ""))
17271 (use (match_operand:XF 1 "register_operand" ""))]
17272 "TARGET_USE_FANCY_MATH_387
17273 && flag_unsafe_math_optimizations && !optimize_size"
17275 rtx op2 = gen_reg_rtx (XFmode);
17276 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17278 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17282 (define_expand "exp2<mode>2"
17283 [(use (match_operand:MODEF 0 "register_operand" ""))
17284 (use (match_operand:MODEF 1 "general_operand" ""))]
17285 "TARGET_USE_FANCY_MATH_387
17286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17287 || TARGET_MIX_SSE_I387)
17288 && flag_unsafe_math_optimizations && !optimize_size"
17290 rtx op0 = gen_reg_rtx (XFmode);
17291 rtx op1 = gen_reg_rtx (XFmode);
17293 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17294 emit_insn (gen_exp2xf2 (op0, op1));
17295 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17299 (define_expand "expm1xf2"
17300 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17302 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17303 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17304 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17305 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17306 (parallel [(set (match_dup 7)
17307 (unspec:XF [(match_dup 6) (match_dup 4)]
17308 UNSPEC_FSCALE_FRACT))
17310 (unspec:XF [(match_dup 6) (match_dup 4)]
17311 UNSPEC_FSCALE_EXP))])
17312 (parallel [(set (match_dup 10)
17313 (unspec:XF [(match_dup 9) (match_dup 8)]
17314 UNSPEC_FSCALE_FRACT))
17315 (set (match_dup 11)
17316 (unspec:XF [(match_dup 9) (match_dup 8)]
17317 UNSPEC_FSCALE_EXP))])
17318 (set (match_dup 12) (minus:XF (match_dup 10)
17319 (float_extend:XF (match_dup 13))))
17320 (set (match_operand:XF 0 "register_operand" "")
17321 (plus:XF (match_dup 12) (match_dup 7)))]
17322 "TARGET_USE_FANCY_MATH_387
17323 && flag_unsafe_math_optimizations && !optimize_size"
17327 for (i = 2; i < 13; i++)
17328 operands[i] = gen_reg_rtx (XFmode);
17331 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17333 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17336 (define_expand "expm1<mode>2"
17337 [(use (match_operand:MODEF 0 "register_operand" ""))
17338 (use (match_operand:MODEF 1 "general_operand" ""))]
17339 "TARGET_USE_FANCY_MATH_387
17340 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17341 || TARGET_MIX_SSE_I387)
17342 && flag_unsafe_math_optimizations && !optimize_size"
17344 rtx op0 = gen_reg_rtx (XFmode);
17345 rtx op1 = gen_reg_rtx (XFmode);
17347 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17348 emit_insn (gen_expm1xf2 (op0, op1));
17349 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17353 (define_expand "ldexpxf3"
17354 [(set (match_dup 3)
17355 (float:XF (match_operand:SI 2 "register_operand" "")))
17356 (parallel [(set (match_operand:XF 0 " register_operand" "")
17357 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17359 UNSPEC_FSCALE_FRACT))
17361 (unspec:XF [(match_dup 1) (match_dup 3)]
17362 UNSPEC_FSCALE_EXP))])]
17363 "TARGET_USE_FANCY_MATH_387
17364 && flag_unsafe_math_optimizations && !optimize_size"
17366 operands[3] = gen_reg_rtx (XFmode);
17367 operands[4] = gen_reg_rtx (XFmode);
17370 (define_expand "ldexp<mode>3"
17371 [(use (match_operand:MODEF 0 "register_operand" ""))
17372 (use (match_operand:MODEF 1 "general_operand" ""))
17373 (use (match_operand:SI 2 "register_operand" ""))]
17374 "TARGET_USE_FANCY_MATH_387
17375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17376 || TARGET_MIX_SSE_I387)
17377 && flag_unsafe_math_optimizations && !optimize_size"
17379 rtx op0 = gen_reg_rtx (XFmode);
17380 rtx op1 = gen_reg_rtx (XFmode);
17382 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17383 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17384 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17388 (define_expand "scalbxf3"
17389 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17390 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17391 (match_operand:XF 2 "register_operand" "")]
17392 UNSPEC_FSCALE_FRACT))
17394 (unspec:XF [(match_dup 1) (match_dup 2)]
17395 UNSPEC_FSCALE_EXP))])]
17396 "TARGET_USE_FANCY_MATH_387
17397 && flag_unsafe_math_optimizations && !optimize_size"
17399 operands[3] = gen_reg_rtx (XFmode);
17402 (define_expand "scalb<mode>3"
17403 [(use (match_operand:MODEF 0 "register_operand" ""))
17404 (use (match_operand:MODEF 1 "general_operand" ""))
17405 (use (match_operand:MODEF 2 "register_operand" ""))]
17406 "TARGET_USE_FANCY_MATH_387
17407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17408 || TARGET_MIX_SSE_I387)
17409 && flag_unsafe_math_optimizations && !optimize_size"
17411 rtx op0 = gen_reg_rtx (XFmode);
17412 rtx op1 = gen_reg_rtx (XFmode);
17413 rtx op2 = gen_reg_rtx (XFmode);
17415 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17416 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17417 emit_insn (gen_scalbxf3 (op0, op1, op2));
17418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17423 (define_insn "sse4_1_round<mode>2"
17424 [(set (match_operand:MODEF 0 "register_operand" "=x")
17425 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17426 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17429 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17430 [(set_attr "type" "ssecvt")
17431 (set_attr "prefix_extra" "1")
17432 (set_attr "mode" "<MODE>")])
17434 (define_insn "rintxf2"
17435 [(set (match_operand:XF 0 "register_operand" "=f")
17436 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17438 "TARGET_USE_FANCY_MATH_387
17439 && flag_unsafe_math_optimizations"
17441 [(set_attr "type" "fpspc")
17442 (set_attr "mode" "XF")])
17444 (define_expand "rint<mode>2"
17445 [(use (match_operand:MODEF 0 "register_operand" ""))
17446 (use (match_operand:MODEF 1 "register_operand" ""))]
17447 "(TARGET_USE_FANCY_MATH_387
17448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17449 || TARGET_MIX_SSE_I387)
17450 && flag_unsafe_math_optimizations)
17451 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17452 && !flag_trapping_math
17453 && (TARGET_ROUND || !optimize_size))"
17455 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17456 && !flag_trapping_math
17457 && (TARGET_ROUND || !optimize_size))
17460 emit_insn (gen_sse4_1_round<mode>2
17461 (operands[0], operands[1], GEN_INT (0x04)));
17463 ix86_expand_rint (operand0, operand1);
17467 rtx op0 = gen_reg_rtx (XFmode);
17468 rtx op1 = gen_reg_rtx (XFmode);
17470 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17471 emit_insn (gen_rintxf2 (op0, op1));
17473 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17478 (define_expand "round<mode>2"
17479 [(match_operand:MODEF 0 "register_operand" "")
17480 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17481 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17482 && !flag_trapping_math && !flag_rounding_math
17485 if (TARGET_64BIT || (<MODE>mode != DFmode))
17486 ix86_expand_round (operand0, operand1);
17488 ix86_expand_rounddf_32 (operand0, operand1);
17492 (define_insn_and_split "*fistdi2_1"
17493 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17494 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17496 "TARGET_USE_FANCY_MATH_387
17497 && !(reload_completed || reload_in_progress)"
17502 if (memory_operand (operands[0], VOIDmode))
17503 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17506 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17507 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17512 [(set_attr "type" "fpspc")
17513 (set_attr "mode" "DI")])
17515 (define_insn "fistdi2"
17516 [(set (match_operand:DI 0 "memory_operand" "=m")
17517 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17519 (clobber (match_scratch:XF 2 "=&1f"))]
17520 "TARGET_USE_FANCY_MATH_387"
17521 "* return output_fix_trunc (insn, operands, 0);"
17522 [(set_attr "type" "fpspc")
17523 (set_attr "mode" "DI")])
17525 (define_insn "fistdi2_with_temp"
17526 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17527 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17529 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17530 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17531 "TARGET_USE_FANCY_MATH_387"
17533 [(set_attr "type" "fpspc")
17534 (set_attr "mode" "DI")])
17537 [(set (match_operand:DI 0 "register_operand" "")
17538 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17540 (clobber (match_operand:DI 2 "memory_operand" ""))
17541 (clobber (match_scratch 3 ""))]
17543 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17544 (clobber (match_dup 3))])
17545 (set (match_dup 0) (match_dup 2))]
17549 [(set (match_operand:DI 0 "memory_operand" "")
17550 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17552 (clobber (match_operand:DI 2 "memory_operand" ""))
17553 (clobber (match_scratch 3 ""))]
17555 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17556 (clobber (match_dup 3))])]
17559 (define_insn_and_split "*fist<mode>2_1"
17560 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17561 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17563 "TARGET_USE_FANCY_MATH_387
17564 && !(reload_completed || reload_in_progress)"
17569 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17570 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17574 [(set_attr "type" "fpspc")
17575 (set_attr "mode" "<MODE>")])
17577 (define_insn "fist<mode>2"
17578 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17579 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17581 "TARGET_USE_FANCY_MATH_387"
17582 "* return output_fix_trunc (insn, operands, 0);"
17583 [(set_attr "type" "fpspc")
17584 (set_attr "mode" "<MODE>")])
17586 (define_insn "fist<mode>2_with_temp"
17587 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17588 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17590 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17591 "TARGET_USE_FANCY_MATH_387"
17593 [(set_attr "type" "fpspc")
17594 (set_attr "mode" "<MODE>")])
17597 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17598 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17600 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17602 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17603 (set (match_dup 0) (match_dup 2))]
17607 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17608 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17610 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17612 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17615 (define_expand "lrintxf<mode>2"
17616 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17617 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17619 "TARGET_USE_FANCY_MATH_387"
17622 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17623 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17624 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17625 UNSPEC_FIX_NOTRUNC))]
17626 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17627 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17630 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17631 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17632 (match_operand:MODEF 1 "register_operand" "")]
17633 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17634 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17635 && !flag_trapping_math && !flag_rounding_math
17638 ix86_expand_lround (operand0, operand1);
17642 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17643 (define_insn_and_split "frndintxf2_floor"
17644 [(set (match_operand:XF 0 "register_operand" "")
17645 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17646 UNSPEC_FRNDINT_FLOOR))
17647 (clobber (reg:CC FLAGS_REG))]
17648 "TARGET_USE_FANCY_MATH_387
17649 && flag_unsafe_math_optimizations
17650 && !(reload_completed || reload_in_progress)"
17655 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17657 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17658 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17660 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17661 operands[2], operands[3]));
17664 [(set_attr "type" "frndint")
17665 (set_attr "i387_cw" "floor")
17666 (set_attr "mode" "XF")])
17668 (define_insn "frndintxf2_floor_i387"
17669 [(set (match_operand:XF 0 "register_operand" "=f")
17670 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17671 UNSPEC_FRNDINT_FLOOR))
17672 (use (match_operand:HI 2 "memory_operand" "m"))
17673 (use (match_operand:HI 3 "memory_operand" "m"))]
17674 "TARGET_USE_FANCY_MATH_387
17675 && flag_unsafe_math_optimizations"
17676 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17677 [(set_attr "type" "frndint")
17678 (set_attr "i387_cw" "floor")
17679 (set_attr "mode" "XF")])
17681 (define_expand "floorxf2"
17682 [(use (match_operand:XF 0 "register_operand" ""))
17683 (use (match_operand:XF 1 "register_operand" ""))]
17684 "TARGET_USE_FANCY_MATH_387
17685 && flag_unsafe_math_optimizations && !optimize_size"
17687 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17691 (define_expand "floor<mode>2"
17692 [(use (match_operand:MODEF 0 "register_operand" ""))
17693 (use (match_operand:MODEF 1 "register_operand" ""))]
17694 "(TARGET_USE_FANCY_MATH_387
17695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17696 || TARGET_MIX_SSE_I387)
17697 && flag_unsafe_math_optimizations && !optimize_size)
17698 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17699 && !flag_trapping_math
17700 && (TARGET_ROUND || !optimize_size))"
17702 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17703 && !flag_trapping_math
17704 && (TARGET_ROUND || !optimize_size))
17707 emit_insn (gen_sse4_1_round<mode>2
17708 (operands[0], operands[1], GEN_INT (0x01)));
17709 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17710 ix86_expand_floorceil (operand0, operand1, true);
17712 ix86_expand_floorceildf_32 (operand0, operand1, true);
17716 rtx op0 = gen_reg_rtx (XFmode);
17717 rtx op1 = gen_reg_rtx (XFmode);
17719 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17720 emit_insn (gen_frndintxf2_floor (op0, op1));
17722 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17727 (define_insn_and_split "*fist<mode>2_floor_1"
17728 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17729 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17730 UNSPEC_FIST_FLOOR))
17731 (clobber (reg:CC FLAGS_REG))]
17732 "TARGET_USE_FANCY_MATH_387
17733 && flag_unsafe_math_optimizations
17734 && !(reload_completed || reload_in_progress)"
17739 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17741 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17742 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17743 if (memory_operand (operands[0], VOIDmode))
17744 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17745 operands[2], operands[3]));
17748 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17749 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17750 operands[2], operands[3],
17755 [(set_attr "type" "fistp")
17756 (set_attr "i387_cw" "floor")
17757 (set_attr "mode" "<MODE>")])
17759 (define_insn "fistdi2_floor"
17760 [(set (match_operand:DI 0 "memory_operand" "=m")
17761 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17762 UNSPEC_FIST_FLOOR))
17763 (use (match_operand:HI 2 "memory_operand" "m"))
17764 (use (match_operand:HI 3 "memory_operand" "m"))
17765 (clobber (match_scratch:XF 4 "=&1f"))]
17766 "TARGET_USE_FANCY_MATH_387
17767 && flag_unsafe_math_optimizations"
17768 "* return output_fix_trunc (insn, operands, 0);"
17769 [(set_attr "type" "fistp")
17770 (set_attr "i387_cw" "floor")
17771 (set_attr "mode" "DI")])
17773 (define_insn "fistdi2_floor_with_temp"
17774 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17775 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17776 UNSPEC_FIST_FLOOR))
17777 (use (match_operand:HI 2 "memory_operand" "m,m"))
17778 (use (match_operand:HI 3 "memory_operand" "m,m"))
17779 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17780 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17781 "TARGET_USE_FANCY_MATH_387
17782 && flag_unsafe_math_optimizations"
17784 [(set_attr "type" "fistp")
17785 (set_attr "i387_cw" "floor")
17786 (set_attr "mode" "DI")])
17789 [(set (match_operand:DI 0 "register_operand" "")
17790 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17791 UNSPEC_FIST_FLOOR))
17792 (use (match_operand:HI 2 "memory_operand" ""))
17793 (use (match_operand:HI 3 "memory_operand" ""))
17794 (clobber (match_operand:DI 4 "memory_operand" ""))
17795 (clobber (match_scratch 5 ""))]
17797 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17798 (use (match_dup 2))
17799 (use (match_dup 3))
17800 (clobber (match_dup 5))])
17801 (set (match_dup 0) (match_dup 4))]
17805 [(set (match_operand:DI 0 "memory_operand" "")
17806 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17807 UNSPEC_FIST_FLOOR))
17808 (use (match_operand:HI 2 "memory_operand" ""))
17809 (use (match_operand:HI 3 "memory_operand" ""))
17810 (clobber (match_operand:DI 4 "memory_operand" ""))
17811 (clobber (match_scratch 5 ""))]
17813 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17814 (use (match_dup 2))
17815 (use (match_dup 3))
17816 (clobber (match_dup 5))])]
17819 (define_insn "fist<mode>2_floor"
17820 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17821 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17822 UNSPEC_FIST_FLOOR))
17823 (use (match_operand:HI 2 "memory_operand" "m"))
17824 (use (match_operand:HI 3 "memory_operand" "m"))]
17825 "TARGET_USE_FANCY_MATH_387
17826 && flag_unsafe_math_optimizations"
17827 "* return output_fix_trunc (insn, operands, 0);"
17828 [(set_attr "type" "fistp")
17829 (set_attr "i387_cw" "floor")
17830 (set_attr "mode" "<MODE>")])
17832 (define_insn "fist<mode>2_floor_with_temp"
17833 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17834 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17835 UNSPEC_FIST_FLOOR))
17836 (use (match_operand:HI 2 "memory_operand" "m,m"))
17837 (use (match_operand:HI 3 "memory_operand" "m,m"))
17838 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17839 "TARGET_USE_FANCY_MATH_387
17840 && flag_unsafe_math_optimizations"
17842 [(set_attr "type" "fistp")
17843 (set_attr "i387_cw" "floor")
17844 (set_attr "mode" "<MODE>")])
17847 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17848 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17849 UNSPEC_FIST_FLOOR))
17850 (use (match_operand:HI 2 "memory_operand" ""))
17851 (use (match_operand:HI 3 "memory_operand" ""))
17852 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17854 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17855 UNSPEC_FIST_FLOOR))
17856 (use (match_dup 2))
17857 (use (match_dup 3))])
17858 (set (match_dup 0) (match_dup 4))]
17862 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17863 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17864 UNSPEC_FIST_FLOOR))
17865 (use (match_operand:HI 2 "memory_operand" ""))
17866 (use (match_operand:HI 3 "memory_operand" ""))
17867 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17869 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17870 UNSPEC_FIST_FLOOR))
17871 (use (match_dup 2))
17872 (use (match_dup 3))])]
17875 (define_expand "lfloorxf<mode>2"
17876 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17877 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17878 UNSPEC_FIST_FLOOR))
17879 (clobber (reg:CC FLAGS_REG))])]
17880 "TARGET_USE_FANCY_MATH_387
17881 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17882 && flag_unsafe_math_optimizations"
17885 (define_expand "lfloor<mode>di2"
17886 [(match_operand:DI 0 "nonimmediate_operand" "")
17887 (match_operand:MODEF 1 "register_operand" "")]
17888 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17889 && !flag_trapping_math
17892 ix86_expand_lfloorceil (operand0, operand1, true);
17896 (define_expand "lfloor<mode>si2"
17897 [(match_operand:SI 0 "nonimmediate_operand" "")
17898 (match_operand:MODEF 1 "register_operand" "")]
17899 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17900 && !flag_trapping_math
17901 && (!optimize_size || !TARGET_64BIT)"
17903 ix86_expand_lfloorceil (operand0, operand1, true);
17907 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17908 (define_insn_and_split "frndintxf2_ceil"
17909 [(set (match_operand:XF 0 "register_operand" "")
17910 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17911 UNSPEC_FRNDINT_CEIL))
17912 (clobber (reg:CC FLAGS_REG))]
17913 "TARGET_USE_FANCY_MATH_387
17914 && flag_unsafe_math_optimizations
17915 && !(reload_completed || reload_in_progress)"
17920 ix86_optimize_mode_switching[I387_CEIL] = 1;
17922 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17923 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17925 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17926 operands[2], operands[3]));
17929 [(set_attr "type" "frndint")
17930 (set_attr "i387_cw" "ceil")
17931 (set_attr "mode" "XF")])
17933 (define_insn "frndintxf2_ceil_i387"
17934 [(set (match_operand:XF 0 "register_operand" "=f")
17935 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17936 UNSPEC_FRNDINT_CEIL))
17937 (use (match_operand:HI 2 "memory_operand" "m"))
17938 (use (match_operand:HI 3 "memory_operand" "m"))]
17939 "TARGET_USE_FANCY_MATH_387
17940 && flag_unsafe_math_optimizations"
17941 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17942 [(set_attr "type" "frndint")
17943 (set_attr "i387_cw" "ceil")
17944 (set_attr "mode" "XF")])
17946 (define_expand "ceilxf2"
17947 [(use (match_operand:XF 0 "register_operand" ""))
17948 (use (match_operand:XF 1 "register_operand" ""))]
17949 "TARGET_USE_FANCY_MATH_387
17950 && flag_unsafe_math_optimizations && !optimize_size"
17952 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17956 (define_expand "ceil<mode>2"
17957 [(use (match_operand:MODEF 0 "register_operand" ""))
17958 (use (match_operand:MODEF 1 "register_operand" ""))]
17959 "(TARGET_USE_FANCY_MATH_387
17960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17961 || TARGET_MIX_SSE_I387)
17962 && flag_unsafe_math_optimizations && !optimize_size)
17963 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17964 && !flag_trapping_math
17965 && (TARGET_ROUND || !optimize_size))"
17967 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17968 && !flag_trapping_math
17969 && (TARGET_ROUND || !optimize_size))
17972 emit_insn (gen_sse4_1_round<mode>2
17973 (operands[0], operands[1], GEN_INT (0x02)));
17974 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17975 ix86_expand_floorceil (operand0, operand1, false);
17977 ix86_expand_floorceildf_32 (operand0, operand1, false);
17981 rtx op0 = gen_reg_rtx (XFmode);
17982 rtx op1 = gen_reg_rtx (XFmode);
17984 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17985 emit_insn (gen_frndintxf2_ceil (op0, op1));
17987 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17992 (define_insn_and_split "*fist<mode>2_ceil_1"
17993 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17994 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17996 (clobber (reg:CC FLAGS_REG))]
17997 "TARGET_USE_FANCY_MATH_387
17998 && flag_unsafe_math_optimizations
17999 && !(reload_completed || reload_in_progress)"
18004 ix86_optimize_mode_switching[I387_CEIL] = 1;
18006 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18007 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18008 if (memory_operand (operands[0], VOIDmode))
18009 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18010 operands[2], operands[3]));
18013 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18014 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18015 operands[2], operands[3],
18020 [(set_attr "type" "fistp")
18021 (set_attr "i387_cw" "ceil")
18022 (set_attr "mode" "<MODE>")])
18024 (define_insn "fistdi2_ceil"
18025 [(set (match_operand:DI 0 "memory_operand" "=m")
18026 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18028 (use (match_operand:HI 2 "memory_operand" "m"))
18029 (use (match_operand:HI 3 "memory_operand" "m"))
18030 (clobber (match_scratch:XF 4 "=&1f"))]
18031 "TARGET_USE_FANCY_MATH_387
18032 && flag_unsafe_math_optimizations"
18033 "* return output_fix_trunc (insn, operands, 0);"
18034 [(set_attr "type" "fistp")
18035 (set_attr "i387_cw" "ceil")
18036 (set_attr "mode" "DI")])
18038 (define_insn "fistdi2_ceil_with_temp"
18039 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18040 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18042 (use (match_operand:HI 2 "memory_operand" "m,m"))
18043 (use (match_operand:HI 3 "memory_operand" "m,m"))
18044 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18045 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18046 "TARGET_USE_FANCY_MATH_387
18047 && flag_unsafe_math_optimizations"
18049 [(set_attr "type" "fistp")
18050 (set_attr "i387_cw" "ceil")
18051 (set_attr "mode" "DI")])
18054 [(set (match_operand:DI 0 "register_operand" "")
18055 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18057 (use (match_operand:HI 2 "memory_operand" ""))
18058 (use (match_operand:HI 3 "memory_operand" ""))
18059 (clobber (match_operand:DI 4 "memory_operand" ""))
18060 (clobber (match_scratch 5 ""))]
18062 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18063 (use (match_dup 2))
18064 (use (match_dup 3))
18065 (clobber (match_dup 5))])
18066 (set (match_dup 0) (match_dup 4))]
18070 [(set (match_operand:DI 0 "memory_operand" "")
18071 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18073 (use (match_operand:HI 2 "memory_operand" ""))
18074 (use (match_operand:HI 3 "memory_operand" ""))
18075 (clobber (match_operand:DI 4 "memory_operand" ""))
18076 (clobber (match_scratch 5 ""))]
18078 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18079 (use (match_dup 2))
18080 (use (match_dup 3))
18081 (clobber (match_dup 5))])]
18084 (define_insn "fist<mode>2_ceil"
18085 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18086 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18088 (use (match_operand:HI 2 "memory_operand" "m"))
18089 (use (match_operand:HI 3 "memory_operand" "m"))]
18090 "TARGET_USE_FANCY_MATH_387
18091 && flag_unsafe_math_optimizations"
18092 "* return output_fix_trunc (insn, operands, 0);"
18093 [(set_attr "type" "fistp")
18094 (set_attr "i387_cw" "ceil")
18095 (set_attr "mode" "<MODE>")])
18097 (define_insn "fist<mode>2_ceil_with_temp"
18098 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18099 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18101 (use (match_operand:HI 2 "memory_operand" "m,m"))
18102 (use (match_operand:HI 3 "memory_operand" "m,m"))
18103 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18104 "TARGET_USE_FANCY_MATH_387
18105 && flag_unsafe_math_optimizations"
18107 [(set_attr "type" "fistp")
18108 (set_attr "i387_cw" "ceil")
18109 (set_attr "mode" "<MODE>")])
18112 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18113 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18115 (use (match_operand:HI 2 "memory_operand" ""))
18116 (use (match_operand:HI 3 "memory_operand" ""))
18117 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18119 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18121 (use (match_dup 2))
18122 (use (match_dup 3))])
18123 (set (match_dup 0) (match_dup 4))]
18127 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18128 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18130 (use (match_operand:HI 2 "memory_operand" ""))
18131 (use (match_operand:HI 3 "memory_operand" ""))
18132 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18134 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18136 (use (match_dup 2))
18137 (use (match_dup 3))])]
18140 (define_expand "lceilxf<mode>2"
18141 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18142 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18144 (clobber (reg:CC FLAGS_REG))])]
18145 "TARGET_USE_FANCY_MATH_387
18146 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18147 && flag_unsafe_math_optimizations"
18150 (define_expand "lceil<mode>di2"
18151 [(match_operand:DI 0 "nonimmediate_operand" "")
18152 (match_operand:MODEF 1 "register_operand" "")]
18153 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18154 && !flag_trapping_math"
18156 ix86_expand_lfloorceil (operand0, operand1, false);
18160 (define_expand "lceil<mode>si2"
18161 [(match_operand:SI 0 "nonimmediate_operand" "")
18162 (match_operand:MODEF 1 "register_operand" "")]
18163 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18164 && !flag_trapping_math"
18166 ix86_expand_lfloorceil (operand0, operand1, false);
18170 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18171 (define_insn_and_split "frndintxf2_trunc"
18172 [(set (match_operand:XF 0 "register_operand" "")
18173 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18174 UNSPEC_FRNDINT_TRUNC))
18175 (clobber (reg:CC FLAGS_REG))]
18176 "TARGET_USE_FANCY_MATH_387
18177 && flag_unsafe_math_optimizations
18178 && !(reload_completed || reload_in_progress)"
18183 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18185 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18186 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18188 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18189 operands[2], operands[3]));
18192 [(set_attr "type" "frndint")
18193 (set_attr "i387_cw" "trunc")
18194 (set_attr "mode" "XF")])
18196 (define_insn "frndintxf2_trunc_i387"
18197 [(set (match_operand:XF 0 "register_operand" "=f")
18198 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18199 UNSPEC_FRNDINT_TRUNC))
18200 (use (match_operand:HI 2 "memory_operand" "m"))
18201 (use (match_operand:HI 3 "memory_operand" "m"))]
18202 "TARGET_USE_FANCY_MATH_387
18203 && flag_unsafe_math_optimizations"
18204 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18205 [(set_attr "type" "frndint")
18206 (set_attr "i387_cw" "trunc")
18207 (set_attr "mode" "XF")])
18209 (define_expand "btruncxf2"
18210 [(use (match_operand:XF 0 "register_operand" ""))
18211 (use (match_operand:XF 1 "register_operand" ""))]
18212 "TARGET_USE_FANCY_MATH_387
18213 && flag_unsafe_math_optimizations && !optimize_size"
18215 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18219 (define_expand "btrunc<mode>2"
18220 [(use (match_operand:MODEF 0 "register_operand" ""))
18221 (use (match_operand:MODEF 1 "register_operand" ""))]
18222 "(TARGET_USE_FANCY_MATH_387
18223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18224 || TARGET_MIX_SSE_I387)
18225 && flag_unsafe_math_optimizations && !optimize_size)
18226 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18227 && !flag_trapping_math
18228 && (TARGET_ROUND || !optimize_size))"
18230 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18231 && !flag_trapping_math
18232 && (TARGET_ROUND || !optimize_size))
18235 emit_insn (gen_sse4_1_round<mode>2
18236 (operands[0], operands[1], GEN_INT (0x03)));
18237 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18238 ix86_expand_trunc (operand0, operand1);
18240 ix86_expand_truncdf_32 (operand0, operand1);
18244 rtx op0 = gen_reg_rtx (XFmode);
18245 rtx op1 = gen_reg_rtx (XFmode);
18247 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18248 emit_insn (gen_frndintxf2_trunc (op0, op1));
18250 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18255 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18256 (define_insn_and_split "frndintxf2_mask_pm"
18257 [(set (match_operand:XF 0 "register_operand" "")
18258 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18259 UNSPEC_FRNDINT_MASK_PM))
18260 (clobber (reg:CC FLAGS_REG))]
18261 "TARGET_USE_FANCY_MATH_387
18262 && flag_unsafe_math_optimizations
18263 && !(reload_completed || reload_in_progress)"
18268 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18270 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18271 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18273 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18274 operands[2], operands[3]));
18277 [(set_attr "type" "frndint")
18278 (set_attr "i387_cw" "mask_pm")
18279 (set_attr "mode" "XF")])
18281 (define_insn "frndintxf2_mask_pm_i387"
18282 [(set (match_operand:XF 0 "register_operand" "=f")
18283 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18284 UNSPEC_FRNDINT_MASK_PM))
18285 (use (match_operand:HI 2 "memory_operand" "m"))
18286 (use (match_operand:HI 3 "memory_operand" "m"))]
18287 "TARGET_USE_FANCY_MATH_387
18288 && flag_unsafe_math_optimizations"
18289 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18290 [(set_attr "type" "frndint")
18291 (set_attr "i387_cw" "mask_pm")
18292 (set_attr "mode" "XF")])
18294 (define_expand "nearbyintxf2"
18295 [(use (match_operand:XF 0 "register_operand" ""))
18296 (use (match_operand:XF 1 "register_operand" ""))]
18297 "TARGET_USE_FANCY_MATH_387
18298 && flag_unsafe_math_optimizations"
18300 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18305 (define_expand "nearbyint<mode>2"
18306 [(use (match_operand:MODEF 0 "register_operand" ""))
18307 (use (match_operand:MODEF 1 "register_operand" ""))]
18308 "TARGET_USE_FANCY_MATH_387
18309 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18310 || TARGET_MIX_SSE_I387)
18311 && flag_unsafe_math_optimizations"
18313 rtx op0 = gen_reg_rtx (XFmode);
18314 rtx op1 = gen_reg_rtx (XFmode);
18316 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18317 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18319 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18323 (define_insn "fxam<mode>2_i387"
18324 [(set (match_operand:HI 0 "register_operand" "=a")
18326 [(match_operand:X87MODEF 1 "register_operand" "f")]
18328 "TARGET_USE_FANCY_MATH_387"
18329 "fxam\n\tfnstsw\t%0"
18330 [(set_attr "type" "multi")
18331 (set_attr "unit" "i387")
18332 (set_attr "mode" "<MODE>")])
18334 (define_expand "isinf<mode>2"
18335 [(use (match_operand:SI 0 "register_operand" ""))
18336 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18337 "TARGET_USE_FANCY_MATH_387
18338 && TARGET_C99_FUNCTIONS
18339 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18341 rtx mask = GEN_INT (0x45);
18342 rtx val = GEN_INT (0x05);
18346 rtx scratch = gen_reg_rtx (HImode);
18347 rtx res = gen_reg_rtx (QImode);
18349 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18350 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18351 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18352 cond = gen_rtx_fmt_ee (EQ, QImode,
18353 gen_rtx_REG (CCmode, FLAGS_REG),
18355 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18356 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18360 (define_expand "signbit<mode>2"
18361 [(use (match_operand:SI 0 "register_operand" ""))
18362 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18363 "TARGET_USE_FANCY_MATH_387
18364 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18366 rtx mask = GEN_INT (0x0200);
18368 rtx scratch = gen_reg_rtx (HImode);
18370 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18371 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18375 ;; Block operation instructions
18377 (define_expand "movmemsi"
18378 [(use (match_operand:BLK 0 "memory_operand" ""))
18379 (use (match_operand:BLK 1 "memory_operand" ""))
18380 (use (match_operand:SI 2 "nonmemory_operand" ""))
18381 (use (match_operand:SI 3 "const_int_operand" ""))
18382 (use (match_operand:SI 4 "const_int_operand" ""))
18383 (use (match_operand:SI 5 "const_int_operand" ""))]
18386 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18387 operands[4], operands[5]))
18393 (define_expand "movmemdi"
18394 [(use (match_operand:BLK 0 "memory_operand" ""))
18395 (use (match_operand:BLK 1 "memory_operand" ""))
18396 (use (match_operand:DI 2 "nonmemory_operand" ""))
18397 (use (match_operand:DI 3 "const_int_operand" ""))
18398 (use (match_operand:SI 4 "const_int_operand" ""))
18399 (use (match_operand:SI 5 "const_int_operand" ""))]
18402 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18403 operands[4], operands[5]))
18409 ;; Most CPUs don't like single string operations
18410 ;; Handle this case here to simplify previous expander.
18412 (define_expand "strmov"
18413 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18414 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18415 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18416 (clobber (reg:CC FLAGS_REG))])
18417 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18418 (clobber (reg:CC FLAGS_REG))])]
18421 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18423 /* If .md ever supports :P for Pmode, these can be directly
18424 in the pattern above. */
18425 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18426 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18428 /* Can't use this if the user has appropriated esi or edi. */
18429 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18430 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18432 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18433 operands[2], operands[3],
18434 operands[5], operands[6]));
18438 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18441 (define_expand "strmov_singleop"
18442 [(parallel [(set (match_operand 1 "memory_operand" "")
18443 (match_operand 3 "memory_operand" ""))
18444 (set (match_operand 0 "register_operand" "")
18445 (match_operand 4 "" ""))
18446 (set (match_operand 2 "register_operand" "")
18447 (match_operand 5 "" ""))])]
18448 "TARGET_SINGLE_STRINGOP || optimize_size"
18451 (define_insn "*strmovdi_rex_1"
18452 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18453 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18454 (set (match_operand:DI 0 "register_operand" "=D")
18455 (plus:DI (match_dup 2)
18457 (set (match_operand:DI 1 "register_operand" "=S")
18458 (plus:DI (match_dup 3)
18460 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18462 [(set_attr "type" "str")
18463 (set_attr "mode" "DI")
18464 (set_attr "memory" "both")])
18466 (define_insn "*strmovsi_1"
18467 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18468 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18469 (set (match_operand:SI 0 "register_operand" "=D")
18470 (plus:SI (match_dup 2)
18472 (set (match_operand:SI 1 "register_operand" "=S")
18473 (plus:SI (match_dup 3)
18475 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18477 [(set_attr "type" "str")
18478 (set_attr "mode" "SI")
18479 (set_attr "memory" "both")])
18481 (define_insn "*strmovsi_rex_1"
18482 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18483 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18484 (set (match_operand:DI 0 "register_operand" "=D")
18485 (plus:DI (match_dup 2)
18487 (set (match_operand:DI 1 "register_operand" "=S")
18488 (plus:DI (match_dup 3)
18490 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18492 [(set_attr "type" "str")
18493 (set_attr "mode" "SI")
18494 (set_attr "memory" "both")])
18496 (define_insn "*strmovhi_1"
18497 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18498 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18499 (set (match_operand:SI 0 "register_operand" "=D")
18500 (plus:SI (match_dup 2)
18502 (set (match_operand:SI 1 "register_operand" "=S")
18503 (plus:SI (match_dup 3)
18505 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18507 [(set_attr "type" "str")
18508 (set_attr "memory" "both")
18509 (set_attr "mode" "HI")])
18511 (define_insn "*strmovhi_rex_1"
18512 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18513 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18514 (set (match_operand:DI 0 "register_operand" "=D")
18515 (plus:DI (match_dup 2)
18517 (set (match_operand:DI 1 "register_operand" "=S")
18518 (plus:DI (match_dup 3)
18520 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18522 [(set_attr "type" "str")
18523 (set_attr "memory" "both")
18524 (set_attr "mode" "HI")])
18526 (define_insn "*strmovqi_1"
18527 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18528 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18529 (set (match_operand:SI 0 "register_operand" "=D")
18530 (plus:SI (match_dup 2)
18532 (set (match_operand:SI 1 "register_operand" "=S")
18533 (plus:SI (match_dup 3)
18535 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18537 [(set_attr "type" "str")
18538 (set_attr "memory" "both")
18539 (set_attr "mode" "QI")])
18541 (define_insn "*strmovqi_rex_1"
18542 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18543 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18544 (set (match_operand:DI 0 "register_operand" "=D")
18545 (plus:DI (match_dup 2)
18547 (set (match_operand:DI 1 "register_operand" "=S")
18548 (plus:DI (match_dup 3)
18550 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18552 [(set_attr "type" "str")
18553 (set_attr "memory" "both")
18554 (set_attr "mode" "QI")])
18556 (define_expand "rep_mov"
18557 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18558 (set (match_operand 0 "register_operand" "")
18559 (match_operand 5 "" ""))
18560 (set (match_operand 2 "register_operand" "")
18561 (match_operand 6 "" ""))
18562 (set (match_operand 1 "memory_operand" "")
18563 (match_operand 3 "memory_operand" ""))
18564 (use (match_dup 4))])]
18568 (define_insn "*rep_movdi_rex64"
18569 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18570 (set (match_operand:DI 0 "register_operand" "=D")
18571 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18573 (match_operand:DI 3 "register_operand" "0")))
18574 (set (match_operand:DI 1 "register_operand" "=S")
18575 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18576 (match_operand:DI 4 "register_operand" "1")))
18577 (set (mem:BLK (match_dup 3))
18578 (mem:BLK (match_dup 4)))
18579 (use (match_dup 5))]
18582 [(set_attr "type" "str")
18583 (set_attr "prefix_rep" "1")
18584 (set_attr "memory" "both")
18585 (set_attr "mode" "DI")])
18587 (define_insn "*rep_movsi"
18588 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18589 (set (match_operand:SI 0 "register_operand" "=D")
18590 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18592 (match_operand:SI 3 "register_operand" "0")))
18593 (set (match_operand:SI 1 "register_operand" "=S")
18594 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18595 (match_operand:SI 4 "register_operand" "1")))
18596 (set (mem:BLK (match_dup 3))
18597 (mem:BLK (match_dup 4)))
18598 (use (match_dup 5))]
18601 [(set_attr "type" "str")
18602 (set_attr "prefix_rep" "1")
18603 (set_attr "memory" "both")
18604 (set_attr "mode" "SI")])
18606 (define_insn "*rep_movsi_rex64"
18607 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18608 (set (match_operand:DI 0 "register_operand" "=D")
18609 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18611 (match_operand:DI 3 "register_operand" "0")))
18612 (set (match_operand:DI 1 "register_operand" "=S")
18613 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18614 (match_operand:DI 4 "register_operand" "1")))
18615 (set (mem:BLK (match_dup 3))
18616 (mem:BLK (match_dup 4)))
18617 (use (match_dup 5))]
18620 [(set_attr "type" "str")
18621 (set_attr "prefix_rep" "1")
18622 (set_attr "memory" "both")
18623 (set_attr "mode" "SI")])
18625 (define_insn "*rep_movqi"
18626 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18627 (set (match_operand:SI 0 "register_operand" "=D")
18628 (plus:SI (match_operand:SI 3 "register_operand" "0")
18629 (match_operand:SI 5 "register_operand" "2")))
18630 (set (match_operand:SI 1 "register_operand" "=S")
18631 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18632 (set (mem:BLK (match_dup 3))
18633 (mem:BLK (match_dup 4)))
18634 (use (match_dup 5))]
18637 [(set_attr "type" "str")
18638 (set_attr "prefix_rep" "1")
18639 (set_attr "memory" "both")
18640 (set_attr "mode" "SI")])
18642 (define_insn "*rep_movqi_rex64"
18643 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18644 (set (match_operand:DI 0 "register_operand" "=D")
18645 (plus:DI (match_operand:DI 3 "register_operand" "0")
18646 (match_operand:DI 5 "register_operand" "2")))
18647 (set (match_operand:DI 1 "register_operand" "=S")
18648 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18649 (set (mem:BLK (match_dup 3))
18650 (mem:BLK (match_dup 4)))
18651 (use (match_dup 5))]
18654 [(set_attr "type" "str")
18655 (set_attr "prefix_rep" "1")
18656 (set_attr "memory" "both")
18657 (set_attr "mode" "SI")])
18659 (define_expand "setmemsi"
18660 [(use (match_operand:BLK 0 "memory_operand" ""))
18661 (use (match_operand:SI 1 "nonmemory_operand" ""))
18662 (use (match_operand 2 "const_int_operand" ""))
18663 (use (match_operand 3 "const_int_operand" ""))
18664 (use (match_operand:SI 4 "const_int_operand" ""))
18665 (use (match_operand:SI 5 "const_int_operand" ""))]
18668 if (ix86_expand_setmem (operands[0], operands[1],
18669 operands[2], operands[3],
18670 operands[4], operands[5]))
18676 (define_expand "setmemdi"
18677 [(use (match_operand:BLK 0 "memory_operand" ""))
18678 (use (match_operand:DI 1 "nonmemory_operand" ""))
18679 (use (match_operand 2 "const_int_operand" ""))
18680 (use (match_operand 3 "const_int_operand" ""))
18681 (use (match_operand 4 "const_int_operand" ""))
18682 (use (match_operand 5 "const_int_operand" ""))]
18685 if (ix86_expand_setmem (operands[0], operands[1],
18686 operands[2], operands[3],
18687 operands[4], operands[5]))
18693 ;; Most CPUs don't like single string operations
18694 ;; Handle this case here to simplify previous expander.
18696 (define_expand "strset"
18697 [(set (match_operand 1 "memory_operand" "")
18698 (match_operand 2 "register_operand" ""))
18699 (parallel [(set (match_operand 0 "register_operand" "")
18701 (clobber (reg:CC FLAGS_REG))])]
18704 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18705 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18707 /* If .md ever supports :P for Pmode, this can be directly
18708 in the pattern above. */
18709 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18710 GEN_INT (GET_MODE_SIZE (GET_MODE
18712 if (TARGET_SINGLE_STRINGOP || optimize_size)
18714 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18720 (define_expand "strset_singleop"
18721 [(parallel [(set (match_operand 1 "memory_operand" "")
18722 (match_operand 2 "register_operand" ""))
18723 (set (match_operand 0 "register_operand" "")
18724 (match_operand 3 "" ""))])]
18725 "TARGET_SINGLE_STRINGOP || optimize_size"
18728 (define_insn "*strsetdi_rex_1"
18729 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18730 (match_operand:DI 2 "register_operand" "a"))
18731 (set (match_operand:DI 0 "register_operand" "=D")
18732 (plus:DI (match_dup 1)
18734 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18736 [(set_attr "type" "str")
18737 (set_attr "memory" "store")
18738 (set_attr "mode" "DI")])
18740 (define_insn "*strsetsi_1"
18741 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18742 (match_operand:SI 2 "register_operand" "a"))
18743 (set (match_operand:SI 0 "register_operand" "=D")
18744 (plus:SI (match_dup 1)
18746 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18748 [(set_attr "type" "str")
18749 (set_attr "memory" "store")
18750 (set_attr "mode" "SI")])
18752 (define_insn "*strsetsi_rex_1"
18753 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18754 (match_operand:SI 2 "register_operand" "a"))
18755 (set (match_operand:DI 0 "register_operand" "=D")
18756 (plus:DI (match_dup 1)
18758 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18760 [(set_attr "type" "str")
18761 (set_attr "memory" "store")
18762 (set_attr "mode" "SI")])
18764 (define_insn "*strsethi_1"
18765 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18766 (match_operand:HI 2 "register_operand" "a"))
18767 (set (match_operand:SI 0 "register_operand" "=D")
18768 (plus:SI (match_dup 1)
18770 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18772 [(set_attr "type" "str")
18773 (set_attr "memory" "store")
18774 (set_attr "mode" "HI")])
18776 (define_insn "*strsethi_rex_1"
18777 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18778 (match_operand:HI 2 "register_operand" "a"))
18779 (set (match_operand:DI 0 "register_operand" "=D")
18780 (plus:DI (match_dup 1)
18782 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18784 [(set_attr "type" "str")
18785 (set_attr "memory" "store")
18786 (set_attr "mode" "HI")])
18788 (define_insn "*strsetqi_1"
18789 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18790 (match_operand:QI 2 "register_operand" "a"))
18791 (set (match_operand:SI 0 "register_operand" "=D")
18792 (plus:SI (match_dup 1)
18794 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18796 [(set_attr "type" "str")
18797 (set_attr "memory" "store")
18798 (set_attr "mode" "QI")])
18800 (define_insn "*strsetqi_rex_1"
18801 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18802 (match_operand:QI 2 "register_operand" "a"))
18803 (set (match_operand:DI 0 "register_operand" "=D")
18804 (plus:DI (match_dup 1)
18806 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18808 [(set_attr "type" "str")
18809 (set_attr "memory" "store")
18810 (set_attr "mode" "QI")])
18812 (define_expand "rep_stos"
18813 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18814 (set (match_operand 0 "register_operand" "")
18815 (match_operand 4 "" ""))
18816 (set (match_operand 2 "memory_operand" "") (const_int 0))
18817 (use (match_operand 3 "register_operand" ""))
18818 (use (match_dup 1))])]
18822 (define_insn "*rep_stosdi_rex64"
18823 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18824 (set (match_operand:DI 0 "register_operand" "=D")
18825 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18827 (match_operand:DI 3 "register_operand" "0")))
18828 (set (mem:BLK (match_dup 3))
18830 (use (match_operand:DI 2 "register_operand" "a"))
18831 (use (match_dup 4))]
18834 [(set_attr "type" "str")
18835 (set_attr "prefix_rep" "1")
18836 (set_attr "memory" "store")
18837 (set_attr "mode" "DI")])
18839 (define_insn "*rep_stossi"
18840 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18841 (set (match_operand:SI 0 "register_operand" "=D")
18842 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18844 (match_operand:SI 3 "register_operand" "0")))
18845 (set (mem:BLK (match_dup 3))
18847 (use (match_operand:SI 2 "register_operand" "a"))
18848 (use (match_dup 4))]
18851 [(set_attr "type" "str")
18852 (set_attr "prefix_rep" "1")
18853 (set_attr "memory" "store")
18854 (set_attr "mode" "SI")])
18856 (define_insn "*rep_stossi_rex64"
18857 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18858 (set (match_operand:DI 0 "register_operand" "=D")
18859 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18861 (match_operand:DI 3 "register_operand" "0")))
18862 (set (mem:BLK (match_dup 3))
18864 (use (match_operand:SI 2 "register_operand" "a"))
18865 (use (match_dup 4))]
18868 [(set_attr "type" "str")
18869 (set_attr "prefix_rep" "1")
18870 (set_attr "memory" "store")
18871 (set_attr "mode" "SI")])
18873 (define_insn "*rep_stosqi"
18874 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18875 (set (match_operand:SI 0 "register_operand" "=D")
18876 (plus:SI (match_operand:SI 3 "register_operand" "0")
18877 (match_operand:SI 4 "register_operand" "1")))
18878 (set (mem:BLK (match_dup 3))
18880 (use (match_operand:QI 2 "register_operand" "a"))
18881 (use (match_dup 4))]
18884 [(set_attr "type" "str")
18885 (set_attr "prefix_rep" "1")
18886 (set_attr "memory" "store")
18887 (set_attr "mode" "QI")])
18889 (define_insn "*rep_stosqi_rex64"
18890 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18891 (set (match_operand:DI 0 "register_operand" "=D")
18892 (plus:DI (match_operand:DI 3 "register_operand" "0")
18893 (match_operand:DI 4 "register_operand" "1")))
18894 (set (mem:BLK (match_dup 3))
18896 (use (match_operand:QI 2 "register_operand" "a"))
18897 (use (match_dup 4))]
18900 [(set_attr "type" "str")
18901 (set_attr "prefix_rep" "1")
18902 (set_attr "memory" "store")
18903 (set_attr "mode" "QI")])
18905 (define_expand "cmpstrnsi"
18906 [(set (match_operand:SI 0 "register_operand" "")
18907 (compare:SI (match_operand:BLK 1 "general_operand" "")
18908 (match_operand:BLK 2 "general_operand" "")))
18909 (use (match_operand 3 "general_operand" ""))
18910 (use (match_operand 4 "immediate_operand" ""))]
18911 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18913 rtx addr1, addr2, out, outlow, count, countreg, align;
18915 /* Can't use this if the user has appropriated esi or edi. */
18916 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18921 out = gen_reg_rtx (SImode);
18923 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18924 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18925 if (addr1 != XEXP (operands[1], 0))
18926 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18927 if (addr2 != XEXP (operands[2], 0))
18928 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18930 count = operands[3];
18931 countreg = ix86_zero_extend_to_Pmode (count);
18933 /* %%% Iff we are testing strict equality, we can use known alignment
18934 to good advantage. This may be possible with combine, particularly
18935 once cc0 is dead. */
18936 align = operands[4];
18938 if (CONST_INT_P (count))
18940 if (INTVAL (count) == 0)
18942 emit_move_insn (operands[0], const0_rtx);
18945 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18946 operands[1], operands[2]));
18951 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18953 emit_insn (gen_cmpsi_1 (countreg, countreg));
18954 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18955 operands[1], operands[2]));
18958 outlow = gen_lowpart (QImode, out);
18959 emit_insn (gen_cmpintqi (outlow));
18960 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18962 if (operands[0] != out)
18963 emit_move_insn (operands[0], out);
18968 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18970 (define_expand "cmpintqi"
18971 [(set (match_dup 1)
18972 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18974 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18975 (parallel [(set (match_operand:QI 0 "register_operand" "")
18976 (minus:QI (match_dup 1)
18978 (clobber (reg:CC FLAGS_REG))])]
18980 "operands[1] = gen_reg_rtx (QImode);
18981 operands[2] = gen_reg_rtx (QImode);")
18983 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18984 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18986 (define_expand "cmpstrnqi_nz_1"
18987 [(parallel [(set (reg:CC FLAGS_REG)
18988 (compare:CC (match_operand 4 "memory_operand" "")
18989 (match_operand 5 "memory_operand" "")))
18990 (use (match_operand 2 "register_operand" ""))
18991 (use (match_operand:SI 3 "immediate_operand" ""))
18992 (clobber (match_operand 0 "register_operand" ""))
18993 (clobber (match_operand 1 "register_operand" ""))
18994 (clobber (match_dup 2))])]
18998 (define_insn "*cmpstrnqi_nz_1"
18999 [(set (reg:CC FLAGS_REG)
19000 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19001 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19002 (use (match_operand:SI 6 "register_operand" "2"))
19003 (use (match_operand:SI 3 "immediate_operand" "i"))
19004 (clobber (match_operand:SI 0 "register_operand" "=S"))
19005 (clobber (match_operand:SI 1 "register_operand" "=D"))
19006 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19009 [(set_attr "type" "str")
19010 (set_attr "mode" "QI")
19011 (set_attr "prefix_rep" "1")])
19013 (define_insn "*cmpstrnqi_nz_rex_1"
19014 [(set (reg:CC FLAGS_REG)
19015 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19016 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19017 (use (match_operand:DI 6 "register_operand" "2"))
19018 (use (match_operand:SI 3 "immediate_operand" "i"))
19019 (clobber (match_operand:DI 0 "register_operand" "=S"))
19020 (clobber (match_operand:DI 1 "register_operand" "=D"))
19021 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19024 [(set_attr "type" "str")
19025 (set_attr "mode" "QI")
19026 (set_attr "prefix_rep" "1")])
19028 ;; The same, but the count is not known to not be zero.
19030 (define_expand "cmpstrnqi_1"
19031 [(parallel [(set (reg:CC FLAGS_REG)
19032 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19034 (compare:CC (match_operand 4 "memory_operand" "")
19035 (match_operand 5 "memory_operand" ""))
19037 (use (match_operand:SI 3 "immediate_operand" ""))
19038 (use (reg:CC FLAGS_REG))
19039 (clobber (match_operand 0 "register_operand" ""))
19040 (clobber (match_operand 1 "register_operand" ""))
19041 (clobber (match_dup 2))])]
19045 (define_insn "*cmpstrnqi_1"
19046 [(set (reg:CC FLAGS_REG)
19047 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19049 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19050 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19052 (use (match_operand:SI 3 "immediate_operand" "i"))
19053 (use (reg:CC FLAGS_REG))
19054 (clobber (match_operand:SI 0 "register_operand" "=S"))
19055 (clobber (match_operand:SI 1 "register_operand" "=D"))
19056 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19059 [(set_attr "type" "str")
19060 (set_attr "mode" "QI")
19061 (set_attr "prefix_rep" "1")])
19063 (define_insn "*cmpstrnqi_rex_1"
19064 [(set (reg:CC FLAGS_REG)
19065 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19067 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19068 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19070 (use (match_operand:SI 3 "immediate_operand" "i"))
19071 (use (reg:CC FLAGS_REG))
19072 (clobber (match_operand:DI 0 "register_operand" "=S"))
19073 (clobber (match_operand:DI 1 "register_operand" "=D"))
19074 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19077 [(set_attr "type" "str")
19078 (set_attr "mode" "QI")
19079 (set_attr "prefix_rep" "1")])
19081 (define_expand "strlensi"
19082 [(set (match_operand:SI 0 "register_operand" "")
19083 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19084 (match_operand:QI 2 "immediate_operand" "")
19085 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19088 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19094 (define_expand "strlendi"
19095 [(set (match_operand:DI 0 "register_operand" "")
19096 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19097 (match_operand:QI 2 "immediate_operand" "")
19098 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19101 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19107 (define_expand "strlenqi_1"
19108 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19109 (clobber (match_operand 1 "register_operand" ""))
19110 (clobber (reg:CC FLAGS_REG))])]
19114 (define_insn "*strlenqi_1"
19115 [(set (match_operand:SI 0 "register_operand" "=&c")
19116 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19117 (match_operand:QI 2 "register_operand" "a")
19118 (match_operand:SI 3 "immediate_operand" "i")
19119 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19120 (clobber (match_operand:SI 1 "register_operand" "=D"))
19121 (clobber (reg:CC FLAGS_REG))]
19124 [(set_attr "type" "str")
19125 (set_attr "mode" "QI")
19126 (set_attr "prefix_rep" "1")])
19128 (define_insn "*strlenqi_rex_1"
19129 [(set (match_operand:DI 0 "register_operand" "=&c")
19130 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19131 (match_operand:QI 2 "register_operand" "a")
19132 (match_operand:DI 3 "immediate_operand" "i")
19133 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19134 (clobber (match_operand:DI 1 "register_operand" "=D"))
19135 (clobber (reg:CC FLAGS_REG))]
19138 [(set_attr "type" "str")
19139 (set_attr "mode" "QI")
19140 (set_attr "prefix_rep" "1")])
19142 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19143 ;; handled in combine, but it is not currently up to the task.
19144 ;; When used for their truth value, the cmpstrn* expanders generate
19153 ;; The intermediate three instructions are unnecessary.
19155 ;; This one handles cmpstrn*_nz_1...
19158 (set (reg:CC FLAGS_REG)
19159 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19160 (mem:BLK (match_operand 5 "register_operand" ""))))
19161 (use (match_operand 6 "register_operand" ""))
19162 (use (match_operand:SI 3 "immediate_operand" ""))
19163 (clobber (match_operand 0 "register_operand" ""))
19164 (clobber (match_operand 1 "register_operand" ""))
19165 (clobber (match_operand 2 "register_operand" ""))])
19166 (set (match_operand:QI 7 "register_operand" "")
19167 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19168 (set (match_operand:QI 8 "register_operand" "")
19169 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19170 (set (reg FLAGS_REG)
19171 (compare (match_dup 7) (match_dup 8)))
19173 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19175 (set (reg:CC FLAGS_REG)
19176 (compare:CC (mem:BLK (match_dup 4))
19177 (mem:BLK (match_dup 5))))
19178 (use (match_dup 6))
19179 (use (match_dup 3))
19180 (clobber (match_dup 0))
19181 (clobber (match_dup 1))
19182 (clobber (match_dup 2))])]
19185 ;; ...and this one handles cmpstrn*_1.
19188 (set (reg:CC FLAGS_REG)
19189 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19191 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19192 (mem:BLK (match_operand 5 "register_operand" "")))
19194 (use (match_operand:SI 3 "immediate_operand" ""))
19195 (use (reg:CC FLAGS_REG))
19196 (clobber (match_operand 0 "register_operand" ""))
19197 (clobber (match_operand 1 "register_operand" ""))
19198 (clobber (match_operand 2 "register_operand" ""))])
19199 (set (match_operand:QI 7 "register_operand" "")
19200 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19201 (set (match_operand:QI 8 "register_operand" "")
19202 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19203 (set (reg FLAGS_REG)
19204 (compare (match_dup 7) (match_dup 8)))
19206 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19208 (set (reg:CC FLAGS_REG)
19209 (if_then_else:CC (ne (match_dup 6)
19211 (compare:CC (mem:BLK (match_dup 4))
19212 (mem:BLK (match_dup 5)))
19214 (use (match_dup 3))
19215 (use (reg:CC FLAGS_REG))
19216 (clobber (match_dup 0))
19217 (clobber (match_dup 1))
19218 (clobber (match_dup 2))])]
19223 ;; Conditional move instructions.
19225 (define_expand "movdicc"
19226 [(set (match_operand:DI 0 "register_operand" "")
19227 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19228 (match_operand:DI 2 "general_operand" "")
19229 (match_operand:DI 3 "general_operand" "")))]
19231 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19233 (define_insn "x86_movdicc_0_m1_rex64"
19234 [(set (match_operand:DI 0 "register_operand" "=r")
19235 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19238 (clobber (reg:CC FLAGS_REG))]
19241 ; Since we don't have the proper number of operands for an alu insn,
19242 ; fill in all the blanks.
19243 [(set_attr "type" "alu")
19244 (set_attr "pent_pair" "pu")
19245 (set_attr "memory" "none")
19246 (set_attr "imm_disp" "false")
19247 (set_attr "mode" "DI")
19248 (set_attr "length_immediate" "0")])
19250 (define_insn "*x86_movdicc_0_m1_se"
19251 [(set (match_operand:DI 0 "register_operand" "=r")
19252 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19255 (clobber (reg:CC FLAGS_REG))]
19258 [(set_attr "type" "alu")
19259 (set_attr "pent_pair" "pu")
19260 (set_attr "memory" "none")
19261 (set_attr "imm_disp" "false")
19262 (set_attr "mode" "DI")
19263 (set_attr "length_immediate" "0")])
19265 (define_insn "*movdicc_c_rex64"
19266 [(set (match_operand:DI 0 "register_operand" "=r,r")
19267 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19268 [(reg FLAGS_REG) (const_int 0)])
19269 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19270 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19271 "TARGET_64BIT && TARGET_CMOVE
19272 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19274 cmov%O2%C1\t{%2, %0|%0, %2}
19275 cmov%O2%c1\t{%3, %0|%0, %3}"
19276 [(set_attr "type" "icmov")
19277 (set_attr "mode" "DI")])
19279 (define_expand "movsicc"
19280 [(set (match_operand:SI 0 "register_operand" "")
19281 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19282 (match_operand:SI 2 "general_operand" "")
19283 (match_operand:SI 3 "general_operand" "")))]
19285 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19287 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19288 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19289 ;; So just document what we're doing explicitly.
19291 (define_insn "x86_movsicc_0_m1"
19292 [(set (match_operand:SI 0 "register_operand" "=r")
19293 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19296 (clobber (reg:CC FLAGS_REG))]
19299 ; Since we don't have the proper number of operands for an alu insn,
19300 ; fill in all the blanks.
19301 [(set_attr "type" "alu")
19302 (set_attr "pent_pair" "pu")
19303 (set_attr "memory" "none")
19304 (set_attr "imm_disp" "false")
19305 (set_attr "mode" "SI")
19306 (set_attr "length_immediate" "0")])
19308 (define_insn "*x86_movsicc_0_m1_se"
19309 [(set (match_operand:SI 0 "register_operand" "=r")
19310 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19313 (clobber (reg:CC FLAGS_REG))]
19316 [(set_attr "type" "alu")
19317 (set_attr "pent_pair" "pu")
19318 (set_attr "memory" "none")
19319 (set_attr "imm_disp" "false")
19320 (set_attr "mode" "SI")
19321 (set_attr "length_immediate" "0")])
19323 (define_insn "*movsicc_noc"
19324 [(set (match_operand:SI 0 "register_operand" "=r,r")
19325 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19326 [(reg FLAGS_REG) (const_int 0)])
19327 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19328 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19330 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19332 cmov%O2%C1\t{%2, %0|%0, %2}
19333 cmov%O2%c1\t{%3, %0|%0, %3}"
19334 [(set_attr "type" "icmov")
19335 (set_attr "mode" "SI")])
19337 (define_expand "movhicc"
19338 [(set (match_operand:HI 0 "register_operand" "")
19339 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19340 (match_operand:HI 2 "general_operand" "")
19341 (match_operand:HI 3 "general_operand" "")))]
19342 "TARGET_HIMODE_MATH"
19343 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19345 (define_insn "*movhicc_noc"
19346 [(set (match_operand:HI 0 "register_operand" "=r,r")
19347 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19348 [(reg FLAGS_REG) (const_int 0)])
19349 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19350 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19352 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19354 cmov%O2%C1\t{%2, %0|%0, %2}
19355 cmov%O2%c1\t{%3, %0|%0, %3}"
19356 [(set_attr "type" "icmov")
19357 (set_attr "mode" "HI")])
19359 (define_expand "movqicc"
19360 [(set (match_operand:QI 0 "register_operand" "")
19361 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19362 (match_operand:QI 2 "general_operand" "")
19363 (match_operand:QI 3 "general_operand" "")))]
19364 "TARGET_QIMODE_MATH"
19365 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19367 (define_insn_and_split "*movqicc_noc"
19368 [(set (match_operand:QI 0 "register_operand" "=r,r")
19369 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19370 [(match_operand 4 "flags_reg_operand" "")
19372 (match_operand:QI 2 "register_operand" "r,0")
19373 (match_operand:QI 3 "register_operand" "0,r")))]
19374 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19376 "&& reload_completed"
19377 [(set (match_dup 0)
19378 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19381 "operands[0] = gen_lowpart (SImode, operands[0]);
19382 operands[2] = gen_lowpart (SImode, operands[2]);
19383 operands[3] = gen_lowpart (SImode, operands[3]);"
19384 [(set_attr "type" "icmov")
19385 (set_attr "mode" "SI")])
19387 (define_expand "mov<mode>cc"
19388 [(set (match_operand:X87MODEF 0 "register_operand" "")
19389 (if_then_else:X87MODEF
19390 (match_operand 1 "comparison_operator" "")
19391 (match_operand:X87MODEF 2 "register_operand" "")
19392 (match_operand:X87MODEF 3 "register_operand" "")))]
19393 "(TARGET_80387 && TARGET_CMOVE)
19394 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19395 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19397 (define_insn "*movsfcc_1_387"
19398 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19399 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19400 [(reg FLAGS_REG) (const_int 0)])
19401 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19402 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19403 "TARGET_80387 && TARGET_CMOVE
19404 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19406 fcmov%F1\t{%2, %0|%0, %2}
19407 fcmov%f1\t{%3, %0|%0, %3}
19408 cmov%O2%C1\t{%2, %0|%0, %2}
19409 cmov%O2%c1\t{%3, %0|%0, %3}"
19410 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19411 (set_attr "mode" "SF,SF,SI,SI")])
19413 (define_insn "*movdfcc_1"
19414 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19415 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19416 [(reg FLAGS_REG) (const_int 0)])
19417 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19418 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19419 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19420 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19422 fcmov%F1\t{%2, %0|%0, %2}
19423 fcmov%f1\t{%3, %0|%0, %3}
19426 [(set_attr "type" "fcmov,fcmov,multi,multi")
19427 (set_attr "mode" "DF")])
19429 (define_insn "*movdfcc_1_rex64"
19430 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19431 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19432 [(reg FLAGS_REG) (const_int 0)])
19433 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19434 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19435 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19436 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19438 fcmov%F1\t{%2, %0|%0, %2}
19439 fcmov%f1\t{%3, %0|%0, %3}
19440 cmov%O2%C1\t{%2, %0|%0, %2}
19441 cmov%O2%c1\t{%3, %0|%0, %3}"
19442 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19443 (set_attr "mode" "DF")])
19446 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19447 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19448 [(match_operand 4 "flags_reg_operand" "")
19450 (match_operand:DF 2 "nonimmediate_operand" "")
19451 (match_operand:DF 3 "nonimmediate_operand" "")))]
19452 "!TARGET_64BIT && reload_completed"
19453 [(set (match_dup 2)
19454 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19458 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19461 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19462 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19464 (define_insn "*movxfcc_1"
19465 [(set (match_operand:XF 0 "register_operand" "=f,f")
19466 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19467 [(reg FLAGS_REG) (const_int 0)])
19468 (match_operand:XF 2 "register_operand" "f,0")
19469 (match_operand:XF 3 "register_operand" "0,f")))]
19470 "TARGET_80387 && TARGET_CMOVE"
19472 fcmov%F1\t{%2, %0|%0, %2}
19473 fcmov%f1\t{%3, %0|%0, %3}"
19474 [(set_attr "type" "fcmov")
19475 (set_attr "mode" "XF")])
19477 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19478 ;; the scalar versions to have only XMM registers as operands.
19480 ;; SSE5 conditional move
19481 (define_insn "*sse5_pcmov_<mode>"
19482 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19483 (if_then_else:MODEF
19484 (match_operand:MODEF 1 "register_operand" "x,0")
19485 (match_operand:MODEF 2 "register_operand" "0,x")
19486 (match_operand:MODEF 3 "register_operand" "x,x")))]
19487 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19488 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19489 [(set_attr "type" "sse4arg")])
19491 ;; These versions of the min/max patterns are intentionally ignorant of
19492 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19493 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19494 ;; are undefined in this condition, we're certain this is correct.
19496 (define_insn "<code><mode>3"
19497 [(set (match_operand:MODEF 0 "register_operand" "=x")
19499 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19500 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19501 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19502 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19503 [(set_attr "type" "sseadd")
19504 (set_attr "mode" "<MODE>")])
19506 ;; These versions of the min/max patterns implement exactly the operations
19507 ;; min = (op1 < op2 ? op1 : op2)
19508 ;; max = (!(op1 < op2) ? op1 : op2)
19509 ;; Their operands are not commutative, and thus they may be used in the
19510 ;; presence of -0.0 and NaN.
19512 (define_insn "*ieee_smin<mode>3"
19513 [(set (match_operand:MODEF 0 "register_operand" "=x")
19515 [(match_operand:MODEF 1 "register_operand" "0")
19516 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19518 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19519 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19520 [(set_attr "type" "sseadd")
19521 (set_attr "mode" "<MODE>")])
19523 (define_insn "*ieee_smax<mode>3"
19524 [(set (match_operand:MODEF 0 "register_operand" "=x")
19526 [(match_operand:MODEF 1 "register_operand" "0")
19527 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19529 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19530 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19531 [(set_attr "type" "sseadd")
19532 (set_attr "mode" "<MODE>")])
19534 ;; Make two stack loads independent:
19536 ;; fld %st(0) -> fld bb
19537 ;; fmul bb fmul %st(1), %st
19539 ;; Actually we only match the last two instructions for simplicity.
19541 [(set (match_operand 0 "fp_register_operand" "")
19542 (match_operand 1 "fp_register_operand" ""))
19544 (match_operator 2 "binary_fp_operator"
19546 (match_operand 3 "memory_operand" "")]))]
19547 "REGNO (operands[0]) != REGNO (operands[1])"
19548 [(set (match_dup 0) (match_dup 3))
19549 (set (match_dup 0) (match_dup 4))]
19551 ;; The % modifier is not operational anymore in peephole2's, so we have to
19552 ;; swap the operands manually in the case of addition and multiplication.
19553 "if (COMMUTATIVE_ARITH_P (operands[2]))
19554 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19555 operands[0], operands[1]);
19557 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19558 operands[1], operands[0]);")
19560 ;; Conditional addition patterns
19561 (define_expand "add<mode>cc"
19562 [(match_operand:SWI 0 "register_operand" "")
19563 (match_operand 1 "comparison_operator" "")
19564 (match_operand:SWI 2 "register_operand" "")
19565 (match_operand:SWI 3 "const_int_operand" "")]
19567 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19570 ;; Misc patterns (?)
19572 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19573 ;; Otherwise there will be nothing to keep
19575 ;; [(set (reg ebp) (reg esp))]
19576 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19577 ;; (clobber (eflags)]
19578 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19580 ;; in proper program order.
19581 (define_insn "pro_epilogue_adjust_stack_1"
19582 [(set (match_operand:SI 0 "register_operand" "=r,r")
19583 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19584 (match_operand:SI 2 "immediate_operand" "i,i")))
19585 (clobber (reg:CC FLAGS_REG))
19586 (clobber (mem:BLK (scratch)))]
19589 switch (get_attr_type (insn))
19592 return "mov{l}\t{%1, %0|%0, %1}";
19595 if (CONST_INT_P (operands[2])
19596 && (INTVAL (operands[2]) == 128
19597 || (INTVAL (operands[2]) < 0
19598 && INTVAL (operands[2]) != -128)))
19600 operands[2] = GEN_INT (-INTVAL (operands[2]));
19601 return "sub{l}\t{%2, %0|%0, %2}";
19603 return "add{l}\t{%2, %0|%0, %2}";
19606 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19607 return "lea{l}\t{%a2, %0|%0, %a2}";
19610 gcc_unreachable ();
19613 [(set (attr "type")
19614 (cond [(eq_attr "alternative" "0")
19615 (const_string "alu")
19616 (match_operand:SI 2 "const0_operand" "")
19617 (const_string "imov")
19619 (const_string "lea")))
19620 (set_attr "mode" "SI")])
19622 (define_insn "pro_epilogue_adjust_stack_rex64"
19623 [(set (match_operand:DI 0 "register_operand" "=r,r")
19624 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19625 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19626 (clobber (reg:CC FLAGS_REG))
19627 (clobber (mem:BLK (scratch)))]
19630 switch (get_attr_type (insn))
19633 return "mov{q}\t{%1, %0|%0, %1}";
19636 if (CONST_INT_P (operands[2])
19637 /* Avoid overflows. */
19638 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19639 && (INTVAL (operands[2]) == 128
19640 || (INTVAL (operands[2]) < 0
19641 && INTVAL (operands[2]) != -128)))
19643 operands[2] = GEN_INT (-INTVAL (operands[2]));
19644 return "sub{q}\t{%2, %0|%0, %2}";
19646 return "add{q}\t{%2, %0|%0, %2}";
19649 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19650 return "lea{q}\t{%a2, %0|%0, %a2}";
19653 gcc_unreachable ();
19656 [(set (attr "type")
19657 (cond [(eq_attr "alternative" "0")
19658 (const_string "alu")
19659 (match_operand:DI 2 "const0_operand" "")
19660 (const_string "imov")
19662 (const_string "lea")))
19663 (set_attr "mode" "DI")])
19665 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19666 [(set (match_operand:DI 0 "register_operand" "=r,r")
19667 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19668 (match_operand:DI 3 "immediate_operand" "i,i")))
19669 (use (match_operand:DI 2 "register_operand" "r,r"))
19670 (clobber (reg:CC FLAGS_REG))
19671 (clobber (mem:BLK (scratch)))]
19674 switch (get_attr_type (insn))
19677 return "add{q}\t{%2, %0|%0, %2}";
19680 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19681 return "lea{q}\t{%a2, %0|%0, %a2}";
19684 gcc_unreachable ();
19687 [(set_attr "type" "alu,lea")
19688 (set_attr "mode" "DI")])
19690 (define_insn "allocate_stack_worker_32"
19691 [(set (match_operand:SI 0 "register_operand" "+a")
19692 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19693 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19694 (clobber (reg:CC FLAGS_REG))]
19695 "!TARGET_64BIT && TARGET_STACK_PROBE"
19697 [(set_attr "type" "multi")
19698 (set_attr "length" "5")])
19700 (define_insn "allocate_stack_worker_64"
19701 [(set (match_operand:DI 0 "register_operand" "=a")
19702 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19703 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19704 (clobber (reg:DI R10_REG))
19705 (clobber (reg:DI R11_REG))
19706 (clobber (reg:CC FLAGS_REG))]
19707 "TARGET_64BIT && TARGET_STACK_PROBE"
19709 [(set_attr "type" "multi")
19710 (set_attr "length" "5")])
19712 (define_expand "allocate_stack"
19713 [(match_operand 0 "register_operand" "")
19714 (match_operand 1 "general_operand" "")]
19715 "TARGET_STACK_PROBE"
19719 #ifndef CHECK_STACK_LIMIT
19720 #define CHECK_STACK_LIMIT 0
19723 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19724 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19726 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19727 stack_pointer_rtx, 0, OPTAB_DIRECT);
19728 if (x != stack_pointer_rtx)
19729 emit_move_insn (stack_pointer_rtx, x);
19733 x = copy_to_mode_reg (Pmode, operands[1]);
19735 x = gen_allocate_stack_worker_64 (x);
19737 x = gen_allocate_stack_worker_32 (x);
19741 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19745 (define_expand "builtin_setjmp_receiver"
19746 [(label_ref (match_operand 0 "" ""))]
19747 "!TARGET_64BIT && flag_pic"
19752 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19753 rtx label_rtx = gen_label_rtx ();
19754 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19755 xops[0] = xops[1] = picreg;
19756 xops[2] = gen_rtx_CONST (SImode,
19757 gen_rtx_MINUS (SImode,
19758 gen_rtx_LABEL_REF (SImode, label_rtx),
19759 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19760 ix86_expand_binary_operator (MINUS, SImode, xops);
19763 emit_insn (gen_set_got (pic_offset_table_rtx));
19767 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19770 [(set (match_operand 0 "register_operand" "")
19771 (match_operator 3 "promotable_binary_operator"
19772 [(match_operand 1 "register_operand" "")
19773 (match_operand 2 "aligned_operand" "")]))
19774 (clobber (reg:CC FLAGS_REG))]
19775 "! TARGET_PARTIAL_REG_STALL && reload_completed
19776 && ((GET_MODE (operands[0]) == HImode
19777 && ((!optimize_size && !TARGET_FAST_PREFIX)
19778 /* ??? next two lines just !satisfies_constraint_K (...) */
19779 || !CONST_INT_P (operands[2])
19780 || satisfies_constraint_K (operands[2])))
19781 || (GET_MODE (operands[0]) == QImode
19782 && (TARGET_PROMOTE_QImode || optimize_size)))"
19783 [(parallel [(set (match_dup 0)
19784 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19785 (clobber (reg:CC FLAGS_REG))])]
19786 "operands[0] = gen_lowpart (SImode, operands[0]);
19787 operands[1] = gen_lowpart (SImode, operands[1]);
19788 if (GET_CODE (operands[3]) != ASHIFT)
19789 operands[2] = gen_lowpart (SImode, operands[2]);
19790 PUT_MODE (operands[3], SImode);")
19792 ; Promote the QImode tests, as i386 has encoding of the AND
19793 ; instruction with 32-bit sign-extended immediate and thus the
19794 ; instruction size is unchanged, except in the %eax case for
19795 ; which it is increased by one byte, hence the ! optimize_size.
19797 [(set (match_operand 0 "flags_reg_operand" "")
19798 (match_operator 2 "compare_operator"
19799 [(and (match_operand 3 "aligned_operand" "")
19800 (match_operand 4 "const_int_operand" ""))
19802 (set (match_operand 1 "register_operand" "")
19803 (and (match_dup 3) (match_dup 4)))]
19804 "! TARGET_PARTIAL_REG_STALL && reload_completed
19806 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19807 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19808 /* Ensure that the operand will remain sign-extended immediate. */
19809 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19810 [(parallel [(set (match_dup 0)
19811 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19814 (and:SI (match_dup 3) (match_dup 4)))])]
19817 = gen_int_mode (INTVAL (operands[4])
19818 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19819 operands[1] = gen_lowpart (SImode, operands[1]);
19820 operands[3] = gen_lowpart (SImode, operands[3]);
19823 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19824 ; the TEST instruction with 32-bit sign-extended immediate and thus
19825 ; the instruction size would at least double, which is not what we
19826 ; want even with ! optimize_size.
19828 [(set (match_operand 0 "flags_reg_operand" "")
19829 (match_operator 1 "compare_operator"
19830 [(and (match_operand:HI 2 "aligned_operand" "")
19831 (match_operand:HI 3 "const_int_operand" ""))
19833 "! TARGET_PARTIAL_REG_STALL && reload_completed
19834 && ! TARGET_FAST_PREFIX
19836 /* Ensure that the operand will remain sign-extended immediate. */
19837 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19838 [(set (match_dup 0)
19839 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19843 = gen_int_mode (INTVAL (operands[3])
19844 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19845 operands[2] = gen_lowpart (SImode, operands[2]);
19849 [(set (match_operand 0 "register_operand" "")
19850 (neg (match_operand 1 "register_operand" "")))
19851 (clobber (reg:CC FLAGS_REG))]
19852 "! TARGET_PARTIAL_REG_STALL && reload_completed
19853 && (GET_MODE (operands[0]) == HImode
19854 || (GET_MODE (operands[0]) == QImode
19855 && (TARGET_PROMOTE_QImode || optimize_size)))"
19856 [(parallel [(set (match_dup 0)
19857 (neg:SI (match_dup 1)))
19858 (clobber (reg:CC FLAGS_REG))])]
19859 "operands[0] = gen_lowpart (SImode, operands[0]);
19860 operands[1] = gen_lowpart (SImode, operands[1]);")
19863 [(set (match_operand 0 "register_operand" "")
19864 (not (match_operand 1 "register_operand" "")))]
19865 "! TARGET_PARTIAL_REG_STALL && reload_completed
19866 && (GET_MODE (operands[0]) == HImode
19867 || (GET_MODE (operands[0]) == QImode
19868 && (TARGET_PROMOTE_QImode || optimize_size)))"
19869 [(set (match_dup 0)
19870 (not:SI (match_dup 1)))]
19871 "operands[0] = gen_lowpart (SImode, operands[0]);
19872 operands[1] = gen_lowpart (SImode, operands[1]);")
19875 [(set (match_operand 0 "register_operand" "")
19876 (if_then_else (match_operator 1 "comparison_operator"
19877 [(reg FLAGS_REG) (const_int 0)])
19878 (match_operand 2 "register_operand" "")
19879 (match_operand 3 "register_operand" "")))]
19880 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19881 && (GET_MODE (operands[0]) == HImode
19882 || (GET_MODE (operands[0]) == QImode
19883 && (TARGET_PROMOTE_QImode || optimize_size)))"
19884 [(set (match_dup 0)
19885 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19886 "operands[0] = gen_lowpart (SImode, operands[0]);
19887 operands[2] = gen_lowpart (SImode, operands[2]);
19888 operands[3] = gen_lowpart (SImode, operands[3]);")
19891 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19892 ;; transform a complex memory operation into two memory to register operations.
19894 ;; Don't push memory operands
19896 [(set (match_operand:SI 0 "push_operand" "")
19897 (match_operand:SI 1 "memory_operand" ""))
19898 (match_scratch:SI 2 "r")]
19899 "!optimize_size && !TARGET_PUSH_MEMORY
19900 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19901 [(set (match_dup 2) (match_dup 1))
19902 (set (match_dup 0) (match_dup 2))]
19906 [(set (match_operand:DI 0 "push_operand" "")
19907 (match_operand:DI 1 "memory_operand" ""))
19908 (match_scratch:DI 2 "r")]
19909 "!optimize_size && !TARGET_PUSH_MEMORY
19910 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19911 [(set (match_dup 2) (match_dup 1))
19912 (set (match_dup 0) (match_dup 2))]
19915 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19918 [(set (match_operand:SF 0 "push_operand" "")
19919 (match_operand:SF 1 "memory_operand" ""))
19920 (match_scratch:SF 2 "r")]
19921 "!optimize_size && !TARGET_PUSH_MEMORY
19922 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19923 [(set (match_dup 2) (match_dup 1))
19924 (set (match_dup 0) (match_dup 2))]
19928 [(set (match_operand:HI 0 "push_operand" "")
19929 (match_operand:HI 1 "memory_operand" ""))
19930 (match_scratch:HI 2 "r")]
19931 "!optimize_size && !TARGET_PUSH_MEMORY
19932 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19933 [(set (match_dup 2) (match_dup 1))
19934 (set (match_dup 0) (match_dup 2))]
19938 [(set (match_operand:QI 0 "push_operand" "")
19939 (match_operand:QI 1 "memory_operand" ""))
19940 (match_scratch:QI 2 "q")]
19941 "!optimize_size && !TARGET_PUSH_MEMORY
19942 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19943 [(set (match_dup 2) (match_dup 1))
19944 (set (match_dup 0) (match_dup 2))]
19947 ;; Don't move an immediate directly to memory when the instruction
19950 [(match_scratch:SI 1 "r")
19951 (set (match_operand:SI 0 "memory_operand" "")
19954 && ! TARGET_USE_MOV0
19955 && TARGET_SPLIT_LONG_MOVES
19956 && get_attr_length (insn) >= ix86_cost->large_insn
19957 && peep2_regno_dead_p (0, FLAGS_REG)"
19958 [(parallel [(set (match_dup 1) (const_int 0))
19959 (clobber (reg:CC FLAGS_REG))])
19960 (set (match_dup 0) (match_dup 1))]
19964 [(match_scratch:HI 1 "r")
19965 (set (match_operand:HI 0 "memory_operand" "")
19968 && ! TARGET_USE_MOV0
19969 && TARGET_SPLIT_LONG_MOVES
19970 && get_attr_length (insn) >= ix86_cost->large_insn
19971 && peep2_regno_dead_p (0, FLAGS_REG)"
19972 [(parallel [(set (match_dup 2) (const_int 0))
19973 (clobber (reg:CC FLAGS_REG))])
19974 (set (match_dup 0) (match_dup 1))]
19975 "operands[2] = gen_lowpart (SImode, operands[1]);")
19978 [(match_scratch:QI 1 "q")
19979 (set (match_operand:QI 0 "memory_operand" "")
19982 && ! TARGET_USE_MOV0
19983 && TARGET_SPLIT_LONG_MOVES
19984 && get_attr_length (insn) >= ix86_cost->large_insn
19985 && peep2_regno_dead_p (0, FLAGS_REG)"
19986 [(parallel [(set (match_dup 2) (const_int 0))
19987 (clobber (reg:CC FLAGS_REG))])
19988 (set (match_dup 0) (match_dup 1))]
19989 "operands[2] = gen_lowpart (SImode, operands[1]);")
19992 [(match_scratch:SI 2 "r")
19993 (set (match_operand:SI 0 "memory_operand" "")
19994 (match_operand:SI 1 "immediate_operand" ""))]
19996 && TARGET_SPLIT_LONG_MOVES
19997 && get_attr_length (insn) >= ix86_cost->large_insn"
19998 [(set (match_dup 2) (match_dup 1))
19999 (set (match_dup 0) (match_dup 2))]
20003 [(match_scratch:HI 2 "r")
20004 (set (match_operand:HI 0 "memory_operand" "")
20005 (match_operand:HI 1 "immediate_operand" ""))]
20007 && TARGET_SPLIT_LONG_MOVES
20008 && get_attr_length (insn) >= ix86_cost->large_insn"
20009 [(set (match_dup 2) (match_dup 1))
20010 (set (match_dup 0) (match_dup 2))]
20014 [(match_scratch:QI 2 "q")
20015 (set (match_operand:QI 0 "memory_operand" "")
20016 (match_operand:QI 1 "immediate_operand" ""))]
20018 && TARGET_SPLIT_LONG_MOVES
20019 && get_attr_length (insn) >= ix86_cost->large_insn"
20020 [(set (match_dup 2) (match_dup 1))
20021 (set (match_dup 0) (match_dup 2))]
20024 ;; Don't compare memory with zero, load and use a test instead.
20026 [(set (match_operand 0 "flags_reg_operand" "")
20027 (match_operator 1 "compare_operator"
20028 [(match_operand:SI 2 "memory_operand" "")
20030 (match_scratch:SI 3 "r")]
20031 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20032 [(set (match_dup 3) (match_dup 2))
20033 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20036 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20037 ;; Don't split NOTs with a displacement operand, because resulting XOR
20038 ;; will not be pairable anyway.
20040 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20041 ;; represented using a modRM byte. The XOR replacement is long decoded,
20042 ;; so this split helps here as well.
20044 ;; Note: Can't do this as a regular split because we can't get proper
20045 ;; lifetime information then.
20048 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20049 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20051 && ((TARGET_NOT_UNPAIRABLE
20052 && (!MEM_P (operands[0])
20053 || !memory_displacement_operand (operands[0], SImode)))
20054 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20055 && peep2_regno_dead_p (0, FLAGS_REG)"
20056 [(parallel [(set (match_dup 0)
20057 (xor:SI (match_dup 1) (const_int -1)))
20058 (clobber (reg:CC FLAGS_REG))])]
20062 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20063 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20065 && ((TARGET_NOT_UNPAIRABLE
20066 && (!MEM_P (operands[0])
20067 || !memory_displacement_operand (operands[0], HImode)))
20068 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20069 && peep2_regno_dead_p (0, FLAGS_REG)"
20070 [(parallel [(set (match_dup 0)
20071 (xor:HI (match_dup 1) (const_int -1)))
20072 (clobber (reg:CC FLAGS_REG))])]
20076 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20077 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20079 && ((TARGET_NOT_UNPAIRABLE
20080 && (!MEM_P (operands[0])
20081 || !memory_displacement_operand (operands[0], QImode)))
20082 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20083 && peep2_regno_dead_p (0, FLAGS_REG)"
20084 [(parallel [(set (match_dup 0)
20085 (xor:QI (match_dup 1) (const_int -1)))
20086 (clobber (reg:CC FLAGS_REG))])]
20089 ;; Non pairable "test imm, reg" instructions can be translated to
20090 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20091 ;; byte opcode instead of two, have a short form for byte operands),
20092 ;; so do it for other CPUs as well. Given that the value was dead,
20093 ;; this should not create any new dependencies. Pass on the sub-word
20094 ;; versions if we're concerned about partial register stalls.
20097 [(set (match_operand 0 "flags_reg_operand" "")
20098 (match_operator 1 "compare_operator"
20099 [(and:SI (match_operand:SI 2 "register_operand" "")
20100 (match_operand:SI 3 "immediate_operand" ""))
20102 "ix86_match_ccmode (insn, CCNOmode)
20103 && (true_regnum (operands[2]) != AX_REG
20104 || satisfies_constraint_K (operands[3]))
20105 && peep2_reg_dead_p (1, operands[2])"
20107 [(set (match_dup 0)
20108 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20111 (and:SI (match_dup 2) (match_dup 3)))])]
20114 ;; We don't need to handle HImode case, because it will be promoted to SImode
20115 ;; on ! TARGET_PARTIAL_REG_STALL
20118 [(set (match_operand 0 "flags_reg_operand" "")
20119 (match_operator 1 "compare_operator"
20120 [(and:QI (match_operand:QI 2 "register_operand" "")
20121 (match_operand:QI 3 "immediate_operand" ""))
20123 "! TARGET_PARTIAL_REG_STALL
20124 && ix86_match_ccmode (insn, CCNOmode)
20125 && true_regnum (operands[2]) != AX_REG
20126 && peep2_reg_dead_p (1, operands[2])"
20128 [(set (match_dup 0)
20129 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20132 (and:QI (match_dup 2) (match_dup 3)))])]
20136 [(set (match_operand 0 "flags_reg_operand" "")
20137 (match_operator 1 "compare_operator"
20140 (match_operand 2 "ext_register_operand" "")
20143 (match_operand 3 "const_int_operand" ""))
20145 "! TARGET_PARTIAL_REG_STALL
20146 && ix86_match_ccmode (insn, CCNOmode)
20147 && true_regnum (operands[2]) != AX_REG
20148 && peep2_reg_dead_p (1, operands[2])"
20149 [(parallel [(set (match_dup 0)
20158 (set (zero_extract:SI (match_dup 2)
20169 ;; Don't do logical operations with memory inputs.
20171 [(match_scratch:SI 2 "r")
20172 (parallel [(set (match_operand:SI 0 "register_operand" "")
20173 (match_operator:SI 3 "arith_or_logical_operator"
20175 (match_operand:SI 1 "memory_operand" "")]))
20176 (clobber (reg:CC FLAGS_REG))])]
20177 "! optimize_size && ! TARGET_READ_MODIFY"
20178 [(set (match_dup 2) (match_dup 1))
20179 (parallel [(set (match_dup 0)
20180 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20181 (clobber (reg:CC FLAGS_REG))])]
20185 [(match_scratch:SI 2 "r")
20186 (parallel [(set (match_operand:SI 0 "register_operand" "")
20187 (match_operator:SI 3 "arith_or_logical_operator"
20188 [(match_operand:SI 1 "memory_operand" "")
20190 (clobber (reg:CC FLAGS_REG))])]
20191 "! optimize_size && ! TARGET_READ_MODIFY"
20192 [(set (match_dup 2) (match_dup 1))
20193 (parallel [(set (match_dup 0)
20194 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20195 (clobber (reg:CC FLAGS_REG))])]
20198 ; Don't do logical operations with memory outputs
20200 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20201 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20202 ; the same decoder scheduling characteristics as the original.
20205 [(match_scratch:SI 2 "r")
20206 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20207 (match_operator:SI 3 "arith_or_logical_operator"
20209 (match_operand:SI 1 "nonmemory_operand" "")]))
20210 (clobber (reg:CC FLAGS_REG))])]
20211 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20212 [(set (match_dup 2) (match_dup 0))
20213 (parallel [(set (match_dup 2)
20214 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20215 (clobber (reg:CC FLAGS_REG))])
20216 (set (match_dup 0) (match_dup 2))]
20220 [(match_scratch:SI 2 "r")
20221 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20222 (match_operator:SI 3 "arith_or_logical_operator"
20223 [(match_operand:SI 1 "nonmemory_operand" "")
20225 (clobber (reg:CC FLAGS_REG))])]
20226 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20227 [(set (match_dup 2) (match_dup 0))
20228 (parallel [(set (match_dup 2)
20229 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20230 (clobber (reg:CC FLAGS_REG))])
20231 (set (match_dup 0) (match_dup 2))]
20234 ;; Attempt to always use XOR for zeroing registers.
20236 [(set (match_operand 0 "register_operand" "")
20237 (match_operand 1 "const0_operand" ""))]
20238 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20239 && (! TARGET_USE_MOV0 || optimize_size)
20240 && GENERAL_REG_P (operands[0])
20241 && peep2_regno_dead_p (0, FLAGS_REG)"
20242 [(parallel [(set (match_dup 0) (const_int 0))
20243 (clobber (reg:CC FLAGS_REG))])]
20245 operands[0] = gen_lowpart (word_mode, operands[0]);
20249 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20251 "(GET_MODE (operands[0]) == QImode
20252 || GET_MODE (operands[0]) == HImode)
20253 && (! TARGET_USE_MOV0 || optimize_size)
20254 && peep2_regno_dead_p (0, FLAGS_REG)"
20255 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20256 (clobber (reg:CC FLAGS_REG))])])
20258 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20260 [(set (match_operand 0 "register_operand" "")
20262 "(GET_MODE (operands[0]) == HImode
20263 || GET_MODE (operands[0]) == SImode
20264 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20265 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20266 && peep2_regno_dead_p (0, FLAGS_REG)"
20267 [(parallel [(set (match_dup 0) (const_int -1))
20268 (clobber (reg:CC FLAGS_REG))])]
20269 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20272 ;; Attempt to convert simple leas to adds. These can be created by
20275 [(set (match_operand:SI 0 "register_operand" "")
20276 (plus:SI (match_dup 0)
20277 (match_operand:SI 1 "nonmemory_operand" "")))]
20278 "peep2_regno_dead_p (0, FLAGS_REG)"
20279 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20280 (clobber (reg:CC FLAGS_REG))])]
20284 [(set (match_operand:SI 0 "register_operand" "")
20285 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20286 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20287 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20288 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20289 (clobber (reg:CC FLAGS_REG))])]
20290 "operands[2] = gen_lowpart (SImode, operands[2]);")
20293 [(set (match_operand:DI 0 "register_operand" "")
20294 (plus:DI (match_dup 0)
20295 (match_operand:DI 1 "x86_64_general_operand" "")))]
20296 "peep2_regno_dead_p (0, FLAGS_REG)"
20297 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20298 (clobber (reg:CC FLAGS_REG))])]
20302 [(set (match_operand:SI 0 "register_operand" "")
20303 (mult:SI (match_dup 0)
20304 (match_operand:SI 1 "const_int_operand" "")))]
20305 "exact_log2 (INTVAL (operands[1])) >= 0
20306 && peep2_regno_dead_p (0, FLAGS_REG)"
20307 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20308 (clobber (reg:CC FLAGS_REG))])]
20309 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20312 [(set (match_operand:DI 0 "register_operand" "")
20313 (mult:DI (match_dup 0)
20314 (match_operand:DI 1 "const_int_operand" "")))]
20315 "exact_log2 (INTVAL (operands[1])) >= 0
20316 && peep2_regno_dead_p (0, FLAGS_REG)"
20317 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20318 (clobber (reg:CC FLAGS_REG))])]
20319 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20322 [(set (match_operand:SI 0 "register_operand" "")
20323 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20324 (match_operand:DI 2 "const_int_operand" "")) 0))]
20325 "exact_log2 (INTVAL (operands[2])) >= 0
20326 && REGNO (operands[0]) == REGNO (operands[1])
20327 && peep2_regno_dead_p (0, FLAGS_REG)"
20328 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20329 (clobber (reg:CC FLAGS_REG))])]
20330 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20332 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20333 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20334 ;; many CPUs it is also faster, since special hardware to avoid esp
20335 ;; dependencies is present.
20337 ;; While some of these conversions may be done using splitters, we use peepholes
20338 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20340 ;; Convert prologue esp subtractions to push.
20341 ;; We need register to push. In order to keep verify_flow_info happy we have
20343 ;; - use scratch and clobber it in order to avoid dependencies
20344 ;; - use already live register
20345 ;; We can't use the second way right now, since there is no reliable way how to
20346 ;; verify that given register is live. First choice will also most likely in
20347 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20348 ;; call clobbered registers are dead. We may want to use base pointer as an
20349 ;; alternative when no register is available later.
20352 [(match_scratch:SI 0 "r")
20353 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20354 (clobber (reg:CC FLAGS_REG))
20355 (clobber (mem:BLK (scratch)))])]
20356 "optimize_size || !TARGET_SUB_ESP_4"
20357 [(clobber (match_dup 0))
20358 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20359 (clobber (mem:BLK (scratch)))])])
20362 [(match_scratch:SI 0 "r")
20363 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20364 (clobber (reg:CC FLAGS_REG))
20365 (clobber (mem:BLK (scratch)))])]
20366 "optimize_size || !TARGET_SUB_ESP_8"
20367 [(clobber (match_dup 0))
20368 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20369 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20370 (clobber (mem:BLK (scratch)))])])
20372 ;; Convert esp subtractions to push.
20374 [(match_scratch:SI 0 "r")
20375 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20376 (clobber (reg:CC FLAGS_REG))])]
20377 "optimize_size || !TARGET_SUB_ESP_4"
20378 [(clobber (match_dup 0))
20379 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20382 [(match_scratch:SI 0 "r")
20383 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20384 (clobber (reg:CC FLAGS_REG))])]
20385 "optimize_size || !TARGET_SUB_ESP_8"
20386 [(clobber (match_dup 0))
20387 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20388 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20390 ;; Convert epilogue deallocator to pop.
20392 [(match_scratch:SI 0 "r")
20393 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20394 (clobber (reg:CC FLAGS_REG))
20395 (clobber (mem:BLK (scratch)))])]
20396 "optimize_size || !TARGET_ADD_ESP_4"
20397 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20398 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20399 (clobber (mem:BLK (scratch)))])]
20402 ;; Two pops case is tricky, since pop causes dependency on destination register.
20403 ;; We use two registers if available.
20405 [(match_scratch:SI 0 "r")
20406 (match_scratch:SI 1 "r")
20407 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20408 (clobber (reg:CC FLAGS_REG))
20409 (clobber (mem:BLK (scratch)))])]
20410 "optimize_size || !TARGET_ADD_ESP_8"
20411 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20412 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20413 (clobber (mem:BLK (scratch)))])
20414 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20415 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20419 [(match_scratch:SI 0 "r")
20420 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20421 (clobber (reg:CC FLAGS_REG))
20422 (clobber (mem:BLK (scratch)))])]
20424 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20425 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20426 (clobber (mem:BLK (scratch)))])
20427 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20428 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20431 ;; Convert esp additions to pop.
20433 [(match_scratch:SI 0 "r")
20434 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20435 (clobber (reg:CC FLAGS_REG))])]
20437 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20438 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20441 ;; Two pops case is tricky, since pop causes dependency on destination register.
20442 ;; We use two registers if available.
20444 [(match_scratch:SI 0 "r")
20445 (match_scratch:SI 1 "r")
20446 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20447 (clobber (reg:CC FLAGS_REG))])]
20449 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20450 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20451 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20452 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20456 [(match_scratch:SI 0 "r")
20457 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20458 (clobber (reg:CC FLAGS_REG))])]
20460 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20461 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20462 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20463 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20466 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20467 ;; required and register dies. Similarly for 128 to plus -128.
20469 [(set (match_operand 0 "flags_reg_operand" "")
20470 (match_operator 1 "compare_operator"
20471 [(match_operand 2 "register_operand" "")
20472 (match_operand 3 "const_int_operand" "")]))]
20473 "(INTVAL (operands[3]) == -1
20474 || INTVAL (operands[3]) == 1
20475 || INTVAL (operands[3]) == 128)
20476 && ix86_match_ccmode (insn, CCGCmode)
20477 && peep2_reg_dead_p (1, operands[2])"
20478 [(parallel [(set (match_dup 0)
20479 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20480 (clobber (match_dup 2))])]
20484 [(match_scratch:DI 0 "r")
20485 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20486 (clobber (reg:CC FLAGS_REG))
20487 (clobber (mem:BLK (scratch)))])]
20488 "optimize_size || !TARGET_SUB_ESP_4"
20489 [(clobber (match_dup 0))
20490 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20491 (clobber (mem:BLK (scratch)))])])
20494 [(match_scratch:DI 0 "r")
20495 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20496 (clobber (reg:CC FLAGS_REG))
20497 (clobber (mem:BLK (scratch)))])]
20498 "optimize_size || !TARGET_SUB_ESP_8"
20499 [(clobber (match_dup 0))
20500 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20501 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20502 (clobber (mem:BLK (scratch)))])])
20504 ;; Convert esp subtractions to push.
20506 [(match_scratch:DI 0 "r")
20507 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20508 (clobber (reg:CC FLAGS_REG))])]
20509 "optimize_size || !TARGET_SUB_ESP_4"
20510 [(clobber (match_dup 0))
20511 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20514 [(match_scratch:DI 0 "r")
20515 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20516 (clobber (reg:CC FLAGS_REG))])]
20517 "optimize_size || !TARGET_SUB_ESP_8"
20518 [(clobber (match_dup 0))
20519 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20520 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20522 ;; Convert epilogue deallocator to pop.
20524 [(match_scratch:DI 0 "r")
20525 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20526 (clobber (reg:CC FLAGS_REG))
20527 (clobber (mem:BLK (scratch)))])]
20528 "optimize_size || !TARGET_ADD_ESP_4"
20529 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20530 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20531 (clobber (mem:BLK (scratch)))])]
20534 ;; Two pops case is tricky, since pop causes dependency on destination register.
20535 ;; We use two registers if available.
20537 [(match_scratch:DI 0 "r")
20538 (match_scratch:DI 1 "r")
20539 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20540 (clobber (reg:CC FLAGS_REG))
20541 (clobber (mem:BLK (scratch)))])]
20542 "optimize_size || !TARGET_ADD_ESP_8"
20543 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20544 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20545 (clobber (mem:BLK (scratch)))])
20546 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20547 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20551 [(match_scratch:DI 0 "r")
20552 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20553 (clobber (reg:CC FLAGS_REG))
20554 (clobber (mem:BLK (scratch)))])]
20556 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20557 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20558 (clobber (mem:BLK (scratch)))])
20559 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20560 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20563 ;; Convert esp additions to pop.
20565 [(match_scratch:DI 0 "r")
20566 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20567 (clobber (reg:CC FLAGS_REG))])]
20569 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20570 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20573 ;; Two pops case is tricky, since pop causes dependency on destination register.
20574 ;; We use two registers if available.
20576 [(match_scratch:DI 0 "r")
20577 (match_scratch:DI 1 "r")
20578 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20579 (clobber (reg:CC FLAGS_REG))])]
20581 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20582 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20583 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20584 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20588 [(match_scratch:DI 0 "r")
20589 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20590 (clobber (reg:CC FLAGS_REG))])]
20592 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20593 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20594 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20595 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20598 ;; Convert imul by three, five and nine into lea
20601 [(set (match_operand:SI 0 "register_operand" "")
20602 (mult:SI (match_operand:SI 1 "register_operand" "")
20603 (match_operand:SI 2 "const_int_operand" "")))
20604 (clobber (reg:CC FLAGS_REG))])]
20605 "INTVAL (operands[2]) == 3
20606 || INTVAL (operands[2]) == 5
20607 || INTVAL (operands[2]) == 9"
20608 [(set (match_dup 0)
20609 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20611 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20615 [(set (match_operand:SI 0 "register_operand" "")
20616 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20617 (match_operand:SI 2 "const_int_operand" "")))
20618 (clobber (reg:CC FLAGS_REG))])]
20620 && (INTVAL (operands[2]) == 3
20621 || INTVAL (operands[2]) == 5
20622 || INTVAL (operands[2]) == 9)"
20623 [(set (match_dup 0) (match_dup 1))
20625 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20627 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20631 [(set (match_operand:DI 0 "register_operand" "")
20632 (mult:DI (match_operand:DI 1 "register_operand" "")
20633 (match_operand:DI 2 "const_int_operand" "")))
20634 (clobber (reg:CC FLAGS_REG))])]
20636 && (INTVAL (operands[2]) == 3
20637 || INTVAL (operands[2]) == 5
20638 || INTVAL (operands[2]) == 9)"
20639 [(set (match_dup 0)
20640 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20642 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20646 [(set (match_operand:DI 0 "register_operand" "")
20647 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20648 (match_operand:DI 2 "const_int_operand" "")))
20649 (clobber (reg:CC FLAGS_REG))])]
20652 && (INTVAL (operands[2]) == 3
20653 || INTVAL (operands[2]) == 5
20654 || INTVAL (operands[2]) == 9)"
20655 [(set (match_dup 0) (match_dup 1))
20657 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20659 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20661 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20662 ;; imul $32bit_imm, reg, reg is direct decoded.
20664 [(match_scratch:DI 3 "r")
20665 (parallel [(set (match_operand:DI 0 "register_operand" "")
20666 (mult:DI (match_operand:DI 1 "memory_operand" "")
20667 (match_operand:DI 2 "immediate_operand" "")))
20668 (clobber (reg:CC FLAGS_REG))])]
20669 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20670 && !satisfies_constraint_K (operands[2])"
20671 [(set (match_dup 3) (match_dup 1))
20672 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20673 (clobber (reg:CC FLAGS_REG))])]
20677 [(match_scratch:SI 3 "r")
20678 (parallel [(set (match_operand:SI 0 "register_operand" "")
20679 (mult:SI (match_operand:SI 1 "memory_operand" "")
20680 (match_operand:SI 2 "immediate_operand" "")))
20681 (clobber (reg:CC FLAGS_REG))])]
20682 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20683 && !satisfies_constraint_K (operands[2])"
20684 [(set (match_dup 3) (match_dup 1))
20685 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20686 (clobber (reg:CC FLAGS_REG))])]
20690 [(match_scratch:SI 3 "r")
20691 (parallel [(set (match_operand:DI 0 "register_operand" "")
20693 (mult:SI (match_operand:SI 1 "memory_operand" "")
20694 (match_operand:SI 2 "immediate_operand" ""))))
20695 (clobber (reg:CC FLAGS_REG))])]
20696 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20697 && !satisfies_constraint_K (operands[2])"
20698 [(set (match_dup 3) (match_dup 1))
20699 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20700 (clobber (reg:CC FLAGS_REG))])]
20703 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20704 ;; Convert it into imul reg, reg
20705 ;; It would be better to force assembler to encode instruction using long
20706 ;; immediate, but there is apparently no way to do so.
20708 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20709 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20710 (match_operand:DI 2 "const_int_operand" "")))
20711 (clobber (reg:CC FLAGS_REG))])
20712 (match_scratch:DI 3 "r")]
20713 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20714 && satisfies_constraint_K (operands[2])"
20715 [(set (match_dup 3) (match_dup 2))
20716 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20717 (clobber (reg:CC FLAGS_REG))])]
20719 if (!rtx_equal_p (operands[0], operands[1]))
20720 emit_move_insn (operands[0], operands[1]);
20724 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20725 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20726 (match_operand:SI 2 "const_int_operand" "")))
20727 (clobber (reg:CC FLAGS_REG))])
20728 (match_scratch:SI 3 "r")]
20729 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20730 && satisfies_constraint_K (operands[2])"
20731 [(set (match_dup 3) (match_dup 2))
20732 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20733 (clobber (reg:CC FLAGS_REG))])]
20735 if (!rtx_equal_p (operands[0], operands[1]))
20736 emit_move_insn (operands[0], operands[1]);
20740 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20741 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20742 (match_operand:HI 2 "immediate_operand" "")))
20743 (clobber (reg:CC FLAGS_REG))])
20744 (match_scratch:HI 3 "r")]
20745 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20746 [(set (match_dup 3) (match_dup 2))
20747 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20748 (clobber (reg:CC FLAGS_REG))])]
20750 if (!rtx_equal_p (operands[0], operands[1]))
20751 emit_move_insn (operands[0], operands[1]);
20754 ;; After splitting up read-modify operations, array accesses with memory
20755 ;; operands might end up in form:
20757 ;; movl 4(%esp), %edx
20759 ;; instead of pre-splitting:
20761 ;; addl 4(%esp), %eax
20763 ;; movl 4(%esp), %edx
20764 ;; leal (%edx,%eax,4), %eax
20767 [(parallel [(set (match_operand 0 "register_operand" "")
20768 (ashift (match_operand 1 "register_operand" "")
20769 (match_operand 2 "const_int_operand" "")))
20770 (clobber (reg:CC FLAGS_REG))])
20771 (set (match_operand 3 "register_operand")
20772 (match_operand 4 "x86_64_general_operand" ""))
20773 (parallel [(set (match_operand 5 "register_operand" "")
20774 (plus (match_operand 6 "register_operand" "")
20775 (match_operand 7 "register_operand" "")))
20776 (clobber (reg:CC FLAGS_REG))])]
20777 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20778 /* Validate MODE for lea. */
20779 && ((!TARGET_PARTIAL_REG_STALL
20780 && (GET_MODE (operands[0]) == QImode
20781 || GET_MODE (operands[0]) == HImode))
20782 || GET_MODE (operands[0]) == SImode
20783 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20784 /* We reorder load and the shift. */
20785 && !rtx_equal_p (operands[1], operands[3])
20786 && !reg_overlap_mentioned_p (operands[0], operands[4])
20787 /* Last PLUS must consist of operand 0 and 3. */
20788 && !rtx_equal_p (operands[0], operands[3])
20789 && (rtx_equal_p (operands[3], operands[6])
20790 || rtx_equal_p (operands[3], operands[7]))
20791 && (rtx_equal_p (operands[0], operands[6])
20792 || rtx_equal_p (operands[0], operands[7]))
20793 /* The intermediate operand 0 must die or be same as output. */
20794 && (rtx_equal_p (operands[0], operands[5])
20795 || peep2_reg_dead_p (3, operands[0]))"
20796 [(set (match_dup 3) (match_dup 4))
20797 (set (match_dup 0) (match_dup 1))]
20799 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20800 int scale = 1 << INTVAL (operands[2]);
20801 rtx index = gen_lowpart (Pmode, operands[1]);
20802 rtx base = gen_lowpart (Pmode, operands[3]);
20803 rtx dest = gen_lowpart (mode, operands[5]);
20805 operands[1] = gen_rtx_PLUS (Pmode, base,
20806 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20808 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20809 operands[0] = dest;
20812 ;; Call-value patterns last so that the wildcard operand does not
20813 ;; disrupt insn-recog's switch tables.
20815 (define_insn "*call_value_pop_0"
20816 [(set (match_operand 0 "" "")
20817 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20818 (match_operand:SI 2 "" "")))
20819 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20820 (match_operand:SI 3 "immediate_operand" "")))]
20823 if (SIBLING_CALL_P (insn))
20826 return "call\t%P1";
20828 [(set_attr "type" "callv")])
20830 (define_insn "*call_value_pop_1"
20831 [(set (match_operand 0 "" "")
20832 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20833 (match_operand:SI 2 "" "")))
20834 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20835 (match_operand:SI 3 "immediate_operand" "i")))]
20838 if (constant_call_address_operand (operands[1], Pmode))
20840 if (SIBLING_CALL_P (insn))
20843 return "call\t%P1";
20845 if (SIBLING_CALL_P (insn))
20848 return "call\t%A1";
20850 [(set_attr "type" "callv")])
20852 (define_insn "*call_value_0"
20853 [(set (match_operand 0 "" "")
20854 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20855 (match_operand:SI 2 "" "")))]
20858 if (SIBLING_CALL_P (insn))
20861 return "call\t%P1";
20863 [(set_attr "type" "callv")])
20865 (define_insn "*call_value_0_rex64"
20866 [(set (match_operand 0 "" "")
20867 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20868 (match_operand:DI 2 "const_int_operand" "")))]
20871 if (SIBLING_CALL_P (insn))
20874 return "call\t%P1";
20876 [(set_attr "type" "callv")])
20878 (define_insn "*call_value_1"
20879 [(set (match_operand 0 "" "")
20880 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20881 (match_operand:SI 2 "" "")))]
20882 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20884 if (constant_call_address_operand (operands[1], Pmode))
20885 return "call\t%P1";
20886 return "call\t%A1";
20888 [(set_attr "type" "callv")])
20890 (define_insn "*sibcall_value_1"
20891 [(set (match_operand 0 "" "")
20892 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20893 (match_operand:SI 2 "" "")))]
20894 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20896 if (constant_call_address_operand (operands[1], Pmode))
20900 [(set_attr "type" "callv")])
20902 (define_insn "*call_value_1_rex64"
20903 [(set (match_operand 0 "" "")
20904 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20905 (match_operand:DI 2 "" "")))]
20906 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20907 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20909 if (constant_call_address_operand (operands[1], Pmode))
20910 return "call\t%P1";
20911 return "call\t%A1";
20913 [(set_attr "type" "callv")])
20915 (define_insn "*call_value_1_rex64_large"
20916 [(set (match_operand 0 "" "")
20917 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20918 (match_operand:DI 2 "" "")))]
20919 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20921 [(set_attr "type" "callv")])
20923 (define_insn "*sibcall_value_1_rex64"
20924 [(set (match_operand 0 "" "")
20925 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20926 (match_operand:DI 2 "" "")))]
20927 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20929 [(set_attr "type" "callv")])
20931 (define_insn "*sibcall_value_1_rex64_v"
20932 [(set (match_operand 0 "" "")
20933 (call (mem:QI (reg:DI R11_REG))
20934 (match_operand:DI 1 "" "")))]
20935 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20937 [(set_attr "type" "callv")])
20939 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20940 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20941 ;; caught for use by garbage collectors and the like. Using an insn that
20942 ;; maps to SIGILL makes it more likely the program will rightfully die.
20943 ;; Keeping with tradition, "6" is in honor of #UD.
20944 (define_insn "trap"
20945 [(trap_if (const_int 1) (const_int 6))]
20947 { return ASM_SHORT "0x0b0f"; }
20948 [(set_attr "length" "2")])
20950 (define_expand "sse_prologue_save"
20951 [(parallel [(set (match_operand:BLK 0 "" "")
20952 (unspec:BLK [(reg:DI 21)
20959 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20960 (use (match_operand:DI 1 "register_operand" ""))
20961 (use (match_operand:DI 2 "immediate_operand" ""))
20962 (use (label_ref:DI (match_operand 3 "" "")))])]
20966 (define_insn "*sse_prologue_save_insn"
20967 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20968 (match_operand:DI 4 "const_int_operand" "n")))
20969 (unspec:BLK [(reg:DI 21)
20976 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20977 (use (match_operand:DI 1 "register_operand" "r"))
20978 (use (match_operand:DI 2 "const_int_operand" "i"))
20979 (use (label_ref:DI (match_operand 3 "" "X")))]
20981 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20982 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20985 operands[0] = gen_rtx_MEM (Pmode,
20986 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20987 output_asm_insn ("jmp\t%A1", operands);
20988 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20990 operands[4] = adjust_address (operands[0], DImode, i*16);
20991 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20992 PUT_MODE (operands[4], TImode);
20993 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20994 output_asm_insn ("rex", operands);
20995 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
20997 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20998 CODE_LABEL_NUMBER (operands[3]));
21001 [(set_attr "type" "other")
21002 (set_attr "length_immediate" "0")
21003 (set_attr "length_address" "0")
21004 (set_attr "length" "135")
21005 (set_attr "memory" "store")
21006 (set_attr "modrm" "0")
21007 (set_attr "mode" "DI")])
21009 (define_expand "prefetch"
21010 [(prefetch (match_operand 0 "address_operand" "")
21011 (match_operand:SI 1 "const_int_operand" "")
21012 (match_operand:SI 2 "const_int_operand" ""))]
21013 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21015 int rw = INTVAL (operands[1]);
21016 int locality = INTVAL (operands[2]);
21018 gcc_assert (rw == 0 || rw == 1);
21019 gcc_assert (locality >= 0 && locality <= 3);
21020 gcc_assert (GET_MODE (operands[0]) == Pmode
21021 || GET_MODE (operands[0]) == VOIDmode);
21023 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21024 supported by SSE counterpart or the SSE prefetch is not available
21025 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21027 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21028 operands[2] = GEN_INT (3);
21030 operands[1] = const0_rtx;
21033 (define_insn "*prefetch_sse"
21034 [(prefetch (match_operand:SI 0 "address_operand" "p")
21036 (match_operand:SI 1 "const_int_operand" ""))]
21037 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21039 static const char * const patterns[4] = {
21040 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21043 int locality = INTVAL (operands[1]);
21044 gcc_assert (locality >= 0 && locality <= 3);
21046 return patterns[locality];
21048 [(set_attr "type" "sse")
21049 (set_attr "memory" "none")])
21051 (define_insn "*prefetch_sse_rex"
21052 [(prefetch (match_operand:DI 0 "address_operand" "p")
21054 (match_operand:SI 1 "const_int_operand" ""))]
21055 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21057 static const char * const patterns[4] = {
21058 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21061 int locality = INTVAL (operands[1]);
21062 gcc_assert (locality >= 0 && locality <= 3);
21064 return patterns[locality];
21066 [(set_attr "type" "sse")
21067 (set_attr "memory" "none")])
21069 (define_insn "*prefetch_3dnow"
21070 [(prefetch (match_operand:SI 0 "address_operand" "p")
21071 (match_operand:SI 1 "const_int_operand" "n")
21073 "TARGET_3DNOW && !TARGET_64BIT"
21075 if (INTVAL (operands[1]) == 0)
21076 return "prefetch\t%a0";
21078 return "prefetchw\t%a0";
21080 [(set_attr "type" "mmx")
21081 (set_attr "memory" "none")])
21083 (define_insn "*prefetch_3dnow_rex"
21084 [(prefetch (match_operand:DI 0 "address_operand" "p")
21085 (match_operand:SI 1 "const_int_operand" "n")
21087 "TARGET_3DNOW && TARGET_64BIT"
21089 if (INTVAL (operands[1]) == 0)
21090 return "prefetch\t%a0";
21092 return "prefetchw\t%a0";
21094 [(set_attr "type" "mmx")
21095 (set_attr "memory" "none")])
21097 (define_expand "stack_protect_set"
21098 [(match_operand 0 "memory_operand" "")
21099 (match_operand 1 "memory_operand" "")]
21102 #ifdef TARGET_THREAD_SSP_OFFSET
21104 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21105 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21107 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21108 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21111 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21113 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21118 (define_insn "stack_protect_set_si"
21119 [(set (match_operand:SI 0 "memory_operand" "=m")
21120 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21121 (set (match_scratch:SI 2 "=&r") (const_int 0))
21122 (clobber (reg:CC FLAGS_REG))]
21124 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21125 [(set_attr "type" "multi")])
21127 (define_insn "stack_protect_set_di"
21128 [(set (match_operand:DI 0 "memory_operand" "=m")
21129 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21130 (set (match_scratch:DI 2 "=&r") (const_int 0))
21131 (clobber (reg:CC FLAGS_REG))]
21133 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21134 [(set_attr "type" "multi")])
21136 (define_insn "stack_tls_protect_set_si"
21137 [(set (match_operand:SI 0 "memory_operand" "=m")
21138 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21139 (set (match_scratch:SI 2 "=&r") (const_int 0))
21140 (clobber (reg:CC FLAGS_REG))]
21142 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21143 [(set_attr "type" "multi")])
21145 (define_insn "stack_tls_protect_set_di"
21146 [(set (match_operand:DI 0 "memory_operand" "=m")
21147 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21148 (set (match_scratch:DI 2 "=&r") (const_int 0))
21149 (clobber (reg:CC FLAGS_REG))]
21152 /* The kernel uses a different segment register for performance reasons; a
21153 system call would not have to trash the userspace segment register,
21154 which would be expensive */
21155 if (ix86_cmodel != CM_KERNEL)
21156 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21158 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21160 [(set_attr "type" "multi")])
21162 (define_expand "stack_protect_test"
21163 [(match_operand 0 "memory_operand" "")
21164 (match_operand 1 "memory_operand" "")
21165 (match_operand 2 "" "")]
21168 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21169 ix86_compare_op0 = operands[0];
21170 ix86_compare_op1 = operands[1];
21171 ix86_compare_emitted = flags;
21173 #ifdef TARGET_THREAD_SSP_OFFSET
21175 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21176 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21178 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21179 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21182 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21184 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21186 emit_jump_insn (gen_beq (operands[2]));
21190 (define_insn "stack_protect_test_si"
21191 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21192 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21193 (match_operand:SI 2 "memory_operand" "m")]
21195 (clobber (match_scratch:SI 3 "=&r"))]
21197 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21198 [(set_attr "type" "multi")])
21200 (define_insn "stack_protect_test_di"
21201 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21202 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21203 (match_operand:DI 2 "memory_operand" "m")]
21205 (clobber (match_scratch:DI 3 "=&r"))]
21207 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21208 [(set_attr "type" "multi")])
21210 (define_insn "stack_tls_protect_test_si"
21211 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21212 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21213 (match_operand:SI 2 "const_int_operand" "i")]
21214 UNSPEC_SP_TLS_TEST))
21215 (clobber (match_scratch:SI 3 "=r"))]
21217 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21218 [(set_attr "type" "multi")])
21220 (define_insn "stack_tls_protect_test_di"
21221 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21222 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21223 (match_operand:DI 2 "const_int_operand" "i")]
21224 UNSPEC_SP_TLS_TEST))
21225 (clobber (match_scratch:DI 3 "=r"))]
21228 /* The kernel uses a different segment register for performance reasons; a
21229 system call would not have to trash the userspace segment register,
21230 which would be expensive */
21231 if (ix86_cmodel != CM_KERNEL)
21232 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21234 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21236 [(set_attr "type" "multi")])
21238 (define_mode_iterator CRC32MODE [QI HI SI])
21239 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21240 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21242 (define_insn "sse4_2_crc32<mode>"
21243 [(set (match_operand:SI 0 "register_operand" "=r")
21245 [(match_operand:SI 1 "register_operand" "0")
21246 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21249 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21250 [(set_attr "type" "sselog1")
21251 (set_attr "prefix_rep" "1")
21252 (set_attr "prefix_extra" "1")
21253 (set_attr "mode" "SI")])
21255 (define_insn "sse4_2_crc32di"
21256 [(set (match_operand:DI 0 "register_operand" "=r")
21258 [(match_operand:DI 1 "register_operand" "0")
21259 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21261 "TARGET_SSE4_2 && TARGET_64BIT"
21262 "crc32q\t{%2, %0|%0, %2}"
21263 [(set_attr "type" "sselog1")
21264 (set_attr "prefix_rep" "1")
21265 (set_attr "prefix_extra" "1")
21266 (set_attr "mode" "DI")])
21270 (include "sync.md")