1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
108 ; Generic math support
110 (UNSPEC_IEEE_MIN 51) ; not commutative
111 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
136 (UNSPEC_XTRACT_FRACT 84)
137 (UNSPEC_XTRACT_EXP 85)
138 (UNSPEC_FSCALE_FRACT 86)
139 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 (UNSPEC_INSERTPS 135)
168 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_PHMINPOSUW 139)
176 (UNSPEC_PCMPESTR 144)
177 (UNSPEC_PCMPISTR 145)
180 (UNSPEC_SSE5_INTRINSIC 150)
181 (UNSPEC_SSE5_UNSIGNED_CMP 151)
182 (UNSPEC_SSE5_TRUEFALSE 152)
183 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_CVTPH2PS 155)
186 (UNSPEC_CVTPS2PH 156)
190 (UNSPEC_AESENCLAST 160)
192 (UNSPEC_AESDECLAST 162)
194 (UNSPEC_AESKEYGENASSIST 164)
201 [(UNSPECV_BLOCKAGE 0)
202 (UNSPECV_STACK_PROBE 1)
211 (UNSPECV_CMPXCHG_1 10)
212 (UNSPECV_CMPXCHG_2 11)
215 (UNSPECV_PROLOGUE_USE 14)
219 ;; Constants to represent pcomtrue/pcomfalse variants
229 ;; Constants used in the SSE5 pperm instruction
231 [(PPERM_SRC 0x00) /* copy source */
232 (PPERM_INVERT 0x20) /* invert source */
233 (PPERM_REVERSE 0x40) /* bit reverse source */
234 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
235 (PPERM_ZERO 0x80) /* all 0's */
236 (PPERM_ONES 0xa0) /* all 1's */
237 (PPERM_SIGN 0xc0) /* propagate sign bit */
238 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
239 (PPERM_SRC1 0x00) /* use first source byte */
240 (PPERM_SRC2 0x10) /* use second source byte */
243 ;; Registers by name.
259 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
262 ;; In C guard expressions, put expressions which may be compile-time
263 ;; constants first. This allows for better optimization. For
264 ;; example, write "TARGET_64BIT && reload_completed", not
265 ;; "reload_completed && TARGET_64BIT".
268 ;; Processor type. This attribute must exactly match the processor_type
269 ;; enumeration in i386.h.
270 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
271 nocona,core2,generic32,generic64,amdfam10"
272 (const (symbol_ref "ix86_tune")))
274 ;; A basic instruction type. Refinements due to arguments to be
275 ;; provided in other attributes.
278 alu,alu1,negnot,imov,imovx,lea,
279 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
280 icmp,test,ibr,setcc,icmov,
281 push,pop,call,callv,leave,
283 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
284 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
285 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
287 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
288 (const_string "other"))
290 ;; Main data type used by the insn
292 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
293 (const_string "unknown"))
295 ;; The CPU unit operations uses.
296 (define_attr "unit" "integer,i387,sse,mmx,unknown"
297 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
298 (const_string "i387")
299 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
300 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
301 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
303 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
305 (eq_attr "type" "other")
306 (const_string "unknown")]
307 (const_string "integer")))
309 ;; The (bounding maximum) length of an instruction immediate.
310 (define_attr "length_immediate" ""
311 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
314 (eq_attr "unit" "i387,sse,mmx")
316 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
318 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
319 (eq_attr "type" "imov,test")
320 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
321 (eq_attr "type" "call")
322 (if_then_else (match_operand 0 "constant_call_address_operand" "")
325 (eq_attr "type" "callv")
326 (if_then_else (match_operand 1 "constant_call_address_operand" "")
329 ;; We don't know the size before shorten_branches. Expect
330 ;; the instruction to fit for better scheduling.
331 (eq_attr "type" "ibr")
334 (symbol_ref "/* Update immediate_length and other attributes! */
335 gcc_unreachable (),1")))
337 ;; The (bounding maximum) length of an instruction address.
338 (define_attr "length_address" ""
339 (cond [(eq_attr "type" "str,other,multi,fxch")
341 (and (eq_attr "type" "call")
342 (match_operand 0 "constant_call_address_operand" ""))
344 (and (eq_attr "type" "callv")
345 (match_operand 1 "constant_call_address_operand" ""))
348 (symbol_ref "ix86_attr_length_address_default (insn)")))
350 ;; Set when length prefix is used.
351 (define_attr "prefix_data16" ""
352 (if_then_else (ior (eq_attr "mode" "HI")
353 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
357 ;; Set when string REP prefix is used.
358 (define_attr "prefix_rep" ""
359 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
363 ;; Set when 0f opcode prefix is used.
364 (define_attr "prefix_0f" ""
366 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
367 (eq_attr "unit" "sse,mmx"))
371 ;; Set when REX opcode prefix is used.
372 (define_attr "prefix_rex" ""
373 (cond [(and (eq_attr "mode" "DI")
374 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
376 (and (eq_attr "mode" "QI")
377 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
380 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
386 ;; There are also additional prefixes in SSSE3.
387 (define_attr "prefix_extra" "" (const_int 0))
389 ;; Set when modrm byte is used.
390 (define_attr "modrm" ""
391 (cond [(eq_attr "type" "str,leave")
393 (eq_attr "unit" "i387")
395 (and (eq_attr "type" "incdec")
396 (ior (match_operand:SI 1 "register_operand" "")
397 (match_operand:HI 1 "register_operand" "")))
399 (and (eq_attr "type" "push")
400 (not (match_operand 1 "memory_operand" "")))
402 (and (eq_attr "type" "pop")
403 (not (match_operand 0 "memory_operand" "")))
405 (and (eq_attr "type" "imov")
406 (ior (and (match_operand 0 "register_operand" "")
407 (match_operand 1 "immediate_operand" ""))
408 (ior (and (match_operand 0 "ax_reg_operand" "")
409 (match_operand 1 "memory_displacement_only_operand" ""))
410 (and (match_operand 0 "memory_displacement_only_operand" "")
411 (match_operand 1 "ax_reg_operand" "")))))
413 (and (eq_attr "type" "call")
414 (match_operand 0 "constant_call_address_operand" ""))
416 (and (eq_attr "type" "callv")
417 (match_operand 1 "constant_call_address_operand" ""))
422 ;; The (bounding maximum) length of an instruction in bytes.
423 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
424 ;; Later we may want to split them and compute proper length as for
426 (define_attr "length" ""
427 (cond [(eq_attr "type" "other,multi,fistp,frndint")
429 (eq_attr "type" "fcmp")
431 (eq_attr "unit" "i387")
433 (plus (attr "prefix_data16")
434 (attr "length_address")))]
435 (plus (plus (attr "modrm")
436 (plus (attr "prefix_0f")
437 (plus (attr "prefix_rex")
438 (plus (attr "prefix_extra")
440 (plus (attr "prefix_rep")
441 (plus (attr "prefix_data16")
442 (plus (attr "length_immediate")
443 (attr "length_address")))))))
445 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
446 ;; `store' if there is a simple memory reference therein, or `unknown'
447 ;; if the instruction is complex.
449 (define_attr "memory" "none,load,store,both,unknown"
450 (cond [(eq_attr "type" "other,multi,str")
451 (const_string "unknown")
452 (eq_attr "type" "lea,fcmov,fpspc")
453 (const_string "none")
454 (eq_attr "type" "fistp,leave")
455 (const_string "both")
456 (eq_attr "type" "frndint")
457 (const_string "load")
458 (eq_attr "type" "push")
459 (if_then_else (match_operand 1 "memory_operand" "")
460 (const_string "both")
461 (const_string "store"))
462 (eq_attr "type" "pop")
463 (if_then_else (match_operand 0 "memory_operand" "")
464 (const_string "both")
465 (const_string "load"))
466 (eq_attr "type" "setcc")
467 (if_then_else (match_operand 0 "memory_operand" "")
468 (const_string "store")
469 (const_string "none"))
470 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
471 (if_then_else (ior (match_operand 0 "memory_operand" "")
472 (match_operand 1 "memory_operand" ""))
473 (const_string "load")
474 (const_string "none"))
475 (eq_attr "type" "ibr")
476 (if_then_else (match_operand 0 "memory_operand" "")
477 (const_string "load")
478 (const_string "none"))
479 (eq_attr "type" "call")
480 (if_then_else (match_operand 0 "constant_call_address_operand" "")
481 (const_string "none")
482 (const_string "load"))
483 (eq_attr "type" "callv")
484 (if_then_else (match_operand 1 "constant_call_address_operand" "")
485 (const_string "none")
486 (const_string "load"))
487 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
488 (match_operand 1 "memory_operand" ""))
489 (const_string "both")
490 (and (match_operand 0 "memory_operand" "")
491 (match_operand 1 "memory_operand" ""))
492 (const_string "both")
493 (match_operand 0 "memory_operand" "")
494 (const_string "store")
495 (match_operand 1 "memory_operand" "")
496 (const_string "load")
498 "!alu1,negnot,ishift1,
499 imov,imovx,icmp,test,bitmanip,
501 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
502 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
503 (match_operand 2 "memory_operand" ""))
504 (const_string "load")
505 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
506 (match_operand 3 "memory_operand" ""))
507 (const_string "load")
509 (const_string "none")))
511 ;; Indicates if an instruction has both an immediate and a displacement.
513 (define_attr "imm_disp" "false,true,unknown"
514 (cond [(eq_attr "type" "other,multi")
515 (const_string "unknown")
516 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
517 (and (match_operand 0 "memory_displacement_operand" "")
518 (match_operand 1 "immediate_operand" "")))
519 (const_string "true")
520 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
521 (and (match_operand 0 "memory_displacement_operand" "")
522 (match_operand 2 "immediate_operand" "")))
523 (const_string "true")
525 (const_string "false")))
527 ;; Indicates if an FP operation has an integer source.
529 (define_attr "fp_int_src" "false,true"
530 (const_string "false"))
532 ;; Defines rounding mode of an FP operation.
534 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
535 (const_string "any"))
537 ;; Describe a user's asm statement.
538 (define_asm_attributes
539 [(set_attr "length" "128")
540 (set_attr "type" "multi")])
542 ;; All integer comparison codes.
543 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
545 ;; All floating-point comparison codes.
546 (define_code_iterator fp_cond [unordered ordered
547 uneq unge ungt unle unlt ltgt ])
549 (define_code_iterator plusminus [plus minus])
551 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
553 ;; Base name for define_insn
554 (define_code_attr plusminus_insn
555 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
556 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
558 ;; Base name for insn mnemonic.
559 (define_code_attr plusminus_mnemonic
560 [(plus "add") (ss_plus "adds") (us_plus "addus")
561 (minus "sub") (ss_minus "subs") (us_minus "subus")])
563 ;; Mark commutative operators as such in constraints.
564 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
565 (minus "") (ss_minus "") (us_minus "")])
567 ;; Mapping of signed max and min
568 (define_code_iterator smaxmin [smax smin])
570 ;; Mapping of unsigned max and min
571 (define_code_iterator umaxmin [umax umin])
573 ;; Base name for integer and FP insn mnemonic
574 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
575 (umax "maxu") (umin "minu")])
576 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
578 ;; Mapping of parallel logic operators
579 (define_code_iterator plogic [and ior xor])
581 ;; Base name for insn mnemonic.
582 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
584 ;; Mapping of abs neg operators
585 (define_code_iterator absneg [abs neg])
587 ;; Base name for x87 insn mnemonic.
588 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
590 ;; All single word integer modes.
591 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
593 ;; Instruction suffix for integer modes.
594 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
596 ;; Register class for integer modes.
597 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
599 ;; Immediate operand constraint for integer modes.
600 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
602 ;; General operand predicate for integer modes.
603 (define_mode_attr general_operand
604 [(QI "general_operand")
605 (HI "general_operand")
606 (SI "general_operand")
607 (DI "x86_64_general_operand")])
609 ;; SSE and x87 SFmode and DFmode floating point modes
610 (define_mode_iterator MODEF [SF DF])
612 ;; All x87 floating point modes
613 (define_mode_iterator X87MODEF [SF DF XF])
615 ;; All integer modes handled by x87 fisttp operator.
616 (define_mode_iterator X87MODEI [HI SI DI])
618 ;; All integer modes handled by integer x87 operators.
619 (define_mode_iterator X87MODEI12 [HI SI])
621 ;; All integer modes handled by SSE cvtts?2si* operators.
622 (define_mode_iterator SSEMODEI24 [SI DI])
624 ;; SSE asm suffix for floating point modes
625 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
627 ;; SSE vector mode corresponding to a scalar mode
628 (define_mode_attr ssevecmode
629 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
631 ;; Instruction suffix for REX 64bit operators.
632 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
634 ;; Scheduling descriptions
636 (include "pentium.md")
639 (include "athlon.md")
643 ;; Operand and operator predicates and constraints
645 (include "predicates.md")
646 (include "constraints.md")
649 ;; Compare instructions.
651 ;; All compare insns have expanders that save the operands away without
652 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
653 ;; after the cmp) will actually emit the cmpM.
655 (define_expand "cmpti"
656 [(set (reg:CC FLAGS_REG)
657 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
658 (match_operand:TI 1 "x86_64_general_operand" "")))]
661 if (MEM_P (operands[0]) && MEM_P (operands[1]))
662 operands[0] = force_reg (TImode, operands[0]);
663 ix86_compare_op0 = operands[0];
664 ix86_compare_op1 = operands[1];
668 (define_expand "cmpdi"
669 [(set (reg:CC FLAGS_REG)
670 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
671 (match_operand:DI 1 "x86_64_general_operand" "")))]
674 if (MEM_P (operands[0]) && MEM_P (operands[1]))
675 operands[0] = force_reg (DImode, operands[0]);
676 ix86_compare_op0 = operands[0];
677 ix86_compare_op1 = operands[1];
681 (define_expand "cmpsi"
682 [(set (reg:CC FLAGS_REG)
683 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
684 (match_operand:SI 1 "general_operand" "")))]
687 if (MEM_P (operands[0]) && MEM_P (operands[1]))
688 operands[0] = force_reg (SImode, operands[0]);
689 ix86_compare_op0 = operands[0];
690 ix86_compare_op1 = operands[1];
694 (define_expand "cmphi"
695 [(set (reg:CC FLAGS_REG)
696 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
697 (match_operand:HI 1 "general_operand" "")))]
700 if (MEM_P (operands[0]) && MEM_P (operands[1]))
701 operands[0] = force_reg (HImode, operands[0]);
702 ix86_compare_op0 = operands[0];
703 ix86_compare_op1 = operands[1];
707 (define_expand "cmpqi"
708 [(set (reg:CC FLAGS_REG)
709 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
710 (match_operand:QI 1 "general_operand" "")))]
713 if (MEM_P (operands[0]) && MEM_P (operands[1]))
714 operands[0] = force_reg (QImode, operands[0]);
715 ix86_compare_op0 = operands[0];
716 ix86_compare_op1 = operands[1];
720 (define_insn "cmpdi_ccno_1_rex64"
721 [(set (reg FLAGS_REG)
722 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
723 (match_operand:DI 1 "const0_operand" "n,n")))]
724 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
727 cmp{q}\t{%1, %0|%0, %1}"
728 [(set_attr "type" "test,icmp")
729 (set_attr "length_immediate" "0,1")
730 (set_attr "mode" "DI")])
732 (define_insn "*cmpdi_minus_1_rex64"
733 [(set (reg FLAGS_REG)
734 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
735 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
737 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
738 "cmp{q}\t{%1, %0|%0, %1}"
739 [(set_attr "type" "icmp")
740 (set_attr "mode" "DI")])
742 (define_expand "cmpdi_1_rex64"
743 [(set (reg:CC FLAGS_REG)
744 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
745 (match_operand:DI 1 "general_operand" "")))]
749 (define_insn "cmpdi_1_insn_rex64"
750 [(set (reg FLAGS_REG)
751 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
752 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
753 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
754 "cmp{q}\t{%1, %0|%0, %1}"
755 [(set_attr "type" "icmp")
756 (set_attr "mode" "DI")])
759 (define_insn "*cmpsi_ccno_1"
760 [(set (reg FLAGS_REG)
761 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
762 (match_operand:SI 1 "const0_operand" "n,n")))]
763 "ix86_match_ccmode (insn, CCNOmode)"
766 cmp{l}\t{%1, %0|%0, %1}"
767 [(set_attr "type" "test,icmp")
768 (set_attr "length_immediate" "0,1")
769 (set_attr "mode" "SI")])
771 (define_insn "*cmpsi_minus_1"
772 [(set (reg FLAGS_REG)
773 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
774 (match_operand:SI 1 "general_operand" "ri,mr"))
776 "ix86_match_ccmode (insn, CCGOCmode)"
777 "cmp{l}\t{%1, %0|%0, %1}"
778 [(set_attr "type" "icmp")
779 (set_attr "mode" "SI")])
781 (define_expand "cmpsi_1"
782 [(set (reg:CC FLAGS_REG)
783 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
784 (match_operand:SI 1 "general_operand" "")))]
788 (define_insn "*cmpsi_1_insn"
789 [(set (reg FLAGS_REG)
790 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
791 (match_operand:SI 1 "general_operand" "ri,mr")))]
792 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
793 && ix86_match_ccmode (insn, CCmode)"
794 "cmp{l}\t{%1, %0|%0, %1}"
795 [(set_attr "type" "icmp")
796 (set_attr "mode" "SI")])
798 (define_insn "*cmphi_ccno_1"
799 [(set (reg FLAGS_REG)
800 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
801 (match_operand:HI 1 "const0_operand" "n,n")))]
802 "ix86_match_ccmode (insn, CCNOmode)"
805 cmp{w}\t{%1, %0|%0, %1}"
806 [(set_attr "type" "test,icmp")
807 (set_attr "length_immediate" "0,1")
808 (set_attr "mode" "HI")])
810 (define_insn "*cmphi_minus_1"
811 [(set (reg FLAGS_REG)
812 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
813 (match_operand:HI 1 "general_operand" "ri,mr"))
815 "ix86_match_ccmode (insn, CCGOCmode)"
816 "cmp{w}\t{%1, %0|%0, %1}"
817 [(set_attr "type" "icmp")
818 (set_attr "mode" "HI")])
820 (define_insn "*cmphi_1"
821 [(set (reg FLAGS_REG)
822 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
823 (match_operand:HI 1 "general_operand" "ri,mr")))]
824 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
825 && ix86_match_ccmode (insn, CCmode)"
826 "cmp{w}\t{%1, %0|%0, %1}"
827 [(set_attr "type" "icmp")
828 (set_attr "mode" "HI")])
830 (define_insn "*cmpqi_ccno_1"
831 [(set (reg FLAGS_REG)
832 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
833 (match_operand:QI 1 "const0_operand" "n,n")))]
834 "ix86_match_ccmode (insn, CCNOmode)"
837 cmp{b}\t{$0, %0|%0, 0}"
838 [(set_attr "type" "test,icmp")
839 (set_attr "length_immediate" "0,1")
840 (set_attr "mode" "QI")])
842 (define_insn "*cmpqi_1"
843 [(set (reg FLAGS_REG)
844 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
845 (match_operand:QI 1 "general_operand" "qi,mq")))]
846 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
847 && ix86_match_ccmode (insn, CCmode)"
848 "cmp{b}\t{%1, %0|%0, %1}"
849 [(set_attr "type" "icmp")
850 (set_attr "mode" "QI")])
852 (define_insn "*cmpqi_minus_1"
853 [(set (reg FLAGS_REG)
854 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
855 (match_operand:QI 1 "general_operand" "qi,mq"))
857 "ix86_match_ccmode (insn, CCGOCmode)"
858 "cmp{b}\t{%1, %0|%0, %1}"
859 [(set_attr "type" "icmp")
860 (set_attr "mode" "QI")])
862 (define_insn "*cmpqi_ext_1"
863 [(set (reg FLAGS_REG)
865 (match_operand:QI 0 "general_operand" "Qm")
868 (match_operand 1 "ext_register_operand" "Q")
871 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
872 "cmp{b}\t{%h1, %0|%0, %h1}"
873 [(set_attr "type" "icmp")
874 (set_attr "mode" "QI")])
876 (define_insn "*cmpqi_ext_1_rex64"
877 [(set (reg FLAGS_REG)
879 (match_operand:QI 0 "register_operand" "Q")
882 (match_operand 1 "ext_register_operand" "Q")
885 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
886 "cmp{b}\t{%h1, %0|%0, %h1}"
887 [(set_attr "type" "icmp")
888 (set_attr "mode" "QI")])
890 (define_insn "*cmpqi_ext_2"
891 [(set (reg FLAGS_REG)
895 (match_operand 0 "ext_register_operand" "Q")
898 (match_operand:QI 1 "const0_operand" "n")))]
899 "ix86_match_ccmode (insn, CCNOmode)"
901 [(set_attr "type" "test")
902 (set_attr "length_immediate" "0")
903 (set_attr "mode" "QI")])
905 (define_expand "cmpqi_ext_3"
906 [(set (reg:CC FLAGS_REG)
910 (match_operand 0 "ext_register_operand" "")
913 (match_operand:QI 1 "general_operand" "")))]
917 (define_insn "cmpqi_ext_3_insn"
918 [(set (reg FLAGS_REG)
922 (match_operand 0 "ext_register_operand" "Q")
925 (match_operand:QI 1 "general_operand" "Qmn")))]
926 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
927 "cmp{b}\t{%1, %h0|%h0, %1}"
928 [(set_attr "type" "icmp")
929 (set_attr "mode" "QI")])
931 (define_insn "cmpqi_ext_3_insn_rex64"
932 [(set (reg FLAGS_REG)
936 (match_operand 0 "ext_register_operand" "Q")
939 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
940 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
941 "cmp{b}\t{%1, %h0|%h0, %1}"
942 [(set_attr "type" "icmp")
943 (set_attr "mode" "QI")])
945 (define_insn "*cmpqi_ext_4"
946 [(set (reg FLAGS_REG)
950 (match_operand 0 "ext_register_operand" "Q")
955 (match_operand 1 "ext_register_operand" "Q")
958 "ix86_match_ccmode (insn, CCmode)"
959 "cmp{b}\t{%h1, %h0|%h0, %h1}"
960 [(set_attr "type" "icmp")
961 (set_attr "mode" "QI")])
963 ;; These implement float point compares.
964 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
965 ;; which would allow mix and match FP modes on the compares. Which is what
966 ;; the old patterns did, but with many more of them.
968 (define_expand "cmpxf"
969 [(set (reg:CC FLAGS_REG)
970 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
971 (match_operand:XF 1 "nonmemory_operand" "")))]
974 ix86_compare_op0 = operands[0];
975 ix86_compare_op1 = operands[1];
979 (define_expand "cmp<mode>"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
982 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
983 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
985 ix86_compare_op0 = operands[0];
986 ix86_compare_op1 = operands[1];
990 ;; FP compares, step 1:
991 ;; Set the FP condition codes.
993 ;; CCFPmode compare with exceptions
994 ;; CCFPUmode compare with no exceptions
996 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
997 ;; used to manage the reg stack popping would not be preserved.
999 (define_insn "*cmpfp_0"
1000 [(set (match_operand:HI 0 "register_operand" "=a")
1003 (match_operand 1 "register_operand" "f")
1004 (match_operand 2 "const0_operand" "X"))]
1006 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1007 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1008 "* return output_fp_compare (insn, operands, 0, 0);"
1009 [(set_attr "type" "multi")
1010 (set_attr "unit" "i387")
1012 (cond [(match_operand:SF 1 "" "")
1014 (match_operand:DF 1 "" "")
1017 (const_string "XF")))])
1019 (define_insn_and_split "*cmpfp_0_cc"
1020 [(set (reg:CCFP FLAGS_REG)
1022 (match_operand 1 "register_operand" "f")
1023 (match_operand 2 "const0_operand" "X")))
1024 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1025 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1026 && TARGET_SAHF && !TARGET_CMOVE
1027 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1029 "&& reload_completed"
1032 [(compare:CCFP (match_dup 1)(match_dup 2))]
1034 (set (reg:CC FLAGS_REG)
1035 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1037 [(set_attr "type" "multi")
1038 (set_attr "unit" "i387")
1040 (cond [(match_operand:SF 1 "" "")
1042 (match_operand:DF 1 "" "")
1045 (const_string "XF")))])
1047 (define_insn "*cmpfp_xf"
1048 [(set (match_operand:HI 0 "register_operand" "=a")
1051 (match_operand:XF 1 "register_operand" "f")
1052 (match_operand:XF 2 "register_operand" "f"))]
1055 "* return output_fp_compare (insn, operands, 0, 0);"
1056 [(set_attr "type" "multi")
1057 (set_attr "unit" "i387")
1058 (set_attr "mode" "XF")])
1060 (define_insn_and_split "*cmpfp_xf_cc"
1061 [(set (reg:CCFP FLAGS_REG)
1063 (match_operand:XF 1 "register_operand" "f")
1064 (match_operand:XF 2 "register_operand" "f")))
1065 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1067 && TARGET_SAHF && !TARGET_CMOVE"
1069 "&& reload_completed"
1072 [(compare:CCFP (match_dup 1)(match_dup 2))]
1074 (set (reg:CC FLAGS_REG)
1075 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1077 [(set_attr "type" "multi")
1078 (set_attr "unit" "i387")
1079 (set_attr "mode" "XF")])
1081 (define_insn "*cmpfp_<mode>"
1082 [(set (match_operand:HI 0 "register_operand" "=a")
1085 (match_operand:MODEF 1 "register_operand" "f")
1086 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1089 "* return output_fp_compare (insn, operands, 0, 0);"
1090 [(set_attr "type" "multi")
1091 (set_attr "unit" "i387")
1092 (set_attr "mode" "<MODE>")])
1094 (define_insn_and_split "*cmpfp_<mode>_cc"
1095 [(set (reg:CCFP FLAGS_REG)
1097 (match_operand:MODEF 1 "register_operand" "f")
1098 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1099 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1101 && TARGET_SAHF && !TARGET_CMOVE"
1103 "&& reload_completed"
1106 [(compare:CCFP (match_dup 1)(match_dup 2))]
1108 (set (reg:CC FLAGS_REG)
1109 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1111 [(set_attr "type" "multi")
1112 (set_attr "unit" "i387")
1113 (set_attr "mode" "<MODE>")])
1115 (define_insn "*cmpfp_u"
1116 [(set (match_operand:HI 0 "register_operand" "=a")
1119 (match_operand 1 "register_operand" "f")
1120 (match_operand 2 "register_operand" "f"))]
1122 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1123 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1124 "* return output_fp_compare (insn, operands, 0, 1);"
1125 [(set_attr "type" "multi")
1126 (set_attr "unit" "i387")
1128 (cond [(match_operand:SF 1 "" "")
1130 (match_operand:DF 1 "" "")
1133 (const_string "XF")))])
1135 (define_insn_and_split "*cmpfp_u_cc"
1136 [(set (reg:CCFPU FLAGS_REG)
1138 (match_operand 1 "register_operand" "f")
1139 (match_operand 2 "register_operand" "f")))
1140 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1141 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1142 && TARGET_SAHF && !TARGET_CMOVE
1143 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1145 "&& reload_completed"
1148 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1150 (set (reg:CC FLAGS_REG)
1151 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1153 [(set_attr "type" "multi")
1154 (set_attr "unit" "i387")
1156 (cond [(match_operand:SF 1 "" "")
1158 (match_operand:DF 1 "" "")
1161 (const_string "XF")))])
1163 (define_insn "*cmpfp_<mode>"
1164 [(set (match_operand:HI 0 "register_operand" "=a")
1167 (match_operand 1 "register_operand" "f")
1168 (match_operator 3 "float_operator"
1169 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1171 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1172 && TARGET_USE_<MODE>MODE_FIOP
1173 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1174 "* return output_fp_compare (insn, operands, 0, 0);"
1175 [(set_attr "type" "multi")
1176 (set_attr "unit" "i387")
1177 (set_attr "fp_int_src" "true")
1178 (set_attr "mode" "<MODE>")])
1180 (define_insn_and_split "*cmpfp_<mode>_cc"
1181 [(set (reg:CCFP FLAGS_REG)
1183 (match_operand 1 "register_operand" "f")
1184 (match_operator 3 "float_operator"
1185 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1186 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1187 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1188 && TARGET_SAHF && !TARGET_CMOVE
1189 && TARGET_USE_<MODE>MODE_FIOP
1190 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1192 "&& reload_completed"
1197 (match_op_dup 3 [(match_dup 2)]))]
1199 (set (reg:CC FLAGS_REG)
1200 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1202 [(set_attr "type" "multi")
1203 (set_attr "unit" "i387")
1204 (set_attr "fp_int_src" "true")
1205 (set_attr "mode" "<MODE>")])
1207 ;; FP compares, step 2
1208 ;; Move the fpsw to ax.
1210 (define_insn "x86_fnstsw_1"
1211 [(set (match_operand:HI 0 "register_operand" "=a")
1212 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1215 [(set_attr "length" "2")
1216 (set_attr "mode" "SI")
1217 (set_attr "unit" "i387")])
1219 ;; FP compares, step 3
1220 ;; Get ax into flags, general case.
1222 (define_insn "x86_sahf_1"
1223 [(set (reg:CC FLAGS_REG)
1224 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1228 #ifdef HAVE_AS_IX86_SAHF
1231 return ".byte\t0x9e";
1234 [(set_attr "length" "1")
1235 (set_attr "athlon_decode" "vector")
1236 (set_attr "amdfam10_decode" "direct")
1237 (set_attr "mode" "SI")])
1239 ;; Pentium Pro can do steps 1 through 3 in one go.
1240 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1241 (define_insn "*cmpfp_i_mixed"
1242 [(set (reg:CCFP FLAGS_REG)
1243 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1244 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1245 "TARGET_MIX_SSE_I387
1246 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1247 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1248 "* return output_fp_compare (insn, operands, 1, 0);"
1249 [(set_attr "type" "fcmp,ssecomi")
1251 (if_then_else (match_operand:SF 1 "" "")
1253 (const_string "DF")))
1254 (set_attr "athlon_decode" "vector")
1255 (set_attr "amdfam10_decode" "direct")])
1257 (define_insn "*cmpfp_i_sse"
1258 [(set (reg:CCFP FLAGS_REG)
1259 (compare:CCFP (match_operand 0 "register_operand" "x")
1260 (match_operand 1 "nonimmediate_operand" "xm")))]
1262 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1263 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1264 "* return output_fp_compare (insn, operands, 1, 0);"
1265 [(set_attr "type" "ssecomi")
1267 (if_then_else (match_operand:SF 1 "" "")
1269 (const_string "DF")))
1270 (set_attr "athlon_decode" "vector")
1271 (set_attr "amdfam10_decode" "direct")])
1273 (define_insn "*cmpfp_i_i387"
1274 [(set (reg:CCFP FLAGS_REG)
1275 (compare:CCFP (match_operand 0 "register_operand" "f")
1276 (match_operand 1 "register_operand" "f")))]
1277 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1279 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1280 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1281 "* return output_fp_compare (insn, operands, 1, 0);"
1282 [(set_attr "type" "fcmp")
1284 (cond [(match_operand:SF 1 "" "")
1286 (match_operand:DF 1 "" "")
1289 (const_string "XF")))
1290 (set_attr "athlon_decode" "vector")
1291 (set_attr "amdfam10_decode" "direct")])
1293 (define_insn "*cmpfp_iu_mixed"
1294 [(set (reg:CCFPU FLAGS_REG)
1295 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1296 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1297 "TARGET_MIX_SSE_I387
1298 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1299 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1300 "* return output_fp_compare (insn, operands, 1, 1);"
1301 [(set_attr "type" "fcmp,ssecomi")
1303 (if_then_else (match_operand:SF 1 "" "")
1305 (const_string "DF")))
1306 (set_attr "athlon_decode" "vector")
1307 (set_attr "amdfam10_decode" "direct")])
1309 (define_insn "*cmpfp_iu_sse"
1310 [(set (reg:CCFPU FLAGS_REG)
1311 (compare:CCFPU (match_operand 0 "register_operand" "x")
1312 (match_operand 1 "nonimmediate_operand" "xm")))]
1314 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1315 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1316 "* return output_fp_compare (insn, operands, 1, 1);"
1317 [(set_attr "type" "ssecomi")
1319 (if_then_else (match_operand:SF 1 "" "")
1321 (const_string "DF")))
1322 (set_attr "athlon_decode" "vector")
1323 (set_attr "amdfam10_decode" "direct")])
1325 (define_insn "*cmpfp_iu_387"
1326 [(set (reg:CCFPU FLAGS_REG)
1327 (compare:CCFPU (match_operand 0 "register_operand" "f")
1328 (match_operand 1 "register_operand" "f")))]
1329 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1331 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1332 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1333 "* return output_fp_compare (insn, operands, 1, 1);"
1334 [(set_attr "type" "fcmp")
1336 (cond [(match_operand:SF 1 "" "")
1338 (match_operand:DF 1 "" "")
1341 (const_string "XF")))
1342 (set_attr "athlon_decode" "vector")
1343 (set_attr "amdfam10_decode" "direct")])
1345 ;; Move instructions.
1347 ;; General case of fullword move.
1349 (define_expand "movsi"
1350 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1351 (match_operand:SI 1 "general_operand" ""))]
1353 "ix86_expand_move (SImode, operands); DONE;")
1355 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1358 ;; %%% We don't use a post-inc memory reference because x86 is not a
1359 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1360 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1361 ;; targets without our curiosities, and it is just as easy to represent
1362 ;; this differently.
1364 (define_insn "*pushsi2"
1365 [(set (match_operand:SI 0 "push_operand" "=<")
1366 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1369 [(set_attr "type" "push")
1370 (set_attr "mode" "SI")])
1372 ;; For 64BIT abi we always round up to 8 bytes.
1373 (define_insn "*pushsi2_rex64"
1374 [(set (match_operand:SI 0 "push_operand" "=X")
1375 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1378 [(set_attr "type" "push")
1379 (set_attr "mode" "SI")])
1381 (define_insn "*pushsi2_prologue"
1382 [(set (match_operand:SI 0 "push_operand" "=<")
1383 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1384 (clobber (mem:BLK (scratch)))]
1387 [(set_attr "type" "push")
1388 (set_attr "mode" "SI")])
1390 (define_insn "*popsi1_epilogue"
1391 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1392 (mem:SI (reg:SI SP_REG)))
1393 (set (reg:SI SP_REG)
1394 (plus:SI (reg:SI SP_REG) (const_int 4)))
1395 (clobber (mem:BLK (scratch)))]
1398 [(set_attr "type" "pop")
1399 (set_attr "mode" "SI")])
1401 (define_insn "popsi1"
1402 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1403 (mem:SI (reg:SI SP_REG)))
1404 (set (reg:SI SP_REG)
1405 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1408 [(set_attr "type" "pop")
1409 (set_attr "mode" "SI")])
1411 (define_insn "*movsi_xor"
1412 [(set (match_operand:SI 0 "register_operand" "=r")
1413 (match_operand:SI 1 "const0_operand" "i"))
1414 (clobber (reg:CC FLAGS_REG))]
1415 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1417 [(set_attr "type" "alu1")
1418 (set_attr "mode" "SI")
1419 (set_attr "length_immediate" "0")])
1421 (define_insn "*movsi_or"
1422 [(set (match_operand:SI 0 "register_operand" "=r")
1423 (match_operand:SI 1 "immediate_operand" "i"))
1424 (clobber (reg:CC FLAGS_REG))]
1426 && operands[1] == constm1_rtx
1427 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1429 operands[1] = constm1_rtx;
1430 return "or{l}\t{%1, %0|%0, %1}";
1432 [(set_attr "type" "alu1")
1433 (set_attr "mode" "SI")
1434 (set_attr "length_immediate" "1")])
1436 (define_insn "*movsi_1"
1437 [(set (match_operand:SI 0 "nonimmediate_operand"
1438 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1439 (match_operand:SI 1 "general_operand"
1440 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1441 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1443 switch (get_attr_type (insn))
1446 if (get_attr_mode (insn) == MODE_TI)
1447 return "pxor\t%0, %0";
1448 return "xorps\t%0, %0";
1451 switch (get_attr_mode (insn))
1454 return "movdqa\t{%1, %0|%0, %1}";
1456 return "movaps\t{%1, %0|%0, %1}";
1458 return "movd\t{%1, %0|%0, %1}";
1460 return "movss\t{%1, %0|%0, %1}";
1466 return "pxor\t%0, %0";
1469 if (get_attr_mode (insn) == MODE_DI)
1470 return "movq\t{%1, %0|%0, %1}";
1471 return "movd\t{%1, %0|%0, %1}";
1474 return "lea{l}\t{%1, %0|%0, %1}";
1477 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1478 return "mov{l}\t{%1, %0|%0, %1}";
1482 (cond [(eq_attr "alternative" "2")
1483 (const_string "mmxadd")
1484 (eq_attr "alternative" "3,4,5")
1485 (const_string "mmxmov")
1486 (eq_attr "alternative" "6")
1487 (const_string "sselog1")
1488 (eq_attr "alternative" "7,8,9,10,11")
1489 (const_string "ssemov")
1490 (match_operand:DI 1 "pic_32bit_operand" "")
1491 (const_string "lea")
1493 (const_string "imov")))
1495 (cond [(eq_attr "alternative" "2,3")
1497 (eq_attr "alternative" "6,7")
1499 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1500 (const_string "V4SF")
1501 (const_string "TI"))
1502 (and (eq_attr "alternative" "8,9,10,11")
1503 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1506 (const_string "SI")))])
1508 ;; Stores and loads of ax to arbitrary constant address.
1509 ;; We fake an second form of instruction to force reload to load address
1510 ;; into register when rax is not available
1511 (define_insn "*movabssi_1_rex64"
1512 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1513 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1514 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1516 movabs{l}\t{%1, %P0|%P0, %1}
1517 mov{l}\t{%1, %a0|%a0, %1}"
1518 [(set_attr "type" "imov")
1519 (set_attr "modrm" "0,*")
1520 (set_attr "length_address" "8,0")
1521 (set_attr "length_immediate" "0,*")
1522 (set_attr "memory" "store")
1523 (set_attr "mode" "SI")])
1525 (define_insn "*movabssi_2_rex64"
1526 [(set (match_operand:SI 0 "register_operand" "=a,r")
1527 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1528 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1530 movabs{l}\t{%P1, %0|%0, %P1}
1531 mov{l}\t{%a1, %0|%0, %a1}"
1532 [(set_attr "type" "imov")
1533 (set_attr "modrm" "0,*")
1534 (set_attr "length_address" "8,0")
1535 (set_attr "length_immediate" "0")
1536 (set_attr "memory" "load")
1537 (set_attr "mode" "SI")])
1539 (define_insn "*swapsi"
1540 [(set (match_operand:SI 0 "register_operand" "+r")
1541 (match_operand:SI 1 "register_operand" "+r"))
1546 [(set_attr "type" "imov")
1547 (set_attr "mode" "SI")
1548 (set_attr "pent_pair" "np")
1549 (set_attr "athlon_decode" "vector")
1550 (set_attr "amdfam10_decode" "double")])
1552 (define_expand "movhi"
1553 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1554 (match_operand:HI 1 "general_operand" ""))]
1556 "ix86_expand_move (HImode, operands); DONE;")
1558 (define_insn "*pushhi2"
1559 [(set (match_operand:HI 0 "push_operand" "=X")
1560 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1563 [(set_attr "type" "push")
1564 (set_attr "mode" "SI")])
1566 ;; For 64BIT abi we always round up to 8 bytes.
1567 (define_insn "*pushhi2_rex64"
1568 [(set (match_operand:HI 0 "push_operand" "=X")
1569 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1572 [(set_attr "type" "push")
1573 (set_attr "mode" "DI")])
1575 (define_insn "*movhi_1"
1576 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1577 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1578 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1580 switch (get_attr_type (insn))
1583 /* movzwl is faster than movw on p2 due to partial word stalls,
1584 though not as fast as an aligned movl. */
1585 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1587 if (get_attr_mode (insn) == MODE_SI)
1588 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1590 return "mov{w}\t{%1, %0|%0, %1}";
1594 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1595 (const_string "imov")
1596 (and (eq_attr "alternative" "0")
1597 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1599 (eq (symbol_ref "TARGET_HIMODE_MATH")
1601 (const_string "imov")
1602 (and (eq_attr "alternative" "1,2")
1603 (match_operand:HI 1 "aligned_operand" ""))
1604 (const_string "imov")
1605 (and (ne (symbol_ref "TARGET_MOVX")
1607 (eq_attr "alternative" "0,2"))
1608 (const_string "imovx")
1610 (const_string "imov")))
1612 (cond [(eq_attr "type" "imovx")
1614 (and (eq_attr "alternative" "1,2")
1615 (match_operand:HI 1 "aligned_operand" ""))
1617 (and (eq_attr "alternative" "0")
1618 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1620 (eq (symbol_ref "TARGET_HIMODE_MATH")
1624 (const_string "HI")))])
1626 ;; Stores and loads of ax to arbitrary constant address.
1627 ;; We fake an second form of instruction to force reload to load address
1628 ;; into register when rax is not available
1629 (define_insn "*movabshi_1_rex64"
1630 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1631 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1632 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1634 movabs{w}\t{%1, %P0|%P0, %1}
1635 mov{w}\t{%1, %a0|%a0, %1}"
1636 [(set_attr "type" "imov")
1637 (set_attr "modrm" "0,*")
1638 (set_attr "length_address" "8,0")
1639 (set_attr "length_immediate" "0,*")
1640 (set_attr "memory" "store")
1641 (set_attr "mode" "HI")])
1643 (define_insn "*movabshi_2_rex64"
1644 [(set (match_operand:HI 0 "register_operand" "=a,r")
1645 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1646 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1648 movabs{w}\t{%P1, %0|%0, %P1}
1649 mov{w}\t{%a1, %0|%0, %a1}"
1650 [(set_attr "type" "imov")
1651 (set_attr "modrm" "0,*")
1652 (set_attr "length_address" "8,0")
1653 (set_attr "length_immediate" "0")
1654 (set_attr "memory" "load")
1655 (set_attr "mode" "HI")])
1657 (define_insn "*swaphi_1"
1658 [(set (match_operand:HI 0 "register_operand" "+r")
1659 (match_operand:HI 1 "register_operand" "+r"))
1662 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1664 [(set_attr "type" "imov")
1665 (set_attr "mode" "SI")
1666 (set_attr "pent_pair" "np")
1667 (set_attr "athlon_decode" "vector")
1668 (set_attr "amdfam10_decode" "double")])
1670 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1671 (define_insn "*swaphi_2"
1672 [(set (match_operand:HI 0 "register_operand" "+r")
1673 (match_operand:HI 1 "register_operand" "+r"))
1676 "TARGET_PARTIAL_REG_STALL"
1678 [(set_attr "type" "imov")
1679 (set_attr "mode" "HI")
1680 (set_attr "pent_pair" "np")
1681 (set_attr "athlon_decode" "vector")])
1683 (define_expand "movstricthi"
1684 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1685 (match_operand:HI 1 "general_operand" ""))]
1686 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1688 /* Don't generate memory->memory moves, go through a register */
1689 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1690 operands[1] = force_reg (HImode, operands[1]);
1693 (define_insn "*movstricthi_1"
1694 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1695 (match_operand:HI 1 "general_operand" "rn,m"))]
1696 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1697 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1698 "mov{w}\t{%1, %0|%0, %1}"
1699 [(set_attr "type" "imov")
1700 (set_attr "mode" "HI")])
1702 (define_insn "*movstricthi_xor"
1703 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1704 (match_operand:HI 1 "const0_operand" "i"))
1705 (clobber (reg:CC FLAGS_REG))]
1707 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1709 [(set_attr "type" "alu1")
1710 (set_attr "mode" "HI")
1711 (set_attr "length_immediate" "0")])
1713 (define_expand "movqi"
1714 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1715 (match_operand:QI 1 "general_operand" ""))]
1717 "ix86_expand_move (QImode, operands); DONE;")
1719 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1720 ;; "push a byte". But actually we use pushl, which has the effect
1721 ;; of rounding the amount pushed up to a word.
1723 (define_insn "*pushqi2"
1724 [(set (match_operand:QI 0 "push_operand" "=X")
1725 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1728 [(set_attr "type" "push")
1729 (set_attr "mode" "SI")])
1731 ;; For 64BIT abi we always round up to 8 bytes.
1732 (define_insn "*pushqi2_rex64"
1733 [(set (match_operand:QI 0 "push_operand" "=X")
1734 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1737 [(set_attr "type" "push")
1738 (set_attr "mode" "DI")])
1740 ;; Situation is quite tricky about when to choose full sized (SImode) move
1741 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1742 ;; partial register dependency machines (such as AMD Athlon), where QImode
1743 ;; moves issue extra dependency and for partial register stalls machines
1744 ;; that don't use QImode patterns (and QImode move cause stall on the next
1747 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1748 ;; register stall machines with, where we use QImode instructions, since
1749 ;; partial register stall can be caused there. Then we use movzx.
1750 (define_insn "*movqi_1"
1751 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1752 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1753 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1755 switch (get_attr_type (insn))
1758 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1759 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1761 if (get_attr_mode (insn) == MODE_SI)
1762 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1764 return "mov{b}\t{%1, %0|%0, %1}";
1768 (cond [(and (eq_attr "alternative" "5")
1769 (not (match_operand:QI 1 "aligned_operand" "")))
1770 (const_string "imovx")
1771 (ne (symbol_ref "optimize_size") (const_int 0))
1772 (const_string "imov")
1773 (and (eq_attr "alternative" "3")
1774 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1776 (eq (symbol_ref "TARGET_QIMODE_MATH")
1778 (const_string "imov")
1779 (eq_attr "alternative" "3,5")
1780 (const_string "imovx")
1781 (and (ne (symbol_ref "TARGET_MOVX")
1783 (eq_attr "alternative" "2"))
1784 (const_string "imovx")
1786 (const_string "imov")))
1788 (cond [(eq_attr "alternative" "3,4,5")
1790 (eq_attr "alternative" "6")
1792 (eq_attr "type" "imovx")
1794 (and (eq_attr "type" "imov")
1795 (and (eq_attr "alternative" "0,1")
1796 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1798 (and (eq (symbol_ref "optimize_size")
1800 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1803 ;; Avoid partial register stalls when not using QImode arithmetic
1804 (and (eq_attr "type" "imov")
1805 (and (eq_attr "alternative" "0,1")
1806 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1808 (eq (symbol_ref "TARGET_QIMODE_MATH")
1812 (const_string "QI")))])
1814 (define_insn "*swapqi_1"
1815 [(set (match_operand:QI 0 "register_operand" "+r")
1816 (match_operand:QI 1 "register_operand" "+r"))
1819 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1821 [(set_attr "type" "imov")
1822 (set_attr "mode" "SI")
1823 (set_attr "pent_pair" "np")
1824 (set_attr "athlon_decode" "vector")
1825 (set_attr "amdfam10_decode" "vector")])
1827 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1828 (define_insn "*swapqi_2"
1829 [(set (match_operand:QI 0 "register_operand" "+q")
1830 (match_operand:QI 1 "register_operand" "+q"))
1833 "TARGET_PARTIAL_REG_STALL"
1835 [(set_attr "type" "imov")
1836 (set_attr "mode" "QI")
1837 (set_attr "pent_pair" "np")
1838 (set_attr "athlon_decode" "vector")])
1840 (define_expand "movstrictqi"
1841 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1842 (match_operand:QI 1 "general_operand" ""))]
1843 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1845 /* Don't generate memory->memory moves, go through a register. */
1846 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1847 operands[1] = force_reg (QImode, operands[1]);
1850 (define_insn "*movstrictqi_1"
1851 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1852 (match_operand:QI 1 "general_operand" "*qn,m"))]
1853 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1854 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1855 "mov{b}\t{%1, %0|%0, %1}"
1856 [(set_attr "type" "imov")
1857 (set_attr "mode" "QI")])
1859 (define_insn "*movstrictqi_xor"
1860 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1861 (match_operand:QI 1 "const0_operand" "i"))
1862 (clobber (reg:CC FLAGS_REG))]
1863 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1865 [(set_attr "type" "alu1")
1866 (set_attr "mode" "QI")
1867 (set_attr "length_immediate" "0")])
1869 (define_insn "*movsi_extv_1"
1870 [(set (match_operand:SI 0 "register_operand" "=R")
1871 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1875 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1876 [(set_attr "type" "imovx")
1877 (set_attr "mode" "SI")])
1879 (define_insn "*movhi_extv_1"
1880 [(set (match_operand:HI 0 "register_operand" "=R")
1881 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1885 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1886 [(set_attr "type" "imovx")
1887 (set_attr "mode" "SI")])
1889 (define_insn "*movqi_extv_1"
1890 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1891 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1896 switch (get_attr_type (insn))
1899 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1901 return "mov{b}\t{%h1, %0|%0, %h1}";
1905 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1906 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1907 (ne (symbol_ref "TARGET_MOVX")
1909 (const_string "imovx")
1910 (const_string "imov")))
1912 (if_then_else (eq_attr "type" "imovx")
1914 (const_string "QI")))])
1916 (define_insn "*movqi_extv_1_rex64"
1917 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1918 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1923 switch (get_attr_type (insn))
1926 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1928 return "mov{b}\t{%h1, %0|%0, %h1}";
1932 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1933 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1934 (ne (symbol_ref "TARGET_MOVX")
1936 (const_string "imovx")
1937 (const_string "imov")))
1939 (if_then_else (eq_attr "type" "imovx")
1941 (const_string "QI")))])
1943 ;; Stores and loads of ax to arbitrary constant address.
1944 ;; We fake an second form of instruction to force reload to load address
1945 ;; into register when rax is not available
1946 (define_insn "*movabsqi_1_rex64"
1947 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1948 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1949 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1951 movabs{b}\t{%1, %P0|%P0, %1}
1952 mov{b}\t{%1, %a0|%a0, %1}"
1953 [(set_attr "type" "imov")
1954 (set_attr "modrm" "0,*")
1955 (set_attr "length_address" "8,0")
1956 (set_attr "length_immediate" "0,*")
1957 (set_attr "memory" "store")
1958 (set_attr "mode" "QI")])
1960 (define_insn "*movabsqi_2_rex64"
1961 [(set (match_operand:QI 0 "register_operand" "=a,r")
1962 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1963 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1965 movabs{b}\t{%P1, %0|%0, %P1}
1966 mov{b}\t{%a1, %0|%0, %a1}"
1967 [(set_attr "type" "imov")
1968 (set_attr "modrm" "0,*")
1969 (set_attr "length_address" "8,0")
1970 (set_attr "length_immediate" "0")
1971 (set_attr "memory" "load")
1972 (set_attr "mode" "QI")])
1974 (define_insn "*movdi_extzv_1"
1975 [(set (match_operand:DI 0 "register_operand" "=R")
1976 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1980 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1981 [(set_attr "type" "imovx")
1982 (set_attr "mode" "DI")])
1984 (define_insn "*movsi_extzv_1"
1985 [(set (match_operand:SI 0 "register_operand" "=R")
1986 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1990 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1991 [(set_attr "type" "imovx")
1992 (set_attr "mode" "SI")])
1994 (define_insn "*movqi_extzv_2"
1995 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1996 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2001 switch (get_attr_type (insn))
2004 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2006 return "mov{b}\t{%h1, %0|%0, %h1}";
2010 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2011 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2012 (ne (symbol_ref "TARGET_MOVX")
2014 (const_string "imovx")
2015 (const_string "imov")))
2017 (if_then_else (eq_attr "type" "imovx")
2019 (const_string "QI")))])
2021 (define_insn "*movqi_extzv_2_rex64"
2022 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2023 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2028 switch (get_attr_type (insn))
2031 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2033 return "mov{b}\t{%h1, %0|%0, %h1}";
2037 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2038 (ne (symbol_ref "TARGET_MOVX")
2040 (const_string "imovx")
2041 (const_string "imov")))
2043 (if_then_else (eq_attr "type" "imovx")
2045 (const_string "QI")))])
2047 (define_insn "movsi_insv_1"
2048 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2051 (match_operand:SI 1 "general_operand" "Qmn"))]
2053 "mov{b}\t{%b1, %h0|%h0, %b1}"
2054 [(set_attr "type" "imov")
2055 (set_attr "mode" "QI")])
2057 (define_insn "*movsi_insv_1_rex64"
2058 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2061 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2063 "mov{b}\t{%b1, %h0|%h0, %b1}"
2064 [(set_attr "type" "imov")
2065 (set_attr "mode" "QI")])
2067 (define_insn "movdi_insv_1_rex64"
2068 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2071 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2073 "mov{b}\t{%b1, %h0|%h0, %b1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "mode" "QI")])
2077 (define_insn "*movqi_insv_2"
2078 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2081 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2084 "mov{b}\t{%h1, %h0|%h0, %h1}"
2085 [(set_attr "type" "imov")
2086 (set_attr "mode" "QI")])
2088 (define_expand "movdi"
2089 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2090 (match_operand:DI 1 "general_operand" ""))]
2092 "ix86_expand_move (DImode, operands); DONE;")
2094 (define_insn "*pushdi"
2095 [(set (match_operand:DI 0 "push_operand" "=<")
2096 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2100 (define_insn "*pushdi2_rex64"
2101 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2102 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2107 [(set_attr "type" "push,multi")
2108 (set_attr "mode" "DI")])
2110 ;; Convert impossible pushes of immediate to existing instructions.
2111 ;; First try to get scratch register and go through it. In case this
2112 ;; fails, push sign extended lower part first and then overwrite
2113 ;; upper part by 32bit move.
2115 [(match_scratch:DI 2 "r")
2116 (set (match_operand:DI 0 "push_operand" "")
2117 (match_operand:DI 1 "immediate_operand" ""))]
2118 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2119 && !x86_64_immediate_operand (operands[1], DImode)"
2120 [(set (match_dup 2) (match_dup 1))
2121 (set (match_dup 0) (match_dup 2))]
2124 ;; We need to define this as both peepholer and splitter for case
2125 ;; peephole2 pass is not run.
2126 ;; "&& 1" is needed to keep it from matching the previous pattern.
2128 [(set (match_operand:DI 0 "push_operand" "")
2129 (match_operand:DI 1 "immediate_operand" ""))]
2130 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2131 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2132 [(set (match_dup 0) (match_dup 1))
2133 (set (match_dup 2) (match_dup 3))]
2134 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2135 operands[1] = gen_lowpart (DImode, operands[2]);
2136 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2141 [(set (match_operand:DI 0 "push_operand" "")
2142 (match_operand:DI 1 "immediate_operand" ""))]
2143 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2144 ? epilogue_completed : reload_completed)
2145 && !symbolic_operand (operands[1], DImode)
2146 && !x86_64_immediate_operand (operands[1], DImode)"
2147 [(set (match_dup 0) (match_dup 1))
2148 (set (match_dup 2) (match_dup 3))]
2149 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2150 operands[1] = gen_lowpart (DImode, operands[2]);
2151 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2155 (define_insn "*pushdi2_prologue_rex64"
2156 [(set (match_operand:DI 0 "push_operand" "=<")
2157 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2158 (clobber (mem:BLK (scratch)))]
2161 [(set_attr "type" "push")
2162 (set_attr "mode" "DI")])
2164 (define_insn "*popdi1_epilogue_rex64"
2165 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2166 (mem:DI (reg:DI SP_REG)))
2167 (set (reg:DI SP_REG)
2168 (plus:DI (reg:DI SP_REG) (const_int 8)))
2169 (clobber (mem:BLK (scratch)))]
2172 [(set_attr "type" "pop")
2173 (set_attr "mode" "DI")])
2175 (define_insn "popdi1"
2176 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2177 (mem:DI (reg:DI SP_REG)))
2178 (set (reg:DI SP_REG)
2179 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2182 [(set_attr "type" "pop")
2183 (set_attr "mode" "DI")])
2185 (define_insn "*movdi_xor_rex64"
2186 [(set (match_operand:DI 0 "register_operand" "=r")
2187 (match_operand:DI 1 "const0_operand" "i"))
2188 (clobber (reg:CC FLAGS_REG))]
2189 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2190 && reload_completed"
2192 [(set_attr "type" "alu1")
2193 (set_attr "mode" "SI")
2194 (set_attr "length_immediate" "0")])
2196 (define_insn "*movdi_or_rex64"
2197 [(set (match_operand:DI 0 "register_operand" "=r")
2198 (match_operand:DI 1 "const_int_operand" "i"))
2199 (clobber (reg:CC FLAGS_REG))]
2200 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2202 && operands[1] == constm1_rtx"
2204 operands[1] = constm1_rtx;
2205 return "or{q}\t{%1, %0|%0, %1}";
2207 [(set_attr "type" "alu1")
2208 (set_attr "mode" "DI")
2209 (set_attr "length_immediate" "1")])
2211 (define_insn "*movdi_2"
2212 [(set (match_operand:DI 0 "nonimmediate_operand"
2213 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2214 (match_operand:DI 1 "general_operand"
2215 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2216 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2221 movq\t{%1, %0|%0, %1}
2222 movq\t{%1, %0|%0, %1}
2224 movq\t{%1, %0|%0, %1}
2225 movdqa\t{%1, %0|%0, %1}
2226 movq\t{%1, %0|%0, %1}
2228 movlps\t{%1, %0|%0, %1}
2229 movaps\t{%1, %0|%0, %1}
2230 movlps\t{%1, %0|%0, %1}"
2231 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2232 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2235 [(set (match_operand:DI 0 "push_operand" "")
2236 (match_operand:DI 1 "general_operand" ""))]
2237 "!TARGET_64BIT && reload_completed
2238 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2240 "ix86_split_long_move (operands); DONE;")
2242 ;; %%% This multiword shite has got to go.
2244 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2245 (match_operand:DI 1 "general_operand" ""))]
2246 "!TARGET_64BIT && reload_completed
2247 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2248 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2250 "ix86_split_long_move (operands); DONE;")
2252 (define_insn "*movdi_1_rex64"
2253 [(set (match_operand:DI 0 "nonimmediate_operand"
2254 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2255 (match_operand:DI 1 "general_operand"
2256 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2257 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2259 switch (get_attr_type (insn))
2262 if (SSE_REG_P (operands[0]))
2263 return "movq2dq\t{%1, %0|%0, %1}";
2265 return "movdq2q\t{%1, %0|%0, %1}";
2268 if (get_attr_mode (insn) == MODE_TI)
2269 return "movdqa\t{%1, %0|%0, %1}";
2273 /* Moves from and into integer register is done using movd
2274 opcode with REX prefix. */
2275 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2276 return "movd\t{%1, %0|%0, %1}";
2277 return "movq\t{%1, %0|%0, %1}";
2281 return "pxor\t%0, %0";
2287 return "lea{q}\t{%a1, %0|%0, %a1}";
2290 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2291 if (get_attr_mode (insn) == MODE_SI)
2292 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2293 else if (which_alternative == 2)
2294 return "movabs{q}\t{%1, %0|%0, %1}";
2296 return "mov{q}\t{%1, %0|%0, %1}";
2300 (cond [(eq_attr "alternative" "5")
2301 (const_string "mmxadd")
2302 (eq_attr "alternative" "6,7,8,9,10")
2303 (const_string "mmxmov")
2304 (eq_attr "alternative" "11")
2305 (const_string "sselog1")
2306 (eq_attr "alternative" "12,13,14,15,16")
2307 (const_string "ssemov")
2308 (eq_attr "alternative" "17,18")
2309 (const_string "ssecvt")
2310 (eq_attr "alternative" "4")
2311 (const_string "multi")
2312 (match_operand:DI 1 "pic_32bit_operand" "")
2313 (const_string "lea")
2315 (const_string "imov")))
2316 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2317 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2318 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2320 ;; Stores and loads of ax to arbitrary constant address.
2321 ;; We fake an second form of instruction to force reload to load address
2322 ;; into register when rax is not available
2323 (define_insn "*movabsdi_1_rex64"
2324 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2325 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2326 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2328 movabs{q}\t{%1, %P0|%P0, %1}
2329 mov{q}\t{%1, %a0|%a0, %1}"
2330 [(set_attr "type" "imov")
2331 (set_attr "modrm" "0,*")
2332 (set_attr "length_address" "8,0")
2333 (set_attr "length_immediate" "0,*")
2334 (set_attr "memory" "store")
2335 (set_attr "mode" "DI")])
2337 (define_insn "*movabsdi_2_rex64"
2338 [(set (match_operand:DI 0 "register_operand" "=a,r")
2339 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2340 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2342 movabs{q}\t{%P1, %0|%0, %P1}
2343 mov{q}\t{%a1, %0|%0, %a1}"
2344 [(set_attr "type" "imov")
2345 (set_attr "modrm" "0,*")
2346 (set_attr "length_address" "8,0")
2347 (set_attr "length_immediate" "0")
2348 (set_attr "memory" "load")
2349 (set_attr "mode" "DI")])
2351 ;; Convert impossible stores of immediate to existing instructions.
2352 ;; First try to get scratch register and go through it. In case this
2353 ;; fails, move by 32bit parts.
2355 [(match_scratch:DI 2 "r")
2356 (set (match_operand:DI 0 "memory_operand" "")
2357 (match_operand:DI 1 "immediate_operand" ""))]
2358 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2359 && !x86_64_immediate_operand (operands[1], DImode)"
2360 [(set (match_dup 2) (match_dup 1))
2361 (set (match_dup 0) (match_dup 2))]
2364 ;; We need to define this as both peepholer and splitter for case
2365 ;; peephole2 pass is not run.
2366 ;; "&& 1" is needed to keep it from matching the previous pattern.
2368 [(set (match_operand:DI 0 "memory_operand" "")
2369 (match_operand:DI 1 "immediate_operand" ""))]
2370 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2371 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2372 [(set (match_dup 2) (match_dup 3))
2373 (set (match_dup 4) (match_dup 5))]
2374 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2377 [(set (match_operand:DI 0 "memory_operand" "")
2378 (match_operand:DI 1 "immediate_operand" ""))]
2379 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2380 ? epilogue_completed : reload_completed)
2381 && !symbolic_operand (operands[1], DImode)
2382 && !x86_64_immediate_operand (operands[1], DImode)"
2383 [(set (match_dup 2) (match_dup 3))
2384 (set (match_dup 4) (match_dup 5))]
2385 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2387 (define_insn "*swapdi_rex64"
2388 [(set (match_operand:DI 0 "register_operand" "+r")
2389 (match_operand:DI 1 "register_operand" "+r"))
2394 [(set_attr "type" "imov")
2395 (set_attr "mode" "DI")
2396 (set_attr "pent_pair" "np")
2397 (set_attr "athlon_decode" "vector")
2398 (set_attr "amdfam10_decode" "double")])
2400 (define_expand "movti"
2401 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2402 (match_operand:TI 1 "nonimmediate_operand" ""))]
2403 "TARGET_SSE || TARGET_64BIT"
2406 ix86_expand_move (TImode, operands);
2407 else if (push_operand (operands[0], TImode))
2408 ix86_expand_push (TImode, operands[1]);
2410 ix86_expand_vector_move (TImode, operands);
2414 (define_insn "*movti_internal"
2415 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2416 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2417 "TARGET_SSE && !TARGET_64BIT
2418 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2420 switch (which_alternative)
2423 if (get_attr_mode (insn) == MODE_V4SF)
2424 return "xorps\t%0, %0";
2426 return "pxor\t%0, %0";
2429 /* TDmode values are passed as TImode on the stack. Moving them
2430 to stack may result in unaligned memory access. */
2431 if (misaligned_operand (operands[0], TImode)
2432 || misaligned_operand (operands[1], TImode))
2434 if (get_attr_mode (insn) == MODE_V4SF)
2435 return "movups\t{%1, %0|%0, %1}";
2437 return "movdqu\t{%1, %0|%0, %1}";
2441 if (get_attr_mode (insn) == MODE_V4SF)
2442 return "movaps\t{%1, %0|%0, %1}";
2444 return "movdqa\t{%1, %0|%0, %1}";
2450 [(set_attr "type" "sselog1,ssemov,ssemov")
2452 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2453 (ne (symbol_ref "optimize_size") (const_int 0)))
2454 (const_string "V4SF")
2455 (and (eq_attr "alternative" "2")
2456 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2458 (const_string "V4SF")]
2459 (const_string "TI")))])
2461 (define_insn "*movti_rex64"
2462 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2463 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2465 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2467 switch (which_alternative)
2473 if (get_attr_mode (insn) == MODE_V4SF)
2474 return "xorps\t%0, %0";
2476 return "pxor\t%0, %0";
2479 /* TDmode values are passed as TImode on the stack. Moving them
2480 to stack may result in unaligned memory access. */
2481 if (misaligned_operand (operands[0], TImode)
2482 || misaligned_operand (operands[1], TImode))
2484 if (get_attr_mode (insn) == MODE_V4SF)
2485 return "movups\t{%1, %0|%0, %1}";
2487 return "movdqu\t{%1, %0|%0, %1}";
2491 if (get_attr_mode (insn) == MODE_V4SF)
2492 return "movaps\t{%1, %0|%0, %1}";
2494 return "movdqa\t{%1, %0|%0, %1}";
2500 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2502 (cond [(eq_attr "alternative" "2,3")
2504 (ne (symbol_ref "optimize_size")
2506 (const_string "V4SF")
2507 (const_string "TI"))
2508 (eq_attr "alternative" "4")
2510 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2512 (ne (symbol_ref "optimize_size")
2514 (const_string "V4SF")
2515 (const_string "TI"))]
2516 (const_string "DI")))])
2519 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2520 (match_operand:TI 1 "general_operand" ""))]
2521 "reload_completed && !SSE_REG_P (operands[0])
2522 && !SSE_REG_P (operands[1])"
2524 "ix86_split_long_move (operands); DONE;")
2526 ;; This expands to what emit_move_complex would generate if we didn't
2527 ;; have a movti pattern. Having this avoids problems with reload on
2528 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2529 ;; to have around all the time.
2530 (define_expand "movcdi"
2531 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2532 (match_operand:CDI 1 "general_operand" ""))]
2535 if (push_operand (operands[0], CDImode))
2536 emit_move_complex_push (CDImode, operands[0], operands[1]);
2538 emit_move_complex_parts (operands[0], operands[1]);
2542 (define_expand "movsf"
2543 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2544 (match_operand:SF 1 "general_operand" ""))]
2546 "ix86_expand_move (SFmode, operands); DONE;")
2548 (define_insn "*pushsf"
2549 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2550 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2553 /* Anything else should be already split before reg-stack. */
2554 gcc_assert (which_alternative == 1);
2555 return "push{l}\t%1";
2557 [(set_attr "type" "multi,push,multi")
2558 (set_attr "unit" "i387,*,*")
2559 (set_attr "mode" "SF,SI,SF")])
2561 (define_insn "*pushsf_rex64"
2562 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2563 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2566 /* Anything else should be already split before reg-stack. */
2567 gcc_assert (which_alternative == 1);
2568 return "push{q}\t%q1";
2570 [(set_attr "type" "multi,push,multi")
2571 (set_attr "unit" "i387,*,*")
2572 (set_attr "mode" "SF,DI,SF")])
2575 [(set (match_operand:SF 0 "push_operand" "")
2576 (match_operand:SF 1 "memory_operand" ""))]
2578 && MEM_P (operands[1])
2579 && (operands[2] = find_constant_src (insn))"
2584 ;; %%% Kill this when call knows how to work this out.
2586 [(set (match_operand:SF 0 "push_operand" "")
2587 (match_operand:SF 1 "any_fp_register_operand" ""))]
2589 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2590 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2593 [(set (match_operand:SF 0 "push_operand" "")
2594 (match_operand:SF 1 "any_fp_register_operand" ""))]
2596 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2597 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2599 (define_insn "*movsf_1"
2600 [(set (match_operand:SF 0 "nonimmediate_operand"
2601 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2602 (match_operand:SF 1 "general_operand"
2603 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2604 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2605 && (reload_in_progress || reload_completed
2606 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2607 || (!TARGET_SSE_MATH && optimize_size
2608 && standard_80387_constant_p (operands[1]))
2609 || GET_CODE (operands[1]) != CONST_DOUBLE
2610 || memory_operand (operands[0], SFmode))"
2612 switch (which_alternative)
2616 return output_387_reg_move (insn, operands);
2619 return standard_80387_constant_opcode (operands[1]);
2623 return "mov{l}\t{%1, %0|%0, %1}";
2625 if (get_attr_mode (insn) == MODE_TI)
2626 return "pxor\t%0, %0";
2628 return "xorps\t%0, %0";
2630 if (get_attr_mode (insn) == MODE_V4SF)
2631 return "movaps\t{%1, %0|%0, %1}";
2633 return "movss\t{%1, %0|%0, %1}";
2635 return "movss\t{%1, %0|%0, %1}";
2638 case 12: case 13: case 14: case 15:
2639 return "movd\t{%1, %0|%0, %1}";
2642 return "movq\t{%1, %0|%0, %1}";
2648 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2650 (cond [(eq_attr "alternative" "3,4,9,10")
2652 (eq_attr "alternative" "5")
2654 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2656 (ne (symbol_ref "TARGET_SSE2")
2658 (eq (symbol_ref "optimize_size")
2661 (const_string "V4SF"))
2662 /* For architectures resolving dependencies on
2663 whole SSE registers use APS move to break dependency
2664 chains, otherwise use short move to avoid extra work.
2666 Do the same for architectures resolving dependencies on
2667 the parts. While in DF mode it is better to always handle
2668 just register parts, the SF mode is different due to lack
2669 of instructions to load just part of the register. It is
2670 better to maintain the whole registers in single format
2671 to avoid problems on using packed logical operations. */
2672 (eq_attr "alternative" "6")
2674 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2676 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678 (const_string "V4SF")
2679 (const_string "SF"))
2680 (eq_attr "alternative" "11")
2681 (const_string "DI")]
2682 (const_string "SF")))])
2684 (define_insn "*swapsf"
2685 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2686 (match_operand:SF 1 "fp_register_operand" "+f"))
2689 "reload_completed || TARGET_80387"
2691 if (STACK_TOP_P (operands[0]))
2696 [(set_attr "type" "fxch")
2697 (set_attr "mode" "SF")])
2699 (define_expand "movdf"
2700 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2701 (match_operand:DF 1 "general_operand" ""))]
2703 "ix86_expand_move (DFmode, operands); DONE;")
2705 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter. Allow this
2708 ;; pattern for optimize_size too.
2710 (define_insn "*pushdf_nointeger"
2711 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2712 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2713 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2715 /* This insn should be already split before reg-stack. */
2718 [(set_attr "type" "multi")
2719 (set_attr "unit" "i387,*,*,*")
2720 (set_attr "mode" "DF,SI,SI,DF")])
2722 (define_insn "*pushdf_integer"
2723 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2724 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2725 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2727 /* This insn should be already split before reg-stack. */
2730 [(set_attr "type" "multi")
2731 (set_attr "unit" "i387,*,*")
2732 (set_attr "mode" "DF,SI,DF")])
2734 ;; %%% Kill this when call knows how to work this out.
2736 [(set (match_operand:DF 0 "push_operand" "")
2737 (match_operand:DF 1 "any_fp_register_operand" ""))]
2738 "!TARGET_64BIT && reload_completed"
2739 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2740 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2744 [(set (match_operand:DF 0 "push_operand" "")
2745 (match_operand:DF 1 "any_fp_register_operand" ""))]
2746 "TARGET_64BIT && reload_completed"
2747 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2748 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2752 [(set (match_operand:DF 0 "push_operand" "")
2753 (match_operand:DF 1 "general_operand" ""))]
2756 "ix86_split_long_move (operands); DONE;")
2758 ;; Moving is usually shorter when only FP registers are used. This separate
2759 ;; movdf pattern avoids the use of integer registers for FP operations
2760 ;; when optimizing for size.
2762 (define_insn "*movdf_nointeger"
2763 [(set (match_operand:DF 0 "nonimmediate_operand"
2764 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2765 (match_operand:DF 1 "general_operand"
2766 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2767 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2768 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2769 && (reload_in_progress || reload_completed
2770 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2771 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2772 && !memory_operand (operands[0], DFmode)
2773 && standard_80387_constant_p (operands[1]))
2774 || GET_CODE (operands[1]) != CONST_DOUBLE
2776 || !TARGET_MEMORY_MISMATCH_STALL
2777 || reload_in_progress || reload_completed)
2778 && memory_operand (operands[0], DFmode)))"
2780 switch (which_alternative)
2784 return output_387_reg_move (insn, operands);
2787 return standard_80387_constant_opcode (operands[1]);
2793 switch (get_attr_mode (insn))
2796 return "xorps\t%0, %0";
2798 return "xorpd\t%0, %0";
2800 return "pxor\t%0, %0";
2807 switch (get_attr_mode (insn))
2810 return "movaps\t{%1, %0|%0, %1}";
2812 return "movapd\t{%1, %0|%0, %1}";
2814 return "movdqa\t{%1, %0|%0, %1}";
2816 return "movq\t{%1, %0|%0, %1}";
2818 return "movsd\t{%1, %0|%0, %1}";
2820 return "movlpd\t{%1, %0|%0, %1}";
2822 return "movlps\t{%1, %0|%0, %1}";
2831 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2833 (cond [(eq_attr "alternative" "0,1,2")
2835 (eq_attr "alternative" "3,4")
2838 /* For SSE1, we have many fewer alternatives. */
2839 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2840 (cond [(eq_attr "alternative" "5,6")
2841 (const_string "V4SF")
2843 (const_string "V2SF"))
2845 /* xorps is one byte shorter. */
2846 (eq_attr "alternative" "5")
2847 (cond [(ne (symbol_ref "optimize_size")
2849 (const_string "V4SF")
2850 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2854 (const_string "V2DF"))
2856 /* For architectures resolving dependencies on
2857 whole SSE registers use APD move to break dependency
2858 chains, otherwise use short move to avoid extra work.
2860 movaps encodes one byte shorter. */
2861 (eq_attr "alternative" "6")
2863 [(ne (symbol_ref "optimize_size")
2865 (const_string "V4SF")
2866 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2868 (const_string "V2DF")
2870 (const_string "DF"))
2871 /* For architectures resolving dependencies on register
2872 parts we may avoid extra work to zero out upper part
2874 (eq_attr "alternative" "7")
2876 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2878 (const_string "V1DF")
2879 (const_string "DF"))
2881 (const_string "DF")))])
2883 (define_insn "*movdf_integer_rex64"
2884 [(set (match_operand:DF 0 "nonimmediate_operand"
2885 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2886 (match_operand:DF 1 "general_operand"
2887 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2888 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2889 && (reload_in_progress || reload_completed
2890 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2891 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2892 && standard_80387_constant_p (operands[1]))
2893 || GET_CODE (operands[1]) != CONST_DOUBLE
2894 || memory_operand (operands[0], DFmode))"
2896 switch (which_alternative)
2900 return output_387_reg_move (insn, operands);
2903 return standard_80387_constant_opcode (operands[1]);
2910 switch (get_attr_mode (insn))
2913 return "xorps\t%0, %0";
2915 return "xorpd\t%0, %0";
2917 return "pxor\t%0, %0";
2924 switch (get_attr_mode (insn))
2927 return "movaps\t{%1, %0|%0, %1}";
2929 return "movapd\t{%1, %0|%0, %1}";
2931 return "movdqa\t{%1, %0|%0, %1}";
2933 return "movq\t{%1, %0|%0, %1}";
2935 return "movsd\t{%1, %0|%0, %1}";
2937 return "movlpd\t{%1, %0|%0, %1}";
2939 return "movlps\t{%1, %0|%0, %1}";
2946 return "movd\t{%1, %0|%0, %1}";
2952 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2954 (cond [(eq_attr "alternative" "0,1,2")
2956 (eq_attr "alternative" "3,4,9,10")
2959 /* For SSE1, we have many fewer alternatives. */
2960 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2961 (cond [(eq_attr "alternative" "5,6")
2962 (const_string "V4SF")
2964 (const_string "V2SF"))
2966 /* xorps is one byte shorter. */
2967 (eq_attr "alternative" "5")
2968 (cond [(ne (symbol_ref "optimize_size")
2970 (const_string "V4SF")
2971 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2975 (const_string "V2DF"))
2977 /* For architectures resolving dependencies on
2978 whole SSE registers use APD move to break dependency
2979 chains, otherwise use short move to avoid extra work.
2981 movaps encodes one byte shorter. */
2982 (eq_attr "alternative" "6")
2984 [(ne (symbol_ref "optimize_size")
2986 (const_string "V4SF")
2987 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2989 (const_string "V2DF")
2991 (const_string "DF"))
2992 /* For architectures resolving dependencies on register
2993 parts we may avoid extra work to zero out upper part
2995 (eq_attr "alternative" "7")
2997 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2999 (const_string "V1DF")
3000 (const_string "DF"))
3002 (const_string "DF")))])
3004 (define_insn "*movdf_integer"
3005 [(set (match_operand:DF 0 "nonimmediate_operand"
3006 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3007 (match_operand:DF 1 "general_operand"
3008 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3009 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3010 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3011 && (reload_in_progress || reload_completed
3012 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3013 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3014 && standard_80387_constant_p (operands[1]))
3015 || GET_CODE (operands[1]) != CONST_DOUBLE
3016 || memory_operand (operands[0], DFmode))"
3018 switch (which_alternative)
3022 return output_387_reg_move (insn, operands);
3025 return standard_80387_constant_opcode (operands[1]);
3032 switch (get_attr_mode (insn))
3035 return "xorps\t%0, %0";
3037 return "xorpd\t%0, %0";
3039 return "pxor\t%0, %0";
3046 switch (get_attr_mode (insn))
3049 return "movaps\t{%1, %0|%0, %1}";
3051 return "movapd\t{%1, %0|%0, %1}";
3053 return "movdqa\t{%1, %0|%0, %1}";
3055 return "movq\t{%1, %0|%0, %1}";
3057 return "movsd\t{%1, %0|%0, %1}";
3059 return "movlpd\t{%1, %0|%0, %1}";
3061 return "movlps\t{%1, %0|%0, %1}";
3070 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3072 (cond [(eq_attr "alternative" "0,1,2")
3074 (eq_attr "alternative" "3,4")
3077 /* For SSE1, we have many fewer alternatives. */
3078 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3079 (cond [(eq_attr "alternative" "5,6")
3080 (const_string "V4SF")
3082 (const_string "V2SF"))
3084 /* xorps is one byte shorter. */
3085 (eq_attr "alternative" "5")
3086 (cond [(ne (symbol_ref "optimize_size")
3088 (const_string "V4SF")
3089 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3093 (const_string "V2DF"))
3095 /* For architectures resolving dependencies on
3096 whole SSE registers use APD move to break dependency
3097 chains, otherwise use short move to avoid extra work.
3099 movaps encodes one byte shorter. */
3100 (eq_attr "alternative" "6")
3102 [(ne (symbol_ref "optimize_size")
3104 (const_string "V4SF")
3105 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3107 (const_string "V2DF")
3109 (const_string "DF"))
3110 /* For architectures resolving dependencies on register
3111 parts we may avoid extra work to zero out upper part
3113 (eq_attr "alternative" "7")
3115 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3117 (const_string "V1DF")
3118 (const_string "DF"))
3120 (const_string "DF")))])
3123 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3124 (match_operand:DF 1 "general_operand" ""))]
3126 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3127 && ! (ANY_FP_REG_P (operands[0]) ||
3128 (GET_CODE (operands[0]) == SUBREG
3129 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3130 && ! (ANY_FP_REG_P (operands[1]) ||
3131 (GET_CODE (operands[1]) == SUBREG
3132 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3134 "ix86_split_long_move (operands); DONE;")
3136 (define_insn "*swapdf"
3137 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3138 (match_operand:DF 1 "fp_register_operand" "+f"))
3141 "reload_completed || TARGET_80387"
3143 if (STACK_TOP_P (operands[0]))
3148 [(set_attr "type" "fxch")
3149 (set_attr "mode" "DF")])
3151 (define_expand "movxf"
3152 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3153 (match_operand:XF 1 "general_operand" ""))]
3155 "ix86_expand_move (XFmode, operands); DONE;")
3157 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3158 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3159 ;; Pushing using integer instructions is longer except for constants
3160 ;; and direct memory references.
3161 ;; (assuming that any given constant is pushed only once, but this ought to be
3162 ;; handled elsewhere).
3164 (define_insn "*pushxf_nointeger"
3165 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3166 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3169 /* This insn should be already split before reg-stack. */
3172 [(set_attr "type" "multi")
3173 (set_attr "unit" "i387,*,*")
3174 (set_attr "mode" "XF,SI,SI")])
3176 (define_insn "*pushxf_integer"
3177 [(set (match_operand:XF 0 "push_operand" "=<,<")
3178 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3181 /* This insn should be already split before reg-stack. */
3184 [(set_attr "type" "multi")
3185 (set_attr "unit" "i387,*")
3186 (set_attr "mode" "XF,SI")])
3189 [(set (match_operand 0 "push_operand" "")
3190 (match_operand 1 "general_operand" ""))]
3192 && (GET_MODE (operands[0]) == XFmode
3193 || GET_MODE (operands[0]) == DFmode)
3194 && !ANY_FP_REG_P (operands[1])"
3196 "ix86_split_long_move (operands); DONE;")
3199 [(set (match_operand:XF 0 "push_operand" "")
3200 (match_operand:XF 1 "any_fp_register_operand" ""))]
3202 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3203 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3204 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3207 [(set (match_operand:XF 0 "push_operand" "")
3208 (match_operand:XF 1 "any_fp_register_operand" ""))]
3210 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3211 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3212 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3214 ;; Do not use integer registers when optimizing for size
3215 (define_insn "*movxf_nointeger"
3216 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3217 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3219 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3220 && (reload_in_progress || reload_completed
3221 || (optimize_size && standard_80387_constant_p (operands[1]))
3222 || GET_CODE (operands[1]) != CONST_DOUBLE
3223 || memory_operand (operands[0], XFmode))"
3225 switch (which_alternative)
3229 return output_387_reg_move (insn, operands);
3232 return standard_80387_constant_opcode (operands[1]);
3240 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3241 (set_attr "mode" "XF,XF,XF,SI,SI")])
3243 (define_insn "*movxf_integer"
3244 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3245 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3247 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3248 && (reload_in_progress || reload_completed
3249 || (optimize_size && standard_80387_constant_p (operands[1]))
3250 || GET_CODE (operands[1]) != CONST_DOUBLE
3251 || memory_operand (operands[0], XFmode))"
3253 switch (which_alternative)
3257 return output_387_reg_move (insn, operands);
3260 return standard_80387_constant_opcode (operands[1]);
3269 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3270 (set_attr "mode" "XF,XF,XF,SI,SI")])
3272 (define_expand "movtf"
3273 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3274 (match_operand:TF 1 "nonimmediate_operand" ""))]
3277 ix86_expand_move (TFmode, operands);
3281 (define_insn "*movtf_internal"
3282 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3283 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3285 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3287 switch (which_alternative)
3291 if (get_attr_mode (insn) == MODE_V4SF)
3292 return "movaps\t{%1, %0|%0, %1}";
3294 return "movdqa\t{%1, %0|%0, %1}";
3296 if (get_attr_mode (insn) == MODE_V4SF)
3297 return "xorps\t%0, %0";
3299 return "pxor\t%0, %0";
3307 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3309 (cond [(eq_attr "alternative" "0,2")
3311 (ne (symbol_ref "optimize_size")
3313 (const_string "V4SF")
3314 (const_string "TI"))
3315 (eq_attr "alternative" "1")
3317 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3319 (ne (symbol_ref "optimize_size")
3321 (const_string "V4SF")
3322 (const_string "TI"))]
3323 (const_string "DI")))])
3326 [(set (match_operand 0 "nonimmediate_operand" "")
3327 (match_operand 1 "general_operand" ""))]
3329 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3330 && GET_MODE (operands[0]) == XFmode
3331 && ! (ANY_FP_REG_P (operands[0]) ||
3332 (GET_CODE (operands[0]) == SUBREG
3333 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3334 && ! (ANY_FP_REG_P (operands[1]) ||
3335 (GET_CODE (operands[1]) == SUBREG
3336 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3338 "ix86_split_long_move (operands); DONE;")
3341 [(set (match_operand 0 "register_operand" "")
3342 (match_operand 1 "memory_operand" ""))]
3344 && MEM_P (operands[1])
3345 && (GET_MODE (operands[0]) == TFmode
3346 || GET_MODE (operands[0]) == XFmode
3347 || GET_MODE (operands[0]) == SFmode
3348 || GET_MODE (operands[0]) == DFmode)
3349 && (operands[2] = find_constant_src (insn))"
3350 [(set (match_dup 0) (match_dup 2))]
3352 rtx c = operands[2];
3353 rtx r = operands[0];
3355 if (GET_CODE (r) == SUBREG)
3360 if (!standard_sse_constant_p (c))
3363 else if (FP_REG_P (r))
3365 if (!standard_80387_constant_p (c))
3368 else if (MMX_REG_P (r))
3373 [(set (match_operand 0 "register_operand" "")
3374 (float_extend (match_operand 1 "memory_operand" "")))]
3376 && MEM_P (operands[1])
3377 && (GET_MODE (operands[0]) == TFmode
3378 || GET_MODE (operands[0]) == XFmode
3379 || GET_MODE (operands[0]) == SFmode
3380 || GET_MODE (operands[0]) == DFmode)
3381 && (operands[2] = find_constant_src (insn))"
3382 [(set (match_dup 0) (match_dup 2))]
3384 rtx c = operands[2];
3385 rtx r = operands[0];
3387 if (GET_CODE (r) == SUBREG)
3392 if (!standard_sse_constant_p (c))
3395 else if (FP_REG_P (r))
3397 if (!standard_80387_constant_p (c))
3400 else if (MMX_REG_P (r))
3404 (define_insn "swapxf"
3405 [(set (match_operand:XF 0 "register_operand" "+f")
3406 (match_operand:XF 1 "register_operand" "+f"))
3411 if (STACK_TOP_P (operands[0]))
3416 [(set_attr "type" "fxch")
3417 (set_attr "mode" "XF")])
3419 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3421 [(set (match_operand:X87MODEF 0 "register_operand" "")
3422 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3423 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3424 && (standard_80387_constant_p (operands[1]) == 8
3425 || standard_80387_constant_p (operands[1]) == 9)"
3426 [(set (match_dup 0)(match_dup 1))
3428 (neg:X87MODEF (match_dup 0)))]
3432 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3433 if (real_isnegzero (&r))
3434 operands[1] = CONST0_RTX (<MODE>mode);
3436 operands[1] = CONST1_RTX (<MODE>mode);
3440 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3441 (match_operand:TF 1 "general_operand" ""))]
3443 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3445 "ix86_split_long_move (operands); DONE;")
3447 ;; Zero extension instructions
3449 (define_expand "zero_extendhisi2"
3450 [(set (match_operand:SI 0 "register_operand" "")
3451 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3454 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3456 operands[1] = force_reg (HImode, operands[1]);
3457 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3462 (define_insn "zero_extendhisi2_and"
3463 [(set (match_operand:SI 0 "register_operand" "=r")
3464 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3465 (clobber (reg:CC FLAGS_REG))]
3466 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3468 [(set_attr "type" "alu1")
3469 (set_attr "mode" "SI")])
3472 [(set (match_operand:SI 0 "register_operand" "")
3473 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3474 (clobber (reg:CC FLAGS_REG))]
3475 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3476 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3477 (clobber (reg:CC FLAGS_REG))])]
3480 (define_insn "*zero_extendhisi2_movzwl"
3481 [(set (match_operand:SI 0 "register_operand" "=r")
3482 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3483 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3484 "movz{wl|x}\t{%1, %0|%0, %1}"
3485 [(set_attr "type" "imovx")
3486 (set_attr "mode" "SI")])
3488 (define_expand "zero_extendqihi2"
3490 [(set (match_operand:HI 0 "register_operand" "")
3491 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3492 (clobber (reg:CC FLAGS_REG))])]
3496 (define_insn "*zero_extendqihi2_and"
3497 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3498 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3499 (clobber (reg:CC FLAGS_REG))]
3500 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3502 [(set_attr "type" "alu1")
3503 (set_attr "mode" "HI")])
3505 (define_insn "*zero_extendqihi2_movzbw_and"
3506 [(set (match_operand:HI 0 "register_operand" "=r,r")
3507 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3508 (clobber (reg:CC FLAGS_REG))]
3509 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3511 [(set_attr "type" "imovx,alu1")
3512 (set_attr "mode" "HI")])
3514 ; zero extend to SImode here to avoid partial register stalls
3515 (define_insn "*zero_extendqihi2_movzbl"
3516 [(set (match_operand:HI 0 "register_operand" "=r")
3517 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3518 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3519 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3520 [(set_attr "type" "imovx")
3521 (set_attr "mode" "SI")])
3523 ;; For the movzbw case strip only the clobber
3525 [(set (match_operand:HI 0 "register_operand" "")
3526 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3527 (clobber (reg:CC FLAGS_REG))]
3529 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3530 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3531 [(set (match_operand:HI 0 "register_operand" "")
3532 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3534 ;; When source and destination does not overlap, clear destination
3535 ;; first and then do the movb
3537 [(set (match_operand:HI 0 "register_operand" "")
3538 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3539 (clobber (reg:CC FLAGS_REG))]
3541 && ANY_QI_REG_P (operands[0])
3542 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3543 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3544 [(set (match_dup 0) (const_int 0))
3545 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3546 "operands[2] = gen_lowpart (QImode, operands[0]);")
3548 ;; Rest is handled by single and.
3550 [(set (match_operand:HI 0 "register_operand" "")
3551 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3552 (clobber (reg:CC FLAGS_REG))]
3554 && true_regnum (operands[0]) == true_regnum (operands[1])"
3555 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3556 (clobber (reg:CC FLAGS_REG))])]
3559 (define_expand "zero_extendqisi2"
3561 [(set (match_operand:SI 0 "register_operand" "")
3562 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3563 (clobber (reg:CC FLAGS_REG))])]
3567 (define_insn "*zero_extendqisi2_and"
3568 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3569 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3570 (clobber (reg:CC FLAGS_REG))]
3571 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3573 [(set_attr "type" "alu1")
3574 (set_attr "mode" "SI")])
3576 (define_insn "*zero_extendqisi2_movzbw_and"
3577 [(set (match_operand:SI 0 "register_operand" "=r,r")
3578 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3579 (clobber (reg:CC FLAGS_REG))]
3580 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3582 [(set_attr "type" "imovx,alu1")
3583 (set_attr "mode" "SI")])
3585 (define_insn "*zero_extendqisi2_movzbw"
3586 [(set (match_operand:SI 0 "register_operand" "=r")
3587 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3588 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3589 "movz{bl|x}\t{%1, %0|%0, %1}"
3590 [(set_attr "type" "imovx")
3591 (set_attr "mode" "SI")])
3593 ;; For the movzbl case strip only the clobber
3595 [(set (match_operand:SI 0 "register_operand" "")
3596 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3597 (clobber (reg:CC FLAGS_REG))]
3599 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3600 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3602 (zero_extend:SI (match_dup 1)))])
3604 ;; When source and destination does not overlap, clear destination
3605 ;; first and then do the movb
3607 [(set (match_operand:SI 0 "register_operand" "")
3608 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3609 (clobber (reg:CC FLAGS_REG))]
3611 && ANY_QI_REG_P (operands[0])
3612 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3613 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3614 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3615 [(set (match_dup 0) (const_int 0))
3616 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3617 "operands[2] = gen_lowpart (QImode, operands[0]);")
3619 ;; Rest is handled by single and.
3621 [(set (match_operand:SI 0 "register_operand" "")
3622 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3623 (clobber (reg:CC FLAGS_REG))]
3625 && true_regnum (operands[0]) == true_regnum (operands[1])"
3626 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3627 (clobber (reg:CC FLAGS_REG))])]
3630 ;; %%% Kill me once multi-word ops are sane.
3631 (define_expand "zero_extendsidi2"
3632 [(set (match_operand:DI 0 "register_operand" "")
3633 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3638 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3643 (define_insn "zero_extendsidi2_32"
3644 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3646 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3647 (clobber (reg:CC FLAGS_REG))]
3653 movd\t{%1, %0|%0, %1}
3654 movd\t{%1, %0|%0, %1}
3655 movd\t{%1, %0|%0, %1}
3656 movd\t{%1, %0|%0, %1}"
3657 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3658 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3660 (define_insn "zero_extendsidi2_rex64"
3661 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3663 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3666 mov\t{%k1, %k0|%k0, %k1}
3668 movd\t{%1, %0|%0, %1}
3669 movd\t{%1, %0|%0, %1}
3670 movd\t{%1, %0|%0, %1}
3671 movd\t{%1, %0|%0, %1}"
3672 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3673 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3676 [(set (match_operand:DI 0 "memory_operand" "")
3677 (zero_extend:DI (match_dup 0)))]
3679 [(set (match_dup 4) (const_int 0))]
3680 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3683 [(set (match_operand:DI 0 "register_operand" "")
3684 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3685 (clobber (reg:CC FLAGS_REG))]
3686 "!TARGET_64BIT && reload_completed
3687 && true_regnum (operands[0]) == true_regnum (operands[1])"
3688 [(set (match_dup 4) (const_int 0))]
3689 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3692 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3693 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3694 (clobber (reg:CC FLAGS_REG))]
3695 "!TARGET_64BIT && reload_completed
3696 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3697 [(set (match_dup 3) (match_dup 1))
3698 (set (match_dup 4) (const_int 0))]
3699 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3701 (define_insn "zero_extendhidi2"
3702 [(set (match_operand:DI 0 "register_operand" "=r")
3703 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3705 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3706 [(set_attr "type" "imovx")
3707 (set_attr "mode" "DI")])
3709 (define_insn "zero_extendqidi2"
3710 [(set (match_operand:DI 0 "register_operand" "=r")
3711 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3713 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "DI")])
3717 ;; Sign extension instructions
3719 (define_expand "extendsidi2"
3720 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3721 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3722 (clobber (reg:CC FLAGS_REG))
3723 (clobber (match_scratch:SI 2 ""))])]
3728 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3733 (define_insn "*extendsidi2_1"
3734 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3735 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3736 (clobber (reg:CC FLAGS_REG))
3737 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3741 (define_insn "extendsidi2_rex64"
3742 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3743 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3747 movs{lq|x}\t{%1,%0|%0, %1}"
3748 [(set_attr "type" "imovx")
3749 (set_attr "mode" "DI")
3750 (set_attr "prefix_0f" "0")
3751 (set_attr "modrm" "0,1")])
3753 (define_insn "extendhidi2"
3754 [(set (match_operand:DI 0 "register_operand" "=r")
3755 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3757 "movs{wq|x}\t{%1,%0|%0, %1}"
3758 [(set_attr "type" "imovx")
3759 (set_attr "mode" "DI")])
3761 (define_insn "extendqidi2"
3762 [(set (match_operand:DI 0 "register_operand" "=r")
3763 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3765 "movs{bq|x}\t{%1,%0|%0, %1}"
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "DI")])
3769 ;; Extend to memory case when source register does die.
3771 [(set (match_operand:DI 0 "memory_operand" "")
3772 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3773 (clobber (reg:CC FLAGS_REG))
3774 (clobber (match_operand:SI 2 "register_operand" ""))]
3776 && dead_or_set_p (insn, operands[1])
3777 && !reg_mentioned_p (operands[1], operands[0]))"
3778 [(set (match_dup 3) (match_dup 1))
3779 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3780 (clobber (reg:CC FLAGS_REG))])
3781 (set (match_dup 4) (match_dup 1))]
3782 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3784 ;; Extend to memory case when source register does not die.
3786 [(set (match_operand:DI 0 "memory_operand" "")
3787 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3788 (clobber (reg:CC FLAGS_REG))
3789 (clobber (match_operand:SI 2 "register_operand" ""))]
3793 split_di (&operands[0], 1, &operands[3], &operands[4]);
3795 emit_move_insn (operands[3], operands[1]);
3797 /* Generate a cltd if possible and doing so it profitable. */
3798 if ((optimize_size || TARGET_USE_CLTD)
3799 && true_regnum (operands[1]) == AX_REG
3800 && true_regnum (operands[2]) == DX_REG)
3802 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3806 emit_move_insn (operands[2], operands[1]);
3807 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3809 emit_move_insn (operands[4], operands[2]);
3813 ;; Extend to register case. Optimize case where source and destination
3814 ;; registers match and cases where we can use cltd.
3816 [(set (match_operand:DI 0 "register_operand" "")
3817 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3818 (clobber (reg:CC FLAGS_REG))
3819 (clobber (match_scratch:SI 2 ""))]
3823 split_di (&operands[0], 1, &operands[3], &operands[4]);
3825 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3826 emit_move_insn (operands[3], operands[1]);
3828 /* Generate a cltd if possible and doing so it profitable. */
3829 if ((optimize_size || TARGET_USE_CLTD)
3830 && true_regnum (operands[3]) == AX_REG)
3832 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3836 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3837 emit_move_insn (operands[4], operands[1]);
3839 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3843 (define_insn "extendhisi2"
3844 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3845 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3848 switch (get_attr_prefix_0f (insn))
3851 return "{cwtl|cwde}";
3853 return "movs{wl|x}\t{%1,%0|%0, %1}";
3856 [(set_attr "type" "imovx")
3857 (set_attr "mode" "SI")
3858 (set (attr "prefix_0f")
3859 ;; movsx is short decodable while cwtl is vector decoded.
3860 (if_then_else (and (eq_attr "cpu" "!k6")
3861 (eq_attr "alternative" "0"))
3863 (const_string "1")))
3865 (if_then_else (eq_attr "prefix_0f" "0")
3867 (const_string "1")))])
3869 (define_insn "*extendhisi2_zext"
3870 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3872 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3875 switch (get_attr_prefix_0f (insn))
3878 return "{cwtl|cwde}";
3880 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3883 [(set_attr "type" "imovx")
3884 (set_attr "mode" "SI")
3885 (set (attr "prefix_0f")
3886 ;; movsx is short decodable while cwtl is vector decoded.
3887 (if_then_else (and (eq_attr "cpu" "!k6")
3888 (eq_attr "alternative" "0"))
3890 (const_string "1")))
3892 (if_then_else (eq_attr "prefix_0f" "0")
3894 (const_string "1")))])
3896 (define_insn "extendqihi2"
3897 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3898 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3901 switch (get_attr_prefix_0f (insn))
3904 return "{cbtw|cbw}";
3906 return "movs{bw|x}\t{%1,%0|%0, %1}";
3909 [(set_attr "type" "imovx")
3910 (set_attr "mode" "HI")
3911 (set (attr "prefix_0f")
3912 ;; movsx is short decodable while cwtl is vector decoded.
3913 (if_then_else (and (eq_attr "cpu" "!k6")
3914 (eq_attr "alternative" "0"))
3916 (const_string "1")))
3918 (if_then_else (eq_attr "prefix_0f" "0")
3920 (const_string "1")))])
3922 (define_insn "extendqisi2"
3923 [(set (match_operand:SI 0 "register_operand" "=r")
3924 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3926 "movs{bl|x}\t{%1,%0|%0, %1}"
3927 [(set_attr "type" "imovx")
3928 (set_attr "mode" "SI")])
3930 (define_insn "*extendqisi2_zext"
3931 [(set (match_operand:DI 0 "register_operand" "=r")
3933 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3935 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3936 [(set_attr "type" "imovx")
3937 (set_attr "mode" "SI")])
3939 ;; Conversions between float and double.
3941 ;; These are all no-ops in the model used for the 80387. So just
3944 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3945 (define_insn "*dummy_extendsfdf2"
3946 [(set (match_operand:DF 0 "push_operand" "=<")
3947 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3952 [(set (match_operand:DF 0 "push_operand" "")
3953 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3955 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3956 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3959 [(set (match_operand:DF 0 "push_operand" "")
3960 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3962 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3963 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3965 (define_insn "*dummy_extendsfxf2"
3966 [(set (match_operand:XF 0 "push_operand" "=<")
3967 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3972 [(set (match_operand:XF 0 "push_operand" "")
3973 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3975 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3976 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3977 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3980 [(set (match_operand:XF 0 "push_operand" "")
3981 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3983 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3984 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3985 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3988 [(set (match_operand:XF 0 "push_operand" "")
3989 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3991 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3992 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3993 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3996 [(set (match_operand:XF 0 "push_operand" "")
3997 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3999 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
4000 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
4001 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4003 (define_expand "extendsfdf2"
4004 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4005 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4006 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4008 /* ??? Needed for compress_float_constant since all fp constants
4009 are LEGITIMATE_CONSTANT_P. */
4010 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4012 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4013 && standard_80387_constant_p (operands[1]) > 0)
4015 operands[1] = simplify_const_unary_operation
4016 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4017 emit_move_insn_1 (operands[0], operands[1]);
4020 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4024 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4026 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4028 We do the conversion post reload to avoid producing of 128bit spills
4029 that might lead to ICE on 32bit target. The sequence unlikely combine
4032 [(set (match_operand:DF 0 "register_operand" "")
4034 (match_operand:SF 1 "nonimmediate_operand" "")))]
4035 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4036 && reload_completed && SSE_REG_P (operands[0])"
4041 (parallel [(const_int 0) (const_int 1)]))))]
4043 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4044 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4045 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4046 Try to avoid move when unpacking can be done in source. */
4047 if (REG_P (operands[1]))
4049 /* If it is unsafe to overwrite upper half of source, we need
4050 to move to destination and unpack there. */
4051 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4052 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4053 && true_regnum (operands[0]) != true_regnum (operands[1]))
4055 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4056 emit_move_insn (tmp, operands[1]);
4059 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4060 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4063 emit_insn (gen_vec_setv4sf_0 (operands[3],
4064 CONST0_RTX (V4SFmode), operands[1]));
4067 (define_insn "*extendsfdf2_mixed"
4068 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4070 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4071 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4073 switch (which_alternative)
4077 return output_387_reg_move (insn, operands);
4080 return "cvtss2sd\t{%1, %0|%0, %1}";
4086 [(set_attr "type" "fmov,fmov,ssecvt")
4087 (set_attr "mode" "SF,XF,DF")])
4089 (define_insn "*extendsfdf2_sse"
4090 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4091 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4092 "TARGET_SSE2 && TARGET_SSE_MATH"
4093 "cvtss2sd\t{%1, %0|%0, %1}"
4094 [(set_attr "type" "ssecvt")
4095 (set_attr "mode" "DF")])
4097 (define_insn "*extendsfdf2_i387"
4098 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4099 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4101 "* return output_387_reg_move (insn, operands);"
4102 [(set_attr "type" "fmov")
4103 (set_attr "mode" "SF,XF")])
4105 (define_expand "extend<mode>xf2"
4106 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4107 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4110 /* ??? Needed for compress_float_constant since all fp constants
4111 are LEGITIMATE_CONSTANT_P. */
4112 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4114 if (standard_80387_constant_p (operands[1]) > 0)
4116 operands[1] = simplify_const_unary_operation
4117 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4118 emit_move_insn_1 (operands[0], operands[1]);
4121 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4125 (define_insn "*extend<mode>xf2_i387"
4126 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4128 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4130 "* return output_387_reg_move (insn, operands);"
4131 [(set_attr "type" "fmov")
4132 (set_attr "mode" "<MODE>,XF")])
4134 ;; %%% This seems bad bad news.
4135 ;; This cannot output into an f-reg because there is no way to be sure
4136 ;; of truncating in that case. Otherwise this is just like a simple move
4137 ;; insn. So we pretend we can output to a reg in order to get better
4138 ;; register preferencing, but we really use a stack slot.
4140 ;; Conversion from DFmode to SFmode.
4142 (define_expand "truncdfsf2"
4143 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4145 (match_operand:DF 1 "nonimmediate_operand" "")))]
4146 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4148 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4150 else if (flag_unsafe_math_optimizations)
4154 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4155 rtx temp = assign_386_stack_local (SFmode, slot);
4156 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4161 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4163 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4165 We do the conversion post reload to avoid producing of 128bit spills
4166 that might lead to ICE on 32bit target. The sequence unlikely combine
4169 [(set (match_operand:SF 0 "register_operand" "")
4171 (match_operand:DF 1 "nonimmediate_operand" "")))]
4172 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4173 && reload_completed && SSE_REG_P (operands[0])"
4176 (float_truncate:V2SF
4180 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4181 operands[3] = CONST0_RTX (V2SFmode);
4182 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4183 /* Use movsd for loading from memory, unpcklpd for registers.
4184 Try to avoid move when unpacking can be done in source, or SSE3
4185 movddup is available. */
4186 if (REG_P (operands[1]))
4189 && true_regnum (operands[0]) != true_regnum (operands[1])
4190 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4191 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4193 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4194 emit_move_insn (tmp, operands[1]);
4197 else if (!TARGET_SSE3)
4198 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4199 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4202 emit_insn (gen_sse2_loadlpd (operands[4],
4203 CONST0_RTX (V2DFmode), operands[1]));
4206 (define_expand "truncdfsf2_with_temp"
4207 [(parallel [(set (match_operand:SF 0 "" "")
4208 (float_truncate:SF (match_operand:DF 1 "" "")))
4209 (clobber (match_operand:SF 2 "" ""))])]
4212 (define_insn "*truncdfsf_fast_mixed"
4213 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4215 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4216 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4218 switch (which_alternative)
4221 return output_387_reg_move (insn, operands);
4223 return "cvtsd2ss\t{%1, %0|%0, %1}";
4228 [(set_attr "type" "fmov,ssecvt")
4229 (set_attr "mode" "SF")])
4231 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4232 ;; because nothing we do here is unsafe.
4233 (define_insn "*truncdfsf_fast_sse"
4234 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4236 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4237 "TARGET_SSE2 && TARGET_SSE_MATH"
4238 "cvtsd2ss\t{%1, %0|%0, %1}"
4239 [(set_attr "type" "ssecvt")
4240 (set_attr "mode" "SF")])
4242 (define_insn "*truncdfsf_fast_i387"
4243 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4245 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4246 "TARGET_80387 && flag_unsafe_math_optimizations"
4247 "* return output_387_reg_move (insn, operands);"
4248 [(set_attr "type" "fmov")
4249 (set_attr "mode" "SF")])
4251 (define_insn "*truncdfsf_mixed"
4252 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4254 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4255 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4256 "TARGET_MIX_SSE_I387"
4258 switch (which_alternative)
4261 return output_387_reg_move (insn, operands);
4266 return "cvtsd2ss\t{%1, %0|%0, %1}";
4271 [(set_attr "type" "fmov,multi,ssecvt")
4272 (set_attr "unit" "*,i387,*")
4273 (set_attr "mode" "SF")])
4275 (define_insn "*truncdfsf_i387"
4276 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4278 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4279 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4282 switch (which_alternative)
4285 return output_387_reg_move (insn, operands);
4293 [(set_attr "type" "fmov,multi")
4294 (set_attr "unit" "*,i387")
4295 (set_attr "mode" "SF")])
4297 (define_insn "*truncdfsf2_i387_1"
4298 [(set (match_operand:SF 0 "memory_operand" "=m")
4300 (match_operand:DF 1 "register_operand" "f")))]
4302 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4303 && !TARGET_MIX_SSE_I387"
4304 "* return output_387_reg_move (insn, operands);"
4305 [(set_attr "type" "fmov")
4306 (set_attr "mode" "SF")])
4309 [(set (match_operand:SF 0 "register_operand" "")
4311 (match_operand:DF 1 "fp_register_operand" "")))
4312 (clobber (match_operand 2 "" ""))]
4314 [(set (match_dup 2) (match_dup 1))
4315 (set (match_dup 0) (match_dup 2))]
4317 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4320 ;; Conversion from XFmode to {SF,DF}mode
4322 (define_expand "truncxf<mode>2"
4323 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4324 (float_truncate:MODEF
4325 (match_operand:XF 1 "register_operand" "")))
4326 (clobber (match_dup 2))])]
4329 if (flag_unsafe_math_optimizations)
4331 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4332 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4333 if (reg != operands[0])
4334 emit_move_insn (operands[0], reg);
4339 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4340 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4344 (define_insn "*truncxfsf2_mixed"
4345 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4347 (match_operand:XF 1 "register_operand" "f,f")))
4348 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4351 gcc_assert (!which_alternative);
4352 return output_387_reg_move (insn, operands);
4354 [(set_attr "type" "fmov,multi")
4355 (set_attr "unit" "*,i387")
4356 (set_attr "mode" "SF")])
4358 (define_insn "*truncxfdf2_mixed"
4359 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4361 (match_operand:XF 1 "register_operand" "f,f")))
4362 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4365 gcc_assert (!which_alternative);
4366 return output_387_reg_move (insn, operands);
4368 [(set_attr "type" "fmov,multi")
4369 (set_attr "unit" "*,i387")
4370 (set_attr "mode" "DF")])
4372 (define_insn "truncxf<mode>2_i387_noop"
4373 [(set (match_operand:MODEF 0 "register_operand" "=f")
4374 (float_truncate:MODEF
4375 (match_operand:XF 1 "register_operand" "f")))]
4376 "TARGET_80387 && flag_unsafe_math_optimizations"
4377 "* return output_387_reg_move (insn, operands);"
4378 [(set_attr "type" "fmov")
4379 (set_attr "mode" "<MODE>")])
4381 (define_insn "*truncxf<mode>2_i387"
4382 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4383 (float_truncate:MODEF
4384 (match_operand:XF 1 "register_operand" "f")))]
4386 "* return output_387_reg_move (insn, operands);"
4387 [(set_attr "type" "fmov")
4388 (set_attr "mode" "<MODE>")])
4391 [(set (match_operand:MODEF 0 "register_operand" "")
4392 (float_truncate:MODEF
4393 (match_operand:XF 1 "register_operand" "")))
4394 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4395 "TARGET_80387 && reload_completed"
4396 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4397 (set (match_dup 0) (match_dup 2))]
4401 [(set (match_operand:MODEF 0 "memory_operand" "")
4402 (float_truncate:MODEF
4403 (match_operand:XF 1 "register_operand" "")))
4404 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4406 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4409 ;; Signed conversion to DImode.
4411 (define_expand "fix_truncxfdi2"
4412 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4413 (fix:DI (match_operand:XF 1 "register_operand" "")))
4414 (clobber (reg:CC FLAGS_REG))])]
4419 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4424 (define_expand "fix_trunc<mode>di2"
4425 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4426 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4427 (clobber (reg:CC FLAGS_REG))])]
4428 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4431 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4433 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4436 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4438 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4439 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4440 if (out != operands[0])
4441 emit_move_insn (operands[0], out);
4446 ;; Signed conversion to SImode.
4448 (define_expand "fix_truncxfsi2"
4449 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4450 (fix:SI (match_operand:XF 1 "register_operand" "")))
4451 (clobber (reg:CC FLAGS_REG))])]
4456 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4461 (define_expand "fix_trunc<mode>si2"
4462 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4463 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4464 (clobber (reg:CC FLAGS_REG))])]
4465 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4468 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4470 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4473 if (SSE_FLOAT_MODE_P (<MODE>mode))
4475 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4476 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4477 if (out != operands[0])
4478 emit_move_insn (operands[0], out);
4483 ;; Signed conversion to HImode.
4485 (define_expand "fix_trunc<mode>hi2"
4486 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4487 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4488 (clobber (reg:CC FLAGS_REG))])]
4490 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4494 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4499 ;; Unsigned conversion to SImode.
4501 (define_expand "fixuns_trunc<mode>si2"
4503 [(set (match_operand:SI 0 "register_operand" "")
4505 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4507 (clobber (match_scratch:<ssevecmode> 3 ""))
4508 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4509 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4511 enum machine_mode mode = <MODE>mode;
4512 enum machine_mode vecmode = <ssevecmode>mode;
4513 REAL_VALUE_TYPE TWO31r;
4516 real_ldexp (&TWO31r, &dconst1, 31);
4517 two31 = const_double_from_real_value (TWO31r, mode);
4518 two31 = ix86_build_const_vector (mode, true, two31);
4519 operands[2] = force_reg (vecmode, two31);
4522 (define_insn_and_split "*fixuns_trunc<mode>_1"
4523 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4525 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4526 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4527 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4528 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4529 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4531 "&& reload_completed"
4534 ix86_split_convert_uns_si_sse (operands);
4538 ;; Unsigned conversion to HImode.
4539 ;; Without these patterns, we'll try the unsigned SI conversion which
4540 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4542 (define_expand "fixuns_trunc<mode>hi2"
4544 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4545 (set (match_operand:HI 0 "nonimmediate_operand" "")
4546 (subreg:HI (match_dup 2) 0))]
4547 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4548 "operands[2] = gen_reg_rtx (SImode);")
4550 ;; When SSE is available, it is always faster to use it!
4551 (define_insn "fix_trunc<mode>di_sse"
4552 [(set (match_operand:DI 0 "register_operand" "=r,r")
4553 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4554 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4555 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4556 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4557 [(set_attr "type" "sseicvt")
4558 (set_attr "mode" "<MODE>")
4559 (set_attr "athlon_decode" "double,vector")
4560 (set_attr "amdfam10_decode" "double,double")])
4562 (define_insn "fix_trunc<mode>si_sse"
4563 [(set (match_operand:SI 0 "register_operand" "=r,r")
4564 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4565 "SSE_FLOAT_MODE_P (<MODE>mode)
4566 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4567 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4568 [(set_attr "type" "sseicvt")
4569 (set_attr "mode" "<MODE>")
4570 (set_attr "athlon_decode" "double,vector")
4571 (set_attr "amdfam10_decode" "double,double")])
4573 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4575 [(set (match_operand:MODEF 0 "register_operand" "")
4576 (match_operand:MODEF 1 "memory_operand" ""))
4577 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4578 (fix:SSEMODEI24 (match_dup 0)))]
4579 "TARGET_SHORTEN_X87_SSE
4580 && peep2_reg_dead_p (2, operands[0])"
4581 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4584 ;; Avoid vector decoded forms of the instruction.
4586 [(match_scratch:DF 2 "Y2")
4587 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4588 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4589 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4590 [(set (match_dup 2) (match_dup 1))
4591 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4595 [(match_scratch:SF 2 "x")
4596 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4597 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4598 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4599 [(set (match_dup 2) (match_dup 1))
4600 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4603 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4604 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4605 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4606 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4608 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4609 && (TARGET_64BIT || <MODE>mode != DImode))
4611 && !(reload_completed || reload_in_progress)"
4616 if (memory_operand (operands[0], VOIDmode))
4617 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4620 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4621 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4627 [(set_attr "type" "fisttp")
4628 (set_attr "mode" "<MODE>")])
4630 (define_insn "fix_trunc<mode>_i387_fisttp"
4631 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4632 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4633 (clobber (match_scratch:XF 2 "=&1f"))]
4634 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4636 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4637 && (TARGET_64BIT || <MODE>mode != DImode))
4638 && TARGET_SSE_MATH)"
4639 "* return output_fix_trunc (insn, operands, 1);"
4640 [(set_attr "type" "fisttp")
4641 (set_attr "mode" "<MODE>")])
4643 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4644 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4645 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4646 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4647 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4648 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4650 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4651 && (TARGET_64BIT || <MODE>mode != DImode))
4652 && TARGET_SSE_MATH)"
4654 [(set_attr "type" "fisttp")
4655 (set_attr "mode" "<MODE>")])
4658 [(set (match_operand:X87MODEI 0 "register_operand" "")
4659 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4660 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4661 (clobber (match_scratch 3 ""))]
4663 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4664 (clobber (match_dup 3))])
4665 (set (match_dup 0) (match_dup 2))]
4669 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4670 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4671 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4672 (clobber (match_scratch 3 ""))]
4674 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4675 (clobber (match_dup 3))])]
4678 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4679 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4680 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4681 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4682 ;; function in i386.c.
4683 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4684 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4685 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4686 (clobber (reg:CC FLAGS_REG))]
4687 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4689 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4690 && (TARGET_64BIT || <MODE>mode != DImode))
4691 && !(reload_completed || reload_in_progress)"
4696 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4698 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4699 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4700 if (memory_operand (operands[0], VOIDmode))
4701 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4702 operands[2], operands[3]));
4705 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4706 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4707 operands[2], operands[3],
4712 [(set_attr "type" "fistp")
4713 (set_attr "i387_cw" "trunc")
4714 (set_attr "mode" "<MODE>")])
4716 (define_insn "fix_truncdi_i387"
4717 [(set (match_operand:DI 0 "memory_operand" "=m")
4718 (fix:DI (match_operand 1 "register_operand" "f")))
4719 (use (match_operand:HI 2 "memory_operand" "m"))
4720 (use (match_operand:HI 3 "memory_operand" "m"))
4721 (clobber (match_scratch:XF 4 "=&1f"))]
4722 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4724 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4725 "* return output_fix_trunc (insn, operands, 0);"
4726 [(set_attr "type" "fistp")
4727 (set_attr "i387_cw" "trunc")
4728 (set_attr "mode" "DI")])
4730 (define_insn "fix_truncdi_i387_with_temp"
4731 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4732 (fix:DI (match_operand 1 "register_operand" "f,f")))
4733 (use (match_operand:HI 2 "memory_operand" "m,m"))
4734 (use (match_operand:HI 3 "memory_operand" "m,m"))
4735 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4736 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4737 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4739 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4741 [(set_attr "type" "fistp")
4742 (set_attr "i387_cw" "trunc")
4743 (set_attr "mode" "DI")])
4746 [(set (match_operand:DI 0 "register_operand" "")
4747 (fix:DI (match_operand 1 "register_operand" "")))
4748 (use (match_operand:HI 2 "memory_operand" ""))
4749 (use (match_operand:HI 3 "memory_operand" ""))
4750 (clobber (match_operand:DI 4 "memory_operand" ""))
4751 (clobber (match_scratch 5 ""))]
4753 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4756 (clobber (match_dup 5))])
4757 (set (match_dup 0) (match_dup 4))]
4761 [(set (match_operand:DI 0 "memory_operand" "")
4762 (fix:DI (match_operand 1 "register_operand" "")))
4763 (use (match_operand:HI 2 "memory_operand" ""))
4764 (use (match_operand:HI 3 "memory_operand" ""))
4765 (clobber (match_operand:DI 4 "memory_operand" ""))
4766 (clobber (match_scratch 5 ""))]
4768 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4771 (clobber (match_dup 5))])]
4774 (define_insn "fix_trunc<mode>_i387"
4775 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4776 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4777 (use (match_operand:HI 2 "memory_operand" "m"))
4778 (use (match_operand:HI 3 "memory_operand" "m"))]
4779 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4781 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4782 "* return output_fix_trunc (insn, operands, 0);"
4783 [(set_attr "type" "fistp")
4784 (set_attr "i387_cw" "trunc")
4785 (set_attr "mode" "<MODE>")])
4787 (define_insn "fix_trunc<mode>_i387_with_temp"
4788 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4789 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4790 (use (match_operand:HI 2 "memory_operand" "m,m"))
4791 (use (match_operand:HI 3 "memory_operand" "m,m"))
4792 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4793 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4795 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4797 [(set_attr "type" "fistp")
4798 (set_attr "i387_cw" "trunc")
4799 (set_attr "mode" "<MODE>")])
4802 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4803 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4804 (use (match_operand:HI 2 "memory_operand" ""))
4805 (use (match_operand:HI 3 "memory_operand" ""))
4806 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4808 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4810 (use (match_dup 3))])
4811 (set (match_dup 0) (match_dup 4))]
4815 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4816 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4817 (use (match_operand:HI 2 "memory_operand" ""))
4818 (use (match_operand:HI 3 "memory_operand" ""))
4819 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4821 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4823 (use (match_dup 3))])]
4826 (define_insn "x86_fnstcw_1"
4827 [(set (match_operand:HI 0 "memory_operand" "=m")
4828 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4831 [(set_attr "length" "2")
4832 (set_attr "mode" "HI")
4833 (set_attr "unit" "i387")])
4835 (define_insn "x86_fldcw_1"
4836 [(set (reg:HI FPCR_REG)
4837 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4840 [(set_attr "length" "2")
4841 (set_attr "mode" "HI")
4842 (set_attr "unit" "i387")
4843 (set_attr "athlon_decode" "vector")
4844 (set_attr "amdfam10_decode" "vector")])
4846 ;; Conversion between fixed point and floating point.
4848 ;; Even though we only accept memory inputs, the backend _really_
4849 ;; wants to be able to do this between registers.
4851 (define_expand "floathi<mode>2"
4852 [(set (match_operand:X87MODEF 0 "register_operand" "")
4853 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4855 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4856 || TARGET_MIX_SSE_I387)"
4859 ;; Pre-reload splitter to add memory clobber to the pattern.
4860 (define_insn_and_split "*floathi<mode>2_1"
4861 [(set (match_operand:X87MODEF 0 "register_operand" "")
4862 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4865 || TARGET_MIX_SSE_I387)
4866 && !(reload_completed || reload_in_progress)"
4869 [(parallel [(set (match_dup 0)
4870 (float:X87MODEF (match_dup 1)))
4871 (clobber (match_dup 2))])]
4872 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4874 (define_insn "*floathi<mode>2_i387_with_temp"
4875 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4876 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4877 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4879 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4880 || TARGET_MIX_SSE_I387)"
4882 [(set_attr "type" "fmov,multi")
4883 (set_attr "mode" "<MODE>")
4884 (set_attr "unit" "*,i387")
4885 (set_attr "fp_int_src" "true")])
4887 (define_insn "*floathi<mode>2_i387"
4888 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4889 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4892 || TARGET_MIX_SSE_I387)"
4894 [(set_attr "type" "fmov")
4895 (set_attr "mode" "<MODE>")
4896 (set_attr "fp_int_src" "true")])
4899 [(set (match_operand:X87MODEF 0 "register_operand" "")
4900 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4901 (clobber (match_operand:HI 2 "memory_operand" ""))]
4903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4904 || TARGET_MIX_SSE_I387)
4905 && reload_completed"
4906 [(set (match_dup 2) (match_dup 1))
4907 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4911 [(set (match_operand:X87MODEF 0 "register_operand" "")
4912 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4913 (clobber (match_operand:HI 2 "memory_operand" ""))]
4915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4916 || TARGET_MIX_SSE_I387)
4917 && reload_completed"
4918 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4921 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4922 [(set (match_operand:X87MODEF 0 "register_operand" "")
4924 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4926 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4927 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4930 ;; Pre-reload splitter to add memory clobber to the pattern.
4931 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4932 [(set (match_operand:X87MODEF 0 "register_operand" "")
4933 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4935 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4936 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4937 || TARGET_MIX_SSE_I387))
4938 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4939 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4940 && ((<SSEMODEI24:MODE>mode == SImode
4941 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4942 && flag_trapping_math)
4943 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4944 && !(reload_completed || reload_in_progress)"
4947 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4948 (clobber (match_dup 2))])]
4950 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4952 /* Avoid store forwarding (partial memory) stall penalty
4953 by passing DImode value through XMM registers. */
4954 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4955 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4958 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4965 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4966 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4968 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4969 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4970 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4971 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4973 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4974 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4975 (set_attr "unit" "*,i387,*,*,*")
4976 (set_attr "athlon_decode" "*,*,double,direct,double")
4977 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4978 (set_attr "fp_int_src" "true")])
4980 (define_insn "*floatsi<mode>2_vector_mixed"
4981 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4982 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4983 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4984 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4988 [(set_attr "type" "fmov,sseicvt")
4989 (set_attr "mode" "<MODE>,<ssevecmode>")
4990 (set_attr "unit" "i387,*")
4991 (set_attr "athlon_decode" "*,direct")
4992 (set_attr "amdfam10_decode" "*,double")
4993 (set_attr "fp_int_src" "true")])
4995 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4996 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4998 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4999 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5000 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5001 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5003 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5004 (set_attr "mode" "<MODEF:MODE>")
5005 (set_attr "unit" "*,i387,*,*")
5006 (set_attr "athlon_decode" "*,*,double,direct")
5007 (set_attr "amdfam10_decode" "*,*,vector,double")
5008 (set_attr "fp_int_src" "true")])
5011 [(set (match_operand:MODEF 0 "register_operand" "")
5012 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5013 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5014 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5015 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5016 && TARGET_INTER_UNIT_CONVERSIONS
5018 && (SSE_REG_P (operands[0])
5019 || (GET_CODE (operands[0]) == SUBREG
5020 && SSE_REG_P (operands[0])))"
5021 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5025 [(set (match_operand:MODEF 0 "register_operand" "")
5026 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5027 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5028 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5029 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5030 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5032 && (SSE_REG_P (operands[0])
5033 || (GET_CODE (operands[0]) == SUBREG
5034 && SSE_REG_P (operands[0])))"
5035 [(set (match_dup 2) (match_dup 1))
5036 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5039 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5040 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5042 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5043 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5044 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5045 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5048 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5049 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5050 [(set_attr "type" "fmov,sseicvt,sseicvt")
5051 (set_attr "mode" "<MODEF:MODE>")
5052 (set_attr "unit" "i387,*,*")
5053 (set_attr "athlon_decode" "*,double,direct")
5054 (set_attr "amdfam10_decode" "*,vector,double")
5055 (set_attr "fp_int_src" "true")])
5057 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5058 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5060 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5061 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5062 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5063 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5066 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5067 [(set_attr "type" "fmov,sseicvt")
5068 (set_attr "mode" "<MODEF:MODE>")
5069 (set_attr "athlon_decode" "*,direct")
5070 (set_attr "amdfam10_decode" "*,double")
5071 (set_attr "fp_int_src" "true")])
5073 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5074 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5076 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5077 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5078 "TARGET_SSE2 && TARGET_SSE_MATH
5079 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5081 [(set_attr "type" "sseicvt")
5082 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5083 (set_attr "athlon_decode" "double,direct,double")
5084 (set_attr "amdfam10_decode" "vector,double,double")
5085 (set_attr "fp_int_src" "true")])
5087 (define_insn "*floatsi<mode>2_vector_sse"
5088 [(set (match_operand:MODEF 0 "register_operand" "=x")
5089 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5090 "TARGET_SSE2 && TARGET_SSE_MATH
5091 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5093 [(set_attr "type" "sseicvt")
5094 (set_attr "mode" "<MODE>")
5095 (set_attr "athlon_decode" "direct")
5096 (set_attr "amdfam10_decode" "double")
5097 (set_attr "fp_int_src" "true")])
5100 [(set (match_operand:MODEF 0 "register_operand" "")
5101 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5102 (clobber (match_operand:SI 2 "memory_operand" ""))]
5103 "TARGET_SSE2 && TARGET_SSE_MATH
5104 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5106 && (SSE_REG_P (operands[0])
5107 || (GET_CODE (operands[0]) == SUBREG
5108 && SSE_REG_P (operands[0])))"
5111 rtx op1 = operands[1];
5113 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5115 if (GET_CODE (op1) == SUBREG)
5116 op1 = SUBREG_REG (op1);
5118 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5120 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5121 emit_insn (gen_sse2_loadld (operands[4],
5122 CONST0_RTX (V4SImode), operands[1]));
5124 /* We can ignore possible trapping value in the
5125 high part of SSE register for non-trapping math. */
5126 else if (SSE_REG_P (op1) && !flag_trapping_math)
5127 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5130 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5131 emit_move_insn (operands[2], operands[1]);
5132 emit_insn (gen_sse2_loadld (operands[4],
5133 CONST0_RTX (V4SImode), operands[2]));
5136 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5141 [(set (match_operand:MODEF 0 "register_operand" "")
5142 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5143 (clobber (match_operand:SI 2 "memory_operand" ""))]
5144 "TARGET_SSE2 && TARGET_SSE_MATH
5145 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5147 && (SSE_REG_P (operands[0])
5148 || (GET_CODE (operands[0]) == SUBREG
5149 && SSE_REG_P (operands[0])))"
5152 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5154 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5156 emit_insn (gen_sse2_loadld (operands[4],
5157 CONST0_RTX (V4SImode), operands[1]));
5159 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5164 [(set (match_operand:MODEF 0 "register_operand" "")
5165 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5166 "TARGET_SSE2 && TARGET_SSE_MATH
5167 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5169 && (SSE_REG_P (operands[0])
5170 || (GET_CODE (operands[0]) == SUBREG
5171 && SSE_REG_P (operands[0])))"
5174 rtx op1 = operands[1];
5176 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5178 if (GET_CODE (op1) == SUBREG)
5179 op1 = SUBREG_REG (op1);
5181 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5183 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5184 emit_insn (gen_sse2_loadld (operands[4],
5185 CONST0_RTX (V4SImode), operands[1]));
5187 /* We can ignore possible trapping value in the
5188 high part of SSE register for non-trapping math. */
5189 else if (SSE_REG_P (op1) && !flag_trapping_math)
5190 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5196 [(set (match_operand:MODEF 0 "register_operand" "")
5197 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5198 "TARGET_SSE2 && TARGET_SSE_MATH
5199 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5201 && (SSE_REG_P (operands[0])
5202 || (GET_CODE (operands[0]) == SUBREG
5203 && SSE_REG_P (operands[0])))"
5206 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5208 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5210 emit_insn (gen_sse2_loadld (operands[4],
5211 CONST0_RTX (V4SImode), operands[1]));
5213 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5217 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5218 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5220 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5221 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5222 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5223 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5225 [(set_attr "type" "sseicvt")
5226 (set_attr "mode" "<MODEF:MODE>")
5227 (set_attr "athlon_decode" "double,direct")
5228 (set_attr "amdfam10_decode" "vector,double")
5229 (set_attr "fp_int_src" "true")])
5231 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5232 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5234 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5235 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5236 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5237 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5238 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5239 [(set_attr "type" "sseicvt")
5240 (set_attr "mode" "<MODEF:MODE>")
5241 (set_attr "athlon_decode" "double,direct")
5242 (set_attr "amdfam10_decode" "vector,double")
5243 (set_attr "fp_int_src" "true")])
5246 [(set (match_operand:MODEF 0 "register_operand" "")
5247 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5248 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5249 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5250 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5251 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5253 && (SSE_REG_P (operands[0])
5254 || (GET_CODE (operands[0]) == SUBREG
5255 && SSE_REG_P (operands[0])))"
5256 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5259 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5260 [(set (match_operand:MODEF 0 "register_operand" "=x")
5262 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5263 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5264 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5265 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5266 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5267 [(set_attr "type" "sseicvt")
5268 (set_attr "mode" "<MODEF:MODE>")
5269 (set_attr "athlon_decode" "direct")
5270 (set_attr "amdfam10_decode" "double")
5271 (set_attr "fp_int_src" "true")])
5274 [(set (match_operand:MODEF 0 "register_operand" "")
5275 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5276 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5277 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5278 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5279 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5281 && (SSE_REG_P (operands[0])
5282 || (GET_CODE (operands[0]) == SUBREG
5283 && SSE_REG_P (operands[0])))"
5284 [(set (match_dup 2) (match_dup 1))
5285 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5289 [(set (match_operand:MODEF 0 "register_operand" "")
5290 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5291 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5292 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5293 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5295 && (SSE_REG_P (operands[0])
5296 || (GET_CODE (operands[0]) == SUBREG
5297 && SSE_REG_P (operands[0])))"
5298 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5301 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5302 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5304 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5305 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5310 [(set_attr "type" "fmov,multi")
5311 (set_attr "mode" "<X87MODEF:MODE>")
5312 (set_attr "unit" "*,i387")
5313 (set_attr "fp_int_src" "true")])
5315 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5316 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5318 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5321 [(set_attr "type" "fmov")
5322 (set_attr "mode" "<X87MODEF:MODE>")
5323 (set_attr "fp_int_src" "true")])
5326 [(set (match_operand:X87MODEF 0 "register_operand" "")
5327 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5328 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5331 && FP_REG_P (operands[0])"
5332 [(set (match_dup 2) (match_dup 1))
5333 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5337 [(set (match_operand:X87MODEF 0 "register_operand" "")
5338 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5339 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5342 && FP_REG_P (operands[0])"
5343 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5346 ;; Avoid store forwarding (partial memory) stall penalty
5347 ;; by passing DImode value through XMM registers. */
5349 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5350 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5352 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5353 (clobber (match_scratch:V4SI 3 "=X,x"))
5354 (clobber (match_scratch:V4SI 4 "=X,x"))
5355 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5356 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5357 && !TARGET_64BIT && !optimize_size"
5359 [(set_attr "type" "multi")
5360 (set_attr "mode" "<X87MODEF:MODE>")
5361 (set_attr "unit" "i387")
5362 (set_attr "fp_int_src" "true")])
5365 [(set (match_operand:X87MODEF 0 "register_operand" "")
5366 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5367 (clobber (match_scratch:V4SI 3 ""))
5368 (clobber (match_scratch:V4SI 4 ""))
5369 (clobber (match_operand:DI 2 "memory_operand" ""))]
5370 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5371 && !TARGET_64BIT && !optimize_size
5373 && FP_REG_P (operands[0])"
5374 [(set (match_dup 2) (match_dup 3))
5375 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5377 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5378 Assemble the 64-bit DImode value in an xmm register. */
5379 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5380 gen_rtx_SUBREG (SImode, operands[1], 0)));
5381 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5382 gen_rtx_SUBREG (SImode, operands[1], 4)));
5383 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5385 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5389 [(set (match_operand:X87MODEF 0 "register_operand" "")
5390 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5391 (clobber (match_scratch:V4SI 3 ""))
5392 (clobber (match_scratch:V4SI 4 ""))
5393 (clobber (match_operand:DI 2 "memory_operand" ""))]
5394 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5395 && !TARGET_64BIT && !optimize_size
5397 && FP_REG_P (operands[0])"
5398 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5401 ;; Avoid store forwarding (partial memory) stall penalty by extending
5402 ;; SImode value to DImode through XMM register instead of pushing two
5403 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5404 ;; targets benefit from this optimization. Also note that fild
5405 ;; loads from memory only.
5407 (define_insn "*floatunssi<mode>2_1"
5408 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5409 (unsigned_float:X87MODEF
5410 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5411 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5412 (clobber (match_scratch:SI 3 "=X,x"))]
5414 && TARGET_80387 && TARGET_SSE"
5416 [(set_attr "type" "multi")
5417 (set_attr "mode" "<MODE>")])
5420 [(set (match_operand:X87MODEF 0 "register_operand" "")
5421 (unsigned_float:X87MODEF
5422 (match_operand:SI 1 "register_operand" "")))
5423 (clobber (match_operand:DI 2 "memory_operand" ""))
5424 (clobber (match_scratch:SI 3 ""))]
5426 && TARGET_80387 && TARGET_SSE
5427 && reload_completed"
5428 [(set (match_dup 2) (match_dup 1))
5430 (float:X87MODEF (match_dup 2)))]
5431 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5434 [(set (match_operand:X87MODEF 0 "register_operand" "")
5435 (unsigned_float:X87MODEF
5436 (match_operand:SI 1 "memory_operand" "")))
5437 (clobber (match_operand:DI 2 "memory_operand" ""))
5438 (clobber (match_scratch:SI 3 ""))]
5440 && TARGET_80387 && TARGET_SSE
5441 && reload_completed"
5442 [(set (match_dup 2) (match_dup 3))
5444 (float:X87MODEF (match_dup 2)))]
5446 emit_move_insn (operands[3], operands[1]);
5447 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5450 (define_expand "floatunssi<mode>2"
5452 [(set (match_operand:X87MODEF 0 "register_operand" "")
5453 (unsigned_float:X87MODEF
5454 (match_operand:SI 1 "nonimmediate_operand" "")))
5455 (clobber (match_dup 2))
5456 (clobber (match_scratch:SI 3 ""))])]
5458 && ((TARGET_80387 && TARGET_SSE)
5459 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5461 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5463 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5468 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5469 operands[2] = assign_386_stack_local (DImode, slot);
5473 (define_expand "floatunsdisf2"
5474 [(use (match_operand:SF 0 "register_operand" ""))
5475 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5476 "TARGET_64BIT && TARGET_SSE_MATH"
5477 "x86_emit_floatuns (operands); DONE;")
5479 (define_expand "floatunsdidf2"
5480 [(use (match_operand:DF 0 "register_operand" ""))
5481 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5482 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5483 && TARGET_SSE2 && TARGET_SSE_MATH"
5486 x86_emit_floatuns (operands);
5488 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5494 ;; %%% splits for addditi3
5496 (define_expand "addti3"
5497 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5498 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5499 (match_operand:TI 2 "x86_64_general_operand" "")))
5500 (clobber (reg:CC FLAGS_REG))]
5502 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5504 (define_insn "*addti3_1"
5505 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5506 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5507 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5508 (clobber (reg:CC FLAGS_REG))]
5509 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5513 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5514 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5515 (match_operand:TI 2 "x86_64_general_operand" "")))
5516 (clobber (reg:CC FLAGS_REG))]
5517 "TARGET_64BIT && reload_completed"
5518 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5520 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5521 (parallel [(set (match_dup 3)
5522 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5525 (clobber (reg:CC FLAGS_REG))])]
5526 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5528 ;; %%% splits for addsidi3
5529 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5530 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5531 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5533 (define_expand "adddi3"
5534 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5535 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5536 (match_operand:DI 2 "x86_64_general_operand" "")))
5537 (clobber (reg:CC FLAGS_REG))]
5539 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5541 (define_insn "*adddi3_1"
5542 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5543 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5544 (match_operand:DI 2 "general_operand" "roiF,riF")))
5545 (clobber (reg:CC FLAGS_REG))]
5546 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5550 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5551 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5552 (match_operand:DI 2 "general_operand" "")))
5553 (clobber (reg:CC FLAGS_REG))]
5554 "!TARGET_64BIT && reload_completed"
5555 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5557 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5558 (parallel [(set (match_dup 3)
5559 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5562 (clobber (reg:CC FLAGS_REG))])]
5563 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5565 (define_insn "adddi3_carry_rex64"
5566 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5567 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5568 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5569 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5570 (clobber (reg:CC FLAGS_REG))]
5571 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5572 "adc{q}\t{%2, %0|%0, %2}"
5573 [(set_attr "type" "alu")
5574 (set_attr "pent_pair" "pu")
5575 (set_attr "mode" "DI")])
5577 (define_insn "*adddi3_cc_rex64"
5578 [(set (reg:CC FLAGS_REG)
5579 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5580 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5582 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5583 (plus:DI (match_dup 1) (match_dup 2)))]
5584 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5585 "add{q}\t{%2, %0|%0, %2}"
5586 [(set_attr "type" "alu")
5587 (set_attr "mode" "DI")])
5589 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5590 [(set (reg:CCC FLAGS_REG)
5593 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5594 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5596 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5597 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5598 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5599 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5600 [(set_attr "type" "alu")
5601 (set_attr "mode" "<MODE>")])
5603 (define_insn "*add<mode>3_cconly_overflow"
5604 [(set (reg:CCC FLAGS_REG)
5606 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5607 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5609 (clobber (match_scratch:SWI 0 "=<r>"))]
5610 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5611 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5612 [(set_attr "type" "alu")
5613 (set_attr "mode" "<MODE>")])
5615 (define_insn "*sub<mode>3_cconly_overflow"
5616 [(set (reg:CCC FLAGS_REG)
5618 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5619 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5622 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5623 [(set_attr "type" "icmp")
5624 (set_attr "mode" "<MODE>")])
5626 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5627 [(set (reg:CCC FLAGS_REG)
5629 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5630 (match_operand:SI 2 "general_operand" "g"))
5632 (set (match_operand:DI 0 "register_operand" "=r")
5633 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5634 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5635 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5636 [(set_attr "type" "alu")
5637 (set_attr "mode" "SI")])
5639 (define_insn "addqi3_carry"
5640 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5641 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5642 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5643 (match_operand:QI 2 "general_operand" "qi,qm")))
5644 (clobber (reg:CC FLAGS_REG))]
5645 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5646 "adc{b}\t{%2, %0|%0, %2}"
5647 [(set_attr "type" "alu")
5648 (set_attr "pent_pair" "pu")
5649 (set_attr "mode" "QI")])
5651 (define_insn "addhi3_carry"
5652 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5653 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5654 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5655 (match_operand:HI 2 "general_operand" "ri,rm")))
5656 (clobber (reg:CC FLAGS_REG))]
5657 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5658 "adc{w}\t{%2, %0|%0, %2}"
5659 [(set_attr "type" "alu")
5660 (set_attr "pent_pair" "pu")
5661 (set_attr "mode" "HI")])
5663 (define_insn "addsi3_carry"
5664 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5665 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5666 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5667 (match_operand:SI 2 "general_operand" "ri,rm")))
5668 (clobber (reg:CC FLAGS_REG))]
5669 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5670 "adc{l}\t{%2, %0|%0, %2}"
5671 [(set_attr "type" "alu")
5672 (set_attr "pent_pair" "pu")
5673 (set_attr "mode" "SI")])
5675 (define_insn "*addsi3_carry_zext"
5676 [(set (match_operand:DI 0 "register_operand" "=r")
5678 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5679 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5680 (match_operand:SI 2 "general_operand" "g"))))
5681 (clobber (reg:CC FLAGS_REG))]
5682 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5683 "adc{l}\t{%2, %k0|%k0, %2}"
5684 [(set_attr "type" "alu")
5685 (set_attr "pent_pair" "pu")
5686 (set_attr "mode" "SI")])
5688 (define_insn "*addsi3_cc"
5689 [(set (reg:CC FLAGS_REG)
5690 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5691 (match_operand:SI 2 "general_operand" "ri,rm")]
5693 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5694 (plus:SI (match_dup 1) (match_dup 2)))]
5695 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5696 "add{l}\t{%2, %0|%0, %2}"
5697 [(set_attr "type" "alu")
5698 (set_attr "mode" "SI")])
5700 (define_insn "addqi3_cc"
5701 [(set (reg:CC FLAGS_REG)
5702 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5703 (match_operand:QI 2 "general_operand" "qi,qm")]
5705 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5706 (plus:QI (match_dup 1) (match_dup 2)))]
5707 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5708 "add{b}\t{%2, %0|%0, %2}"
5709 [(set_attr "type" "alu")
5710 (set_attr "mode" "QI")])
5712 (define_expand "addsi3"
5713 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5714 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5715 (match_operand:SI 2 "general_operand" "")))
5716 (clobber (reg:CC FLAGS_REG))])]
5718 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5720 (define_insn "*lea_1"
5721 [(set (match_operand:SI 0 "register_operand" "=r")
5722 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5724 "lea{l}\t{%a1, %0|%0, %a1}"
5725 [(set_attr "type" "lea")
5726 (set_attr "mode" "SI")])
5728 (define_insn "*lea_1_rex64"
5729 [(set (match_operand:SI 0 "register_operand" "=r")
5730 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5732 "lea{l}\t{%a1, %0|%0, %a1}"
5733 [(set_attr "type" "lea")
5734 (set_attr "mode" "SI")])
5736 (define_insn "*lea_1_zext"
5737 [(set (match_operand:DI 0 "register_operand" "=r")
5739 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5741 "lea{l}\t{%a1, %k0|%k0, %a1}"
5742 [(set_attr "type" "lea")
5743 (set_attr "mode" "SI")])
5745 (define_insn "*lea_2_rex64"
5746 [(set (match_operand:DI 0 "register_operand" "=r")
5747 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5749 "lea{q}\t{%a1, %0|%0, %a1}"
5750 [(set_attr "type" "lea")
5751 (set_attr "mode" "DI")])
5753 ;; The lea patterns for non-Pmodes needs to be matched by several
5754 ;; insns converted to real lea by splitters.
5756 (define_insn_and_split "*lea_general_1"
5757 [(set (match_operand 0 "register_operand" "=r")
5758 (plus (plus (match_operand 1 "index_register_operand" "l")
5759 (match_operand 2 "register_operand" "r"))
5760 (match_operand 3 "immediate_operand" "i")))]
5761 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5762 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5763 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5764 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5765 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5766 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5767 || GET_MODE (operands[3]) == VOIDmode)"
5769 "&& reload_completed"
5773 operands[0] = gen_lowpart (SImode, operands[0]);
5774 operands[1] = gen_lowpart (Pmode, operands[1]);
5775 operands[2] = gen_lowpart (Pmode, operands[2]);
5776 operands[3] = gen_lowpart (Pmode, operands[3]);
5777 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5779 if (Pmode != SImode)
5780 pat = gen_rtx_SUBREG (SImode, pat, 0);
5781 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5784 [(set_attr "type" "lea")
5785 (set_attr "mode" "SI")])
5787 (define_insn_and_split "*lea_general_1_zext"
5788 [(set (match_operand:DI 0 "register_operand" "=r")
5790 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5791 (match_operand:SI 2 "register_operand" "r"))
5792 (match_operand:SI 3 "immediate_operand" "i"))))]
5795 "&& reload_completed"
5797 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5799 (match_dup 3)) 0)))]
5801 operands[1] = gen_lowpart (Pmode, operands[1]);
5802 operands[2] = gen_lowpart (Pmode, operands[2]);
5803 operands[3] = gen_lowpart (Pmode, operands[3]);
5805 [(set_attr "type" "lea")
5806 (set_attr "mode" "SI")])
5808 (define_insn_and_split "*lea_general_2"
5809 [(set (match_operand 0 "register_operand" "=r")
5810 (plus (mult (match_operand 1 "index_register_operand" "l")
5811 (match_operand 2 "const248_operand" "i"))
5812 (match_operand 3 "nonmemory_operand" "ri")))]
5813 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5814 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5815 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5816 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5817 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5818 || GET_MODE (operands[3]) == VOIDmode)"
5820 "&& reload_completed"
5824 operands[0] = gen_lowpart (SImode, operands[0]);
5825 operands[1] = gen_lowpart (Pmode, operands[1]);
5826 operands[3] = gen_lowpart (Pmode, operands[3]);
5827 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5829 if (Pmode != SImode)
5830 pat = gen_rtx_SUBREG (SImode, pat, 0);
5831 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5834 [(set_attr "type" "lea")
5835 (set_attr "mode" "SI")])
5837 (define_insn_and_split "*lea_general_2_zext"
5838 [(set (match_operand:DI 0 "register_operand" "=r")
5840 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5841 (match_operand:SI 2 "const248_operand" "n"))
5842 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5845 "&& reload_completed"
5847 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5849 (match_dup 3)) 0)))]
5851 operands[1] = gen_lowpart (Pmode, operands[1]);
5852 operands[3] = gen_lowpart (Pmode, operands[3]);
5854 [(set_attr "type" "lea")
5855 (set_attr "mode" "SI")])
5857 (define_insn_and_split "*lea_general_3"
5858 [(set (match_operand 0 "register_operand" "=r")
5859 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5860 (match_operand 2 "const248_operand" "i"))
5861 (match_operand 3 "register_operand" "r"))
5862 (match_operand 4 "immediate_operand" "i")))]
5863 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5864 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5865 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5866 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5867 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5869 "&& reload_completed"
5873 operands[0] = gen_lowpart (SImode, operands[0]);
5874 operands[1] = gen_lowpart (Pmode, operands[1]);
5875 operands[3] = gen_lowpart (Pmode, operands[3]);
5876 operands[4] = gen_lowpart (Pmode, operands[4]);
5877 pat = gen_rtx_PLUS (Pmode,
5878 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5882 if (Pmode != SImode)
5883 pat = gen_rtx_SUBREG (SImode, pat, 0);
5884 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5887 [(set_attr "type" "lea")
5888 (set_attr "mode" "SI")])
5890 (define_insn_and_split "*lea_general_3_zext"
5891 [(set (match_operand:DI 0 "register_operand" "=r")
5893 (plus:SI (plus:SI (mult:SI
5894 (match_operand:SI 1 "index_register_operand" "l")
5895 (match_operand:SI 2 "const248_operand" "n"))
5896 (match_operand:SI 3 "register_operand" "r"))
5897 (match_operand:SI 4 "immediate_operand" "i"))))]
5900 "&& reload_completed"
5902 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5905 (match_dup 4)) 0)))]
5907 operands[1] = gen_lowpart (Pmode, operands[1]);
5908 operands[3] = gen_lowpart (Pmode, operands[3]);
5909 operands[4] = gen_lowpart (Pmode, operands[4]);
5911 [(set_attr "type" "lea")
5912 (set_attr "mode" "SI")])
5914 (define_insn "*adddi_1_rex64"
5915 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5916 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5917 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5918 (clobber (reg:CC FLAGS_REG))]
5919 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5921 switch (get_attr_type (insn))
5924 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5925 return "lea{q}\t{%a2, %0|%0, %a2}";
5928 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5929 if (operands[2] == const1_rtx)
5930 return "inc{q}\t%0";
5933 gcc_assert (operands[2] == constm1_rtx);
5934 return "dec{q}\t%0";
5938 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5940 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5941 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5942 if (CONST_INT_P (operands[2])
5943 /* Avoid overflows. */
5944 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5945 && (INTVAL (operands[2]) == 128
5946 || (INTVAL (operands[2]) < 0
5947 && INTVAL (operands[2]) != -128)))
5949 operands[2] = GEN_INT (-INTVAL (operands[2]));
5950 return "sub{q}\t{%2, %0|%0, %2}";
5952 return "add{q}\t{%2, %0|%0, %2}";
5956 (cond [(eq_attr "alternative" "2")
5957 (const_string "lea")
5958 ; Current assemblers are broken and do not allow @GOTOFF in
5959 ; ought but a memory context.
5960 (match_operand:DI 2 "pic_symbolic_operand" "")
5961 (const_string "lea")
5962 (match_operand:DI 2 "incdec_operand" "")
5963 (const_string "incdec")
5965 (const_string "alu")))
5966 (set_attr "mode" "DI")])
5968 ;; Convert lea to the lea pattern to avoid flags dependency.
5970 [(set (match_operand:DI 0 "register_operand" "")
5971 (plus:DI (match_operand:DI 1 "register_operand" "")
5972 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5973 (clobber (reg:CC FLAGS_REG))]
5974 "TARGET_64BIT && reload_completed
5975 && true_regnum (operands[0]) != true_regnum (operands[1])"
5977 (plus:DI (match_dup 1)
5981 (define_insn "*adddi_2_rex64"
5982 [(set (reg FLAGS_REG)
5984 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5985 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5987 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5988 (plus:DI (match_dup 1) (match_dup 2)))]
5989 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5990 && ix86_binary_operator_ok (PLUS, DImode, operands)
5991 /* Current assemblers are broken and do not allow @GOTOFF in
5992 ought but a memory context. */
5993 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5995 switch (get_attr_type (insn))
5998 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5999 if (operands[2] == const1_rtx)
6000 return "inc{q}\t%0";
6003 gcc_assert (operands[2] == constm1_rtx);
6004 return "dec{q}\t%0";
6008 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6009 /* ???? We ought to handle there the 32bit case too
6010 - do we need new constraint? */
6011 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6012 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6013 if (CONST_INT_P (operands[2])
6014 /* Avoid overflows. */
6015 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6016 && (INTVAL (operands[2]) == 128
6017 || (INTVAL (operands[2]) < 0
6018 && INTVAL (operands[2]) != -128)))
6020 operands[2] = GEN_INT (-INTVAL (operands[2]));
6021 return "sub{q}\t{%2, %0|%0, %2}";
6023 return "add{q}\t{%2, %0|%0, %2}";
6027 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6028 (const_string "incdec")
6029 (const_string "alu")))
6030 (set_attr "mode" "DI")])
6032 (define_insn "*adddi_3_rex64"
6033 [(set (reg FLAGS_REG)
6034 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6035 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6036 (clobber (match_scratch:DI 0 "=r"))]
6038 && ix86_match_ccmode (insn, CCZmode)
6039 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6040 /* Current assemblers are broken and do not allow @GOTOFF in
6041 ought but a memory context. */
6042 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6044 switch (get_attr_type (insn))
6047 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6048 if (operands[2] == const1_rtx)
6049 return "inc{q}\t%0";
6052 gcc_assert (operands[2] == constm1_rtx);
6053 return "dec{q}\t%0";
6057 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6058 /* ???? We ought to handle there the 32bit case too
6059 - do we need new constraint? */
6060 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6061 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6062 if (CONST_INT_P (operands[2])
6063 /* Avoid overflows. */
6064 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6065 && (INTVAL (operands[2]) == 128
6066 || (INTVAL (operands[2]) < 0
6067 && INTVAL (operands[2]) != -128)))
6069 operands[2] = GEN_INT (-INTVAL (operands[2]));
6070 return "sub{q}\t{%2, %0|%0, %2}";
6072 return "add{q}\t{%2, %0|%0, %2}";
6076 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6077 (const_string "incdec")
6078 (const_string "alu")))
6079 (set_attr "mode" "DI")])
6081 ; For comparisons against 1, -1 and 128, we may generate better code
6082 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6083 ; is matched then. We can't accept general immediate, because for
6084 ; case of overflows, the result is messed up.
6085 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6087 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6088 ; only for comparisons not depending on it.
6089 (define_insn "*adddi_4_rex64"
6090 [(set (reg FLAGS_REG)
6091 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6092 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6093 (clobber (match_scratch:DI 0 "=rm"))]
6095 && ix86_match_ccmode (insn, CCGCmode)"
6097 switch (get_attr_type (insn))
6100 if (operands[2] == constm1_rtx)
6101 return "inc{q}\t%0";
6104 gcc_assert (operands[2] == const1_rtx);
6105 return "dec{q}\t%0";
6109 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6110 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6111 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6112 if ((INTVAL (operands[2]) == -128
6113 || (INTVAL (operands[2]) > 0
6114 && INTVAL (operands[2]) != 128))
6115 /* Avoid overflows. */
6116 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6117 return "sub{q}\t{%2, %0|%0, %2}";
6118 operands[2] = GEN_INT (-INTVAL (operands[2]));
6119 return "add{q}\t{%2, %0|%0, %2}";
6123 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6124 (const_string "incdec")
6125 (const_string "alu")))
6126 (set_attr "mode" "DI")])
6128 (define_insn "*adddi_5_rex64"
6129 [(set (reg FLAGS_REG)
6131 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6132 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6134 (clobber (match_scratch:DI 0 "=r"))]
6136 && ix86_match_ccmode (insn, CCGOCmode)
6137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6138 /* Current assemblers are broken and do not allow @GOTOFF in
6139 ought but a memory context. */
6140 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6142 switch (get_attr_type (insn))
6145 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6146 if (operands[2] == const1_rtx)
6147 return "inc{q}\t%0";
6150 gcc_assert (operands[2] == constm1_rtx);
6151 return "dec{q}\t%0";
6155 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6156 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6157 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6158 if (CONST_INT_P (operands[2])
6159 /* Avoid overflows. */
6160 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6161 && (INTVAL (operands[2]) == 128
6162 || (INTVAL (operands[2]) < 0
6163 && INTVAL (operands[2]) != -128)))
6165 operands[2] = GEN_INT (-INTVAL (operands[2]));
6166 return "sub{q}\t{%2, %0|%0, %2}";
6168 return "add{q}\t{%2, %0|%0, %2}";
6172 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6173 (const_string "incdec")
6174 (const_string "alu")))
6175 (set_attr "mode" "DI")])
6178 (define_insn "*addsi_1"
6179 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6180 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6181 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6182 (clobber (reg:CC FLAGS_REG))]
6183 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6185 switch (get_attr_type (insn))
6188 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6189 return "lea{l}\t{%a2, %0|%0, %a2}";
6192 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6193 if (operands[2] == const1_rtx)
6194 return "inc{l}\t%0";
6197 gcc_assert (operands[2] == constm1_rtx);
6198 return "dec{l}\t%0";
6202 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6204 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6205 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6206 if (CONST_INT_P (operands[2])
6207 && (INTVAL (operands[2]) == 128
6208 || (INTVAL (operands[2]) < 0
6209 && INTVAL (operands[2]) != -128)))
6211 operands[2] = GEN_INT (-INTVAL (operands[2]));
6212 return "sub{l}\t{%2, %0|%0, %2}";
6214 return "add{l}\t{%2, %0|%0, %2}";
6218 (cond [(eq_attr "alternative" "2")
6219 (const_string "lea")
6220 ; Current assemblers are broken and do not allow @GOTOFF in
6221 ; ought but a memory context.
6222 (match_operand:SI 2 "pic_symbolic_operand" "")
6223 (const_string "lea")
6224 (match_operand:SI 2 "incdec_operand" "")
6225 (const_string "incdec")
6227 (const_string "alu")))
6228 (set_attr "mode" "SI")])
6230 ;; Convert lea to the lea pattern to avoid flags dependency.
6232 [(set (match_operand 0 "register_operand" "")
6233 (plus (match_operand 1 "register_operand" "")
6234 (match_operand 2 "nonmemory_operand" "")))
6235 (clobber (reg:CC FLAGS_REG))]
6237 && true_regnum (operands[0]) != true_regnum (operands[1])"
6241 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6242 may confuse gen_lowpart. */
6243 if (GET_MODE (operands[0]) != Pmode)
6245 operands[1] = gen_lowpart (Pmode, operands[1]);
6246 operands[2] = gen_lowpart (Pmode, operands[2]);
6248 operands[0] = gen_lowpart (SImode, operands[0]);
6249 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6250 if (Pmode != SImode)
6251 pat = gen_rtx_SUBREG (SImode, pat, 0);
6252 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6256 ;; It may seem that nonimmediate operand is proper one for operand 1.
6257 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6258 ;; we take care in ix86_binary_operator_ok to not allow two memory
6259 ;; operands so proper swapping will be done in reload. This allow
6260 ;; patterns constructed from addsi_1 to match.
6261 (define_insn "addsi_1_zext"
6262 [(set (match_operand:DI 0 "register_operand" "=r,r")
6264 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6265 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6266 (clobber (reg:CC FLAGS_REG))]
6267 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6269 switch (get_attr_type (insn))
6272 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6273 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6276 if (operands[2] == const1_rtx)
6277 return "inc{l}\t%k0";
6280 gcc_assert (operands[2] == constm1_rtx);
6281 return "dec{l}\t%k0";
6285 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6286 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6287 if (CONST_INT_P (operands[2])
6288 && (INTVAL (operands[2]) == 128
6289 || (INTVAL (operands[2]) < 0
6290 && INTVAL (operands[2]) != -128)))
6292 operands[2] = GEN_INT (-INTVAL (operands[2]));
6293 return "sub{l}\t{%2, %k0|%k0, %2}";
6295 return "add{l}\t{%2, %k0|%k0, %2}";
6299 (cond [(eq_attr "alternative" "1")
6300 (const_string "lea")
6301 ; Current assemblers are broken and do not allow @GOTOFF in
6302 ; ought but a memory context.
6303 (match_operand:SI 2 "pic_symbolic_operand" "")
6304 (const_string "lea")
6305 (match_operand:SI 2 "incdec_operand" "")
6306 (const_string "incdec")
6308 (const_string "alu")))
6309 (set_attr "mode" "SI")])
6311 ;; Convert lea to the lea pattern to avoid flags dependency.
6313 [(set (match_operand:DI 0 "register_operand" "")
6315 (plus:SI (match_operand:SI 1 "register_operand" "")
6316 (match_operand:SI 2 "nonmemory_operand" ""))))
6317 (clobber (reg:CC FLAGS_REG))]
6318 "TARGET_64BIT && reload_completed
6319 && true_regnum (operands[0]) != true_regnum (operands[1])"
6321 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6323 operands[1] = gen_lowpart (Pmode, operands[1]);
6324 operands[2] = gen_lowpart (Pmode, operands[2]);
6327 (define_insn "*addsi_2"
6328 [(set (reg FLAGS_REG)
6330 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6331 (match_operand:SI 2 "general_operand" "rmni,rni"))
6333 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6334 (plus:SI (match_dup 1) (match_dup 2)))]
6335 "ix86_match_ccmode (insn, CCGOCmode)
6336 && ix86_binary_operator_ok (PLUS, SImode, operands)
6337 /* Current assemblers are broken and do not allow @GOTOFF in
6338 ought but a memory context. */
6339 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6341 switch (get_attr_type (insn))
6344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345 if (operands[2] == const1_rtx)
6346 return "inc{l}\t%0";
6349 gcc_assert (operands[2] == constm1_rtx);
6350 return "dec{l}\t%0";
6354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6356 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6357 if (CONST_INT_P (operands[2])
6358 && (INTVAL (operands[2]) == 128
6359 || (INTVAL (operands[2]) < 0
6360 && INTVAL (operands[2]) != -128)))
6362 operands[2] = GEN_INT (-INTVAL (operands[2]));
6363 return "sub{l}\t{%2, %0|%0, %2}";
6365 return "add{l}\t{%2, %0|%0, %2}";
6369 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6370 (const_string "incdec")
6371 (const_string "alu")))
6372 (set_attr "mode" "SI")])
6374 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6375 (define_insn "*addsi_2_zext"
6376 [(set (reg FLAGS_REG)
6378 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6379 (match_operand:SI 2 "general_operand" "rmni"))
6381 (set (match_operand:DI 0 "register_operand" "=r")
6382 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6383 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6384 && ix86_binary_operator_ok (PLUS, SImode, operands)
6385 /* Current assemblers are broken and do not allow @GOTOFF in
6386 ought but a memory context. */
6387 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6389 switch (get_attr_type (insn))
6392 if (operands[2] == const1_rtx)
6393 return "inc{l}\t%k0";
6396 gcc_assert (operands[2] == constm1_rtx);
6397 return "dec{l}\t%k0";
6401 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6402 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6403 if (CONST_INT_P (operands[2])
6404 && (INTVAL (operands[2]) == 128
6405 || (INTVAL (operands[2]) < 0
6406 && INTVAL (operands[2]) != -128)))
6408 operands[2] = GEN_INT (-INTVAL (operands[2]));
6409 return "sub{l}\t{%2, %k0|%k0, %2}";
6411 return "add{l}\t{%2, %k0|%k0, %2}";
6415 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6416 (const_string "incdec")
6417 (const_string "alu")))
6418 (set_attr "mode" "SI")])
6420 (define_insn "*addsi_3"
6421 [(set (reg FLAGS_REG)
6422 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6423 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6424 (clobber (match_scratch:SI 0 "=r"))]
6425 "ix86_match_ccmode (insn, CCZmode)
6426 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6427 /* Current assemblers are broken and do not allow @GOTOFF in
6428 ought but a memory context. */
6429 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6431 switch (get_attr_type (insn))
6434 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6435 if (operands[2] == const1_rtx)
6436 return "inc{l}\t%0";
6439 gcc_assert (operands[2] == constm1_rtx);
6440 return "dec{l}\t%0";
6444 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6445 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6446 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6447 if (CONST_INT_P (operands[2])
6448 && (INTVAL (operands[2]) == 128
6449 || (INTVAL (operands[2]) < 0
6450 && INTVAL (operands[2]) != -128)))
6452 operands[2] = GEN_INT (-INTVAL (operands[2]));
6453 return "sub{l}\t{%2, %0|%0, %2}";
6455 return "add{l}\t{%2, %0|%0, %2}";
6459 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6460 (const_string "incdec")
6461 (const_string "alu")))
6462 (set_attr "mode" "SI")])
6464 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6465 (define_insn "*addsi_3_zext"
6466 [(set (reg FLAGS_REG)
6467 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6468 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6469 (set (match_operand:DI 0 "register_operand" "=r")
6470 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6471 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6472 && ix86_binary_operator_ok (PLUS, SImode, operands)
6473 /* Current assemblers are broken and do not allow @GOTOFF in
6474 ought but a memory context. */
6475 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6477 switch (get_attr_type (insn))
6480 if (operands[2] == const1_rtx)
6481 return "inc{l}\t%k0";
6484 gcc_assert (operands[2] == constm1_rtx);
6485 return "dec{l}\t%k0";
6489 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6490 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6491 if (CONST_INT_P (operands[2])
6492 && (INTVAL (operands[2]) == 128
6493 || (INTVAL (operands[2]) < 0
6494 && INTVAL (operands[2]) != -128)))
6496 operands[2] = GEN_INT (-INTVAL (operands[2]));
6497 return "sub{l}\t{%2, %k0|%k0, %2}";
6499 return "add{l}\t{%2, %k0|%k0, %2}";
6503 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6504 (const_string "incdec")
6505 (const_string "alu")))
6506 (set_attr "mode" "SI")])
6508 ; For comparisons against 1, -1 and 128, we may generate better code
6509 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6510 ; is matched then. We can't accept general immediate, because for
6511 ; case of overflows, the result is messed up.
6512 ; This pattern also don't hold of 0x80000000, since the value overflows
6514 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6515 ; only for comparisons not depending on it.
6516 (define_insn "*addsi_4"
6517 [(set (reg FLAGS_REG)
6518 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6519 (match_operand:SI 2 "const_int_operand" "n")))
6520 (clobber (match_scratch:SI 0 "=rm"))]
6521 "ix86_match_ccmode (insn, CCGCmode)
6522 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6524 switch (get_attr_type (insn))
6527 if (operands[2] == constm1_rtx)
6528 return "inc{l}\t%0";
6531 gcc_assert (operands[2] == const1_rtx);
6532 return "dec{l}\t%0";
6536 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6537 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6538 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6539 if ((INTVAL (operands[2]) == -128
6540 || (INTVAL (operands[2]) > 0
6541 && INTVAL (operands[2]) != 128)))
6542 return "sub{l}\t{%2, %0|%0, %2}";
6543 operands[2] = GEN_INT (-INTVAL (operands[2]));
6544 return "add{l}\t{%2, %0|%0, %2}";
6548 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6549 (const_string "incdec")
6550 (const_string "alu")))
6551 (set_attr "mode" "SI")])
6553 (define_insn "*addsi_5"
6554 [(set (reg FLAGS_REG)
6556 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6557 (match_operand:SI 2 "general_operand" "rmni"))
6559 (clobber (match_scratch:SI 0 "=r"))]
6560 "ix86_match_ccmode (insn, CCGOCmode)
6561 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6562 /* Current assemblers are broken and do not allow @GOTOFF in
6563 ought but a memory context. */
6564 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6566 switch (get_attr_type (insn))
6569 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6570 if (operands[2] == const1_rtx)
6571 return "inc{l}\t%0";
6574 gcc_assert (operands[2] == constm1_rtx);
6575 return "dec{l}\t%0";
6579 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6580 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6581 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6582 if (CONST_INT_P (operands[2])
6583 && (INTVAL (operands[2]) == 128
6584 || (INTVAL (operands[2]) < 0
6585 && INTVAL (operands[2]) != -128)))
6587 operands[2] = GEN_INT (-INTVAL (operands[2]));
6588 return "sub{l}\t{%2, %0|%0, %2}";
6590 return "add{l}\t{%2, %0|%0, %2}";
6594 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6595 (const_string "incdec")
6596 (const_string "alu")))
6597 (set_attr "mode" "SI")])
6599 (define_expand "addhi3"
6600 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6601 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6602 (match_operand:HI 2 "general_operand" "")))
6603 (clobber (reg:CC FLAGS_REG))])]
6604 "TARGET_HIMODE_MATH"
6605 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6607 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6608 ;; type optimizations enabled by define-splits. This is not important
6609 ;; for PII, and in fact harmful because of partial register stalls.
6611 (define_insn "*addhi_1_lea"
6612 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6613 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6614 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6615 (clobber (reg:CC FLAGS_REG))]
6616 "!TARGET_PARTIAL_REG_STALL
6617 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6619 switch (get_attr_type (insn))
6624 if (operands[2] == const1_rtx)
6625 return "inc{w}\t%0";
6628 gcc_assert (operands[2] == constm1_rtx);
6629 return "dec{w}\t%0";
6633 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6634 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6635 if (CONST_INT_P (operands[2])
6636 && (INTVAL (operands[2]) == 128
6637 || (INTVAL (operands[2]) < 0
6638 && INTVAL (operands[2]) != -128)))
6640 operands[2] = GEN_INT (-INTVAL (operands[2]));
6641 return "sub{w}\t{%2, %0|%0, %2}";
6643 return "add{w}\t{%2, %0|%0, %2}";
6647 (if_then_else (eq_attr "alternative" "2")
6648 (const_string "lea")
6649 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6650 (const_string "incdec")
6651 (const_string "alu"))))
6652 (set_attr "mode" "HI,HI,SI")])
6654 (define_insn "*addhi_1"
6655 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6656 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6657 (match_operand:HI 2 "general_operand" "ri,rm")))
6658 (clobber (reg:CC FLAGS_REG))]
6659 "TARGET_PARTIAL_REG_STALL
6660 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6662 switch (get_attr_type (insn))
6665 if (operands[2] == const1_rtx)
6666 return "inc{w}\t%0";
6669 gcc_assert (operands[2] == constm1_rtx);
6670 return "dec{w}\t%0";
6674 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6675 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6676 if (CONST_INT_P (operands[2])
6677 && (INTVAL (operands[2]) == 128
6678 || (INTVAL (operands[2]) < 0
6679 && INTVAL (operands[2]) != -128)))
6681 operands[2] = GEN_INT (-INTVAL (operands[2]));
6682 return "sub{w}\t{%2, %0|%0, %2}";
6684 return "add{w}\t{%2, %0|%0, %2}";
6688 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6689 (const_string "incdec")
6690 (const_string "alu")))
6691 (set_attr "mode" "HI")])
6693 (define_insn "*addhi_2"
6694 [(set (reg FLAGS_REG)
6696 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6697 (match_operand:HI 2 "general_operand" "rmni,rni"))
6699 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6700 (plus:HI (match_dup 1) (match_dup 2)))]
6701 "ix86_match_ccmode (insn, CCGOCmode)
6702 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6704 switch (get_attr_type (insn))
6707 if (operands[2] == const1_rtx)
6708 return "inc{w}\t%0";
6711 gcc_assert (operands[2] == constm1_rtx);
6712 return "dec{w}\t%0";
6716 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6717 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6718 if (CONST_INT_P (operands[2])
6719 && (INTVAL (operands[2]) == 128
6720 || (INTVAL (operands[2]) < 0
6721 && INTVAL (operands[2]) != -128)))
6723 operands[2] = GEN_INT (-INTVAL (operands[2]));
6724 return "sub{w}\t{%2, %0|%0, %2}";
6726 return "add{w}\t{%2, %0|%0, %2}";
6730 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6731 (const_string "incdec")
6732 (const_string "alu")))
6733 (set_attr "mode" "HI")])
6735 (define_insn "*addhi_3"
6736 [(set (reg FLAGS_REG)
6737 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6738 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6739 (clobber (match_scratch:HI 0 "=r"))]
6740 "ix86_match_ccmode (insn, CCZmode)
6741 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6743 switch (get_attr_type (insn))
6746 if (operands[2] == const1_rtx)
6747 return "inc{w}\t%0";
6750 gcc_assert (operands[2] == constm1_rtx);
6751 return "dec{w}\t%0";
6755 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6756 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6757 if (CONST_INT_P (operands[2])
6758 && (INTVAL (operands[2]) == 128
6759 || (INTVAL (operands[2]) < 0
6760 && INTVAL (operands[2]) != -128)))
6762 operands[2] = GEN_INT (-INTVAL (operands[2]));
6763 return "sub{w}\t{%2, %0|%0, %2}";
6765 return "add{w}\t{%2, %0|%0, %2}";
6769 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6770 (const_string "incdec")
6771 (const_string "alu")))
6772 (set_attr "mode" "HI")])
6774 ; See comments above addsi_4 for details.
6775 (define_insn "*addhi_4"
6776 [(set (reg FLAGS_REG)
6777 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6778 (match_operand:HI 2 "const_int_operand" "n")))
6779 (clobber (match_scratch:HI 0 "=rm"))]
6780 "ix86_match_ccmode (insn, CCGCmode)
6781 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6783 switch (get_attr_type (insn))
6786 if (operands[2] == constm1_rtx)
6787 return "inc{w}\t%0";
6790 gcc_assert (operands[2] == const1_rtx);
6791 return "dec{w}\t%0";
6795 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6796 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6797 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6798 if ((INTVAL (operands[2]) == -128
6799 || (INTVAL (operands[2]) > 0
6800 && INTVAL (operands[2]) != 128)))
6801 return "sub{w}\t{%2, %0|%0, %2}";
6802 operands[2] = GEN_INT (-INTVAL (operands[2]));
6803 return "add{w}\t{%2, %0|%0, %2}";
6807 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6808 (const_string "incdec")
6809 (const_string "alu")))
6810 (set_attr "mode" "SI")])
6813 (define_insn "*addhi_5"
6814 [(set (reg FLAGS_REG)
6816 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6817 (match_operand:HI 2 "general_operand" "rmni"))
6819 (clobber (match_scratch:HI 0 "=r"))]
6820 "ix86_match_ccmode (insn, CCGOCmode)
6821 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823 switch (get_attr_type (insn))
6826 if (operands[2] == const1_rtx)
6827 return "inc{w}\t%0";
6830 gcc_assert (operands[2] == constm1_rtx);
6831 return "dec{w}\t%0";
6835 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6836 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6837 if (CONST_INT_P (operands[2])
6838 && (INTVAL (operands[2]) == 128
6839 || (INTVAL (operands[2]) < 0
6840 && INTVAL (operands[2]) != -128)))
6842 operands[2] = GEN_INT (-INTVAL (operands[2]));
6843 return "sub{w}\t{%2, %0|%0, %2}";
6845 return "add{w}\t{%2, %0|%0, %2}";
6849 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6850 (const_string "incdec")
6851 (const_string "alu")))
6852 (set_attr "mode" "HI")])
6854 (define_expand "addqi3"
6855 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6856 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6857 (match_operand:QI 2 "general_operand" "")))
6858 (clobber (reg:CC FLAGS_REG))])]
6859 "TARGET_QIMODE_MATH"
6860 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6862 ;; %%% Potential partial reg stall on alternative 2. What to do?
6863 (define_insn "*addqi_1_lea"
6864 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6865 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6866 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6867 (clobber (reg:CC FLAGS_REG))]
6868 "!TARGET_PARTIAL_REG_STALL
6869 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6871 int widen = (which_alternative == 2);
6872 switch (get_attr_type (insn))
6877 if (operands[2] == const1_rtx)
6878 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6881 gcc_assert (operands[2] == constm1_rtx);
6882 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6888 if (CONST_INT_P (operands[2])
6889 && (INTVAL (operands[2]) == 128
6890 || (INTVAL (operands[2]) < 0
6891 && INTVAL (operands[2]) != -128)))
6893 operands[2] = GEN_INT (-INTVAL (operands[2]));
6895 return "sub{l}\t{%2, %k0|%k0, %2}";
6897 return "sub{b}\t{%2, %0|%0, %2}";
6900 return "add{l}\t{%k2, %k0|%k0, %k2}";
6902 return "add{b}\t{%2, %0|%0, %2}";
6906 (if_then_else (eq_attr "alternative" "3")
6907 (const_string "lea")
6908 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6909 (const_string "incdec")
6910 (const_string "alu"))))
6911 (set_attr "mode" "QI,QI,SI,SI")])
6913 (define_insn "*addqi_1"
6914 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6915 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6916 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6917 (clobber (reg:CC FLAGS_REG))]
6918 "TARGET_PARTIAL_REG_STALL
6919 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6921 int widen = (which_alternative == 2);
6922 switch (get_attr_type (insn))
6925 if (operands[2] == const1_rtx)
6926 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6929 gcc_assert (operands[2] == constm1_rtx);
6930 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6934 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6935 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6936 if (CONST_INT_P (operands[2])
6937 && (INTVAL (operands[2]) == 128
6938 || (INTVAL (operands[2]) < 0
6939 && INTVAL (operands[2]) != -128)))
6941 operands[2] = GEN_INT (-INTVAL (operands[2]));
6943 return "sub{l}\t{%2, %k0|%k0, %2}";
6945 return "sub{b}\t{%2, %0|%0, %2}";
6948 return "add{l}\t{%k2, %k0|%k0, %k2}";
6950 return "add{b}\t{%2, %0|%0, %2}";
6954 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6955 (const_string "incdec")
6956 (const_string "alu")))
6957 (set_attr "mode" "QI,QI,SI")])
6959 (define_insn "*addqi_1_slp"
6960 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6961 (plus:QI (match_dup 0)
6962 (match_operand:QI 1 "general_operand" "qn,qnm")))
6963 (clobber (reg:CC FLAGS_REG))]
6964 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6965 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6967 switch (get_attr_type (insn))
6970 if (operands[1] == const1_rtx)
6971 return "inc{b}\t%0";
6974 gcc_assert (operands[1] == constm1_rtx);
6975 return "dec{b}\t%0";
6979 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6980 if (CONST_INT_P (operands[1])
6981 && INTVAL (operands[1]) < 0)
6983 operands[1] = GEN_INT (-INTVAL (operands[1]));
6984 return "sub{b}\t{%1, %0|%0, %1}";
6986 return "add{b}\t{%1, %0|%0, %1}";
6990 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6991 (const_string "incdec")
6992 (const_string "alu1")))
6993 (set (attr "memory")
6994 (if_then_else (match_operand 1 "memory_operand" "")
6995 (const_string "load")
6996 (const_string "none")))
6997 (set_attr "mode" "QI")])
6999 (define_insn "*addqi_2"
7000 [(set (reg FLAGS_REG)
7002 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7003 (match_operand:QI 2 "general_operand" "qmni,qni"))
7005 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7006 (plus:QI (match_dup 1) (match_dup 2)))]
7007 "ix86_match_ccmode (insn, CCGOCmode)
7008 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7010 switch (get_attr_type (insn))
7013 if (operands[2] == const1_rtx)
7014 return "inc{b}\t%0";
7017 gcc_assert (operands[2] == constm1_rtx
7018 || (CONST_INT_P (operands[2])
7019 && INTVAL (operands[2]) == 255));
7020 return "dec{b}\t%0";
7024 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7025 if (CONST_INT_P (operands[2])
7026 && INTVAL (operands[2]) < 0)
7028 operands[2] = GEN_INT (-INTVAL (operands[2]));
7029 return "sub{b}\t{%2, %0|%0, %2}";
7031 return "add{b}\t{%2, %0|%0, %2}";
7035 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7036 (const_string "incdec")
7037 (const_string "alu")))
7038 (set_attr "mode" "QI")])
7040 (define_insn "*addqi_3"
7041 [(set (reg FLAGS_REG)
7042 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7043 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7044 (clobber (match_scratch:QI 0 "=q"))]
7045 "ix86_match_ccmode (insn, CCZmode)
7046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7048 switch (get_attr_type (insn))
7051 if (operands[2] == const1_rtx)
7052 return "inc{b}\t%0";
7055 gcc_assert (operands[2] == constm1_rtx
7056 || (CONST_INT_P (operands[2])
7057 && INTVAL (operands[2]) == 255));
7058 return "dec{b}\t%0";
7062 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7063 if (CONST_INT_P (operands[2])
7064 && INTVAL (operands[2]) < 0)
7066 operands[2] = GEN_INT (-INTVAL (operands[2]));
7067 return "sub{b}\t{%2, %0|%0, %2}";
7069 return "add{b}\t{%2, %0|%0, %2}";
7073 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7074 (const_string "incdec")
7075 (const_string "alu")))
7076 (set_attr "mode" "QI")])
7078 ; See comments above addsi_4 for details.
7079 (define_insn "*addqi_4"
7080 [(set (reg FLAGS_REG)
7081 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7082 (match_operand:QI 2 "const_int_operand" "n")))
7083 (clobber (match_scratch:QI 0 "=qm"))]
7084 "ix86_match_ccmode (insn, CCGCmode)
7085 && (INTVAL (operands[2]) & 0xff) != 0x80"
7087 switch (get_attr_type (insn))
7090 if (operands[2] == constm1_rtx
7091 || (CONST_INT_P (operands[2])
7092 && INTVAL (operands[2]) == 255))
7093 return "inc{b}\t%0";
7096 gcc_assert (operands[2] == const1_rtx);
7097 return "dec{b}\t%0";
7101 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7102 if (INTVAL (operands[2]) < 0)
7104 operands[2] = GEN_INT (-INTVAL (operands[2]));
7105 return "add{b}\t{%2, %0|%0, %2}";
7107 return "sub{b}\t{%2, %0|%0, %2}";
7111 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7112 (const_string "incdec")
7113 (const_string "alu")))
7114 (set_attr "mode" "QI")])
7117 (define_insn "*addqi_5"
7118 [(set (reg FLAGS_REG)
7120 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7121 (match_operand:QI 2 "general_operand" "qmni"))
7123 (clobber (match_scratch:QI 0 "=q"))]
7124 "ix86_match_ccmode (insn, CCGOCmode)
7125 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7127 switch (get_attr_type (insn))
7130 if (operands[2] == const1_rtx)
7131 return "inc{b}\t%0";
7134 gcc_assert (operands[2] == constm1_rtx
7135 || (CONST_INT_P (operands[2])
7136 && INTVAL (operands[2]) == 255));
7137 return "dec{b}\t%0";
7141 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7142 if (CONST_INT_P (operands[2])
7143 && INTVAL (operands[2]) < 0)
7145 operands[2] = GEN_INT (-INTVAL (operands[2]));
7146 return "sub{b}\t{%2, %0|%0, %2}";
7148 return "add{b}\t{%2, %0|%0, %2}";
7152 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7153 (const_string "incdec")
7154 (const_string "alu")))
7155 (set_attr "mode" "QI")])
7158 (define_insn "addqi_ext_1"
7159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7164 (match_operand 1 "ext_register_operand" "0")
7167 (match_operand:QI 2 "general_operand" "Qmn")))
7168 (clobber (reg:CC FLAGS_REG))]
7171 switch (get_attr_type (insn))
7174 if (operands[2] == const1_rtx)
7175 return "inc{b}\t%h0";
7178 gcc_assert (operands[2] == constm1_rtx
7179 || (CONST_INT_P (operands[2])
7180 && INTVAL (operands[2]) == 255));
7181 return "dec{b}\t%h0";
7185 return "add{b}\t{%2, %h0|%h0, %2}";
7189 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7190 (const_string "incdec")
7191 (const_string "alu")))
7192 (set_attr "mode" "QI")])
7194 (define_insn "*addqi_ext_1_rex64"
7195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7200 (match_operand 1 "ext_register_operand" "0")
7203 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7204 (clobber (reg:CC FLAGS_REG))]
7207 switch (get_attr_type (insn))
7210 if (operands[2] == const1_rtx)
7211 return "inc{b}\t%h0";
7214 gcc_assert (operands[2] == constm1_rtx
7215 || (CONST_INT_P (operands[2])
7216 && INTVAL (operands[2]) == 255));
7217 return "dec{b}\t%h0";
7221 return "add{b}\t{%2, %h0|%h0, %2}";
7225 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7226 (const_string "incdec")
7227 (const_string "alu")))
7228 (set_attr "mode" "QI")])
7230 (define_insn "*addqi_ext_2"
7231 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7236 (match_operand 1 "ext_register_operand" "%0")
7240 (match_operand 2 "ext_register_operand" "Q")
7243 (clobber (reg:CC FLAGS_REG))]
7245 "add{b}\t{%h2, %h0|%h0, %h2}"
7246 [(set_attr "type" "alu")
7247 (set_attr "mode" "QI")])
7249 ;; The patterns that match these are at the end of this file.
7251 (define_expand "addxf3"
7252 [(set (match_operand:XF 0 "register_operand" "")
7253 (plus:XF (match_operand:XF 1 "register_operand" "")
7254 (match_operand:XF 2 "register_operand" "")))]
7258 (define_expand "add<mode>3"
7259 [(set (match_operand:MODEF 0 "register_operand" "")
7260 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7261 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7262 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7265 ;; Subtract instructions
7267 ;; %%% splits for subditi3
7269 (define_expand "subti3"
7270 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7271 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7272 (match_operand:TI 2 "x86_64_general_operand" "")))
7273 (clobber (reg:CC FLAGS_REG))])]
7275 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7277 (define_insn "*subti3_1"
7278 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7279 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7280 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7281 (clobber (reg:CC FLAGS_REG))]
7282 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7286 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7287 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7288 (match_operand:TI 2 "x86_64_general_operand" "")))
7289 (clobber (reg:CC FLAGS_REG))]
7290 "TARGET_64BIT && reload_completed"
7291 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7292 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7293 (parallel [(set (match_dup 3)
7294 (minus:DI (match_dup 4)
7295 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7297 (clobber (reg:CC FLAGS_REG))])]
7298 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7300 ;; %%% splits for subsidi3
7302 (define_expand "subdi3"
7303 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7304 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7305 (match_operand:DI 2 "x86_64_general_operand" "")))
7306 (clobber (reg:CC FLAGS_REG))])]
7308 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7310 (define_insn "*subdi3_1"
7311 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7312 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7313 (match_operand:DI 2 "general_operand" "roiF,riF")))
7314 (clobber (reg:CC FLAGS_REG))]
7315 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7319 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7320 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7321 (match_operand:DI 2 "general_operand" "")))
7322 (clobber (reg:CC FLAGS_REG))]
7323 "!TARGET_64BIT && reload_completed"
7324 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7325 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7326 (parallel [(set (match_dup 3)
7327 (minus:SI (match_dup 4)
7328 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7330 (clobber (reg:CC FLAGS_REG))])]
7331 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7333 (define_insn "subdi3_carry_rex64"
7334 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7335 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7336 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7337 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7338 (clobber (reg:CC FLAGS_REG))]
7339 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7340 "sbb{q}\t{%2, %0|%0, %2}"
7341 [(set_attr "type" "alu")
7342 (set_attr "pent_pair" "pu")
7343 (set_attr "mode" "DI")])
7345 (define_insn "*subdi_1_rex64"
7346 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7347 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7348 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7349 (clobber (reg:CC FLAGS_REG))]
7350 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7351 "sub{q}\t{%2, %0|%0, %2}"
7352 [(set_attr "type" "alu")
7353 (set_attr "mode" "DI")])
7355 (define_insn "*subdi_2_rex64"
7356 [(set (reg FLAGS_REG)
7358 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7359 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7361 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7362 (minus:DI (match_dup 1) (match_dup 2)))]
7363 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7364 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7365 "sub{q}\t{%2, %0|%0, %2}"
7366 [(set_attr "type" "alu")
7367 (set_attr "mode" "DI")])
7369 (define_insn "*subdi_3_rex63"
7370 [(set (reg FLAGS_REG)
7371 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7372 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7373 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7374 (minus:DI (match_dup 1) (match_dup 2)))]
7375 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7376 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7377 "sub{q}\t{%2, %0|%0, %2}"
7378 [(set_attr "type" "alu")
7379 (set_attr "mode" "DI")])
7381 (define_insn "subqi3_carry"
7382 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7383 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7384 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7385 (match_operand:QI 2 "general_operand" "qi,qm"))))
7386 (clobber (reg:CC FLAGS_REG))]
7387 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7388 "sbb{b}\t{%2, %0|%0, %2}"
7389 [(set_attr "type" "alu")
7390 (set_attr "pent_pair" "pu")
7391 (set_attr "mode" "QI")])
7393 (define_insn "subhi3_carry"
7394 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7395 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7396 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7397 (match_operand:HI 2 "general_operand" "ri,rm"))))
7398 (clobber (reg:CC FLAGS_REG))]
7399 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7400 "sbb{w}\t{%2, %0|%0, %2}"
7401 [(set_attr "type" "alu")
7402 (set_attr "pent_pair" "pu")
7403 (set_attr "mode" "HI")])
7405 (define_insn "subsi3_carry"
7406 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7407 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7408 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7409 (match_operand:SI 2 "general_operand" "ri,rm"))))
7410 (clobber (reg:CC FLAGS_REG))]
7411 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7412 "sbb{l}\t{%2, %0|%0, %2}"
7413 [(set_attr "type" "alu")
7414 (set_attr "pent_pair" "pu")
7415 (set_attr "mode" "SI")])
7417 (define_insn "subsi3_carry_zext"
7418 [(set (match_operand:DI 0 "register_operand" "=r")
7420 (minus:SI (match_operand:SI 1 "register_operand" "0")
7421 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7422 (match_operand:SI 2 "general_operand" "g")))))
7423 (clobber (reg:CC FLAGS_REG))]
7424 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7425 "sbb{l}\t{%2, %k0|%k0, %2}"
7426 [(set_attr "type" "alu")
7427 (set_attr "pent_pair" "pu")
7428 (set_attr "mode" "SI")])
7430 (define_expand "subsi3"
7431 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7432 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7433 (match_operand:SI 2 "general_operand" "")))
7434 (clobber (reg:CC FLAGS_REG))])]
7436 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7438 (define_insn "*subsi_1"
7439 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7440 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7441 (match_operand:SI 2 "general_operand" "ri,rm")))
7442 (clobber (reg:CC FLAGS_REG))]
7443 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7444 "sub{l}\t{%2, %0|%0, %2}"
7445 [(set_attr "type" "alu")
7446 (set_attr "mode" "SI")])
7448 (define_insn "*subsi_1_zext"
7449 [(set (match_operand:DI 0 "register_operand" "=r")
7451 (minus:SI (match_operand:SI 1 "register_operand" "0")
7452 (match_operand:SI 2 "general_operand" "g"))))
7453 (clobber (reg:CC FLAGS_REG))]
7454 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7455 "sub{l}\t{%2, %k0|%k0, %2}"
7456 [(set_attr "type" "alu")
7457 (set_attr "mode" "SI")])
7459 (define_insn "*subsi_2"
7460 [(set (reg FLAGS_REG)
7462 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7463 (match_operand:SI 2 "general_operand" "ri,rm"))
7465 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7466 (minus:SI (match_dup 1) (match_dup 2)))]
7467 "ix86_match_ccmode (insn, CCGOCmode)
7468 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7469 "sub{l}\t{%2, %0|%0, %2}"
7470 [(set_attr "type" "alu")
7471 (set_attr "mode" "SI")])
7473 (define_insn "*subsi_2_zext"
7474 [(set (reg FLAGS_REG)
7476 (minus:SI (match_operand:SI 1 "register_operand" "0")
7477 (match_operand:SI 2 "general_operand" "g"))
7479 (set (match_operand:DI 0 "register_operand" "=r")
7481 (minus:SI (match_dup 1)
7483 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7484 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7485 "sub{l}\t{%2, %k0|%k0, %2}"
7486 [(set_attr "type" "alu")
7487 (set_attr "mode" "SI")])
7489 (define_insn "*subsi_3"
7490 [(set (reg FLAGS_REG)
7491 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7492 (match_operand:SI 2 "general_operand" "ri,rm")))
7493 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7494 (minus:SI (match_dup 1) (match_dup 2)))]
7495 "ix86_match_ccmode (insn, CCmode)
7496 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7497 "sub{l}\t{%2, %0|%0, %2}"
7498 [(set_attr "type" "alu")
7499 (set_attr "mode" "SI")])
7501 (define_insn "*subsi_3_zext"
7502 [(set (reg FLAGS_REG)
7503 (compare (match_operand:SI 1 "register_operand" "0")
7504 (match_operand:SI 2 "general_operand" "g")))
7505 (set (match_operand:DI 0 "register_operand" "=r")
7507 (minus:SI (match_dup 1)
7509 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7510 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7511 "sub{l}\t{%2, %1|%1, %2}"
7512 [(set_attr "type" "alu")
7513 (set_attr "mode" "DI")])
7515 (define_expand "subhi3"
7516 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7517 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7518 (match_operand:HI 2 "general_operand" "")))
7519 (clobber (reg:CC FLAGS_REG))])]
7520 "TARGET_HIMODE_MATH"
7521 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7523 (define_insn "*subhi_1"
7524 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7525 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7526 (match_operand:HI 2 "general_operand" "ri,rm")))
7527 (clobber (reg:CC FLAGS_REG))]
7528 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7529 "sub{w}\t{%2, %0|%0, %2}"
7530 [(set_attr "type" "alu")
7531 (set_attr "mode" "HI")])
7533 (define_insn "*subhi_2"
7534 [(set (reg FLAGS_REG)
7536 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7537 (match_operand:HI 2 "general_operand" "ri,rm"))
7539 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7540 (minus:HI (match_dup 1) (match_dup 2)))]
7541 "ix86_match_ccmode (insn, CCGOCmode)
7542 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7543 "sub{w}\t{%2, %0|%0, %2}"
7544 [(set_attr "type" "alu")
7545 (set_attr "mode" "HI")])
7547 (define_insn "*subhi_3"
7548 [(set (reg FLAGS_REG)
7549 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7550 (match_operand:HI 2 "general_operand" "ri,rm")))
7551 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7552 (minus:HI (match_dup 1) (match_dup 2)))]
7553 "ix86_match_ccmode (insn, CCmode)
7554 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7555 "sub{w}\t{%2, %0|%0, %2}"
7556 [(set_attr "type" "alu")
7557 (set_attr "mode" "HI")])
7559 (define_expand "subqi3"
7560 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7561 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7562 (match_operand:QI 2 "general_operand" "")))
7563 (clobber (reg:CC FLAGS_REG))])]
7564 "TARGET_QIMODE_MATH"
7565 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7567 (define_insn "*subqi_1"
7568 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7569 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7570 (match_operand:QI 2 "general_operand" "qn,qmn")))
7571 (clobber (reg:CC FLAGS_REG))]
7572 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7573 "sub{b}\t{%2, %0|%0, %2}"
7574 [(set_attr "type" "alu")
7575 (set_attr "mode" "QI")])
7577 (define_insn "*subqi_1_slp"
7578 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7579 (minus:QI (match_dup 0)
7580 (match_operand:QI 1 "general_operand" "qn,qmn")))
7581 (clobber (reg:CC FLAGS_REG))]
7582 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7584 "sub{b}\t{%1, %0|%0, %1}"
7585 [(set_attr "type" "alu1")
7586 (set_attr "mode" "QI")])
7588 (define_insn "*subqi_2"
7589 [(set (reg FLAGS_REG)
7591 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7592 (match_operand:QI 2 "general_operand" "qi,qm"))
7594 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7595 (minus:HI (match_dup 1) (match_dup 2)))]
7596 "ix86_match_ccmode (insn, CCGOCmode)
7597 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7598 "sub{b}\t{%2, %0|%0, %2}"
7599 [(set_attr "type" "alu")
7600 (set_attr "mode" "QI")])
7602 (define_insn "*subqi_3"
7603 [(set (reg FLAGS_REG)
7604 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7605 (match_operand:QI 2 "general_operand" "qi,qm")))
7606 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7607 (minus:HI (match_dup 1) (match_dup 2)))]
7608 "ix86_match_ccmode (insn, CCmode)
7609 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7610 "sub{b}\t{%2, %0|%0, %2}"
7611 [(set_attr "type" "alu")
7612 (set_attr "mode" "QI")])
7614 ;; The patterns that match these are at the end of this file.
7616 (define_expand "subxf3"
7617 [(set (match_operand:XF 0 "register_operand" "")
7618 (minus:XF (match_operand:XF 1 "register_operand" "")
7619 (match_operand:XF 2 "register_operand" "")))]
7623 (define_expand "sub<mode>3"
7624 [(set (match_operand:MODEF 0 "register_operand" "")
7625 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7626 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7627 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7630 ;; Multiply instructions
7632 (define_expand "muldi3"
7633 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7634 (mult:DI (match_operand:DI 1 "register_operand" "")
7635 (match_operand:DI 2 "x86_64_general_operand" "")))
7636 (clobber (reg:CC FLAGS_REG))])]
7641 ;; IMUL reg64, reg64, imm8 Direct
7642 ;; IMUL reg64, mem64, imm8 VectorPath
7643 ;; IMUL reg64, reg64, imm32 Direct
7644 ;; IMUL reg64, mem64, imm32 VectorPath
7645 ;; IMUL reg64, reg64 Direct
7646 ;; IMUL reg64, mem64 Direct
7648 (define_insn "*muldi3_1_rex64"
7649 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7650 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7651 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7652 (clobber (reg:CC FLAGS_REG))]
7654 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7656 imul{q}\t{%2, %1, %0|%0, %1, %2}
7657 imul{q}\t{%2, %1, %0|%0, %1, %2}
7658 imul{q}\t{%2, %0|%0, %2}"
7659 [(set_attr "type" "imul")
7660 (set_attr "prefix_0f" "0,0,1")
7661 (set (attr "athlon_decode")
7662 (cond [(eq_attr "cpu" "athlon")
7663 (const_string "vector")
7664 (eq_attr "alternative" "1")
7665 (const_string "vector")
7666 (and (eq_attr "alternative" "2")
7667 (match_operand 1 "memory_operand" ""))
7668 (const_string "vector")]
7669 (const_string "direct")))
7670 (set (attr "amdfam10_decode")
7671 (cond [(and (eq_attr "alternative" "0,1")
7672 (match_operand 1 "memory_operand" ""))
7673 (const_string "vector")]
7674 (const_string "direct")))
7675 (set_attr "mode" "DI")])
7677 (define_expand "mulsi3"
7678 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7679 (mult:SI (match_operand:SI 1 "register_operand" "")
7680 (match_operand:SI 2 "general_operand" "")))
7681 (clobber (reg:CC FLAGS_REG))])]
7686 ;; IMUL reg32, reg32, imm8 Direct
7687 ;; IMUL reg32, mem32, imm8 VectorPath
7688 ;; IMUL reg32, reg32, imm32 Direct
7689 ;; IMUL reg32, mem32, imm32 VectorPath
7690 ;; IMUL reg32, reg32 Direct
7691 ;; IMUL reg32, mem32 Direct
7693 (define_insn "*mulsi3_1"
7694 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7695 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7696 (match_operand:SI 2 "general_operand" "K,i,mr")))
7697 (clobber (reg:CC FLAGS_REG))]
7698 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7700 imul{l}\t{%2, %1, %0|%0, %1, %2}
7701 imul{l}\t{%2, %1, %0|%0, %1, %2}
7702 imul{l}\t{%2, %0|%0, %2}"
7703 [(set_attr "type" "imul")
7704 (set_attr "prefix_0f" "0,0,1")
7705 (set (attr "athlon_decode")
7706 (cond [(eq_attr "cpu" "athlon")
7707 (const_string "vector")
7708 (eq_attr "alternative" "1")
7709 (const_string "vector")
7710 (and (eq_attr "alternative" "2")
7711 (match_operand 1 "memory_operand" ""))
7712 (const_string "vector")]
7713 (const_string "direct")))
7714 (set (attr "amdfam10_decode")
7715 (cond [(and (eq_attr "alternative" "0,1")
7716 (match_operand 1 "memory_operand" ""))
7717 (const_string "vector")]
7718 (const_string "direct")))
7719 (set_attr "mode" "SI")])
7721 (define_insn "*mulsi3_1_zext"
7722 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7724 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7725 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7726 (clobber (reg:CC FLAGS_REG))]
7728 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7730 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7731 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7732 imul{l}\t{%2, %k0|%k0, %2}"
7733 [(set_attr "type" "imul")
7734 (set_attr "prefix_0f" "0,0,1")
7735 (set (attr "athlon_decode")
7736 (cond [(eq_attr "cpu" "athlon")
7737 (const_string "vector")
7738 (eq_attr "alternative" "1")
7739 (const_string "vector")
7740 (and (eq_attr "alternative" "2")
7741 (match_operand 1 "memory_operand" ""))
7742 (const_string "vector")]
7743 (const_string "direct")))
7744 (set (attr "amdfam10_decode")
7745 (cond [(and (eq_attr "alternative" "0,1")
7746 (match_operand 1 "memory_operand" ""))
7747 (const_string "vector")]
7748 (const_string "direct")))
7749 (set_attr "mode" "SI")])
7751 (define_expand "mulhi3"
7752 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7753 (mult:HI (match_operand:HI 1 "register_operand" "")
7754 (match_operand:HI 2 "general_operand" "")))
7755 (clobber (reg:CC FLAGS_REG))])]
7756 "TARGET_HIMODE_MATH"
7760 ;; IMUL reg16, reg16, imm8 VectorPath
7761 ;; IMUL reg16, mem16, imm8 VectorPath
7762 ;; IMUL reg16, reg16, imm16 VectorPath
7763 ;; IMUL reg16, mem16, imm16 VectorPath
7764 ;; IMUL reg16, reg16 Direct
7765 ;; IMUL reg16, mem16 Direct
7766 (define_insn "*mulhi3_1"
7767 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7768 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7769 (match_operand:HI 2 "general_operand" "K,i,mr")))
7770 (clobber (reg:CC FLAGS_REG))]
7771 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7773 imul{w}\t{%2, %1, %0|%0, %1, %2}
7774 imul{w}\t{%2, %1, %0|%0, %1, %2}
7775 imul{w}\t{%2, %0|%0, %2}"
7776 [(set_attr "type" "imul")
7777 (set_attr "prefix_0f" "0,0,1")
7778 (set (attr "athlon_decode")
7779 (cond [(eq_attr "cpu" "athlon")
7780 (const_string "vector")
7781 (eq_attr "alternative" "1,2")
7782 (const_string "vector")]
7783 (const_string "direct")))
7784 (set (attr "amdfam10_decode")
7785 (cond [(eq_attr "alternative" "0,1")
7786 (const_string "vector")]
7787 (const_string "direct")))
7788 (set_attr "mode" "HI")])
7790 (define_expand "mulqi3"
7791 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7792 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7793 (match_operand:QI 2 "register_operand" "")))
7794 (clobber (reg:CC FLAGS_REG))])]
7795 "TARGET_QIMODE_MATH"
7802 (define_insn "*mulqi3_1"
7803 [(set (match_operand:QI 0 "register_operand" "=a")
7804 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7805 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7806 (clobber (reg:CC FLAGS_REG))]
7808 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7810 [(set_attr "type" "imul")
7811 (set_attr "length_immediate" "0")
7812 (set (attr "athlon_decode")
7813 (if_then_else (eq_attr "cpu" "athlon")
7814 (const_string "vector")
7815 (const_string "direct")))
7816 (set_attr "amdfam10_decode" "direct")
7817 (set_attr "mode" "QI")])
7819 (define_expand "umulqihi3"
7820 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7821 (mult:HI (zero_extend:HI
7822 (match_operand:QI 1 "nonimmediate_operand" ""))
7824 (match_operand:QI 2 "register_operand" ""))))
7825 (clobber (reg:CC FLAGS_REG))])]
7826 "TARGET_QIMODE_MATH"
7829 (define_insn "*umulqihi3_1"
7830 [(set (match_operand:HI 0 "register_operand" "=a")
7831 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7832 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7833 (clobber (reg:CC FLAGS_REG))]
7835 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7837 [(set_attr "type" "imul")
7838 (set_attr "length_immediate" "0")
7839 (set (attr "athlon_decode")
7840 (if_then_else (eq_attr "cpu" "athlon")
7841 (const_string "vector")
7842 (const_string "direct")))
7843 (set_attr "amdfam10_decode" "direct")
7844 (set_attr "mode" "QI")])
7846 (define_expand "mulqihi3"
7847 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7848 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7849 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7850 (clobber (reg:CC FLAGS_REG))])]
7851 "TARGET_QIMODE_MATH"
7854 (define_insn "*mulqihi3_insn"
7855 [(set (match_operand:HI 0 "register_operand" "=a")
7856 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7857 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7858 (clobber (reg:CC FLAGS_REG))]
7860 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7862 [(set_attr "type" "imul")
7863 (set_attr "length_immediate" "0")
7864 (set (attr "athlon_decode")
7865 (if_then_else (eq_attr "cpu" "athlon")
7866 (const_string "vector")
7867 (const_string "direct")))
7868 (set_attr "amdfam10_decode" "direct")
7869 (set_attr "mode" "QI")])
7871 (define_expand "umulditi3"
7872 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7873 (mult:TI (zero_extend:TI
7874 (match_operand:DI 1 "nonimmediate_operand" ""))
7876 (match_operand:DI 2 "register_operand" ""))))
7877 (clobber (reg:CC FLAGS_REG))])]
7881 (define_insn "*umulditi3_insn"
7882 [(set (match_operand:TI 0 "register_operand" "=A")
7883 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7884 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7885 (clobber (reg:CC FLAGS_REG))]
7887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7889 [(set_attr "type" "imul")
7890 (set_attr "length_immediate" "0")
7891 (set (attr "athlon_decode")
7892 (if_then_else (eq_attr "cpu" "athlon")
7893 (const_string "vector")
7894 (const_string "double")))
7895 (set_attr "amdfam10_decode" "double")
7896 (set_attr "mode" "DI")])
7898 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7899 (define_expand "umulsidi3"
7900 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7901 (mult:DI (zero_extend:DI
7902 (match_operand:SI 1 "nonimmediate_operand" ""))
7904 (match_operand:SI 2 "register_operand" ""))))
7905 (clobber (reg:CC FLAGS_REG))])]
7909 (define_insn "*umulsidi3_insn"
7910 [(set (match_operand:DI 0 "register_operand" "=A")
7911 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7912 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7913 (clobber (reg:CC FLAGS_REG))]
7915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7917 [(set_attr "type" "imul")
7918 (set_attr "length_immediate" "0")
7919 (set (attr "athlon_decode")
7920 (if_then_else (eq_attr "cpu" "athlon")
7921 (const_string "vector")
7922 (const_string "double")))
7923 (set_attr "amdfam10_decode" "double")
7924 (set_attr "mode" "SI")])
7926 (define_expand "mulditi3"
7927 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7928 (mult:TI (sign_extend:TI
7929 (match_operand:DI 1 "nonimmediate_operand" ""))
7931 (match_operand:DI 2 "register_operand" ""))))
7932 (clobber (reg:CC FLAGS_REG))])]
7936 (define_insn "*mulditi3_insn"
7937 [(set (match_operand:TI 0 "register_operand" "=A")
7938 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7939 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7940 (clobber (reg:CC FLAGS_REG))]
7942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7944 [(set_attr "type" "imul")
7945 (set_attr "length_immediate" "0")
7946 (set (attr "athlon_decode")
7947 (if_then_else (eq_attr "cpu" "athlon")
7948 (const_string "vector")
7949 (const_string "double")))
7950 (set_attr "amdfam10_decode" "double")
7951 (set_attr "mode" "DI")])
7953 (define_expand "mulsidi3"
7954 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7955 (mult:DI (sign_extend:DI
7956 (match_operand:SI 1 "nonimmediate_operand" ""))
7958 (match_operand:SI 2 "register_operand" ""))))
7959 (clobber (reg:CC FLAGS_REG))])]
7963 (define_insn "*mulsidi3_insn"
7964 [(set (match_operand:DI 0 "register_operand" "=A")
7965 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7966 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7967 (clobber (reg:CC FLAGS_REG))]
7969 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7971 [(set_attr "type" "imul")
7972 (set_attr "length_immediate" "0")
7973 (set (attr "athlon_decode")
7974 (if_then_else (eq_attr "cpu" "athlon")
7975 (const_string "vector")
7976 (const_string "double")))
7977 (set_attr "amdfam10_decode" "double")
7978 (set_attr "mode" "SI")])
7980 (define_expand "umuldi3_highpart"
7981 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7984 (mult:TI (zero_extend:TI
7985 (match_operand:DI 1 "nonimmediate_operand" ""))
7987 (match_operand:DI 2 "register_operand" "")))
7989 (clobber (match_scratch:DI 3 ""))
7990 (clobber (reg:CC FLAGS_REG))])]
7994 (define_insn "*umuldi3_highpart_rex64"
7995 [(set (match_operand:DI 0 "register_operand" "=d")
7998 (mult:TI (zero_extend:TI
7999 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8001 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8003 (clobber (match_scratch:DI 3 "=1"))
8004 (clobber (reg:CC FLAGS_REG))]
8006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8008 [(set_attr "type" "imul")
8009 (set_attr "length_immediate" "0")
8010 (set (attr "athlon_decode")
8011 (if_then_else (eq_attr "cpu" "athlon")
8012 (const_string "vector")
8013 (const_string "double")))
8014 (set_attr "amdfam10_decode" "double")
8015 (set_attr "mode" "DI")])
8017 (define_expand "umulsi3_highpart"
8018 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8021 (mult:DI (zero_extend:DI
8022 (match_operand:SI 1 "nonimmediate_operand" ""))
8024 (match_operand:SI 2 "register_operand" "")))
8026 (clobber (match_scratch:SI 3 ""))
8027 (clobber (reg:CC FLAGS_REG))])]
8031 (define_insn "*umulsi3_highpart_insn"
8032 [(set (match_operand:SI 0 "register_operand" "=d")
8035 (mult:DI (zero_extend:DI
8036 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8038 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8040 (clobber (match_scratch:SI 3 "=1"))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8044 [(set_attr "type" "imul")
8045 (set_attr "length_immediate" "0")
8046 (set (attr "athlon_decode")
8047 (if_then_else (eq_attr "cpu" "athlon")
8048 (const_string "vector")
8049 (const_string "double")))
8050 (set_attr "amdfam10_decode" "double")
8051 (set_attr "mode" "SI")])
8053 (define_insn "*umulsi3_highpart_zext"
8054 [(set (match_operand:DI 0 "register_operand" "=d")
8055 (zero_extend:DI (truncate:SI
8057 (mult:DI (zero_extend:DI
8058 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8060 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8062 (clobber (match_scratch:SI 3 "=1"))
8063 (clobber (reg:CC FLAGS_REG))]
8065 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8067 [(set_attr "type" "imul")
8068 (set_attr "length_immediate" "0")
8069 (set (attr "athlon_decode")
8070 (if_then_else (eq_attr "cpu" "athlon")
8071 (const_string "vector")
8072 (const_string "double")))
8073 (set_attr "amdfam10_decode" "double")
8074 (set_attr "mode" "SI")])
8076 (define_expand "smuldi3_highpart"
8077 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8080 (mult:TI (sign_extend:TI
8081 (match_operand:DI 1 "nonimmediate_operand" ""))
8083 (match_operand:DI 2 "register_operand" "")))
8085 (clobber (match_scratch:DI 3 ""))
8086 (clobber (reg:CC FLAGS_REG))])]
8090 (define_insn "*smuldi3_highpart_rex64"
8091 [(set (match_operand:DI 0 "register_operand" "=d")
8094 (mult:TI (sign_extend:TI
8095 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8097 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8099 (clobber (match_scratch:DI 3 "=1"))
8100 (clobber (reg:CC FLAGS_REG))]
8102 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8104 [(set_attr "type" "imul")
8105 (set (attr "athlon_decode")
8106 (if_then_else (eq_attr "cpu" "athlon")
8107 (const_string "vector")
8108 (const_string "double")))
8109 (set_attr "amdfam10_decode" "double")
8110 (set_attr "mode" "DI")])
8112 (define_expand "smulsi3_highpart"
8113 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8116 (mult:DI (sign_extend:DI
8117 (match_operand:SI 1 "nonimmediate_operand" ""))
8119 (match_operand:SI 2 "register_operand" "")))
8121 (clobber (match_scratch:SI 3 ""))
8122 (clobber (reg:CC FLAGS_REG))])]
8126 (define_insn "*smulsi3_highpart_insn"
8127 [(set (match_operand:SI 0 "register_operand" "=d")
8130 (mult:DI (sign_extend:DI
8131 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8133 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8135 (clobber (match_scratch:SI 3 "=1"))
8136 (clobber (reg:CC FLAGS_REG))]
8137 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8139 [(set_attr "type" "imul")
8140 (set (attr "athlon_decode")
8141 (if_then_else (eq_attr "cpu" "athlon")
8142 (const_string "vector")
8143 (const_string "double")))
8144 (set_attr "amdfam10_decode" "double")
8145 (set_attr "mode" "SI")])
8147 (define_insn "*smulsi3_highpart_zext"
8148 [(set (match_operand:DI 0 "register_operand" "=d")
8149 (zero_extend:DI (truncate:SI
8151 (mult:DI (sign_extend:DI
8152 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8154 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8156 (clobber (match_scratch:SI 3 "=1"))
8157 (clobber (reg:CC FLAGS_REG))]
8159 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8161 [(set_attr "type" "imul")
8162 (set (attr "athlon_decode")
8163 (if_then_else (eq_attr "cpu" "athlon")
8164 (const_string "vector")
8165 (const_string "double")))
8166 (set_attr "amdfam10_decode" "double")
8167 (set_attr "mode" "SI")])
8169 ;; The patterns that match these are at the end of this file.
8171 (define_expand "mulxf3"
8172 [(set (match_operand:XF 0 "register_operand" "")
8173 (mult:XF (match_operand:XF 1 "register_operand" "")
8174 (match_operand:XF 2 "register_operand" "")))]
8178 (define_expand "mul<mode>3"
8179 [(set (match_operand:MODEF 0 "register_operand" "")
8180 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8181 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8185 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8188 ;; Divide instructions
8190 (define_insn "divqi3"
8191 [(set (match_operand:QI 0 "register_operand" "=a")
8192 (div:QI (match_operand:HI 1 "register_operand" "0")
8193 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "TARGET_QIMODE_MATH"
8197 [(set_attr "type" "idiv")
8198 (set_attr "mode" "QI")])
8200 (define_insn "udivqi3"
8201 [(set (match_operand:QI 0 "register_operand" "=a")
8202 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8203 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "TARGET_QIMODE_MATH"
8207 [(set_attr "type" "idiv")
8208 (set_attr "mode" "QI")])
8210 ;; The patterns that match these are at the end of this file.
8212 (define_expand "divxf3"
8213 [(set (match_operand:XF 0 "register_operand" "")
8214 (div:XF (match_operand:XF 1 "register_operand" "")
8215 (match_operand:XF 2 "register_operand" "")))]
8219 (define_expand "divdf3"
8220 [(set (match_operand:DF 0 "register_operand" "")
8221 (div:DF (match_operand:DF 1 "register_operand" "")
8222 (match_operand:DF 2 "nonimmediate_operand" "")))]
8223 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8226 (define_expand "divsf3"
8227 [(set (match_operand:SF 0 "register_operand" "")
8228 (div:SF (match_operand:SF 1 "register_operand" "")
8229 (match_operand:SF 2 "nonimmediate_operand" "")))]
8230 "TARGET_80387 || TARGET_SSE_MATH"
8232 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8233 && flag_finite_math_only && !flag_trapping_math
8234 && flag_unsafe_math_optimizations)
8236 ix86_emit_swdivsf (operands[0], operands[1],
8237 operands[2], SFmode);
8242 ;; Remainder instructions.
8244 (define_expand "divmoddi4"
8245 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8246 (div:DI (match_operand:DI 1 "register_operand" "")
8247 (match_operand:DI 2 "nonimmediate_operand" "")))
8248 (set (match_operand:DI 3 "register_operand" "")
8249 (mod:DI (match_dup 1) (match_dup 2)))
8250 (clobber (reg:CC FLAGS_REG))])]
8254 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8255 ;; Penalize eax case slightly because it results in worse scheduling
8257 (define_insn "*divmoddi4_nocltd_rex64"
8258 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8259 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8260 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8261 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8262 (mod:DI (match_dup 2) (match_dup 3)))
8263 (clobber (reg:CC FLAGS_REG))]
8264 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8266 [(set_attr "type" "multi")])
8268 (define_insn "*divmoddi4_cltd_rex64"
8269 [(set (match_operand:DI 0 "register_operand" "=a")
8270 (div:DI (match_operand:DI 2 "register_operand" "a")
8271 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8272 (set (match_operand:DI 1 "register_operand" "=&d")
8273 (mod:DI (match_dup 2) (match_dup 3)))
8274 (clobber (reg:CC FLAGS_REG))]
8275 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8277 [(set_attr "type" "multi")])
8279 (define_insn "*divmoddi_noext_rex64"
8280 [(set (match_operand:DI 0 "register_operand" "=a")
8281 (div:DI (match_operand:DI 1 "register_operand" "0")
8282 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8283 (set (match_operand:DI 3 "register_operand" "=d")
8284 (mod:DI (match_dup 1) (match_dup 2)))
8285 (use (match_operand:DI 4 "register_operand" "3"))
8286 (clobber (reg:CC FLAGS_REG))]
8289 [(set_attr "type" "idiv")
8290 (set_attr "mode" "DI")])
8293 [(set (match_operand:DI 0 "register_operand" "")
8294 (div:DI (match_operand:DI 1 "register_operand" "")
8295 (match_operand:DI 2 "nonimmediate_operand" "")))
8296 (set (match_operand:DI 3 "register_operand" "")
8297 (mod:DI (match_dup 1) (match_dup 2)))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "TARGET_64BIT && reload_completed"
8300 [(parallel [(set (match_dup 3)
8301 (ashiftrt:DI (match_dup 4) (const_int 63)))
8302 (clobber (reg:CC FLAGS_REG))])
8303 (parallel [(set (match_dup 0)
8304 (div:DI (reg:DI 0) (match_dup 2)))
8306 (mod:DI (reg:DI 0) (match_dup 2)))
8308 (clobber (reg:CC FLAGS_REG))])]
8310 /* Avoid use of cltd in favor of a mov+shift. */
8311 if (!TARGET_USE_CLTD && !optimize_size)
8313 if (true_regnum (operands[1]))
8314 emit_move_insn (operands[0], operands[1]);
8316 emit_move_insn (operands[3], operands[1]);
8317 operands[4] = operands[3];
8321 gcc_assert (!true_regnum (operands[1]));
8322 operands[4] = operands[1];
8327 (define_expand "divmodsi4"
8328 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8329 (div:SI (match_operand:SI 1 "register_operand" "")
8330 (match_operand:SI 2 "nonimmediate_operand" "")))
8331 (set (match_operand:SI 3 "register_operand" "")
8332 (mod:SI (match_dup 1) (match_dup 2)))
8333 (clobber (reg:CC FLAGS_REG))])]
8337 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8338 ;; Penalize eax case slightly because it results in worse scheduling
8340 (define_insn "*divmodsi4_nocltd"
8341 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8342 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8343 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8344 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8345 (mod:SI (match_dup 2) (match_dup 3)))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "!optimize_size && !TARGET_USE_CLTD"
8349 [(set_attr "type" "multi")])
8351 (define_insn "*divmodsi4_cltd"
8352 [(set (match_operand:SI 0 "register_operand" "=a")
8353 (div:SI (match_operand:SI 2 "register_operand" "a")
8354 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8355 (set (match_operand:SI 1 "register_operand" "=&d")
8356 (mod:SI (match_dup 2) (match_dup 3)))
8357 (clobber (reg:CC FLAGS_REG))]
8358 "optimize_size || TARGET_USE_CLTD"
8360 [(set_attr "type" "multi")])
8362 (define_insn "*divmodsi_noext"
8363 [(set (match_operand:SI 0 "register_operand" "=a")
8364 (div:SI (match_operand:SI 1 "register_operand" "0")
8365 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8366 (set (match_operand:SI 3 "register_operand" "=d")
8367 (mod:SI (match_dup 1) (match_dup 2)))
8368 (use (match_operand:SI 4 "register_operand" "3"))
8369 (clobber (reg:CC FLAGS_REG))]
8372 [(set_attr "type" "idiv")
8373 (set_attr "mode" "SI")])
8376 [(set (match_operand:SI 0 "register_operand" "")
8377 (div:SI (match_operand:SI 1 "register_operand" "")
8378 (match_operand:SI 2 "nonimmediate_operand" "")))
8379 (set (match_operand:SI 3 "register_operand" "")
8380 (mod:SI (match_dup 1) (match_dup 2)))
8381 (clobber (reg:CC FLAGS_REG))]
8383 [(parallel [(set (match_dup 3)
8384 (ashiftrt:SI (match_dup 4) (const_int 31)))
8385 (clobber (reg:CC FLAGS_REG))])
8386 (parallel [(set (match_dup 0)
8387 (div:SI (reg:SI 0) (match_dup 2)))
8389 (mod:SI (reg:SI 0) (match_dup 2)))
8391 (clobber (reg:CC FLAGS_REG))])]
8393 /* Avoid use of cltd in favor of a mov+shift. */
8394 if (!TARGET_USE_CLTD && !optimize_size)
8396 if (true_regnum (operands[1]))
8397 emit_move_insn (operands[0], operands[1]);
8399 emit_move_insn (operands[3], operands[1]);
8400 operands[4] = operands[3];
8404 gcc_assert (!true_regnum (operands[1]));
8405 operands[4] = operands[1];
8409 (define_insn "divmodhi4"
8410 [(set (match_operand:HI 0 "register_operand" "=a")
8411 (div:HI (match_operand:HI 1 "register_operand" "0")
8412 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8413 (set (match_operand:HI 3 "register_operand" "=&d")
8414 (mod:HI (match_dup 1) (match_dup 2)))
8415 (clobber (reg:CC FLAGS_REG))]
8416 "TARGET_HIMODE_MATH"
8418 [(set_attr "type" "multi")
8419 (set_attr "length_immediate" "0")
8420 (set_attr "mode" "SI")])
8422 (define_insn "udivmoddi4"
8423 [(set (match_operand:DI 0 "register_operand" "=a")
8424 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8425 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8426 (set (match_operand:DI 3 "register_operand" "=&d")
8427 (umod:DI (match_dup 1) (match_dup 2)))
8428 (clobber (reg:CC FLAGS_REG))]
8430 "xor{q}\t%3, %3\;div{q}\t%2"
8431 [(set_attr "type" "multi")
8432 (set_attr "length_immediate" "0")
8433 (set_attr "mode" "DI")])
8435 (define_insn "*udivmoddi4_noext"
8436 [(set (match_operand:DI 0 "register_operand" "=a")
8437 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8438 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8439 (set (match_operand:DI 3 "register_operand" "=d")
8440 (umod:DI (match_dup 1) (match_dup 2)))
8442 (clobber (reg:CC FLAGS_REG))]
8445 [(set_attr "type" "idiv")
8446 (set_attr "mode" "DI")])
8449 [(set (match_operand:DI 0 "register_operand" "")
8450 (udiv:DI (match_operand:DI 1 "register_operand" "")
8451 (match_operand:DI 2 "nonimmediate_operand" "")))
8452 (set (match_operand:DI 3 "register_operand" "")
8453 (umod:DI (match_dup 1) (match_dup 2)))
8454 (clobber (reg:CC FLAGS_REG))]
8455 "TARGET_64BIT && reload_completed"
8456 [(set (match_dup 3) (const_int 0))
8457 (parallel [(set (match_dup 0)
8458 (udiv:DI (match_dup 1) (match_dup 2)))
8460 (umod:DI (match_dup 1) (match_dup 2)))
8462 (clobber (reg:CC FLAGS_REG))])]
8465 (define_insn "udivmodsi4"
8466 [(set (match_operand:SI 0 "register_operand" "=a")
8467 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8468 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8469 (set (match_operand:SI 3 "register_operand" "=&d")
8470 (umod:SI (match_dup 1) (match_dup 2)))
8471 (clobber (reg:CC FLAGS_REG))]
8473 "xor{l}\t%3, %3\;div{l}\t%2"
8474 [(set_attr "type" "multi")
8475 (set_attr "length_immediate" "0")
8476 (set_attr "mode" "SI")])
8478 (define_insn "*udivmodsi4_noext"
8479 [(set (match_operand:SI 0 "register_operand" "=a")
8480 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8481 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8482 (set (match_operand:SI 3 "register_operand" "=d")
8483 (umod:SI (match_dup 1) (match_dup 2)))
8485 (clobber (reg:CC FLAGS_REG))]
8488 [(set_attr "type" "idiv")
8489 (set_attr "mode" "SI")])
8492 [(set (match_operand:SI 0 "register_operand" "")
8493 (udiv:SI (match_operand:SI 1 "register_operand" "")
8494 (match_operand:SI 2 "nonimmediate_operand" "")))
8495 (set (match_operand:SI 3 "register_operand" "")
8496 (umod:SI (match_dup 1) (match_dup 2)))
8497 (clobber (reg:CC FLAGS_REG))]
8499 [(set (match_dup 3) (const_int 0))
8500 (parallel [(set (match_dup 0)
8501 (udiv:SI (match_dup 1) (match_dup 2)))
8503 (umod:SI (match_dup 1) (match_dup 2)))
8505 (clobber (reg:CC FLAGS_REG))])]
8508 (define_expand "udivmodhi4"
8509 [(set (match_dup 4) (const_int 0))
8510 (parallel [(set (match_operand:HI 0 "register_operand" "")
8511 (udiv:HI (match_operand:HI 1 "register_operand" "")
8512 (match_operand:HI 2 "nonimmediate_operand" "")))
8513 (set (match_operand:HI 3 "register_operand" "")
8514 (umod:HI (match_dup 1) (match_dup 2)))
8516 (clobber (reg:CC FLAGS_REG))])]
8517 "TARGET_HIMODE_MATH"
8518 "operands[4] = gen_reg_rtx (HImode);")
8520 (define_insn "*udivmodhi_noext"
8521 [(set (match_operand:HI 0 "register_operand" "=a")
8522 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8523 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8524 (set (match_operand:HI 3 "register_operand" "=d")
8525 (umod:HI (match_dup 1) (match_dup 2)))
8526 (use (match_operand:HI 4 "register_operand" "3"))
8527 (clobber (reg:CC FLAGS_REG))]
8530 [(set_attr "type" "idiv")
8531 (set_attr "mode" "HI")])
8533 ;; We cannot use div/idiv for double division, because it causes
8534 ;; "division by zero" on the overflow and that's not what we expect
8535 ;; from truncate. Because true (non truncating) double division is
8536 ;; never generated, we can't create this insn anyway.
8539 ; [(set (match_operand:SI 0 "register_operand" "=a")
8541 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8543 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8544 ; (set (match_operand:SI 3 "register_operand" "=d")
8546 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8547 ; (clobber (reg:CC FLAGS_REG))]
8549 ; "div{l}\t{%2, %0|%0, %2}"
8550 ; [(set_attr "type" "idiv")])
8552 ;;- Logical AND instructions
8554 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8555 ;; Note that this excludes ah.
8557 (define_insn "*testdi_1_rex64"
8558 [(set (reg FLAGS_REG)
8560 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8561 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8563 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8564 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8566 test{l}\t{%k1, %k0|%k0, %k1}
8567 test{l}\t{%k1, %k0|%k0, %k1}
8568 test{q}\t{%1, %0|%0, %1}
8569 test{q}\t{%1, %0|%0, %1}
8570 test{q}\t{%1, %0|%0, %1}"
8571 [(set_attr "type" "test")
8572 (set_attr "modrm" "0,1,0,1,1")
8573 (set_attr "mode" "SI,SI,DI,DI,DI")
8574 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8576 (define_insn "testsi_1"
8577 [(set (reg FLAGS_REG)
8579 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8580 (match_operand:SI 1 "general_operand" "in,in,rin"))
8582 "ix86_match_ccmode (insn, CCNOmode)
8583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8584 "test{l}\t{%1, %0|%0, %1}"
8585 [(set_attr "type" "test")
8586 (set_attr "modrm" "0,1,1")
8587 (set_attr "mode" "SI")
8588 (set_attr "pent_pair" "uv,np,uv")])
8590 (define_expand "testsi_ccno_1"
8591 [(set (reg:CCNO FLAGS_REG)
8593 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8594 (match_operand:SI 1 "nonmemory_operand" ""))
8599 (define_insn "*testhi_1"
8600 [(set (reg FLAGS_REG)
8601 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8602 (match_operand:HI 1 "general_operand" "n,n,rn"))
8604 "ix86_match_ccmode (insn, CCNOmode)
8605 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8606 "test{w}\t{%1, %0|%0, %1}"
8607 [(set_attr "type" "test")
8608 (set_attr "modrm" "0,1,1")
8609 (set_attr "mode" "HI")
8610 (set_attr "pent_pair" "uv,np,uv")])
8612 (define_expand "testqi_ccz_1"
8613 [(set (reg:CCZ FLAGS_REG)
8614 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8615 (match_operand:QI 1 "nonmemory_operand" ""))
8620 (define_insn "*testqi_1_maybe_si"
8621 [(set (reg FLAGS_REG)
8624 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8625 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8627 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8628 && ix86_match_ccmode (insn,
8629 CONST_INT_P (operands[1])
8630 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8632 if (which_alternative == 3)
8634 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8635 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8636 return "test{l}\t{%1, %k0|%k0, %1}";
8638 return "test{b}\t{%1, %0|%0, %1}";
8640 [(set_attr "type" "test")
8641 (set_attr "modrm" "0,1,1,1")
8642 (set_attr "mode" "QI,QI,QI,SI")
8643 (set_attr "pent_pair" "uv,np,uv,np")])
8645 (define_insn "*testqi_1"
8646 [(set (reg FLAGS_REG)
8649 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8650 (match_operand:QI 1 "general_operand" "n,n,qn"))
8652 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8653 && ix86_match_ccmode (insn, CCNOmode)"
8654 "test{b}\t{%1, %0|%0, %1}"
8655 [(set_attr "type" "test")
8656 (set_attr "modrm" "0,1,1")
8657 (set_attr "mode" "QI")
8658 (set_attr "pent_pair" "uv,np,uv")])
8660 (define_expand "testqi_ext_ccno_0"
8661 [(set (reg:CCNO FLAGS_REG)
8665 (match_operand 0 "ext_register_operand" "")
8668 (match_operand 1 "const_int_operand" ""))
8673 (define_insn "*testqi_ext_0"
8674 [(set (reg FLAGS_REG)
8678 (match_operand 0 "ext_register_operand" "Q")
8681 (match_operand 1 "const_int_operand" "n"))
8683 "ix86_match_ccmode (insn, CCNOmode)"
8684 "test{b}\t{%1, %h0|%h0, %1}"
8685 [(set_attr "type" "test")
8686 (set_attr "mode" "QI")
8687 (set_attr "length_immediate" "1")
8688 (set_attr "pent_pair" "np")])
8690 (define_insn "*testqi_ext_1"
8691 [(set (reg FLAGS_REG)
8695 (match_operand 0 "ext_register_operand" "Q")
8699 (match_operand:QI 1 "general_operand" "Qm")))
8701 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8702 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8703 "test{b}\t{%1, %h0|%h0, %1}"
8704 [(set_attr "type" "test")
8705 (set_attr "mode" "QI")])
8707 (define_insn "*testqi_ext_1_rex64"
8708 [(set (reg FLAGS_REG)
8712 (match_operand 0 "ext_register_operand" "Q")
8716 (match_operand:QI 1 "register_operand" "Q")))
8718 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8719 "test{b}\t{%1, %h0|%h0, %1}"
8720 [(set_attr "type" "test")
8721 (set_attr "mode" "QI")])
8723 (define_insn "*testqi_ext_2"
8724 [(set (reg FLAGS_REG)
8728 (match_operand 0 "ext_register_operand" "Q")
8732 (match_operand 1 "ext_register_operand" "Q")
8736 "ix86_match_ccmode (insn, CCNOmode)"
8737 "test{b}\t{%h1, %h0|%h0, %h1}"
8738 [(set_attr "type" "test")
8739 (set_attr "mode" "QI")])
8741 ;; Combine likes to form bit extractions for some tests. Humor it.
8742 (define_insn "*testqi_ext_3"
8743 [(set (reg FLAGS_REG)
8744 (compare (zero_extract:SI
8745 (match_operand 0 "nonimmediate_operand" "rm")
8746 (match_operand:SI 1 "const_int_operand" "")
8747 (match_operand:SI 2 "const_int_operand" ""))
8749 "ix86_match_ccmode (insn, CCNOmode)
8750 && INTVAL (operands[1]) > 0
8751 && INTVAL (operands[2]) >= 0
8752 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8753 && (GET_MODE (operands[0]) == SImode
8754 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8755 || GET_MODE (operands[0]) == HImode
8756 || GET_MODE (operands[0]) == QImode)"
8759 (define_insn "*testqi_ext_3_rex64"
8760 [(set (reg FLAGS_REG)
8761 (compare (zero_extract:DI
8762 (match_operand 0 "nonimmediate_operand" "rm")
8763 (match_operand:DI 1 "const_int_operand" "")
8764 (match_operand:DI 2 "const_int_operand" ""))
8767 && ix86_match_ccmode (insn, CCNOmode)
8768 && INTVAL (operands[1]) > 0
8769 && INTVAL (operands[2]) >= 0
8770 /* Ensure that resulting mask is zero or sign extended operand. */
8771 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8772 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8773 && INTVAL (operands[1]) > 32))
8774 && (GET_MODE (operands[0]) == SImode
8775 || GET_MODE (operands[0]) == DImode
8776 || GET_MODE (operands[0]) == HImode
8777 || GET_MODE (operands[0]) == QImode)"
8781 [(set (match_operand 0 "flags_reg_operand" "")
8782 (match_operator 1 "compare_operator"
8784 (match_operand 2 "nonimmediate_operand" "")
8785 (match_operand 3 "const_int_operand" "")
8786 (match_operand 4 "const_int_operand" ""))
8788 "ix86_match_ccmode (insn, CCNOmode)"
8789 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8791 rtx val = operands[2];
8792 HOST_WIDE_INT len = INTVAL (operands[3]);
8793 HOST_WIDE_INT pos = INTVAL (operands[4]);
8795 enum machine_mode mode, submode;
8797 mode = GET_MODE (val);
8800 /* ??? Combine likes to put non-volatile mem extractions in QImode
8801 no matter the size of the test. So find a mode that works. */
8802 if (! MEM_VOLATILE_P (val))
8804 mode = smallest_mode_for_size (pos + len, MODE_INT);
8805 val = adjust_address (val, mode, 0);
8808 else if (GET_CODE (val) == SUBREG
8809 && (submode = GET_MODE (SUBREG_REG (val)),
8810 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8811 && pos + len <= GET_MODE_BITSIZE (submode))
8813 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8815 val = SUBREG_REG (val);
8817 else if (mode == HImode && pos + len <= 8)
8819 /* Small HImode tests can be converted to QImode. */
8821 val = gen_lowpart (QImode, val);
8824 if (len == HOST_BITS_PER_WIDE_INT)
8827 mask = ((HOST_WIDE_INT)1 << len) - 1;
8830 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8833 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8834 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8835 ;; this is relatively important trick.
8836 ;; Do the conversion only post-reload to avoid limiting of the register class
8839 [(set (match_operand 0 "flags_reg_operand" "")
8840 (match_operator 1 "compare_operator"
8841 [(and (match_operand 2 "register_operand" "")
8842 (match_operand 3 "const_int_operand" ""))
8845 && QI_REG_P (operands[2])
8846 && GET_MODE (operands[2]) != QImode
8847 && ((ix86_match_ccmode (insn, CCZmode)
8848 && !(INTVAL (operands[3]) & ~(255 << 8)))
8849 || (ix86_match_ccmode (insn, CCNOmode)
8850 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8853 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8856 "operands[2] = gen_lowpart (SImode, operands[2]);
8857 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8860 [(set (match_operand 0 "flags_reg_operand" "")
8861 (match_operator 1 "compare_operator"
8862 [(and (match_operand 2 "nonimmediate_operand" "")
8863 (match_operand 3 "const_int_operand" ""))
8866 && GET_MODE (operands[2]) != QImode
8867 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8868 && ((ix86_match_ccmode (insn, CCZmode)
8869 && !(INTVAL (operands[3]) & ~255))
8870 || (ix86_match_ccmode (insn, CCNOmode)
8871 && !(INTVAL (operands[3]) & ~127)))"
8873 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8875 "operands[2] = gen_lowpart (QImode, operands[2]);
8876 operands[3] = gen_lowpart (QImode, operands[3]);")
8879 ;; %%% This used to optimize known byte-wide and operations to memory,
8880 ;; and sometimes to QImode registers. If this is considered useful,
8881 ;; it should be done with splitters.
8883 (define_expand "anddi3"
8884 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8885 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8886 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8887 (clobber (reg:CC FLAGS_REG))]
8889 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8891 (define_insn "*anddi_1_rex64"
8892 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8893 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8894 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8895 (clobber (reg:CC FLAGS_REG))]
8896 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8898 switch (get_attr_type (insn))
8902 enum machine_mode mode;
8904 gcc_assert (CONST_INT_P (operands[2]));
8905 if (INTVAL (operands[2]) == 0xff)
8909 gcc_assert (INTVAL (operands[2]) == 0xffff);
8913 operands[1] = gen_lowpart (mode, operands[1]);
8915 return "movz{bq|x}\t{%1,%0|%0, %1}";
8917 return "movz{wq|x}\t{%1,%0|%0, %1}";
8921 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8922 if (get_attr_mode (insn) == MODE_SI)
8923 return "and{l}\t{%k2, %k0|%k0, %k2}";
8925 return "and{q}\t{%2, %0|%0, %2}";
8928 [(set_attr "type" "alu,alu,alu,imovx")
8929 (set_attr "length_immediate" "*,*,*,0")
8930 (set_attr "mode" "SI,DI,DI,DI")])
8932 (define_insn "*anddi_2"
8933 [(set (reg FLAGS_REG)
8934 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8935 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8937 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8938 (and:DI (match_dup 1) (match_dup 2)))]
8939 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8940 && ix86_binary_operator_ok (AND, DImode, operands)"
8942 and{l}\t{%k2, %k0|%k0, %k2}
8943 and{q}\t{%2, %0|%0, %2}
8944 and{q}\t{%2, %0|%0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "SI,DI,DI")])
8948 (define_expand "andsi3"
8949 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8950 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8951 (match_operand:SI 2 "general_operand" "")))
8952 (clobber (reg:CC FLAGS_REG))]
8954 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8956 (define_insn "*andsi_1"
8957 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8958 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8959 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8960 (clobber (reg:CC FLAGS_REG))]
8961 "ix86_binary_operator_ok (AND, SImode, operands)"
8963 switch (get_attr_type (insn))
8967 enum machine_mode mode;
8969 gcc_assert (CONST_INT_P (operands[2]));
8970 if (INTVAL (operands[2]) == 0xff)
8974 gcc_assert (INTVAL (operands[2]) == 0xffff);
8978 operands[1] = gen_lowpart (mode, operands[1]);
8980 return "movz{bl|x}\t{%1,%0|%0, %1}";
8982 return "movz{wl|x}\t{%1,%0|%0, %1}";
8986 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8987 return "and{l}\t{%2, %0|%0, %2}";
8990 [(set_attr "type" "alu,alu,imovx")
8991 (set_attr "length_immediate" "*,*,0")
8992 (set_attr "mode" "SI")])
8995 [(set (match_operand 0 "register_operand" "")
8997 (const_int -65536)))
8998 (clobber (reg:CC FLAGS_REG))]
8999 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9000 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9001 "operands[1] = gen_lowpart (HImode, operands[0]);")
9004 [(set (match_operand 0 "ext_register_operand" "")
9007 (clobber (reg:CC FLAGS_REG))]
9008 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9009 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9010 "operands[1] = gen_lowpart (QImode, operands[0]);")
9013 [(set (match_operand 0 "ext_register_operand" "")
9015 (const_int -65281)))
9016 (clobber (reg:CC FLAGS_REG))]
9017 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9018 [(parallel [(set (zero_extract:SI (match_dup 0)
9022 (zero_extract:SI (match_dup 0)
9025 (zero_extract:SI (match_dup 0)
9028 (clobber (reg:CC FLAGS_REG))])]
9029 "operands[0] = gen_lowpart (SImode, operands[0]);")
9031 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9032 (define_insn "*andsi_1_zext"
9033 [(set (match_operand:DI 0 "register_operand" "=r")
9035 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9036 (match_operand:SI 2 "general_operand" "g"))))
9037 (clobber (reg:CC FLAGS_REG))]
9038 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9039 "and{l}\t{%2, %k0|%k0, %2}"
9040 [(set_attr "type" "alu")
9041 (set_attr "mode" "SI")])
9043 (define_insn "*andsi_2"
9044 [(set (reg FLAGS_REG)
9045 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9046 (match_operand:SI 2 "general_operand" "g,ri"))
9048 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9049 (and:SI (match_dup 1) (match_dup 2)))]
9050 "ix86_match_ccmode (insn, CCNOmode)
9051 && ix86_binary_operator_ok (AND, SImode, operands)"
9052 "and{l}\t{%2, %0|%0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "SI")])
9056 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9057 (define_insn "*andsi_2_zext"
9058 [(set (reg FLAGS_REG)
9059 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9060 (match_operand:SI 2 "general_operand" "g"))
9062 (set (match_operand:DI 0 "register_operand" "=r")
9063 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9064 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9065 && ix86_binary_operator_ok (AND, SImode, operands)"
9066 "and{l}\t{%2, %k0|%k0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "SI")])
9070 (define_expand "andhi3"
9071 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9072 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9073 (match_operand:HI 2 "general_operand" "")))
9074 (clobber (reg:CC FLAGS_REG))]
9075 "TARGET_HIMODE_MATH"
9076 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9078 (define_insn "*andhi_1"
9079 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9080 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9081 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "ix86_binary_operator_ok (AND, HImode, operands)"
9085 switch (get_attr_type (insn))
9088 gcc_assert (CONST_INT_P (operands[2]));
9089 gcc_assert (INTVAL (operands[2]) == 0xff);
9090 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9093 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9095 return "and{w}\t{%2, %0|%0, %2}";
9098 [(set_attr "type" "alu,alu,imovx")
9099 (set_attr "length_immediate" "*,*,0")
9100 (set_attr "mode" "HI,HI,SI")])
9102 (define_insn "*andhi_2"
9103 [(set (reg FLAGS_REG)
9104 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9105 (match_operand:HI 2 "general_operand" "g,ri"))
9107 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9108 (and:HI (match_dup 1) (match_dup 2)))]
9109 "ix86_match_ccmode (insn, CCNOmode)
9110 && ix86_binary_operator_ok (AND, HImode, operands)"
9111 "and{w}\t{%2, %0|%0, %2}"
9112 [(set_attr "type" "alu")
9113 (set_attr "mode" "HI")])
9115 (define_expand "andqi3"
9116 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9117 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9118 (match_operand:QI 2 "general_operand" "")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "TARGET_QIMODE_MATH"
9121 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9123 ;; %%% Potential partial reg stall on alternative 2. What to do?
9124 (define_insn "*andqi_1"
9125 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9126 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9127 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "ix86_binary_operator_ok (AND, QImode, operands)"
9131 and{b}\t{%2, %0|%0, %2}
9132 and{b}\t{%2, %0|%0, %2}
9133 and{l}\t{%k2, %k0|%k0, %k2}"
9134 [(set_attr "type" "alu")
9135 (set_attr "mode" "QI,QI,SI")])
9137 (define_insn "*andqi_1_slp"
9138 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9139 (and:QI (match_dup 0)
9140 (match_operand:QI 1 "general_operand" "qi,qmi")))
9141 (clobber (reg:CC FLAGS_REG))]
9142 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9143 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9144 "and{b}\t{%1, %0|%0, %1}"
9145 [(set_attr "type" "alu1")
9146 (set_attr "mode" "QI")])
9148 (define_insn "*andqi_2_maybe_si"
9149 [(set (reg FLAGS_REG)
9151 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9152 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9154 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9155 (and:QI (match_dup 1) (match_dup 2)))]
9156 "ix86_binary_operator_ok (AND, QImode, operands)
9157 && ix86_match_ccmode (insn,
9158 CONST_INT_P (operands[2])
9159 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9161 if (which_alternative == 2)
9163 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9164 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9165 return "and{l}\t{%2, %k0|%k0, %2}";
9167 return "and{b}\t{%2, %0|%0, %2}";
9169 [(set_attr "type" "alu")
9170 (set_attr "mode" "QI,QI,SI")])
9172 (define_insn "*andqi_2"
9173 [(set (reg FLAGS_REG)
9175 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9176 (match_operand:QI 2 "general_operand" "qim,qi"))
9178 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9179 (and:QI (match_dup 1) (match_dup 2)))]
9180 "ix86_match_ccmode (insn, CCNOmode)
9181 && ix86_binary_operator_ok (AND, QImode, operands)"
9182 "and{b}\t{%2, %0|%0, %2}"
9183 [(set_attr "type" "alu")
9184 (set_attr "mode" "QI")])
9186 (define_insn "*andqi_2_slp"
9187 [(set (reg FLAGS_REG)
9189 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9190 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9192 (set (strict_low_part (match_dup 0))
9193 (and:QI (match_dup 0) (match_dup 1)))]
9194 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9195 && ix86_match_ccmode (insn, CCNOmode)
9196 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9197 "and{b}\t{%1, %0|%0, %1}"
9198 [(set_attr "type" "alu1")
9199 (set_attr "mode" "QI")])
9201 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9202 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9203 ;; for a QImode operand, which of course failed.
9205 (define_insn "andqi_ext_0"
9206 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9211 (match_operand 1 "ext_register_operand" "0")
9214 (match_operand 2 "const_int_operand" "n")))
9215 (clobber (reg:CC FLAGS_REG))]
9217 "and{b}\t{%2, %h0|%h0, %2}"
9218 [(set_attr "type" "alu")
9219 (set_attr "length_immediate" "1")
9220 (set_attr "mode" "QI")])
9222 ;; Generated by peephole translating test to and. This shows up
9223 ;; often in fp comparisons.
9225 (define_insn "*andqi_ext_0_cc"
9226 [(set (reg FLAGS_REG)
9230 (match_operand 1 "ext_register_operand" "0")
9233 (match_operand 2 "const_int_operand" "n"))
9235 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9244 "ix86_match_ccmode (insn, CCNOmode)"
9245 "and{b}\t{%2, %h0|%h0, %2}"
9246 [(set_attr "type" "alu")
9247 (set_attr "length_immediate" "1")
9248 (set_attr "mode" "QI")])
9250 (define_insn "*andqi_ext_1"
9251 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9256 (match_operand 1 "ext_register_operand" "0")
9260 (match_operand:QI 2 "general_operand" "Qm"))))
9261 (clobber (reg:CC FLAGS_REG))]
9263 "and{b}\t{%2, %h0|%h0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "length_immediate" "0")
9266 (set_attr "mode" "QI")])
9268 (define_insn "*andqi_ext_1_rex64"
9269 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274 (match_operand 1 "ext_register_operand" "0")
9278 (match_operand 2 "ext_register_operand" "Q"))))
9279 (clobber (reg:CC FLAGS_REG))]
9281 "and{b}\t{%2, %h0|%h0, %2}"
9282 [(set_attr "type" "alu")
9283 (set_attr "length_immediate" "0")
9284 (set_attr "mode" "QI")])
9286 (define_insn "*andqi_ext_2"
9287 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9292 (match_operand 1 "ext_register_operand" "%0")
9296 (match_operand 2 "ext_register_operand" "Q")
9299 (clobber (reg:CC FLAGS_REG))]
9301 "and{b}\t{%h2, %h0|%h0, %h2}"
9302 [(set_attr "type" "alu")
9303 (set_attr "length_immediate" "0")
9304 (set_attr "mode" "QI")])
9306 ;; Convert wide AND instructions with immediate operand to shorter QImode
9307 ;; equivalents when possible.
9308 ;; Don't do the splitting with memory operands, since it introduces risk
9309 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9310 ;; for size, but that can (should?) be handled by generic code instead.
9312 [(set (match_operand 0 "register_operand" "")
9313 (and (match_operand 1 "register_operand" "")
9314 (match_operand 2 "const_int_operand" "")))
9315 (clobber (reg:CC FLAGS_REG))]
9317 && QI_REG_P (operands[0])
9318 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9319 && !(~INTVAL (operands[2]) & ~(255 << 8))
9320 && GET_MODE (operands[0]) != QImode"
9321 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9322 (and:SI (zero_extract:SI (match_dup 1)
9323 (const_int 8) (const_int 8))
9325 (clobber (reg:CC FLAGS_REG))])]
9326 "operands[0] = gen_lowpart (SImode, operands[0]);
9327 operands[1] = gen_lowpart (SImode, operands[1]);
9328 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9330 ;; Since AND can be encoded with sign extended immediate, this is only
9331 ;; profitable when 7th bit is not set.
9333 [(set (match_operand 0 "register_operand" "")
9334 (and (match_operand 1 "general_operand" "")
9335 (match_operand 2 "const_int_operand" "")))
9336 (clobber (reg:CC FLAGS_REG))]
9338 && ANY_QI_REG_P (operands[0])
9339 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9340 && !(~INTVAL (operands[2]) & ~255)
9341 && !(INTVAL (operands[2]) & 128)
9342 && GET_MODE (operands[0]) != QImode"
9343 [(parallel [(set (strict_low_part (match_dup 0))
9344 (and:QI (match_dup 1)
9346 (clobber (reg:CC FLAGS_REG))])]
9347 "operands[0] = gen_lowpart (QImode, operands[0]);
9348 operands[1] = gen_lowpart (QImode, operands[1]);
9349 operands[2] = gen_lowpart (QImode, operands[2]);")
9351 ;; Logical inclusive OR instructions
9353 ;; %%% This used to optimize known byte-wide and operations to memory.
9354 ;; If this is considered useful, it should be done with splitters.
9356 (define_expand "iordi3"
9357 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9358 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9359 (match_operand:DI 2 "x86_64_general_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))]
9362 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9364 (define_insn "*iordi_1_rex64"
9365 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9366 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9367 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9368 (clobber (reg:CC FLAGS_REG))]
9370 && ix86_binary_operator_ok (IOR, DImode, operands)"
9371 "or{q}\t{%2, %0|%0, %2}"
9372 [(set_attr "type" "alu")
9373 (set_attr "mode" "DI")])
9375 (define_insn "*iordi_2_rex64"
9376 [(set (reg FLAGS_REG)
9377 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9378 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9380 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9381 (ior:DI (match_dup 1) (match_dup 2)))]
9383 && ix86_match_ccmode (insn, CCNOmode)
9384 && ix86_binary_operator_ok (IOR, DImode, operands)"
9385 "or{q}\t{%2, %0|%0, %2}"
9386 [(set_attr "type" "alu")
9387 (set_attr "mode" "DI")])
9389 (define_insn "*iordi_3_rex64"
9390 [(set (reg FLAGS_REG)
9391 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9392 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9394 (clobber (match_scratch:DI 0 "=r"))]
9396 && ix86_match_ccmode (insn, CCNOmode)
9397 && ix86_binary_operator_ok (IOR, DImode, operands)"
9398 "or{q}\t{%2, %0|%0, %2}"
9399 [(set_attr "type" "alu")
9400 (set_attr "mode" "DI")])
9403 (define_expand "iorsi3"
9404 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9405 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9406 (match_operand:SI 2 "general_operand" "")))
9407 (clobber (reg:CC FLAGS_REG))]
9409 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9411 (define_insn "*iorsi_1"
9412 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9413 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9414 (match_operand:SI 2 "general_operand" "ri,g")))
9415 (clobber (reg:CC FLAGS_REG))]
9416 "ix86_binary_operator_ok (IOR, SImode, operands)"
9417 "or{l}\t{%2, %0|%0, %2}"
9418 [(set_attr "type" "alu")
9419 (set_attr "mode" "SI")])
9421 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9422 (define_insn "*iorsi_1_zext"
9423 [(set (match_operand:DI 0 "register_operand" "=r")
9425 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9426 (match_operand:SI 2 "general_operand" "g"))))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9429 "or{l}\t{%2, %k0|%k0, %2}"
9430 [(set_attr "type" "alu")
9431 (set_attr "mode" "SI")])
9433 (define_insn "*iorsi_1_zext_imm"
9434 [(set (match_operand:DI 0 "register_operand" "=r")
9435 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9436 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9437 (clobber (reg:CC FLAGS_REG))]
9439 "or{l}\t{%2, %k0|%k0, %2}"
9440 [(set_attr "type" "alu")
9441 (set_attr "mode" "SI")])
9443 (define_insn "*iorsi_2"
9444 [(set (reg FLAGS_REG)
9445 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9446 (match_operand:SI 2 "general_operand" "g,ri"))
9448 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9449 (ior:SI (match_dup 1) (match_dup 2)))]
9450 "ix86_match_ccmode (insn, CCNOmode)
9451 && ix86_binary_operator_ok (IOR, SImode, operands)"
9452 "or{l}\t{%2, %0|%0, %2}"
9453 [(set_attr "type" "alu")
9454 (set_attr "mode" "SI")])
9456 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9457 ;; ??? Special case for immediate operand is missing - it is tricky.
9458 (define_insn "*iorsi_2_zext"
9459 [(set (reg FLAGS_REG)
9460 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9461 (match_operand:SI 2 "general_operand" "g"))
9463 (set (match_operand:DI 0 "register_operand" "=r")
9464 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9465 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9466 && ix86_binary_operator_ok (IOR, SImode, operands)"
9467 "or{l}\t{%2, %k0|%k0, %2}"
9468 [(set_attr "type" "alu")
9469 (set_attr "mode" "SI")])
9471 (define_insn "*iorsi_2_zext_imm"
9472 [(set (reg FLAGS_REG)
9473 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9474 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9476 (set (match_operand:DI 0 "register_operand" "=r")
9477 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9478 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9479 && ix86_binary_operator_ok (IOR, SImode, operands)"
9480 "or{l}\t{%2, %k0|%k0, %2}"
9481 [(set_attr "type" "alu")
9482 (set_attr "mode" "SI")])
9484 (define_insn "*iorsi_3"
9485 [(set (reg FLAGS_REG)
9486 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9487 (match_operand:SI 2 "general_operand" "g"))
9489 (clobber (match_scratch:SI 0 "=r"))]
9490 "ix86_match_ccmode (insn, CCNOmode)
9491 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9492 "or{l}\t{%2, %0|%0, %2}"
9493 [(set_attr "type" "alu")
9494 (set_attr "mode" "SI")])
9496 (define_expand "iorhi3"
9497 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9498 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9499 (match_operand:HI 2 "general_operand" "")))
9500 (clobber (reg:CC FLAGS_REG))]
9501 "TARGET_HIMODE_MATH"
9502 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9504 (define_insn "*iorhi_1"
9505 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9506 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9507 (match_operand:HI 2 "general_operand" "g,ri")))
9508 (clobber (reg:CC FLAGS_REG))]
9509 "ix86_binary_operator_ok (IOR, HImode, operands)"
9510 "or{w}\t{%2, %0|%0, %2}"
9511 [(set_attr "type" "alu")
9512 (set_attr "mode" "HI")])
9514 (define_insn "*iorhi_2"
9515 [(set (reg FLAGS_REG)
9516 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9517 (match_operand:HI 2 "general_operand" "g,ri"))
9519 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9520 (ior:HI (match_dup 1) (match_dup 2)))]
9521 "ix86_match_ccmode (insn, CCNOmode)
9522 && ix86_binary_operator_ok (IOR, HImode, operands)"
9523 "or{w}\t{%2, %0|%0, %2}"
9524 [(set_attr "type" "alu")
9525 (set_attr "mode" "HI")])
9527 (define_insn "*iorhi_3"
9528 [(set (reg FLAGS_REG)
9529 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9530 (match_operand:HI 2 "general_operand" "g"))
9532 (clobber (match_scratch:HI 0 "=r"))]
9533 "ix86_match_ccmode (insn, CCNOmode)
9534 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9535 "or{w}\t{%2, %0|%0, %2}"
9536 [(set_attr "type" "alu")
9537 (set_attr "mode" "HI")])
9539 (define_expand "iorqi3"
9540 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9541 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9542 (match_operand:QI 2 "general_operand" "")))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "TARGET_QIMODE_MATH"
9545 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9547 ;; %%% Potential partial reg stall on alternative 2. What to do?
9548 (define_insn "*iorqi_1"
9549 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9550 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9551 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9552 (clobber (reg:CC FLAGS_REG))]
9553 "ix86_binary_operator_ok (IOR, QImode, operands)"
9555 or{b}\t{%2, %0|%0, %2}
9556 or{b}\t{%2, %0|%0, %2}
9557 or{l}\t{%k2, %k0|%k0, %k2}"
9558 [(set_attr "type" "alu")
9559 (set_attr "mode" "QI,QI,SI")])
9561 (define_insn "*iorqi_1_slp"
9562 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9563 (ior:QI (match_dup 0)
9564 (match_operand:QI 1 "general_operand" "qmi,qi")))
9565 (clobber (reg:CC FLAGS_REG))]
9566 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9567 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9568 "or{b}\t{%1, %0|%0, %1}"
9569 [(set_attr "type" "alu1")
9570 (set_attr "mode" "QI")])
9572 (define_insn "*iorqi_2"
9573 [(set (reg FLAGS_REG)
9574 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9575 (match_operand:QI 2 "general_operand" "qim,qi"))
9577 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9578 (ior:QI (match_dup 1) (match_dup 2)))]
9579 "ix86_match_ccmode (insn, CCNOmode)
9580 && ix86_binary_operator_ok (IOR, QImode, operands)"
9581 "or{b}\t{%2, %0|%0, %2}"
9582 [(set_attr "type" "alu")
9583 (set_attr "mode" "QI")])
9585 (define_insn "*iorqi_2_slp"
9586 [(set (reg FLAGS_REG)
9587 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9588 (match_operand:QI 1 "general_operand" "qim,qi"))
9590 (set (strict_low_part (match_dup 0))
9591 (ior:QI (match_dup 0) (match_dup 1)))]
9592 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9593 && ix86_match_ccmode (insn, CCNOmode)
9594 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9595 "or{b}\t{%1, %0|%0, %1}"
9596 [(set_attr "type" "alu1")
9597 (set_attr "mode" "QI")])
9599 (define_insn "*iorqi_3"
9600 [(set (reg FLAGS_REG)
9601 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9602 (match_operand:QI 2 "general_operand" "qim"))
9604 (clobber (match_scratch:QI 0 "=q"))]
9605 "ix86_match_ccmode (insn, CCNOmode)
9606 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9607 "or{b}\t{%2, %0|%0, %2}"
9608 [(set_attr "type" "alu")
9609 (set_attr "mode" "QI")])
9611 (define_insn "iorqi_ext_0"
9612 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9617 (match_operand 1 "ext_register_operand" "0")
9620 (match_operand 2 "const_int_operand" "n")))
9621 (clobber (reg:CC FLAGS_REG))]
9622 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9623 "or{b}\t{%2, %h0|%h0, %2}"
9624 [(set_attr "type" "alu")
9625 (set_attr "length_immediate" "1")
9626 (set_attr "mode" "QI")])
9628 (define_insn "*iorqi_ext_1"
9629 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9634 (match_operand 1 "ext_register_operand" "0")
9638 (match_operand:QI 2 "general_operand" "Qm"))))
9639 (clobber (reg:CC FLAGS_REG))]
9641 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9642 "or{b}\t{%2, %h0|%h0, %2}"
9643 [(set_attr "type" "alu")
9644 (set_attr "length_immediate" "0")
9645 (set_attr "mode" "QI")])
9647 (define_insn "*iorqi_ext_1_rex64"
9648 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9653 (match_operand 1 "ext_register_operand" "0")
9657 (match_operand 2 "ext_register_operand" "Q"))))
9658 (clobber (reg:CC FLAGS_REG))]
9660 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9661 "or{b}\t{%2, %h0|%h0, %2}"
9662 [(set_attr "type" "alu")
9663 (set_attr "length_immediate" "0")
9664 (set_attr "mode" "QI")])
9666 (define_insn "*iorqi_ext_2"
9667 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9671 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9674 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9677 (clobber (reg:CC FLAGS_REG))]
9678 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9679 "ior{b}\t{%h2, %h0|%h0, %h2}"
9680 [(set_attr "type" "alu")
9681 (set_attr "length_immediate" "0")
9682 (set_attr "mode" "QI")])
9685 [(set (match_operand 0 "register_operand" "")
9686 (ior (match_operand 1 "register_operand" "")
9687 (match_operand 2 "const_int_operand" "")))
9688 (clobber (reg:CC FLAGS_REG))]
9690 && QI_REG_P (operands[0])
9691 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9692 && !(INTVAL (operands[2]) & ~(255 << 8))
9693 && GET_MODE (operands[0]) != QImode"
9694 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9695 (ior:SI (zero_extract:SI (match_dup 1)
9696 (const_int 8) (const_int 8))
9698 (clobber (reg:CC FLAGS_REG))])]
9699 "operands[0] = gen_lowpart (SImode, operands[0]);
9700 operands[1] = gen_lowpart (SImode, operands[1]);
9701 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9703 ;; Since OR can be encoded with sign extended immediate, this is only
9704 ;; profitable when 7th bit is set.
9706 [(set (match_operand 0 "register_operand" "")
9707 (ior (match_operand 1 "general_operand" "")
9708 (match_operand 2 "const_int_operand" "")))
9709 (clobber (reg:CC FLAGS_REG))]
9711 && ANY_QI_REG_P (operands[0])
9712 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9713 && !(INTVAL (operands[2]) & ~255)
9714 && (INTVAL (operands[2]) & 128)
9715 && GET_MODE (operands[0]) != QImode"
9716 [(parallel [(set (strict_low_part (match_dup 0))
9717 (ior:QI (match_dup 1)
9719 (clobber (reg:CC FLAGS_REG))])]
9720 "operands[0] = gen_lowpart (QImode, operands[0]);
9721 operands[1] = gen_lowpart (QImode, operands[1]);
9722 operands[2] = gen_lowpart (QImode, operands[2]);")
9724 ;; Logical XOR instructions
9726 ;; %%% This used to optimize known byte-wide and operations to memory.
9727 ;; If this is considered useful, it should be done with splitters.
9729 (define_expand "xordi3"
9730 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9731 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9732 (match_operand:DI 2 "x86_64_general_operand" "")))
9733 (clobber (reg:CC FLAGS_REG))]
9735 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9737 (define_insn "*xordi_1_rex64"
9738 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9739 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9740 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9741 (clobber (reg:CC FLAGS_REG))]
9743 && ix86_binary_operator_ok (XOR, DImode, operands)"
9744 "xor{q}\t{%2, %0|%0, %2}"
9745 [(set_attr "type" "alu")
9746 (set_attr "mode" "DI")])
9748 (define_insn "*xordi_2_rex64"
9749 [(set (reg FLAGS_REG)
9750 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9751 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9753 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9754 (xor:DI (match_dup 1) (match_dup 2)))]
9756 && ix86_match_ccmode (insn, CCNOmode)
9757 && ix86_binary_operator_ok (XOR, DImode, operands)"
9758 "xor{q}\t{%2, %0|%0, %2}"
9759 [(set_attr "type" "alu")
9760 (set_attr "mode" "DI")])
9762 (define_insn "*xordi_3_rex64"
9763 [(set (reg FLAGS_REG)
9764 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9765 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9767 (clobber (match_scratch:DI 0 "=r"))]
9769 && ix86_match_ccmode (insn, CCNOmode)
9770 && ix86_binary_operator_ok (XOR, DImode, operands)"
9771 "xor{q}\t{%2, %0|%0, %2}"
9772 [(set_attr "type" "alu")
9773 (set_attr "mode" "DI")])
9775 (define_expand "xorsi3"
9776 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9777 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9778 (match_operand:SI 2 "general_operand" "")))
9779 (clobber (reg:CC FLAGS_REG))]
9781 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9783 (define_insn "*xorsi_1"
9784 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9785 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9786 (match_operand:SI 2 "general_operand" "ri,rm")))
9787 (clobber (reg:CC FLAGS_REG))]
9788 "ix86_binary_operator_ok (XOR, SImode, operands)"
9789 "xor{l}\t{%2, %0|%0, %2}"
9790 [(set_attr "type" "alu")
9791 (set_attr "mode" "SI")])
9793 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9794 ;; Add speccase for immediates
9795 (define_insn "*xorsi_1_zext"
9796 [(set (match_operand:DI 0 "register_operand" "=r")
9798 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9799 (match_operand:SI 2 "general_operand" "g"))))
9800 (clobber (reg:CC FLAGS_REG))]
9801 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9802 "xor{l}\t{%2, %k0|%k0, %2}"
9803 [(set_attr "type" "alu")
9804 (set_attr "mode" "SI")])
9806 (define_insn "*xorsi_1_zext_imm"
9807 [(set (match_operand:DI 0 "register_operand" "=r")
9808 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9809 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9810 (clobber (reg:CC FLAGS_REG))]
9811 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9812 "xor{l}\t{%2, %k0|%k0, %2}"
9813 [(set_attr "type" "alu")
9814 (set_attr "mode" "SI")])
9816 (define_insn "*xorsi_2"
9817 [(set (reg FLAGS_REG)
9818 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9819 (match_operand:SI 2 "general_operand" "g,ri"))
9821 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9822 (xor:SI (match_dup 1) (match_dup 2)))]
9823 "ix86_match_ccmode (insn, CCNOmode)
9824 && ix86_binary_operator_ok (XOR, SImode, operands)"
9825 "xor{l}\t{%2, %0|%0, %2}"
9826 [(set_attr "type" "alu")
9827 (set_attr "mode" "SI")])
9829 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9830 ;; ??? Special case for immediate operand is missing - it is tricky.
9831 (define_insn "*xorsi_2_zext"
9832 [(set (reg FLAGS_REG)
9833 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9834 (match_operand:SI 2 "general_operand" "g"))
9836 (set (match_operand:DI 0 "register_operand" "=r")
9837 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9838 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9839 && ix86_binary_operator_ok (XOR, SImode, operands)"
9840 "xor{l}\t{%2, %k0|%k0, %2}"
9841 [(set_attr "type" "alu")
9842 (set_attr "mode" "SI")])
9844 (define_insn "*xorsi_2_zext_imm"
9845 [(set (reg FLAGS_REG)
9846 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9847 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9849 (set (match_operand:DI 0 "register_operand" "=r")
9850 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9851 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9852 && ix86_binary_operator_ok (XOR, SImode, operands)"
9853 "xor{l}\t{%2, %k0|%k0, %2}"
9854 [(set_attr "type" "alu")
9855 (set_attr "mode" "SI")])
9857 (define_insn "*xorsi_3"
9858 [(set (reg FLAGS_REG)
9859 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9860 (match_operand:SI 2 "general_operand" "g"))
9862 (clobber (match_scratch:SI 0 "=r"))]
9863 "ix86_match_ccmode (insn, CCNOmode)
9864 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9865 "xor{l}\t{%2, %0|%0, %2}"
9866 [(set_attr "type" "alu")
9867 (set_attr "mode" "SI")])
9869 (define_expand "xorhi3"
9870 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9871 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9872 (match_operand:HI 2 "general_operand" "")))
9873 (clobber (reg:CC FLAGS_REG))]
9874 "TARGET_HIMODE_MATH"
9875 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9877 (define_insn "*xorhi_1"
9878 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9879 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9880 (match_operand:HI 2 "general_operand" "g,ri")))
9881 (clobber (reg:CC FLAGS_REG))]
9882 "ix86_binary_operator_ok (XOR, HImode, operands)"
9883 "xor{w}\t{%2, %0|%0, %2}"
9884 [(set_attr "type" "alu")
9885 (set_attr "mode" "HI")])
9887 (define_insn "*xorhi_2"
9888 [(set (reg FLAGS_REG)
9889 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9890 (match_operand:HI 2 "general_operand" "g,ri"))
9892 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9893 (xor:HI (match_dup 1) (match_dup 2)))]
9894 "ix86_match_ccmode (insn, CCNOmode)
9895 && ix86_binary_operator_ok (XOR, HImode, operands)"
9896 "xor{w}\t{%2, %0|%0, %2}"
9897 [(set_attr "type" "alu")
9898 (set_attr "mode" "HI")])
9900 (define_insn "*xorhi_3"
9901 [(set (reg FLAGS_REG)
9902 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9903 (match_operand:HI 2 "general_operand" "g"))
9905 (clobber (match_scratch:HI 0 "=r"))]
9906 "ix86_match_ccmode (insn, CCNOmode)
9907 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9908 "xor{w}\t{%2, %0|%0, %2}"
9909 [(set_attr "type" "alu")
9910 (set_attr "mode" "HI")])
9912 (define_expand "xorqi3"
9913 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9914 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9915 (match_operand:QI 2 "general_operand" "")))
9916 (clobber (reg:CC FLAGS_REG))]
9917 "TARGET_QIMODE_MATH"
9918 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9920 ;; %%% Potential partial reg stall on alternative 2. What to do?
9921 (define_insn "*xorqi_1"
9922 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9923 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9924 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9925 (clobber (reg:CC FLAGS_REG))]
9926 "ix86_binary_operator_ok (XOR, QImode, operands)"
9928 xor{b}\t{%2, %0|%0, %2}
9929 xor{b}\t{%2, %0|%0, %2}
9930 xor{l}\t{%k2, %k0|%k0, %k2}"
9931 [(set_attr "type" "alu")
9932 (set_attr "mode" "QI,QI,SI")])
9934 (define_insn "*xorqi_1_slp"
9935 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9936 (xor:QI (match_dup 0)
9937 (match_operand:QI 1 "general_operand" "qi,qmi")))
9938 (clobber (reg:CC FLAGS_REG))]
9939 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9940 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9941 "xor{b}\t{%1, %0|%0, %1}"
9942 [(set_attr "type" "alu1")
9943 (set_attr "mode" "QI")])
9945 (define_insn "xorqi_ext_0"
9946 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9951 (match_operand 1 "ext_register_operand" "0")
9954 (match_operand 2 "const_int_operand" "n")))
9955 (clobber (reg:CC FLAGS_REG))]
9956 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9957 "xor{b}\t{%2, %h0|%h0, %2}"
9958 [(set_attr "type" "alu")
9959 (set_attr "length_immediate" "1")
9960 (set_attr "mode" "QI")])
9962 (define_insn "*xorqi_ext_1"
9963 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9968 (match_operand 1 "ext_register_operand" "0")
9972 (match_operand:QI 2 "general_operand" "Qm"))))
9973 (clobber (reg:CC FLAGS_REG))]
9975 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9976 "xor{b}\t{%2, %h0|%h0, %2}"
9977 [(set_attr "type" "alu")
9978 (set_attr "length_immediate" "0")
9979 (set_attr "mode" "QI")])
9981 (define_insn "*xorqi_ext_1_rex64"
9982 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9987 (match_operand 1 "ext_register_operand" "0")
9991 (match_operand 2 "ext_register_operand" "Q"))))
9992 (clobber (reg:CC FLAGS_REG))]
9994 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9995 "xor{b}\t{%2, %h0|%h0, %2}"
9996 [(set_attr "type" "alu")
9997 (set_attr "length_immediate" "0")
9998 (set_attr "mode" "QI")])
10000 (define_insn "*xorqi_ext_2"
10001 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10005 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10008 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10011 (clobber (reg:CC FLAGS_REG))]
10012 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10013 "xor{b}\t{%h2, %h0|%h0, %h2}"
10014 [(set_attr "type" "alu")
10015 (set_attr "length_immediate" "0")
10016 (set_attr "mode" "QI")])
10018 (define_insn "*xorqi_cc_1"
10019 [(set (reg FLAGS_REG)
10021 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10022 (match_operand:QI 2 "general_operand" "qim,qi"))
10024 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10025 (xor:QI (match_dup 1) (match_dup 2)))]
10026 "ix86_match_ccmode (insn, CCNOmode)
10027 && ix86_binary_operator_ok (XOR, QImode, operands)"
10028 "xor{b}\t{%2, %0|%0, %2}"
10029 [(set_attr "type" "alu")
10030 (set_attr "mode" "QI")])
10032 (define_insn "*xorqi_2_slp"
10033 [(set (reg FLAGS_REG)
10034 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10035 (match_operand:QI 1 "general_operand" "qim,qi"))
10037 (set (strict_low_part (match_dup 0))
10038 (xor:QI (match_dup 0) (match_dup 1)))]
10039 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10040 && ix86_match_ccmode (insn, CCNOmode)
10041 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10042 "xor{b}\t{%1, %0|%0, %1}"
10043 [(set_attr "type" "alu1")
10044 (set_attr "mode" "QI")])
10046 (define_insn "*xorqi_cc_2"
10047 [(set (reg FLAGS_REG)
10049 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10050 (match_operand:QI 2 "general_operand" "qim"))
10052 (clobber (match_scratch:QI 0 "=q"))]
10053 "ix86_match_ccmode (insn, CCNOmode)
10054 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10055 "xor{b}\t{%2, %0|%0, %2}"
10056 [(set_attr "type" "alu")
10057 (set_attr "mode" "QI")])
10059 (define_insn "*xorqi_cc_ext_1"
10060 [(set (reg FLAGS_REG)
10064 (match_operand 1 "ext_register_operand" "0")
10067 (match_operand:QI 2 "general_operand" "qmn"))
10069 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10073 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10075 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10076 "xor{b}\t{%2, %h0|%h0, %2}"
10077 [(set_attr "type" "alu")
10078 (set_attr "mode" "QI")])
10080 (define_insn "*xorqi_cc_ext_1_rex64"
10081 [(set (reg FLAGS_REG)
10085 (match_operand 1 "ext_register_operand" "0")
10088 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10090 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10094 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10097 "xor{b}\t{%2, %h0|%h0, %2}"
10098 [(set_attr "type" "alu")
10099 (set_attr "mode" "QI")])
10101 (define_expand "xorqi_cc_ext_1"
10103 (set (reg:CCNO FLAGS_REG)
10107 (match_operand 1 "ext_register_operand" "")
10110 (match_operand:QI 2 "general_operand" ""))
10112 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10116 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10122 [(set (match_operand 0 "register_operand" "")
10123 (xor (match_operand 1 "register_operand" "")
10124 (match_operand 2 "const_int_operand" "")))
10125 (clobber (reg:CC FLAGS_REG))]
10127 && QI_REG_P (operands[0])
10128 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10129 && !(INTVAL (operands[2]) & ~(255 << 8))
10130 && GET_MODE (operands[0]) != QImode"
10131 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10132 (xor:SI (zero_extract:SI (match_dup 1)
10133 (const_int 8) (const_int 8))
10135 (clobber (reg:CC FLAGS_REG))])]
10136 "operands[0] = gen_lowpart (SImode, operands[0]);
10137 operands[1] = gen_lowpart (SImode, operands[1]);
10138 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10140 ;; Since XOR can be encoded with sign extended immediate, this is only
10141 ;; profitable when 7th bit is set.
10143 [(set (match_operand 0 "register_operand" "")
10144 (xor (match_operand 1 "general_operand" "")
10145 (match_operand 2 "const_int_operand" "")))
10146 (clobber (reg:CC FLAGS_REG))]
10148 && ANY_QI_REG_P (operands[0])
10149 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10150 && !(INTVAL (operands[2]) & ~255)
10151 && (INTVAL (operands[2]) & 128)
10152 && GET_MODE (operands[0]) != QImode"
10153 [(parallel [(set (strict_low_part (match_dup 0))
10154 (xor:QI (match_dup 1)
10156 (clobber (reg:CC FLAGS_REG))])]
10157 "operands[0] = gen_lowpart (QImode, operands[0]);
10158 operands[1] = gen_lowpart (QImode, operands[1]);
10159 operands[2] = gen_lowpart (QImode, operands[2]);")
10161 ;; Negation instructions
10163 (define_expand "negti2"
10164 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10165 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10166 (clobber (reg:CC FLAGS_REG))])]
10168 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10170 (define_insn "*negti2_1"
10171 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10172 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10173 (clobber (reg:CC FLAGS_REG))]
10175 && ix86_unary_operator_ok (NEG, TImode, operands)"
10179 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10180 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10181 (clobber (reg:CC FLAGS_REG))]
10182 "TARGET_64BIT && reload_completed"
10184 [(set (reg:CCZ FLAGS_REG)
10185 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10186 (set (match_dup 0) (neg:DI (match_dup 1)))])
10188 [(set (match_dup 2)
10189 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10192 (clobber (reg:CC FLAGS_REG))])
10194 [(set (match_dup 2)
10195 (neg:DI (match_dup 2)))
10196 (clobber (reg:CC FLAGS_REG))])]
10197 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10199 (define_expand "negdi2"
10200 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10201 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10202 (clobber (reg:CC FLAGS_REG))])]
10204 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10206 (define_insn "*negdi2_1"
10207 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10208 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10209 (clobber (reg:CC FLAGS_REG))]
10211 && ix86_unary_operator_ok (NEG, DImode, operands)"
10215 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10216 (neg:DI (match_operand:DI 1 "general_operand" "")))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "!TARGET_64BIT && reload_completed"
10220 [(set (reg:CCZ FLAGS_REG)
10221 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10222 (set (match_dup 0) (neg:SI (match_dup 1)))])
10224 [(set (match_dup 2)
10225 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10228 (clobber (reg:CC FLAGS_REG))])
10230 [(set (match_dup 2)
10231 (neg:SI (match_dup 2)))
10232 (clobber (reg:CC FLAGS_REG))])]
10233 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10235 (define_insn "*negdi2_1_rex64"
10236 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10237 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10238 (clobber (reg:CC FLAGS_REG))]
10239 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10241 [(set_attr "type" "negnot")
10242 (set_attr "mode" "DI")])
10244 ;; The problem with neg is that it does not perform (compare x 0),
10245 ;; it really performs (compare 0 x), which leaves us with the zero
10246 ;; flag being the only useful item.
10248 (define_insn "*negdi2_cmpz_rex64"
10249 [(set (reg:CCZ FLAGS_REG)
10250 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10252 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10253 (neg:DI (match_dup 1)))]
10254 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10256 [(set_attr "type" "negnot")
10257 (set_attr "mode" "DI")])
10260 (define_expand "negsi2"
10261 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10262 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10263 (clobber (reg:CC FLAGS_REG))])]
10265 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10267 (define_insn "*negsi2_1"
10268 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10269 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10270 (clobber (reg:CC FLAGS_REG))]
10271 "ix86_unary_operator_ok (NEG, SImode, operands)"
10273 [(set_attr "type" "negnot")
10274 (set_attr "mode" "SI")])
10276 ;; Combine is quite creative about this pattern.
10277 (define_insn "*negsi2_1_zext"
10278 [(set (match_operand:DI 0 "register_operand" "=r")
10279 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10282 (clobber (reg:CC FLAGS_REG))]
10283 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10285 [(set_attr "type" "negnot")
10286 (set_attr "mode" "SI")])
10288 ;; The problem with neg is that it does not perform (compare x 0),
10289 ;; it really performs (compare 0 x), which leaves us with the zero
10290 ;; flag being the only useful item.
10292 (define_insn "*negsi2_cmpz"
10293 [(set (reg:CCZ FLAGS_REG)
10294 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10296 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10297 (neg:SI (match_dup 1)))]
10298 "ix86_unary_operator_ok (NEG, SImode, operands)"
10300 [(set_attr "type" "negnot")
10301 (set_attr "mode" "SI")])
10303 (define_insn "*negsi2_cmpz_zext"
10304 [(set (reg:CCZ FLAGS_REG)
10305 (compare:CCZ (lshiftrt:DI
10307 (match_operand:DI 1 "register_operand" "0")
10311 (set (match_operand:DI 0 "register_operand" "=r")
10312 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10315 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10317 [(set_attr "type" "negnot")
10318 (set_attr "mode" "SI")])
10320 (define_expand "neghi2"
10321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10322 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10323 (clobber (reg:CC FLAGS_REG))])]
10324 "TARGET_HIMODE_MATH"
10325 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10327 (define_insn "*neghi2_1"
10328 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10329 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10330 (clobber (reg:CC FLAGS_REG))]
10331 "ix86_unary_operator_ok (NEG, HImode, operands)"
10333 [(set_attr "type" "negnot")
10334 (set_attr "mode" "HI")])
10336 (define_insn "*neghi2_cmpz"
10337 [(set (reg:CCZ FLAGS_REG)
10338 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10340 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10341 (neg:HI (match_dup 1)))]
10342 "ix86_unary_operator_ok (NEG, HImode, operands)"
10344 [(set_attr "type" "negnot")
10345 (set_attr "mode" "HI")])
10347 (define_expand "negqi2"
10348 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10349 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10350 (clobber (reg:CC FLAGS_REG))])]
10351 "TARGET_QIMODE_MATH"
10352 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10354 (define_insn "*negqi2_1"
10355 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10356 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10357 (clobber (reg:CC FLAGS_REG))]
10358 "ix86_unary_operator_ok (NEG, QImode, operands)"
10360 [(set_attr "type" "negnot")
10361 (set_attr "mode" "QI")])
10363 (define_insn "*negqi2_cmpz"
10364 [(set (reg:CCZ FLAGS_REG)
10365 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10367 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10368 (neg:QI (match_dup 1)))]
10369 "ix86_unary_operator_ok (NEG, QImode, operands)"
10371 [(set_attr "type" "negnot")
10372 (set_attr "mode" "QI")])
10374 ;; Changing of sign for FP values is doable using integer unit too.
10376 (define_expand "<code><mode>2"
10377 [(set (match_operand:X87MODEF 0 "register_operand" "")
10378 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10379 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10380 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10382 (define_insn "*absneg<mode>2_mixed"
10383 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10384 (match_operator:MODEF 3 "absneg_operator"
10385 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10386 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10387 (clobber (reg:CC FLAGS_REG))]
10388 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10391 (define_insn "*absneg<mode>2_sse"
10392 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10393 (match_operator:MODEF 3 "absneg_operator"
10394 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10395 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10396 (clobber (reg:CC FLAGS_REG))]
10397 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10400 (define_insn "*absneg<mode>2_i387"
10401 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10402 (match_operator:X87MODEF 3 "absneg_operator"
10403 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10404 (use (match_operand 2 "" ""))
10405 (clobber (reg:CC FLAGS_REG))]
10406 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10409 (define_expand "<code>tf2"
10410 [(set (match_operand:TF 0 "register_operand" "")
10411 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10413 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10415 (define_insn "*absnegtf2_sse"
10416 [(set (match_operand:TF 0 "register_operand" "=x,x")
10417 (match_operator:TF 3 "absneg_operator"
10418 [(match_operand:TF 1 "register_operand" "0,x")]))
10419 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10420 (clobber (reg:CC FLAGS_REG))]
10424 ;; Splitters for fp abs and neg.
10427 [(set (match_operand 0 "fp_register_operand" "")
10428 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10429 (use (match_operand 2 "" ""))
10430 (clobber (reg:CC FLAGS_REG))]
10432 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10435 [(set (match_operand 0 "register_operand" "")
10436 (match_operator 3 "absneg_operator"
10437 [(match_operand 1 "register_operand" "")]))
10438 (use (match_operand 2 "nonimmediate_operand" ""))
10439 (clobber (reg:CC FLAGS_REG))]
10440 "reload_completed && SSE_REG_P (operands[0])"
10441 [(set (match_dup 0) (match_dup 3))]
10443 enum machine_mode mode = GET_MODE (operands[0]);
10444 enum machine_mode vmode = GET_MODE (operands[2]);
10447 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10448 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10449 if (operands_match_p (operands[0], operands[2]))
10452 operands[1] = operands[2];
10455 if (GET_CODE (operands[3]) == ABS)
10456 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10458 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10463 [(set (match_operand:SF 0 "register_operand" "")
10464 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10465 (use (match_operand:V4SF 2 "" ""))
10466 (clobber (reg:CC FLAGS_REG))]
10468 [(parallel [(set (match_dup 0) (match_dup 1))
10469 (clobber (reg:CC FLAGS_REG))])]
10472 operands[0] = gen_lowpart (SImode, operands[0]);
10473 if (GET_CODE (operands[1]) == ABS)
10475 tmp = gen_int_mode (0x7fffffff, SImode);
10476 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10480 tmp = gen_int_mode (0x80000000, SImode);
10481 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10487 [(set (match_operand:DF 0 "register_operand" "")
10488 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10489 (use (match_operand 2 "" ""))
10490 (clobber (reg:CC FLAGS_REG))]
10492 [(parallel [(set (match_dup 0) (match_dup 1))
10493 (clobber (reg:CC FLAGS_REG))])]
10498 tmp = gen_lowpart (DImode, operands[0]);
10499 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10502 if (GET_CODE (operands[1]) == ABS)
10505 tmp = gen_rtx_NOT (DImode, tmp);
10509 operands[0] = gen_highpart (SImode, operands[0]);
10510 if (GET_CODE (operands[1]) == ABS)
10512 tmp = gen_int_mode (0x7fffffff, SImode);
10513 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10517 tmp = gen_int_mode (0x80000000, SImode);
10518 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10525 [(set (match_operand:XF 0 "register_operand" "")
10526 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10527 (use (match_operand 2 "" ""))
10528 (clobber (reg:CC FLAGS_REG))]
10530 [(parallel [(set (match_dup 0) (match_dup 1))
10531 (clobber (reg:CC FLAGS_REG))])]
10534 operands[0] = gen_rtx_REG (SImode,
10535 true_regnum (operands[0])
10536 + (TARGET_64BIT ? 1 : 2));
10537 if (GET_CODE (operands[1]) == ABS)
10539 tmp = GEN_INT (0x7fff);
10540 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10544 tmp = GEN_INT (0x8000);
10545 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10550 ;; Conditionalize these after reload. If they match before reload, we
10551 ;; lose the clobber and ability to use integer instructions.
10553 (define_insn "*<code><mode>2_1"
10554 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10555 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10557 && (reload_completed
10558 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10560 [(set_attr "type" "fsgn")
10561 (set_attr "mode" "<MODE>")])
10563 (define_insn "*<code>extendsfdf2"
10564 [(set (match_operand:DF 0 "register_operand" "=f")
10565 (absneg:DF (float_extend:DF
10566 (match_operand:SF 1 "register_operand" "0"))))]
10567 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10569 [(set_attr "type" "fsgn")
10570 (set_attr "mode" "DF")])
10572 (define_insn "*<code>extendsfxf2"
10573 [(set (match_operand:XF 0 "register_operand" "=f")
10574 (absneg:XF (float_extend:XF
10575 (match_operand:SF 1 "register_operand" "0"))))]
10578 [(set_attr "type" "fsgn")
10579 (set_attr "mode" "XF")])
10581 (define_insn "*<code>extenddfxf2"
10582 [(set (match_operand:XF 0 "register_operand" "=f")
10583 (absneg:XF (float_extend:XF
10584 (match_operand:DF 1 "register_operand" "0"))))]
10587 [(set_attr "type" "fsgn")
10588 (set_attr "mode" "XF")])
10590 ;; Copysign instructions
10592 (define_mode_iterator CSGNMODE [SF DF TF])
10593 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10595 (define_expand "copysign<mode>3"
10596 [(match_operand:CSGNMODE 0 "register_operand" "")
10597 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10598 (match_operand:CSGNMODE 2 "register_operand" "")]
10599 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10600 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10602 ix86_expand_copysign (operands);
10606 (define_insn_and_split "copysign<mode>3_const"
10607 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10609 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10610 (match_operand:CSGNMODE 2 "register_operand" "0")
10611 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10613 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10614 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10616 "&& reload_completed"
10619 ix86_split_copysign_const (operands);
10623 (define_insn "copysign<mode>3_var"
10624 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10626 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10627 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10628 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10629 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10631 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10632 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10633 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10637 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10639 [(match_operand:CSGNMODE 2 "register_operand" "")
10640 (match_operand:CSGNMODE 3 "register_operand" "")
10641 (match_operand:<CSGNVMODE> 4 "" "")
10642 (match_operand:<CSGNVMODE> 5 "" "")]
10644 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10645 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10646 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10647 && reload_completed"
10650 ix86_split_copysign_var (operands);
10654 ;; One complement instructions
10656 (define_expand "one_cmpldi2"
10657 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10658 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10660 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10662 (define_insn "*one_cmpldi2_1_rex64"
10663 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10664 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10665 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10667 [(set_attr "type" "negnot")
10668 (set_attr "mode" "DI")])
10670 (define_insn "*one_cmpldi2_2_rex64"
10671 [(set (reg FLAGS_REG)
10672 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10674 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10675 (not:DI (match_dup 1)))]
10676 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10677 && ix86_unary_operator_ok (NOT, DImode, operands)"
10679 [(set_attr "type" "alu1")
10680 (set_attr "mode" "DI")])
10683 [(set (match_operand 0 "flags_reg_operand" "")
10684 (match_operator 2 "compare_operator"
10685 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10687 (set (match_operand:DI 1 "nonimmediate_operand" "")
10688 (not:DI (match_dup 3)))]
10689 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10690 [(parallel [(set (match_dup 0)
10692 [(xor:DI (match_dup 3) (const_int -1))
10695 (xor:DI (match_dup 3) (const_int -1)))])]
10698 (define_expand "one_cmplsi2"
10699 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10700 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10702 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10704 (define_insn "*one_cmplsi2_1"
10705 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10706 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10707 "ix86_unary_operator_ok (NOT, SImode, operands)"
10709 [(set_attr "type" "negnot")
10710 (set_attr "mode" "SI")])
10712 ;; ??? Currently never generated - xor is used instead.
10713 (define_insn "*one_cmplsi2_1_zext"
10714 [(set (match_operand:DI 0 "register_operand" "=r")
10715 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10716 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10718 [(set_attr "type" "negnot")
10719 (set_attr "mode" "SI")])
10721 (define_insn "*one_cmplsi2_2"
10722 [(set (reg FLAGS_REG)
10723 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10725 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10726 (not:SI (match_dup 1)))]
10727 "ix86_match_ccmode (insn, CCNOmode)
10728 && ix86_unary_operator_ok (NOT, SImode, operands)"
10730 [(set_attr "type" "alu1")
10731 (set_attr "mode" "SI")])
10734 [(set (match_operand 0 "flags_reg_operand" "")
10735 (match_operator 2 "compare_operator"
10736 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10738 (set (match_operand:SI 1 "nonimmediate_operand" "")
10739 (not:SI (match_dup 3)))]
10740 "ix86_match_ccmode (insn, CCNOmode)"
10741 [(parallel [(set (match_dup 0)
10742 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10745 (xor:SI (match_dup 3) (const_int -1)))])]
10748 ;; ??? Currently never generated - xor is used instead.
10749 (define_insn "*one_cmplsi2_2_zext"
10750 [(set (reg FLAGS_REG)
10751 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10753 (set (match_operand:DI 0 "register_operand" "=r")
10754 (zero_extend:DI (not:SI (match_dup 1))))]
10755 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10756 && ix86_unary_operator_ok (NOT, SImode, operands)"
10758 [(set_attr "type" "alu1")
10759 (set_attr "mode" "SI")])
10762 [(set (match_operand 0 "flags_reg_operand" "")
10763 (match_operator 2 "compare_operator"
10764 [(not:SI (match_operand:SI 3 "register_operand" ""))
10766 (set (match_operand:DI 1 "register_operand" "")
10767 (zero_extend:DI (not:SI (match_dup 3))))]
10768 "ix86_match_ccmode (insn, CCNOmode)"
10769 [(parallel [(set (match_dup 0)
10770 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10773 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10776 (define_expand "one_cmplhi2"
10777 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10778 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10779 "TARGET_HIMODE_MATH"
10780 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10782 (define_insn "*one_cmplhi2_1"
10783 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10784 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10785 "ix86_unary_operator_ok (NOT, HImode, operands)"
10787 [(set_attr "type" "negnot")
10788 (set_attr "mode" "HI")])
10790 (define_insn "*one_cmplhi2_2"
10791 [(set (reg FLAGS_REG)
10792 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10794 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10795 (not:HI (match_dup 1)))]
10796 "ix86_match_ccmode (insn, CCNOmode)
10797 && ix86_unary_operator_ok (NEG, HImode, operands)"
10799 [(set_attr "type" "alu1")
10800 (set_attr "mode" "HI")])
10803 [(set (match_operand 0 "flags_reg_operand" "")
10804 (match_operator 2 "compare_operator"
10805 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10807 (set (match_operand:HI 1 "nonimmediate_operand" "")
10808 (not:HI (match_dup 3)))]
10809 "ix86_match_ccmode (insn, CCNOmode)"
10810 [(parallel [(set (match_dup 0)
10811 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10814 (xor:HI (match_dup 3) (const_int -1)))])]
10817 ;; %%% Potential partial reg stall on alternative 1. What to do?
10818 (define_expand "one_cmplqi2"
10819 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10820 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10821 "TARGET_QIMODE_MATH"
10822 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10824 (define_insn "*one_cmplqi2_1"
10825 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10826 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10827 "ix86_unary_operator_ok (NOT, QImode, operands)"
10831 [(set_attr "type" "negnot")
10832 (set_attr "mode" "QI,SI")])
10834 (define_insn "*one_cmplqi2_2"
10835 [(set (reg FLAGS_REG)
10836 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10838 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10839 (not:QI (match_dup 1)))]
10840 "ix86_match_ccmode (insn, CCNOmode)
10841 && ix86_unary_operator_ok (NOT, QImode, operands)"
10843 [(set_attr "type" "alu1")
10844 (set_attr "mode" "QI")])
10847 [(set (match_operand 0 "flags_reg_operand" "")
10848 (match_operator 2 "compare_operator"
10849 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10851 (set (match_operand:QI 1 "nonimmediate_operand" "")
10852 (not:QI (match_dup 3)))]
10853 "ix86_match_ccmode (insn, CCNOmode)"
10854 [(parallel [(set (match_dup 0)
10855 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10858 (xor:QI (match_dup 3) (const_int -1)))])]
10861 ;; Arithmetic shift instructions
10863 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10864 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10865 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10866 ;; from the assembler input.
10868 ;; This instruction shifts the target reg/mem as usual, but instead of
10869 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10870 ;; is a left shift double, bits are taken from the high order bits of
10871 ;; reg, else if the insn is a shift right double, bits are taken from the
10872 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10873 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10875 ;; Since sh[lr]d does not change the `reg' operand, that is done
10876 ;; separately, making all shifts emit pairs of shift double and normal
10877 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10878 ;; support a 63 bit shift, each shift where the count is in a reg expands
10879 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10881 ;; If the shift count is a constant, we need never emit more than one
10882 ;; shift pair, instead using moves and sign extension for counts greater
10885 (define_expand "ashlti3"
10886 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10887 (ashift:TI (match_operand:TI 1 "register_operand" "")
10888 (match_operand:QI 2 "nonmemory_operand" "")))
10889 (clobber (reg:CC FLAGS_REG))])]
10892 if (! immediate_operand (operands[2], QImode))
10894 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10897 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10901 (define_insn "ashlti3_1"
10902 [(set (match_operand:TI 0 "register_operand" "=r")
10903 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10904 (match_operand:QI 2 "register_operand" "c")))
10905 (clobber (match_scratch:DI 3 "=&r"))
10906 (clobber (reg:CC FLAGS_REG))]
10909 [(set_attr "type" "multi")])
10911 ;; This pattern must be defined before *ashlti3_2 to prevent
10912 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10914 (define_insn "sse2_ashlti3"
10915 [(set (match_operand:TI 0 "register_operand" "=x")
10916 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10917 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10920 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10921 return "pslldq\t{%2, %0|%0, %2}";
10923 [(set_attr "type" "sseishft")
10924 (set_attr "prefix_data16" "1")
10925 (set_attr "mode" "TI")])
10927 (define_insn "*ashlti3_2"
10928 [(set (match_operand:TI 0 "register_operand" "=r")
10929 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10930 (match_operand:QI 2 "immediate_operand" "O")))
10931 (clobber (reg:CC FLAGS_REG))]
10934 [(set_attr "type" "multi")])
10937 [(set (match_operand:TI 0 "register_operand" "")
10938 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10939 (match_operand:QI 2 "register_operand" "")))
10940 (clobber (match_scratch:DI 3 ""))
10941 (clobber (reg:CC FLAGS_REG))]
10942 "TARGET_64BIT && reload_completed"
10944 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10947 [(set (match_operand:TI 0 "register_operand" "")
10948 (ashift:TI (match_operand:TI 1 "register_operand" "")
10949 (match_operand:QI 2 "immediate_operand" "")))
10950 (clobber (reg:CC FLAGS_REG))]
10951 "TARGET_64BIT && reload_completed"
10953 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10955 (define_insn "x86_64_shld"
10956 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10957 (ior:DI (ashift:DI (match_dup 0)
10958 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10959 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10960 (minus:QI (const_int 64) (match_dup 2)))))
10961 (clobber (reg:CC FLAGS_REG))]
10964 shld{q}\t{%2, %1, %0|%0, %1, %2}
10965 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10966 [(set_attr "type" "ishift")
10967 (set_attr "prefix_0f" "1")
10968 (set_attr "mode" "DI")
10969 (set_attr "athlon_decode" "vector")
10970 (set_attr "amdfam10_decode" "vector")])
10972 (define_expand "x86_64_shift_adj"
10973 [(set (reg:CCZ FLAGS_REG)
10974 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10977 (set (match_operand:DI 0 "register_operand" "")
10978 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10979 (match_operand:DI 1 "register_operand" "")
10982 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10983 (match_operand:DI 3 "register_operand" "r")
10988 (define_expand "ashldi3"
10989 [(set (match_operand:DI 0 "shiftdi_operand" "")
10990 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10991 (match_operand:QI 2 "nonmemory_operand" "")))]
10993 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10995 (define_insn "*ashldi3_1_rex64"
10996 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10997 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10998 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10999 (clobber (reg:CC FLAGS_REG))]
11000 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11002 switch (get_attr_type (insn))
11005 gcc_assert (operands[2] == const1_rtx);
11006 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11007 return "add{q}\t%0, %0";
11010 gcc_assert (CONST_INT_P (operands[2]));
11011 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11012 operands[1] = gen_rtx_MULT (DImode, operands[1],
11013 GEN_INT (1 << INTVAL (operands[2])));
11014 return "lea{q}\t{%a1, %0|%0, %a1}";
11017 if (REG_P (operands[2]))
11018 return "sal{q}\t{%b2, %0|%0, %b2}";
11019 else if (operands[2] == const1_rtx
11020 && (TARGET_SHIFT1 || optimize_size))
11021 return "sal{q}\t%0";
11023 return "sal{q}\t{%2, %0|%0, %2}";
11026 [(set (attr "type")
11027 (cond [(eq_attr "alternative" "1")
11028 (const_string "lea")
11029 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11031 (match_operand 0 "register_operand" ""))
11032 (match_operand 2 "const1_operand" ""))
11033 (const_string "alu")
11035 (const_string "ishift")))
11036 (set_attr "mode" "DI")])
11038 ;; Convert lea to the lea pattern to avoid flags dependency.
11040 [(set (match_operand:DI 0 "register_operand" "")
11041 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11042 (match_operand:QI 2 "immediate_operand" "")))
11043 (clobber (reg:CC FLAGS_REG))]
11044 "TARGET_64BIT && reload_completed
11045 && true_regnum (operands[0]) != true_regnum (operands[1])"
11046 [(set (match_dup 0)
11047 (mult:DI (match_dup 1)
11049 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11051 ;; This pattern can't accept a variable shift count, since shifts by
11052 ;; zero don't affect the flags. We assume that shifts by constant
11053 ;; zero are optimized away.
11054 (define_insn "*ashldi3_cmp_rex64"
11055 [(set (reg FLAGS_REG)
11057 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11058 (match_operand:QI 2 "immediate_operand" "e"))
11060 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11061 (ashift:DI (match_dup 1) (match_dup 2)))]
11064 || !TARGET_PARTIAL_FLAG_REG_STALL
11065 || (operands[2] == const1_rtx
11067 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11068 && ix86_match_ccmode (insn, CCGOCmode)
11069 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11071 switch (get_attr_type (insn))
11074 gcc_assert (operands[2] == const1_rtx);
11075 return "add{q}\t%0, %0";
11078 if (REG_P (operands[2]))
11079 return "sal{q}\t{%b2, %0|%0, %b2}";
11080 else if (operands[2] == const1_rtx
11081 && (TARGET_SHIFT1 || optimize_size))
11082 return "sal{q}\t%0";
11084 return "sal{q}\t{%2, %0|%0, %2}";
11087 [(set (attr "type")
11088 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11090 (match_operand 0 "register_operand" ""))
11091 (match_operand 2 "const1_operand" ""))
11092 (const_string "alu")
11094 (const_string "ishift")))
11095 (set_attr "mode" "DI")])
11097 (define_insn "*ashldi3_cconly_rex64"
11098 [(set (reg FLAGS_REG)
11100 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11101 (match_operand:QI 2 "immediate_operand" "e"))
11103 (clobber (match_scratch:DI 0 "=r"))]
11106 || !TARGET_PARTIAL_FLAG_REG_STALL
11107 || (operands[2] == const1_rtx
11109 || TARGET_DOUBLE_WITH_ADD)))
11110 && ix86_match_ccmode (insn, CCGOCmode)
11111 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11113 switch (get_attr_type (insn))
11116 gcc_assert (operands[2] == const1_rtx);
11117 return "add{q}\t%0, %0";
11120 if (REG_P (operands[2]))
11121 return "sal{q}\t{%b2, %0|%0, %b2}";
11122 else if (operands[2] == const1_rtx
11123 && (TARGET_SHIFT1 || optimize_size))
11124 return "sal{q}\t%0";
11126 return "sal{q}\t{%2, %0|%0, %2}";
11129 [(set (attr "type")
11130 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11132 (match_operand 0 "register_operand" ""))
11133 (match_operand 2 "const1_operand" ""))
11134 (const_string "alu")
11136 (const_string "ishift")))
11137 (set_attr "mode" "DI")])
11139 (define_insn "*ashldi3_1"
11140 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11141 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11142 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11143 (clobber (reg:CC FLAGS_REG))]
11146 [(set_attr "type" "multi")])
11148 ;; By default we don't ask for a scratch register, because when DImode
11149 ;; values are manipulated, registers are already at a premium. But if
11150 ;; we have one handy, we won't turn it away.
11152 [(match_scratch:SI 3 "r")
11153 (parallel [(set (match_operand:DI 0 "register_operand" "")
11154 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11155 (match_operand:QI 2 "nonmemory_operand" "")))
11156 (clobber (reg:CC FLAGS_REG))])
11158 "!TARGET_64BIT && TARGET_CMOVE"
11160 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11163 [(set (match_operand:DI 0 "register_operand" "")
11164 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11165 (match_operand:QI 2 "nonmemory_operand" "")))
11166 (clobber (reg:CC FLAGS_REG))]
11167 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11168 ? epilogue_completed : reload_completed)"
11170 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11172 (define_insn "x86_shld_1"
11173 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11174 (ior:SI (ashift:SI (match_dup 0)
11175 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11176 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11177 (minus:QI (const_int 32) (match_dup 2)))))
11178 (clobber (reg:CC FLAGS_REG))]
11181 shld{l}\t{%2, %1, %0|%0, %1, %2}
11182 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11183 [(set_attr "type" "ishift")
11184 (set_attr "prefix_0f" "1")
11185 (set_attr "mode" "SI")
11186 (set_attr "pent_pair" "np")
11187 (set_attr "athlon_decode" "vector")
11188 (set_attr "amdfam10_decode" "vector")])
11190 (define_expand "x86_shift_adj_1"
11191 [(set (reg:CCZ FLAGS_REG)
11192 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11195 (set (match_operand:SI 0 "register_operand" "")
11196 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11197 (match_operand:SI 1 "register_operand" "")
11200 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11201 (match_operand:SI 3 "register_operand" "r")
11206 (define_expand "x86_shift_adj_2"
11207 [(use (match_operand:SI 0 "register_operand" ""))
11208 (use (match_operand:SI 1 "register_operand" ""))
11209 (use (match_operand:QI 2 "register_operand" ""))]
11212 rtx label = gen_label_rtx ();
11215 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11217 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11218 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11219 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11220 gen_rtx_LABEL_REF (VOIDmode, label),
11222 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11223 JUMP_LABEL (tmp) = label;
11225 emit_move_insn (operands[0], operands[1]);
11226 ix86_expand_clear (operands[1]);
11228 emit_label (label);
11229 LABEL_NUSES (label) = 1;
11234 (define_expand "ashlsi3"
11235 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11236 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11237 (match_operand:QI 2 "nonmemory_operand" "")))
11238 (clobber (reg:CC FLAGS_REG))]
11240 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11242 (define_insn "*ashlsi3_1"
11243 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11244 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11245 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11246 (clobber (reg:CC FLAGS_REG))]
11247 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11249 switch (get_attr_type (insn))
11252 gcc_assert (operands[2] == const1_rtx);
11253 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11254 return "add{l}\t%0, %0";
11260 if (REG_P (operands[2]))
11261 return "sal{l}\t{%b2, %0|%0, %b2}";
11262 else if (operands[2] == const1_rtx
11263 && (TARGET_SHIFT1 || optimize_size))
11264 return "sal{l}\t%0";
11266 return "sal{l}\t{%2, %0|%0, %2}";
11269 [(set (attr "type")
11270 (cond [(eq_attr "alternative" "1")
11271 (const_string "lea")
11272 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11274 (match_operand 0 "register_operand" ""))
11275 (match_operand 2 "const1_operand" ""))
11276 (const_string "alu")
11278 (const_string "ishift")))
11279 (set_attr "mode" "SI")])
11281 ;; Convert lea to the lea pattern to avoid flags dependency.
11283 [(set (match_operand 0 "register_operand" "")
11284 (ashift (match_operand 1 "index_register_operand" "")
11285 (match_operand:QI 2 "const_int_operand" "")))
11286 (clobber (reg:CC FLAGS_REG))]
11288 && true_regnum (operands[0]) != true_regnum (operands[1])
11289 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11293 enum machine_mode mode = GET_MODE (operands[0]);
11295 if (GET_MODE_SIZE (mode) < 4)
11296 operands[0] = gen_lowpart (SImode, operands[0]);
11298 operands[1] = gen_lowpart (Pmode, operands[1]);
11299 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11301 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11302 if (Pmode != SImode)
11303 pat = gen_rtx_SUBREG (SImode, pat, 0);
11304 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11308 ;; Rare case of shifting RSP is handled by generating move and shift
11310 [(set (match_operand 0 "register_operand" "")
11311 (ashift (match_operand 1 "register_operand" "")
11312 (match_operand:QI 2 "const_int_operand" "")))
11313 (clobber (reg:CC FLAGS_REG))]
11315 && true_regnum (operands[0]) != true_regnum (operands[1])"
11319 emit_move_insn (operands[0], operands[1]);
11320 pat = gen_rtx_SET (VOIDmode, operands[0],
11321 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11322 operands[0], operands[2]));
11323 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11324 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11328 (define_insn "*ashlsi3_1_zext"
11329 [(set (match_operand:DI 0 "register_operand" "=r,r")
11330 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11331 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11332 (clobber (reg:CC FLAGS_REG))]
11333 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11335 switch (get_attr_type (insn))
11338 gcc_assert (operands[2] == const1_rtx);
11339 return "add{l}\t%k0, %k0";
11345 if (REG_P (operands[2]))
11346 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11347 else if (operands[2] == const1_rtx
11348 && (TARGET_SHIFT1 || optimize_size))
11349 return "sal{l}\t%k0";
11351 return "sal{l}\t{%2, %k0|%k0, %2}";
11354 [(set (attr "type")
11355 (cond [(eq_attr "alternative" "1")
11356 (const_string "lea")
11357 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11359 (match_operand 2 "const1_operand" ""))
11360 (const_string "alu")
11362 (const_string "ishift")))
11363 (set_attr "mode" "SI")])
11365 ;; Convert lea to the lea pattern to avoid flags dependency.
11367 [(set (match_operand:DI 0 "register_operand" "")
11368 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11369 (match_operand:QI 2 "const_int_operand" ""))))
11370 (clobber (reg:CC FLAGS_REG))]
11371 "TARGET_64BIT && reload_completed
11372 && true_regnum (operands[0]) != true_regnum (operands[1])"
11373 [(set (match_dup 0) (zero_extend:DI
11374 (subreg:SI (mult:SI (match_dup 1)
11375 (match_dup 2)) 0)))]
11377 operands[1] = gen_lowpart (Pmode, operands[1]);
11378 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11381 ;; This pattern can't accept a variable shift count, since shifts by
11382 ;; zero don't affect the flags. We assume that shifts by constant
11383 ;; zero are optimized away.
11384 (define_insn "*ashlsi3_cmp"
11385 [(set (reg FLAGS_REG)
11387 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11388 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11390 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11391 (ashift:SI (match_dup 1) (match_dup 2)))]
11393 || !TARGET_PARTIAL_FLAG_REG_STALL
11394 || (operands[2] == const1_rtx
11396 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11397 && ix86_match_ccmode (insn, CCGOCmode)
11398 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11400 switch (get_attr_type (insn))
11403 gcc_assert (operands[2] == const1_rtx);
11404 return "add{l}\t%0, %0";
11407 if (REG_P (operands[2]))
11408 return "sal{l}\t{%b2, %0|%0, %b2}";
11409 else if (operands[2] == const1_rtx
11410 && (TARGET_SHIFT1 || optimize_size))
11411 return "sal{l}\t%0";
11413 return "sal{l}\t{%2, %0|%0, %2}";
11416 [(set (attr "type")
11417 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11419 (match_operand 0 "register_operand" ""))
11420 (match_operand 2 "const1_operand" ""))
11421 (const_string "alu")
11423 (const_string "ishift")))
11424 (set_attr "mode" "SI")])
11426 (define_insn "*ashlsi3_cconly"
11427 [(set (reg FLAGS_REG)
11429 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11430 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11432 (clobber (match_scratch:SI 0 "=r"))]
11434 || !TARGET_PARTIAL_FLAG_REG_STALL
11435 || (operands[2] == const1_rtx
11437 || TARGET_DOUBLE_WITH_ADD)))
11438 && ix86_match_ccmode (insn, CCGOCmode)
11439 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11441 switch (get_attr_type (insn))
11444 gcc_assert (operands[2] == const1_rtx);
11445 return "add{l}\t%0, %0";
11448 if (REG_P (operands[2]))
11449 return "sal{l}\t{%b2, %0|%0, %b2}";
11450 else if (operands[2] == const1_rtx
11451 && (TARGET_SHIFT1 || optimize_size))
11452 return "sal{l}\t%0";
11454 return "sal{l}\t{%2, %0|%0, %2}";
11457 [(set (attr "type")
11458 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11460 (match_operand 0 "register_operand" ""))
11461 (match_operand 2 "const1_operand" ""))
11462 (const_string "alu")
11464 (const_string "ishift")))
11465 (set_attr "mode" "SI")])
11467 (define_insn "*ashlsi3_cmp_zext"
11468 [(set (reg FLAGS_REG)
11470 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11471 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11473 (set (match_operand:DI 0 "register_operand" "=r")
11474 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11477 || !TARGET_PARTIAL_FLAG_REG_STALL
11478 || (operands[2] == const1_rtx
11480 || TARGET_DOUBLE_WITH_ADD)))
11481 && ix86_match_ccmode (insn, CCGOCmode)
11482 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11484 switch (get_attr_type (insn))
11487 gcc_assert (operands[2] == const1_rtx);
11488 return "add{l}\t%k0, %k0";
11491 if (REG_P (operands[2]))
11492 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11493 else if (operands[2] == const1_rtx
11494 && (TARGET_SHIFT1 || optimize_size))
11495 return "sal{l}\t%k0";
11497 return "sal{l}\t{%2, %k0|%k0, %2}";
11500 [(set (attr "type")
11501 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11503 (match_operand 2 "const1_operand" ""))
11504 (const_string "alu")
11506 (const_string "ishift")))
11507 (set_attr "mode" "SI")])
11509 (define_expand "ashlhi3"
11510 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11511 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11512 (match_operand:QI 2 "nonmemory_operand" "")))
11513 (clobber (reg:CC FLAGS_REG))]
11514 "TARGET_HIMODE_MATH"
11515 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11517 (define_insn "*ashlhi3_1_lea"
11518 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11519 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11520 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11521 (clobber (reg:CC FLAGS_REG))]
11522 "!TARGET_PARTIAL_REG_STALL
11523 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11525 switch (get_attr_type (insn))
11530 gcc_assert (operands[2] == const1_rtx);
11531 return "add{w}\t%0, %0";
11534 if (REG_P (operands[2]))
11535 return "sal{w}\t{%b2, %0|%0, %b2}";
11536 else if (operands[2] == const1_rtx
11537 && (TARGET_SHIFT1 || optimize_size))
11538 return "sal{w}\t%0";
11540 return "sal{w}\t{%2, %0|%0, %2}";
11543 [(set (attr "type")
11544 (cond [(eq_attr "alternative" "1")
11545 (const_string "lea")
11546 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11548 (match_operand 0 "register_operand" ""))
11549 (match_operand 2 "const1_operand" ""))
11550 (const_string "alu")
11552 (const_string "ishift")))
11553 (set_attr "mode" "HI,SI")])
11555 (define_insn "*ashlhi3_1"
11556 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11557 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11558 (match_operand:QI 2 "nonmemory_operand" "cI")))
11559 (clobber (reg:CC FLAGS_REG))]
11560 "TARGET_PARTIAL_REG_STALL
11561 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11563 switch (get_attr_type (insn))
11566 gcc_assert (operands[2] == const1_rtx);
11567 return "add{w}\t%0, %0";
11570 if (REG_P (operands[2]))
11571 return "sal{w}\t{%b2, %0|%0, %b2}";
11572 else if (operands[2] == const1_rtx
11573 && (TARGET_SHIFT1 || optimize_size))
11574 return "sal{w}\t%0";
11576 return "sal{w}\t{%2, %0|%0, %2}";
11579 [(set (attr "type")
11580 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11582 (match_operand 0 "register_operand" ""))
11583 (match_operand 2 "const1_operand" ""))
11584 (const_string "alu")
11586 (const_string "ishift")))
11587 (set_attr "mode" "HI")])
11589 ;; This pattern can't accept a variable shift count, since shifts by
11590 ;; zero don't affect the flags. We assume that shifts by constant
11591 ;; zero are optimized away.
11592 (define_insn "*ashlhi3_cmp"
11593 [(set (reg FLAGS_REG)
11595 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11596 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11598 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11599 (ashift:HI (match_dup 1) (match_dup 2)))]
11601 || !TARGET_PARTIAL_FLAG_REG_STALL
11602 || (operands[2] == const1_rtx
11604 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11605 && ix86_match_ccmode (insn, CCGOCmode)
11606 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11608 switch (get_attr_type (insn))
11611 gcc_assert (operands[2] == const1_rtx);
11612 return "add{w}\t%0, %0";
11615 if (REG_P (operands[2]))
11616 return "sal{w}\t{%b2, %0|%0, %b2}";
11617 else if (operands[2] == const1_rtx
11618 && (TARGET_SHIFT1 || optimize_size))
11619 return "sal{w}\t%0";
11621 return "sal{w}\t{%2, %0|%0, %2}";
11624 [(set (attr "type")
11625 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11627 (match_operand 0 "register_operand" ""))
11628 (match_operand 2 "const1_operand" ""))
11629 (const_string "alu")
11631 (const_string "ishift")))
11632 (set_attr "mode" "HI")])
11634 (define_insn "*ashlhi3_cconly"
11635 [(set (reg FLAGS_REG)
11637 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11638 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11640 (clobber (match_scratch:HI 0 "=r"))]
11642 || !TARGET_PARTIAL_FLAG_REG_STALL
11643 || (operands[2] == const1_rtx
11645 || TARGET_DOUBLE_WITH_ADD)))
11646 && ix86_match_ccmode (insn, CCGOCmode)
11647 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11649 switch (get_attr_type (insn))
11652 gcc_assert (operands[2] == const1_rtx);
11653 return "add{w}\t%0, %0";
11656 if (REG_P (operands[2]))
11657 return "sal{w}\t{%b2, %0|%0, %b2}";
11658 else if (operands[2] == const1_rtx
11659 && (TARGET_SHIFT1 || optimize_size))
11660 return "sal{w}\t%0";
11662 return "sal{w}\t{%2, %0|%0, %2}";
11665 [(set (attr "type")
11666 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11668 (match_operand 0 "register_operand" ""))
11669 (match_operand 2 "const1_operand" ""))
11670 (const_string "alu")
11672 (const_string "ishift")))
11673 (set_attr "mode" "HI")])
11675 (define_expand "ashlqi3"
11676 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11677 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11678 (match_operand:QI 2 "nonmemory_operand" "")))
11679 (clobber (reg:CC FLAGS_REG))]
11680 "TARGET_QIMODE_MATH"
11681 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11683 ;; %%% Potential partial reg stall on alternative 2. What to do?
11685 (define_insn "*ashlqi3_1_lea"
11686 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11687 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11688 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11689 (clobber (reg:CC FLAGS_REG))]
11690 "!TARGET_PARTIAL_REG_STALL
11691 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11693 switch (get_attr_type (insn))
11698 gcc_assert (operands[2] == const1_rtx);
11699 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11700 return "add{l}\t%k0, %k0";
11702 return "add{b}\t%0, %0";
11705 if (REG_P (operands[2]))
11707 if (get_attr_mode (insn) == MODE_SI)
11708 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11710 return "sal{b}\t{%b2, %0|%0, %b2}";
11712 else if (operands[2] == const1_rtx
11713 && (TARGET_SHIFT1 || optimize_size))
11715 if (get_attr_mode (insn) == MODE_SI)
11716 return "sal{l}\t%0";
11718 return "sal{b}\t%0";
11722 if (get_attr_mode (insn) == MODE_SI)
11723 return "sal{l}\t{%2, %k0|%k0, %2}";
11725 return "sal{b}\t{%2, %0|%0, %2}";
11729 [(set (attr "type")
11730 (cond [(eq_attr "alternative" "2")
11731 (const_string "lea")
11732 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11734 (match_operand 0 "register_operand" ""))
11735 (match_operand 2 "const1_operand" ""))
11736 (const_string "alu")
11738 (const_string "ishift")))
11739 (set_attr "mode" "QI,SI,SI")])
11741 (define_insn "*ashlqi3_1"
11742 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11743 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11744 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11745 (clobber (reg:CC FLAGS_REG))]
11746 "TARGET_PARTIAL_REG_STALL
11747 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11749 switch (get_attr_type (insn))
11752 gcc_assert (operands[2] == const1_rtx);
11753 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11754 return "add{l}\t%k0, %k0";
11756 return "add{b}\t%0, %0";
11759 if (REG_P (operands[2]))
11761 if (get_attr_mode (insn) == MODE_SI)
11762 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11764 return "sal{b}\t{%b2, %0|%0, %b2}";
11766 else if (operands[2] == const1_rtx
11767 && (TARGET_SHIFT1 || optimize_size))
11769 if (get_attr_mode (insn) == MODE_SI)
11770 return "sal{l}\t%0";
11772 return "sal{b}\t%0";
11776 if (get_attr_mode (insn) == MODE_SI)
11777 return "sal{l}\t{%2, %k0|%k0, %2}";
11779 return "sal{b}\t{%2, %0|%0, %2}";
11783 [(set (attr "type")
11784 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11786 (match_operand 0 "register_operand" ""))
11787 (match_operand 2 "const1_operand" ""))
11788 (const_string "alu")
11790 (const_string "ishift")))
11791 (set_attr "mode" "QI,SI")])
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags. We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashlqi3_cmp"
11797 [(set (reg FLAGS_REG)
11799 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11800 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11802 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11803 (ashift:QI (match_dup 1) (match_dup 2)))]
11805 || !TARGET_PARTIAL_FLAG_REG_STALL
11806 || (operands[2] == const1_rtx
11808 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11809 && ix86_match_ccmode (insn, CCGOCmode)
11810 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11812 switch (get_attr_type (insn))
11815 gcc_assert (operands[2] == const1_rtx);
11816 return "add{b}\t%0, %0";
11819 if (REG_P (operands[2]))
11820 return "sal{b}\t{%b2, %0|%0, %b2}";
11821 else if (operands[2] == const1_rtx
11822 && (TARGET_SHIFT1 || optimize_size))
11823 return "sal{b}\t%0";
11825 return "sal{b}\t{%2, %0|%0, %2}";
11828 [(set (attr "type")
11829 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11831 (match_operand 0 "register_operand" ""))
11832 (match_operand 2 "const1_operand" ""))
11833 (const_string "alu")
11835 (const_string "ishift")))
11836 (set_attr "mode" "QI")])
11838 (define_insn "*ashlqi3_cconly"
11839 [(set (reg FLAGS_REG)
11841 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11842 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11844 (clobber (match_scratch:QI 0 "=q"))]
11846 || !TARGET_PARTIAL_FLAG_REG_STALL
11847 || (operands[2] == const1_rtx
11849 || TARGET_DOUBLE_WITH_ADD)))
11850 && ix86_match_ccmode (insn, CCGOCmode)
11851 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11853 switch (get_attr_type (insn))
11856 gcc_assert (operands[2] == const1_rtx);
11857 return "add{b}\t%0, %0";
11860 if (REG_P (operands[2]))
11861 return "sal{b}\t{%b2, %0|%0, %b2}";
11862 else if (operands[2] == const1_rtx
11863 && (TARGET_SHIFT1 || optimize_size))
11864 return "sal{b}\t%0";
11866 return "sal{b}\t{%2, %0|%0, %2}";
11869 [(set (attr "type")
11870 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11872 (match_operand 0 "register_operand" ""))
11873 (match_operand 2 "const1_operand" ""))
11874 (const_string "alu")
11876 (const_string "ishift")))
11877 (set_attr "mode" "QI")])
11879 ;; See comment above `ashldi3' about how this works.
11881 (define_expand "ashrti3"
11882 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11883 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11884 (match_operand:QI 2 "nonmemory_operand" "")))
11885 (clobber (reg:CC FLAGS_REG))])]
11888 if (! immediate_operand (operands[2], QImode))
11890 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11893 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11897 (define_insn "ashrti3_1"
11898 [(set (match_operand:TI 0 "register_operand" "=r")
11899 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11900 (match_operand:QI 2 "register_operand" "c")))
11901 (clobber (match_scratch:DI 3 "=&r"))
11902 (clobber (reg:CC FLAGS_REG))]
11905 [(set_attr "type" "multi")])
11907 (define_insn "*ashrti3_2"
11908 [(set (match_operand:TI 0 "register_operand" "=r")
11909 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11910 (match_operand:QI 2 "immediate_operand" "O")))
11911 (clobber (reg:CC FLAGS_REG))]
11914 [(set_attr "type" "multi")])
11917 [(set (match_operand:TI 0 "register_operand" "")
11918 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11919 (match_operand:QI 2 "register_operand" "")))
11920 (clobber (match_scratch:DI 3 ""))
11921 (clobber (reg:CC FLAGS_REG))]
11922 "TARGET_64BIT && reload_completed"
11924 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11927 [(set (match_operand:TI 0 "register_operand" "")
11928 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11929 (match_operand:QI 2 "immediate_operand" "")))
11930 (clobber (reg:CC FLAGS_REG))]
11931 "TARGET_64BIT && reload_completed"
11933 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11935 (define_insn "x86_64_shrd"
11936 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11937 (ior:DI (ashiftrt:DI (match_dup 0)
11938 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11939 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11940 (minus:QI (const_int 64) (match_dup 2)))))
11941 (clobber (reg:CC FLAGS_REG))]
11944 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11945 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11946 [(set_attr "type" "ishift")
11947 (set_attr "prefix_0f" "1")
11948 (set_attr "mode" "DI")
11949 (set_attr "athlon_decode" "vector")
11950 (set_attr "amdfam10_decode" "vector")])
11952 (define_expand "ashrdi3"
11953 [(set (match_operand:DI 0 "shiftdi_operand" "")
11954 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11955 (match_operand:QI 2 "nonmemory_operand" "")))]
11957 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11959 (define_insn "*ashrdi3_63_rex64"
11960 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11961 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11962 (match_operand:DI 2 "const_int_operand" "i,i")))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "TARGET_64BIT && INTVAL (operands[2]) == 63
11965 && (TARGET_USE_CLTD || optimize_size)
11966 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11969 sar{q}\t{%2, %0|%0, %2}"
11970 [(set_attr "type" "imovx,ishift")
11971 (set_attr "prefix_0f" "0,*")
11972 (set_attr "length_immediate" "0,*")
11973 (set_attr "modrm" "0,1")
11974 (set_attr "mode" "DI")])
11976 (define_insn "*ashrdi3_1_one_bit_rex64"
11977 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11978 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11979 (match_operand:QI 2 "const1_operand" "")))
11980 (clobber (reg:CC FLAGS_REG))]
11982 && (TARGET_SHIFT1 || optimize_size)
11983 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11985 [(set_attr "type" "ishift")
11986 (set (attr "length")
11987 (if_then_else (match_operand:DI 0 "register_operand" "")
11989 (const_string "*")))])
11991 (define_insn "*ashrdi3_1_rex64"
11992 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11993 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11994 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11995 (clobber (reg:CC FLAGS_REG))]
11996 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11998 sar{q}\t{%2, %0|%0, %2}
11999 sar{q}\t{%b2, %0|%0, %b2}"
12000 [(set_attr "type" "ishift")
12001 (set_attr "mode" "DI")])
12003 ;; This pattern can't accept a variable shift count, since shifts by
12004 ;; zero don't affect the flags. We assume that shifts by constant
12005 ;; zero are optimized away.
12006 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12007 [(set (reg FLAGS_REG)
12009 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12010 (match_operand:QI 2 "const1_operand" ""))
12012 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12013 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12015 && (TARGET_SHIFT1 || optimize_size)
12016 && ix86_match_ccmode (insn, CCGOCmode)
12017 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12019 [(set_attr "type" "ishift")
12020 (set (attr "length")
12021 (if_then_else (match_operand:DI 0 "register_operand" "")
12023 (const_string "*")))])
12025 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12026 [(set (reg FLAGS_REG)
12028 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12029 (match_operand:QI 2 "const1_operand" ""))
12031 (clobber (match_scratch:DI 0 "=r"))]
12033 && (TARGET_SHIFT1 || optimize_size)
12034 && ix86_match_ccmode (insn, CCGOCmode)
12035 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12037 [(set_attr "type" "ishift")
12038 (set_attr "length" "2")])
12040 ;; This pattern can't accept a variable shift count, since shifts by
12041 ;; zero don't affect the flags. We assume that shifts by constant
12042 ;; zero are optimized away.
12043 (define_insn "*ashrdi3_cmp_rex64"
12044 [(set (reg FLAGS_REG)
12046 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12047 (match_operand:QI 2 "const_int_operand" "n"))
12049 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12050 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12052 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12053 && ix86_match_ccmode (insn, CCGOCmode)
12054 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12055 "sar{q}\t{%2, %0|%0, %2}"
12056 [(set_attr "type" "ishift")
12057 (set_attr "mode" "DI")])
12059 (define_insn "*ashrdi3_cconly_rex64"
12060 [(set (reg FLAGS_REG)
12062 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12063 (match_operand:QI 2 "const_int_operand" "n"))
12065 (clobber (match_scratch:DI 0 "=r"))]
12067 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12068 && ix86_match_ccmode (insn, CCGOCmode)
12069 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12070 "sar{q}\t{%2, %0|%0, %2}"
12071 [(set_attr "type" "ishift")
12072 (set_attr "mode" "DI")])
12074 (define_insn "*ashrdi3_1"
12075 [(set (match_operand:DI 0 "register_operand" "=r")
12076 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12077 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12078 (clobber (reg:CC FLAGS_REG))]
12081 [(set_attr "type" "multi")])
12083 ;; By default we don't ask for a scratch register, because when DImode
12084 ;; values are manipulated, registers are already at a premium. But if
12085 ;; we have one handy, we won't turn it away.
12087 [(match_scratch:SI 3 "r")
12088 (parallel [(set (match_operand:DI 0 "register_operand" "")
12089 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12090 (match_operand:QI 2 "nonmemory_operand" "")))
12091 (clobber (reg:CC FLAGS_REG))])
12093 "!TARGET_64BIT && TARGET_CMOVE"
12095 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12098 [(set (match_operand:DI 0 "register_operand" "")
12099 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12100 (match_operand:QI 2 "nonmemory_operand" "")))
12101 (clobber (reg:CC FLAGS_REG))]
12102 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12103 ? epilogue_completed : reload_completed)"
12105 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12107 (define_insn "x86_shrd_1"
12108 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12109 (ior:SI (ashiftrt:SI (match_dup 0)
12110 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12111 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12112 (minus:QI (const_int 32) (match_dup 2)))))
12113 (clobber (reg:CC FLAGS_REG))]
12116 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12117 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12118 [(set_attr "type" "ishift")
12119 (set_attr "prefix_0f" "1")
12120 (set_attr "pent_pair" "np")
12121 (set_attr "mode" "SI")])
12123 (define_expand "x86_shift_adj_3"
12124 [(use (match_operand:SI 0 "register_operand" ""))
12125 (use (match_operand:SI 1 "register_operand" ""))
12126 (use (match_operand:QI 2 "register_operand" ""))]
12129 rtx label = gen_label_rtx ();
12132 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12134 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12135 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12136 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12137 gen_rtx_LABEL_REF (VOIDmode, label),
12139 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12140 JUMP_LABEL (tmp) = label;
12142 emit_move_insn (operands[0], operands[1]);
12143 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12145 emit_label (label);
12146 LABEL_NUSES (label) = 1;
12151 (define_insn "ashrsi3_31"
12152 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12153 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12154 (match_operand:SI 2 "const_int_operand" "i,i")))
12155 (clobber (reg:CC FLAGS_REG))]
12156 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12157 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12160 sar{l}\t{%2, %0|%0, %2}"
12161 [(set_attr "type" "imovx,ishift")
12162 (set_attr "prefix_0f" "0,*")
12163 (set_attr "length_immediate" "0,*")
12164 (set_attr "modrm" "0,1")
12165 (set_attr "mode" "SI")])
12167 (define_insn "*ashrsi3_31_zext"
12168 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12169 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12170 (match_operand:SI 2 "const_int_operand" "i,i"))))
12171 (clobber (reg:CC FLAGS_REG))]
12172 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12173 && INTVAL (operands[2]) == 31
12174 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12177 sar{l}\t{%2, %k0|%k0, %2}"
12178 [(set_attr "type" "imovx,ishift")
12179 (set_attr "prefix_0f" "0,*")
12180 (set_attr "length_immediate" "0,*")
12181 (set_attr "modrm" "0,1")
12182 (set_attr "mode" "SI")])
12184 (define_expand "ashrsi3"
12185 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12186 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12187 (match_operand:QI 2 "nonmemory_operand" "")))
12188 (clobber (reg:CC FLAGS_REG))]
12190 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12192 (define_insn "*ashrsi3_1_one_bit"
12193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12194 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12195 (match_operand:QI 2 "const1_operand" "")))
12196 (clobber (reg:CC FLAGS_REG))]
12197 "(TARGET_SHIFT1 || optimize_size)
12198 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12200 [(set_attr "type" "ishift")
12201 (set (attr "length")
12202 (if_then_else (match_operand:SI 0 "register_operand" "")
12204 (const_string "*")))])
12206 (define_insn "*ashrsi3_1_one_bit_zext"
12207 [(set (match_operand:DI 0 "register_operand" "=r")
12208 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12209 (match_operand:QI 2 "const1_operand" ""))))
12210 (clobber (reg:CC FLAGS_REG))]
12212 && (TARGET_SHIFT1 || optimize_size)
12213 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12215 [(set_attr "type" "ishift")
12216 (set_attr "length" "2")])
12218 (define_insn "*ashrsi3_1"
12219 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12220 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12221 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12222 (clobber (reg:CC FLAGS_REG))]
12223 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12225 sar{l}\t{%2, %0|%0, %2}
12226 sar{l}\t{%b2, %0|%0, %b2}"
12227 [(set_attr "type" "ishift")
12228 (set_attr "mode" "SI")])
12230 (define_insn "*ashrsi3_1_zext"
12231 [(set (match_operand:DI 0 "register_operand" "=r,r")
12232 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12233 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12234 (clobber (reg:CC FLAGS_REG))]
12235 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12237 sar{l}\t{%2, %k0|%k0, %2}
12238 sar{l}\t{%b2, %k0|%k0, %b2}"
12239 [(set_attr "type" "ishift")
12240 (set_attr "mode" "SI")])
12242 ;; This pattern can't accept a variable shift count, since shifts by
12243 ;; zero don't affect the flags. We assume that shifts by constant
12244 ;; zero are optimized away.
12245 (define_insn "*ashrsi3_one_bit_cmp"
12246 [(set (reg FLAGS_REG)
12248 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12249 (match_operand:QI 2 "const1_operand" ""))
12251 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12252 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12253 "(TARGET_SHIFT1 || optimize_size)
12254 && ix86_match_ccmode (insn, CCGOCmode)
12255 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12257 [(set_attr "type" "ishift")
12258 (set (attr "length")
12259 (if_then_else (match_operand:SI 0 "register_operand" "")
12261 (const_string "*")))])
12263 (define_insn "*ashrsi3_one_bit_cconly"
12264 [(set (reg FLAGS_REG)
12266 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const1_operand" ""))
12269 (clobber (match_scratch:SI 0 "=r"))]
12270 "(TARGET_SHIFT1 || optimize_size)
12271 && ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12274 [(set_attr "type" "ishift")
12275 (set_attr "length" "2")])
12277 (define_insn "*ashrsi3_one_bit_cmp_zext"
12278 [(set (reg FLAGS_REG)
12280 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12281 (match_operand:QI 2 "const1_operand" ""))
12283 (set (match_operand:DI 0 "register_operand" "=r")
12284 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12286 && (TARGET_SHIFT1 || optimize_size)
12287 && ix86_match_ccmode (insn, CCmode)
12288 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12290 [(set_attr "type" "ishift")
12291 (set_attr "length" "2")])
12293 ;; This pattern can't accept a variable shift count, since shifts by
12294 ;; zero don't affect the flags. We assume that shifts by constant
12295 ;; zero are optimized away.
12296 (define_insn "*ashrsi3_cmp"
12297 [(set (reg FLAGS_REG)
12299 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12300 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12302 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12303 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12304 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12305 && ix86_match_ccmode (insn, CCGOCmode)
12306 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12307 "sar{l}\t{%2, %0|%0, %2}"
12308 [(set_attr "type" "ishift")
12309 (set_attr "mode" "SI")])
12311 (define_insn "*ashrsi3_cconly"
12312 [(set (reg FLAGS_REG)
12314 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12315 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12317 (clobber (match_scratch:SI 0 "=r"))]
12318 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12319 && ix86_match_ccmode (insn, CCGOCmode)
12320 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12321 "sar{l}\t{%2, %0|%0, %2}"
12322 [(set_attr "type" "ishift")
12323 (set_attr "mode" "SI")])
12325 (define_insn "*ashrsi3_cmp_zext"
12326 [(set (reg FLAGS_REG)
12328 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12329 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331 (set (match_operand:DI 0 "register_operand" "=r")
12332 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12334 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12335 && ix86_match_ccmode (insn, CCGOCmode)
12336 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12337 "sar{l}\t{%2, %k0|%k0, %2}"
12338 [(set_attr "type" "ishift")
12339 (set_attr "mode" "SI")])
12341 (define_expand "ashrhi3"
12342 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12343 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12344 (match_operand:QI 2 "nonmemory_operand" "")))
12345 (clobber (reg:CC FLAGS_REG))]
12346 "TARGET_HIMODE_MATH"
12347 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12349 (define_insn "*ashrhi3_1_one_bit"
12350 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12351 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12352 (match_operand:QI 2 "const1_operand" "")))
12353 (clobber (reg:CC FLAGS_REG))]
12354 "(TARGET_SHIFT1 || optimize_size)
12355 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12357 [(set_attr "type" "ishift")
12358 (set (attr "length")
12359 (if_then_else (match_operand 0 "register_operand" "")
12361 (const_string "*")))])
12363 (define_insn "*ashrhi3_1"
12364 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12365 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12366 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12367 (clobber (reg:CC FLAGS_REG))]
12368 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12370 sar{w}\t{%2, %0|%0, %2}
12371 sar{w}\t{%b2, %0|%0, %b2}"
12372 [(set_attr "type" "ishift")
12373 (set_attr "mode" "HI")])
12375 ;; This pattern can't accept a variable shift count, since shifts by
12376 ;; zero don't affect the flags. We assume that shifts by constant
12377 ;; zero are optimized away.
12378 (define_insn "*ashrhi3_one_bit_cmp"
12379 [(set (reg FLAGS_REG)
12381 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12382 (match_operand:QI 2 "const1_operand" ""))
12384 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12385 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12386 "(TARGET_SHIFT1 || optimize_size)
12387 && ix86_match_ccmode (insn, CCGOCmode)
12388 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12390 [(set_attr "type" "ishift")
12391 (set (attr "length")
12392 (if_then_else (match_operand 0 "register_operand" "")
12394 (const_string "*")))])
12396 (define_insn "*ashrhi3_one_bit_cconly"
12397 [(set (reg FLAGS_REG)
12399 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12400 (match_operand:QI 2 "const1_operand" ""))
12402 (clobber (match_scratch:HI 0 "=r"))]
12403 "(TARGET_SHIFT1 || optimize_size)
12404 && ix86_match_ccmode (insn, CCGOCmode)
12405 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12407 [(set_attr "type" "ishift")
12408 (set_attr "length" "2")])
12410 ;; This pattern can't accept a variable shift count, since shifts by
12411 ;; zero don't affect the flags. We assume that shifts by constant
12412 ;; zero are optimized away.
12413 (define_insn "*ashrhi3_cmp"
12414 [(set (reg FLAGS_REG)
12416 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12417 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12419 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12420 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12421 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12422 && ix86_match_ccmode (insn, CCGOCmode)
12423 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12424 "sar{w}\t{%2, %0|%0, %2}"
12425 [(set_attr "type" "ishift")
12426 (set_attr "mode" "HI")])
12428 (define_insn "*ashrhi3_cconly"
12429 [(set (reg FLAGS_REG)
12431 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12432 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12434 (clobber (match_scratch:HI 0 "=r"))]
12435 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12436 && ix86_match_ccmode (insn, CCGOCmode)
12437 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12438 "sar{w}\t{%2, %0|%0, %2}"
12439 [(set_attr "type" "ishift")
12440 (set_attr "mode" "HI")])
12442 (define_expand "ashrqi3"
12443 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12444 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12445 (match_operand:QI 2 "nonmemory_operand" "")))
12446 (clobber (reg:CC FLAGS_REG))]
12447 "TARGET_QIMODE_MATH"
12448 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12450 (define_insn "*ashrqi3_1_one_bit"
12451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12452 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12453 (match_operand:QI 2 "const1_operand" "")))
12454 (clobber (reg:CC FLAGS_REG))]
12455 "(TARGET_SHIFT1 || optimize_size)
12456 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12458 [(set_attr "type" "ishift")
12459 (set (attr "length")
12460 (if_then_else (match_operand 0 "register_operand" "")
12462 (const_string "*")))])
12464 (define_insn "*ashrqi3_1_one_bit_slp"
12465 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12466 (ashiftrt:QI (match_dup 0)
12467 (match_operand:QI 1 "const1_operand" "")))
12468 (clobber (reg:CC FLAGS_REG))]
12469 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12470 && (TARGET_SHIFT1 || optimize_size)
12471 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12473 [(set_attr "type" "ishift1")
12474 (set (attr "length")
12475 (if_then_else (match_operand 0 "register_operand" "")
12477 (const_string "*")))])
12479 (define_insn "*ashrqi3_1"
12480 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12481 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12482 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12483 (clobber (reg:CC FLAGS_REG))]
12484 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12486 sar{b}\t{%2, %0|%0, %2}
12487 sar{b}\t{%b2, %0|%0, %b2}"
12488 [(set_attr "type" "ishift")
12489 (set_attr "mode" "QI")])
12491 (define_insn "*ashrqi3_1_slp"
12492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12493 (ashiftrt:QI (match_dup 0)
12494 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12499 sar{b}\t{%1, %0|%0, %1}
12500 sar{b}\t{%b1, %0|%0, %b1}"
12501 [(set_attr "type" "ishift1")
12502 (set_attr "mode" "QI")])
12504 ;; This pattern can't accept a variable shift count, since shifts by
12505 ;; zero don't affect the flags. We assume that shifts by constant
12506 ;; zero are optimized away.
12507 (define_insn "*ashrqi3_one_bit_cmp"
12508 [(set (reg FLAGS_REG)
12510 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12511 (match_operand:QI 2 "const1_operand" "I"))
12513 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12514 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12515 "(TARGET_SHIFT1 || optimize_size)
12516 && ix86_match_ccmode (insn, CCGOCmode)
12517 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12519 [(set_attr "type" "ishift")
12520 (set (attr "length")
12521 (if_then_else (match_operand 0 "register_operand" "")
12523 (const_string "*")))])
12525 (define_insn "*ashrqi3_one_bit_cconly"
12526 [(set (reg FLAGS_REG)
12528 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12529 (match_operand:QI 2 "const1_operand" "I"))
12531 (clobber (match_scratch:QI 0 "=q"))]
12532 "(TARGET_SHIFT1 || optimize_size)
12533 && ix86_match_ccmode (insn, CCGOCmode)
12534 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12536 [(set_attr "type" "ishift")
12537 (set_attr "length" "2")])
12539 ;; This pattern can't accept a variable shift count, since shifts by
12540 ;; zero don't affect the flags. We assume that shifts by constant
12541 ;; zero are optimized away.
12542 (define_insn "*ashrqi3_cmp"
12543 [(set (reg FLAGS_REG)
12545 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12546 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12548 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12549 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12550 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12551 && ix86_match_ccmode (insn, CCGOCmode)
12552 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12553 "sar{b}\t{%2, %0|%0, %2}"
12554 [(set_attr "type" "ishift")
12555 (set_attr "mode" "QI")])
12557 (define_insn "*ashrqi3_cconly"
12558 [(set (reg FLAGS_REG)
12560 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12561 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12563 (clobber (match_scratch:QI 0 "=q"))]
12564 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12565 && ix86_match_ccmode (insn, CCGOCmode)
12566 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12567 "sar{b}\t{%2, %0|%0, %2}"
12568 [(set_attr "type" "ishift")
12569 (set_attr "mode" "QI")])
12572 ;; Logical shift instructions
12574 ;; See comment above `ashldi3' about how this works.
12576 (define_expand "lshrti3"
12577 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12578 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12579 (match_operand:QI 2 "nonmemory_operand" "")))
12580 (clobber (reg:CC FLAGS_REG))])]
12583 if (! immediate_operand (operands[2], QImode))
12585 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12588 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12592 (define_insn "lshrti3_1"
12593 [(set (match_operand:TI 0 "register_operand" "=r")
12594 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12595 (match_operand:QI 2 "register_operand" "c")))
12596 (clobber (match_scratch:DI 3 "=&r"))
12597 (clobber (reg:CC FLAGS_REG))]
12600 [(set_attr "type" "multi")])
12602 ;; This pattern must be defined before *lshrti3_2 to prevent
12603 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12605 (define_insn "sse2_lshrti3"
12606 [(set (match_operand:TI 0 "register_operand" "=x")
12607 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12608 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12611 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12612 return "psrldq\t{%2, %0|%0, %2}";
12614 [(set_attr "type" "sseishft")
12615 (set_attr "prefix_data16" "1")
12616 (set_attr "mode" "TI")])
12618 (define_insn "*lshrti3_2"
12619 [(set (match_operand:TI 0 "register_operand" "=r")
12620 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12621 (match_operand:QI 2 "immediate_operand" "O")))
12622 (clobber (reg:CC FLAGS_REG))]
12625 [(set_attr "type" "multi")])
12628 [(set (match_operand:TI 0 "register_operand" "")
12629 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12630 (match_operand:QI 2 "register_operand" "")))
12631 (clobber (match_scratch:DI 3 ""))
12632 (clobber (reg:CC FLAGS_REG))]
12633 "TARGET_64BIT && reload_completed"
12635 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12638 [(set (match_operand:TI 0 "register_operand" "")
12639 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12640 (match_operand:QI 2 "immediate_operand" "")))
12641 (clobber (reg:CC FLAGS_REG))]
12642 "TARGET_64BIT && reload_completed"
12644 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12646 (define_expand "lshrdi3"
12647 [(set (match_operand:DI 0 "shiftdi_operand" "")
12648 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12649 (match_operand:QI 2 "nonmemory_operand" "")))]
12651 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12653 (define_insn "*lshrdi3_1_one_bit_rex64"
12654 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12655 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12656 (match_operand:QI 2 "const1_operand" "")))
12657 (clobber (reg:CC FLAGS_REG))]
12659 && (TARGET_SHIFT1 || optimize_size)
12660 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12662 [(set_attr "type" "ishift")
12663 (set (attr "length")
12664 (if_then_else (match_operand:DI 0 "register_operand" "")
12666 (const_string "*")))])
12668 (define_insn "*lshrdi3_1_rex64"
12669 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12670 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12671 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12672 (clobber (reg:CC FLAGS_REG))]
12673 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12675 shr{q}\t{%2, %0|%0, %2}
12676 shr{q}\t{%b2, %0|%0, %b2}"
12677 [(set_attr "type" "ishift")
12678 (set_attr "mode" "DI")])
12680 ;; This pattern can't accept a variable shift count, since shifts by
12681 ;; zero don't affect the flags. We assume that shifts by constant
12682 ;; zero are optimized away.
12683 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12684 [(set (reg FLAGS_REG)
12686 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12687 (match_operand:QI 2 "const1_operand" ""))
12689 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12690 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12692 && (TARGET_SHIFT1 || optimize_size)
12693 && ix86_match_ccmode (insn, CCGOCmode)
12694 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12696 [(set_attr "type" "ishift")
12697 (set (attr "length")
12698 (if_then_else (match_operand:DI 0 "register_operand" "")
12700 (const_string "*")))])
12702 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12703 [(set (reg FLAGS_REG)
12705 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12706 (match_operand:QI 2 "const1_operand" ""))
12708 (clobber (match_scratch:DI 0 "=r"))]
12710 && (TARGET_SHIFT1 || optimize_size)
12711 && ix86_match_ccmode (insn, CCGOCmode)
12712 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12714 [(set_attr "type" "ishift")
12715 (set_attr "length" "2")])
12717 ;; This pattern can't accept a variable shift count, since shifts by
12718 ;; zero don't affect the flags. We assume that shifts by constant
12719 ;; zero are optimized away.
12720 (define_insn "*lshrdi3_cmp_rex64"
12721 [(set (reg FLAGS_REG)
12723 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12724 (match_operand:QI 2 "const_int_operand" "e"))
12726 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12727 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12729 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12730 && ix86_match_ccmode (insn, CCGOCmode)
12731 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12732 "shr{q}\t{%2, %0|%0, %2}"
12733 [(set_attr "type" "ishift")
12734 (set_attr "mode" "DI")])
12736 (define_insn "*lshrdi3_cconly_rex64"
12737 [(set (reg FLAGS_REG)
12739 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12740 (match_operand:QI 2 "const_int_operand" "e"))
12742 (clobber (match_scratch:DI 0 "=r"))]
12744 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12745 && ix86_match_ccmode (insn, CCGOCmode)
12746 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12747 "shr{q}\t{%2, %0|%0, %2}"
12748 [(set_attr "type" "ishift")
12749 (set_attr "mode" "DI")])
12751 (define_insn "*lshrdi3_1"
12752 [(set (match_operand:DI 0 "register_operand" "=r")
12753 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12754 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12755 (clobber (reg:CC FLAGS_REG))]
12758 [(set_attr "type" "multi")])
12760 ;; By default we don't ask for a scratch register, because when DImode
12761 ;; values are manipulated, registers are already at a premium. But if
12762 ;; we have one handy, we won't turn it away.
12764 [(match_scratch:SI 3 "r")
12765 (parallel [(set (match_operand:DI 0 "register_operand" "")
12766 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12767 (match_operand:QI 2 "nonmemory_operand" "")))
12768 (clobber (reg:CC FLAGS_REG))])
12770 "!TARGET_64BIT && TARGET_CMOVE"
12772 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12775 [(set (match_operand:DI 0 "register_operand" "")
12776 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12777 (match_operand:QI 2 "nonmemory_operand" "")))
12778 (clobber (reg:CC FLAGS_REG))]
12779 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12780 ? epilogue_completed : reload_completed)"
12782 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12784 (define_expand "lshrsi3"
12785 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12786 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12787 (match_operand:QI 2 "nonmemory_operand" "")))
12788 (clobber (reg:CC FLAGS_REG))]
12790 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12792 (define_insn "*lshrsi3_1_one_bit"
12793 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12794 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12795 (match_operand:QI 2 "const1_operand" "")))
12796 (clobber (reg:CC FLAGS_REG))]
12797 "(TARGET_SHIFT1 || optimize_size)
12798 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12800 [(set_attr "type" "ishift")
12801 (set (attr "length")
12802 (if_then_else (match_operand:SI 0 "register_operand" "")
12804 (const_string "*")))])
12806 (define_insn "*lshrsi3_1_one_bit_zext"
12807 [(set (match_operand:DI 0 "register_operand" "=r")
12808 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12809 (match_operand:QI 2 "const1_operand" "")))
12810 (clobber (reg:CC FLAGS_REG))]
12812 && (TARGET_SHIFT1 || optimize_size)
12813 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12815 [(set_attr "type" "ishift")
12816 (set_attr "length" "2")])
12818 (define_insn "*lshrsi3_1"
12819 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12820 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12821 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12822 (clobber (reg:CC FLAGS_REG))]
12823 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12825 shr{l}\t{%2, %0|%0, %2}
12826 shr{l}\t{%b2, %0|%0, %b2}"
12827 [(set_attr "type" "ishift")
12828 (set_attr "mode" "SI")])
12830 (define_insn "*lshrsi3_1_zext"
12831 [(set (match_operand:DI 0 "register_operand" "=r,r")
12833 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12834 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12835 (clobber (reg:CC FLAGS_REG))]
12836 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12838 shr{l}\t{%2, %k0|%k0, %2}
12839 shr{l}\t{%b2, %k0|%k0, %b2}"
12840 [(set_attr "type" "ishift")
12841 (set_attr "mode" "SI")])
12843 ;; This pattern can't accept a variable shift count, since shifts by
12844 ;; zero don't affect the flags. We assume that shifts by constant
12845 ;; zero are optimized away.
12846 (define_insn "*lshrsi3_one_bit_cmp"
12847 [(set (reg FLAGS_REG)
12849 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12850 (match_operand:QI 2 "const1_operand" ""))
12852 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12853 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12854 "(TARGET_SHIFT1 || optimize_size)
12855 && ix86_match_ccmode (insn, CCGOCmode)
12856 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12858 [(set_attr "type" "ishift")
12859 (set (attr "length")
12860 (if_then_else (match_operand:SI 0 "register_operand" "")
12862 (const_string "*")))])
12864 (define_insn "*lshrsi3_one_bit_cconly"
12865 [(set (reg FLAGS_REG)
12867 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12868 (match_operand:QI 2 "const1_operand" ""))
12870 (clobber (match_scratch:SI 0 "=r"))]
12871 "(TARGET_SHIFT1 || optimize_size)
12872 && ix86_match_ccmode (insn, CCGOCmode)
12873 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12875 [(set_attr "type" "ishift")
12876 (set_attr "length" "2")])
12878 (define_insn "*lshrsi3_cmp_one_bit_zext"
12879 [(set (reg FLAGS_REG)
12881 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12882 (match_operand:QI 2 "const1_operand" ""))
12884 (set (match_operand:DI 0 "register_operand" "=r")
12885 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12887 && (TARGET_SHIFT1 || optimize_size)
12888 && ix86_match_ccmode (insn, CCGOCmode)
12889 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12891 [(set_attr "type" "ishift")
12892 (set_attr "length" "2")])
12894 ;; This pattern can't accept a variable shift count, since shifts by
12895 ;; zero don't affect the flags. We assume that shifts by constant
12896 ;; zero are optimized away.
12897 (define_insn "*lshrsi3_cmp"
12898 [(set (reg FLAGS_REG)
12900 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12901 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12903 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12904 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12905 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12906 && ix86_match_ccmode (insn, CCGOCmode)
12907 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12908 "shr{l}\t{%2, %0|%0, %2}"
12909 [(set_attr "type" "ishift")
12910 (set_attr "mode" "SI")])
12912 (define_insn "*lshrsi3_cconly"
12913 [(set (reg FLAGS_REG)
12915 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12916 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12918 (clobber (match_scratch:SI 0 "=r"))]
12919 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12920 && ix86_match_ccmode (insn, CCGOCmode)
12921 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12922 "shr{l}\t{%2, %0|%0, %2}"
12923 [(set_attr "type" "ishift")
12924 (set_attr "mode" "SI")])
12926 (define_insn "*lshrsi3_cmp_zext"
12927 [(set (reg FLAGS_REG)
12929 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12930 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12932 (set (match_operand:DI 0 "register_operand" "=r")
12933 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12935 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12936 && ix86_match_ccmode (insn, CCGOCmode)
12937 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12938 "shr{l}\t{%2, %k0|%k0, %2}"
12939 [(set_attr "type" "ishift")
12940 (set_attr "mode" "SI")])
12942 (define_expand "lshrhi3"
12943 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12944 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12945 (match_operand:QI 2 "nonmemory_operand" "")))
12946 (clobber (reg:CC FLAGS_REG))]
12947 "TARGET_HIMODE_MATH"
12948 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12950 (define_insn "*lshrhi3_1_one_bit"
12951 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12952 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12953 (match_operand:QI 2 "const1_operand" "")))
12954 (clobber (reg:CC FLAGS_REG))]
12955 "(TARGET_SHIFT1 || optimize_size)
12956 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12958 [(set_attr "type" "ishift")
12959 (set (attr "length")
12960 (if_then_else (match_operand 0 "register_operand" "")
12962 (const_string "*")))])
12964 (define_insn "*lshrhi3_1"
12965 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12966 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12967 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12968 (clobber (reg:CC FLAGS_REG))]
12969 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12971 shr{w}\t{%2, %0|%0, %2}
12972 shr{w}\t{%b2, %0|%0, %b2}"
12973 [(set_attr "type" "ishift")
12974 (set_attr "mode" "HI")])
12976 ;; This pattern can't accept a variable shift count, since shifts by
12977 ;; zero don't affect the flags. We assume that shifts by constant
12978 ;; zero are optimized away.
12979 (define_insn "*lshrhi3_one_bit_cmp"
12980 [(set (reg FLAGS_REG)
12982 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12983 (match_operand:QI 2 "const1_operand" ""))
12985 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12986 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12987 "(TARGET_SHIFT1 || optimize_size)
12988 && ix86_match_ccmode (insn, CCGOCmode)
12989 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12991 [(set_attr "type" "ishift")
12992 (set (attr "length")
12993 (if_then_else (match_operand:SI 0 "register_operand" "")
12995 (const_string "*")))])
12997 (define_insn "*lshrhi3_one_bit_cconly"
12998 [(set (reg FLAGS_REG)
13000 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13001 (match_operand:QI 2 "const1_operand" ""))
13003 (clobber (match_scratch:HI 0 "=r"))]
13004 "(TARGET_SHIFT1 || optimize_size)
13005 && ix86_match_ccmode (insn, CCGOCmode)
13006 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13008 [(set_attr "type" "ishift")
13009 (set_attr "length" "2")])
13011 ;; This pattern can't accept a variable shift count, since shifts by
13012 ;; zero don't affect the flags. We assume that shifts by constant
13013 ;; zero are optimized away.
13014 (define_insn "*lshrhi3_cmp"
13015 [(set (reg FLAGS_REG)
13017 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13018 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13020 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13021 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13022 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13023 && ix86_match_ccmode (insn, CCGOCmode)
13024 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13025 "shr{w}\t{%2, %0|%0, %2}"
13026 [(set_attr "type" "ishift")
13027 (set_attr "mode" "HI")])
13029 (define_insn "*lshrhi3_cconly"
13030 [(set (reg FLAGS_REG)
13032 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13033 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13035 (clobber (match_scratch:HI 0 "=r"))]
13036 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13037 && ix86_match_ccmode (insn, CCGOCmode)
13038 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13039 "shr{w}\t{%2, %0|%0, %2}"
13040 [(set_attr "type" "ishift")
13041 (set_attr "mode" "HI")])
13043 (define_expand "lshrqi3"
13044 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13045 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13046 (match_operand:QI 2 "nonmemory_operand" "")))
13047 (clobber (reg:CC FLAGS_REG))]
13048 "TARGET_QIMODE_MATH"
13049 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13051 (define_insn "*lshrqi3_1_one_bit"
13052 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13053 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13054 (match_operand:QI 2 "const1_operand" "")))
13055 (clobber (reg:CC FLAGS_REG))]
13056 "(TARGET_SHIFT1 || optimize_size)
13057 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13059 [(set_attr "type" "ishift")
13060 (set (attr "length")
13061 (if_then_else (match_operand 0 "register_operand" "")
13063 (const_string "*")))])
13065 (define_insn "*lshrqi3_1_one_bit_slp"
13066 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13067 (lshiftrt:QI (match_dup 0)
13068 (match_operand:QI 1 "const1_operand" "")))
13069 (clobber (reg:CC FLAGS_REG))]
13070 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13071 && (TARGET_SHIFT1 || optimize_size)"
13073 [(set_attr "type" "ishift1")
13074 (set (attr "length")
13075 (if_then_else (match_operand 0 "register_operand" "")
13077 (const_string "*")))])
13079 (define_insn "*lshrqi3_1"
13080 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13081 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13082 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13083 (clobber (reg:CC FLAGS_REG))]
13084 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13086 shr{b}\t{%2, %0|%0, %2}
13087 shr{b}\t{%b2, %0|%0, %b2}"
13088 [(set_attr "type" "ishift")
13089 (set_attr "mode" "QI")])
13091 (define_insn "*lshrqi3_1_slp"
13092 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13093 (lshiftrt:QI (match_dup 0)
13094 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13095 (clobber (reg:CC FLAGS_REG))]
13096 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13097 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13099 shr{b}\t{%1, %0|%0, %1}
13100 shr{b}\t{%b1, %0|%0, %b1}"
13101 [(set_attr "type" "ishift1")
13102 (set_attr "mode" "QI")])
13104 ;; This pattern can't accept a variable shift count, since shifts by
13105 ;; zero don't affect the flags. We assume that shifts by constant
13106 ;; zero are optimized away.
13107 (define_insn "*lshrqi2_one_bit_cmp"
13108 [(set (reg FLAGS_REG)
13110 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13111 (match_operand:QI 2 "const1_operand" ""))
13113 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13114 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13115 "(TARGET_SHIFT1 || optimize_size)
13116 && ix86_match_ccmode (insn, CCGOCmode)
13117 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13119 [(set_attr "type" "ishift")
13120 (set (attr "length")
13121 (if_then_else (match_operand:SI 0 "register_operand" "")
13123 (const_string "*")))])
13125 (define_insn "*lshrqi2_one_bit_cconly"
13126 [(set (reg FLAGS_REG)
13128 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13129 (match_operand:QI 2 "const1_operand" ""))
13131 (clobber (match_scratch:QI 0 "=q"))]
13132 "(TARGET_SHIFT1 || optimize_size)
13133 && ix86_match_ccmode (insn, CCGOCmode)
13134 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13136 [(set_attr "type" "ishift")
13137 (set_attr "length" "2")])
13139 ;; This pattern can't accept a variable shift count, since shifts by
13140 ;; zero don't affect the flags. We assume that shifts by constant
13141 ;; zero are optimized away.
13142 (define_insn "*lshrqi2_cmp"
13143 [(set (reg FLAGS_REG)
13145 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13146 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13148 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13149 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13150 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13151 && ix86_match_ccmode (insn, CCGOCmode)
13152 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13153 "shr{b}\t{%2, %0|%0, %2}"
13154 [(set_attr "type" "ishift")
13155 (set_attr "mode" "QI")])
13157 (define_insn "*lshrqi2_cconly"
13158 [(set (reg FLAGS_REG)
13160 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13161 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13163 (clobber (match_scratch:QI 0 "=q"))]
13164 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13165 && ix86_match_ccmode (insn, CCGOCmode)
13166 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13167 "shr{b}\t{%2, %0|%0, %2}"
13168 [(set_attr "type" "ishift")
13169 (set_attr "mode" "QI")])
13171 ;; Rotate instructions
13173 (define_expand "rotldi3"
13174 [(set (match_operand:DI 0 "shiftdi_operand" "")
13175 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13176 (match_operand:QI 2 "nonmemory_operand" "")))
13177 (clobber (reg:CC FLAGS_REG))]
13182 ix86_expand_binary_operator (ROTATE, DImode, operands);
13185 if (!const_1_to_31_operand (operands[2], VOIDmode))
13187 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13191 ;; Implement rotation using two double-precision shift instructions
13192 ;; and a scratch register.
13193 (define_insn_and_split "ix86_rotldi3"
13194 [(set (match_operand:DI 0 "register_operand" "=r")
13195 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13196 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13197 (clobber (reg:CC FLAGS_REG))
13198 (clobber (match_scratch:SI 3 "=&r"))]
13201 "&& reload_completed"
13202 [(set (match_dup 3) (match_dup 4))
13204 [(set (match_dup 4)
13205 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13206 (lshiftrt:SI (match_dup 5)
13207 (minus:QI (const_int 32) (match_dup 2)))))
13208 (clobber (reg:CC FLAGS_REG))])
13210 [(set (match_dup 5)
13211 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13212 (lshiftrt:SI (match_dup 3)
13213 (minus:QI (const_int 32) (match_dup 2)))))
13214 (clobber (reg:CC FLAGS_REG))])]
13215 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13217 (define_insn "*rotlsi3_1_one_bit_rex64"
13218 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13219 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13220 (match_operand:QI 2 "const1_operand" "")))
13221 (clobber (reg:CC FLAGS_REG))]
13223 && (TARGET_SHIFT1 || optimize_size)
13224 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13226 [(set_attr "type" "rotate")
13227 (set (attr "length")
13228 (if_then_else (match_operand:DI 0 "register_operand" "")
13230 (const_string "*")))])
13232 (define_insn "*rotldi3_1_rex64"
13233 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13234 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13235 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13236 (clobber (reg:CC FLAGS_REG))]
13237 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13239 rol{q}\t{%2, %0|%0, %2}
13240 rol{q}\t{%b2, %0|%0, %b2}"
13241 [(set_attr "type" "rotate")
13242 (set_attr "mode" "DI")])
13244 (define_expand "rotlsi3"
13245 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13246 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13247 (match_operand:QI 2 "nonmemory_operand" "")))
13248 (clobber (reg:CC FLAGS_REG))]
13250 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13252 (define_insn "*rotlsi3_1_one_bit"
13253 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13254 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13255 (match_operand:QI 2 "const1_operand" "")))
13256 (clobber (reg:CC FLAGS_REG))]
13257 "(TARGET_SHIFT1 || optimize_size)
13258 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13260 [(set_attr "type" "rotate")
13261 (set (attr "length")
13262 (if_then_else (match_operand:SI 0 "register_operand" "")
13264 (const_string "*")))])
13266 (define_insn "*rotlsi3_1_one_bit_zext"
13267 [(set (match_operand:DI 0 "register_operand" "=r")
13269 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13270 (match_operand:QI 2 "const1_operand" ""))))
13271 (clobber (reg:CC FLAGS_REG))]
13273 && (TARGET_SHIFT1 || optimize_size)
13274 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13276 [(set_attr "type" "rotate")
13277 (set_attr "length" "2")])
13279 (define_insn "*rotlsi3_1"
13280 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13281 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13282 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13283 (clobber (reg:CC FLAGS_REG))]
13284 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13286 rol{l}\t{%2, %0|%0, %2}
13287 rol{l}\t{%b2, %0|%0, %b2}"
13288 [(set_attr "type" "rotate")
13289 (set_attr "mode" "SI")])
13291 (define_insn "*rotlsi3_1_zext"
13292 [(set (match_operand:DI 0 "register_operand" "=r,r")
13294 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13295 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13296 (clobber (reg:CC FLAGS_REG))]
13297 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13299 rol{l}\t{%2, %k0|%k0, %2}
13300 rol{l}\t{%b2, %k0|%k0, %b2}"
13301 [(set_attr "type" "rotate")
13302 (set_attr "mode" "SI")])
13304 (define_expand "rotlhi3"
13305 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13306 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13307 (match_operand:QI 2 "nonmemory_operand" "")))
13308 (clobber (reg:CC FLAGS_REG))]
13309 "TARGET_HIMODE_MATH"
13310 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13312 (define_insn "*rotlhi3_1_one_bit"
13313 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13314 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13315 (match_operand:QI 2 "const1_operand" "")))
13316 (clobber (reg:CC FLAGS_REG))]
13317 "(TARGET_SHIFT1 || optimize_size)
13318 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13320 [(set_attr "type" "rotate")
13321 (set (attr "length")
13322 (if_then_else (match_operand 0 "register_operand" "")
13324 (const_string "*")))])
13326 (define_insn "*rotlhi3_1"
13327 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13328 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13329 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13330 (clobber (reg:CC FLAGS_REG))]
13331 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13333 rol{w}\t{%2, %0|%0, %2}
13334 rol{w}\t{%b2, %0|%0, %b2}"
13335 [(set_attr "type" "rotate")
13336 (set_attr "mode" "HI")])
13339 [(set (match_operand:HI 0 "register_operand" "")
13340 (rotate:HI (match_dup 0) (const_int 8)))
13341 (clobber (reg:CC FLAGS_REG))]
13343 [(parallel [(set (strict_low_part (match_dup 0))
13344 (bswap:HI (match_dup 0)))
13345 (clobber (reg:CC FLAGS_REG))])]
13348 (define_expand "rotlqi3"
13349 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13350 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13351 (match_operand:QI 2 "nonmemory_operand" "")))
13352 (clobber (reg:CC FLAGS_REG))]
13353 "TARGET_QIMODE_MATH"
13354 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13356 (define_insn "*rotlqi3_1_one_bit_slp"
13357 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13358 (rotate:QI (match_dup 0)
13359 (match_operand:QI 1 "const1_operand" "")))
13360 (clobber (reg:CC FLAGS_REG))]
13361 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13362 && (TARGET_SHIFT1 || optimize_size)"
13364 [(set_attr "type" "rotate1")
13365 (set (attr "length")
13366 (if_then_else (match_operand 0 "register_operand" "")
13368 (const_string "*")))])
13370 (define_insn "*rotlqi3_1_one_bit"
13371 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13372 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13373 (match_operand:QI 2 "const1_operand" "")))
13374 (clobber (reg:CC FLAGS_REG))]
13375 "(TARGET_SHIFT1 || optimize_size)
13376 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13378 [(set_attr "type" "rotate")
13379 (set (attr "length")
13380 (if_then_else (match_operand 0 "register_operand" "")
13382 (const_string "*")))])
13384 (define_insn "*rotlqi3_1_slp"
13385 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13386 (rotate:QI (match_dup 0)
13387 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13388 (clobber (reg:CC FLAGS_REG))]
13389 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13392 rol{b}\t{%1, %0|%0, %1}
13393 rol{b}\t{%b1, %0|%0, %b1}"
13394 [(set_attr "type" "rotate1")
13395 (set_attr "mode" "QI")])
13397 (define_insn "*rotlqi3_1"
13398 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13399 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13400 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13401 (clobber (reg:CC FLAGS_REG))]
13402 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13404 rol{b}\t{%2, %0|%0, %2}
13405 rol{b}\t{%b2, %0|%0, %b2}"
13406 [(set_attr "type" "rotate")
13407 (set_attr "mode" "QI")])
13409 (define_expand "rotrdi3"
13410 [(set (match_operand:DI 0 "shiftdi_operand" "")
13411 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13412 (match_operand:QI 2 "nonmemory_operand" "")))
13413 (clobber (reg:CC FLAGS_REG))]
13418 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13421 if (!const_1_to_31_operand (operands[2], VOIDmode))
13423 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13427 ;; Implement rotation using two double-precision shift instructions
13428 ;; and a scratch register.
13429 (define_insn_and_split "ix86_rotrdi3"
13430 [(set (match_operand:DI 0 "register_operand" "=r")
13431 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13432 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13433 (clobber (reg:CC FLAGS_REG))
13434 (clobber (match_scratch:SI 3 "=&r"))]
13437 "&& reload_completed"
13438 [(set (match_dup 3) (match_dup 4))
13440 [(set (match_dup 4)
13441 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13442 (ashift:SI (match_dup 5)
13443 (minus:QI (const_int 32) (match_dup 2)))))
13444 (clobber (reg:CC FLAGS_REG))])
13446 [(set (match_dup 5)
13447 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13448 (ashift:SI (match_dup 3)
13449 (minus:QI (const_int 32) (match_dup 2)))))
13450 (clobber (reg:CC FLAGS_REG))])]
13451 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13453 (define_insn "*rotrdi3_1_one_bit_rex64"
13454 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13455 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13456 (match_operand:QI 2 "const1_operand" "")))
13457 (clobber (reg:CC FLAGS_REG))]
13459 && (TARGET_SHIFT1 || optimize_size)
13460 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13462 [(set_attr "type" "rotate")
13463 (set (attr "length")
13464 (if_then_else (match_operand:DI 0 "register_operand" "")
13466 (const_string "*")))])
13468 (define_insn "*rotrdi3_1_rex64"
13469 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13470 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13471 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13472 (clobber (reg:CC FLAGS_REG))]
13473 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13475 ror{q}\t{%2, %0|%0, %2}
13476 ror{q}\t{%b2, %0|%0, %b2}"
13477 [(set_attr "type" "rotate")
13478 (set_attr "mode" "DI")])
13480 (define_expand "rotrsi3"
13481 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13482 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13483 (match_operand:QI 2 "nonmemory_operand" "")))
13484 (clobber (reg:CC FLAGS_REG))]
13486 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13488 (define_insn "*rotrsi3_1_one_bit"
13489 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13490 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13491 (match_operand:QI 2 "const1_operand" "")))
13492 (clobber (reg:CC FLAGS_REG))]
13493 "(TARGET_SHIFT1 || optimize_size)
13494 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13496 [(set_attr "type" "rotate")
13497 (set (attr "length")
13498 (if_then_else (match_operand:SI 0 "register_operand" "")
13500 (const_string "*")))])
13502 (define_insn "*rotrsi3_1_one_bit_zext"
13503 [(set (match_operand:DI 0 "register_operand" "=r")
13505 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13506 (match_operand:QI 2 "const1_operand" ""))))
13507 (clobber (reg:CC FLAGS_REG))]
13509 && (TARGET_SHIFT1 || optimize_size)
13510 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13512 [(set_attr "type" "rotate")
13513 (set (attr "length")
13514 (if_then_else (match_operand:SI 0 "register_operand" "")
13516 (const_string "*")))])
13518 (define_insn "*rotrsi3_1"
13519 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13520 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13521 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13522 (clobber (reg:CC FLAGS_REG))]
13523 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13525 ror{l}\t{%2, %0|%0, %2}
13526 ror{l}\t{%b2, %0|%0, %b2}"
13527 [(set_attr "type" "rotate")
13528 (set_attr "mode" "SI")])
13530 (define_insn "*rotrsi3_1_zext"
13531 [(set (match_operand:DI 0 "register_operand" "=r,r")
13533 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13534 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13535 (clobber (reg:CC FLAGS_REG))]
13536 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13538 ror{l}\t{%2, %k0|%k0, %2}
13539 ror{l}\t{%b2, %k0|%k0, %b2}"
13540 [(set_attr "type" "rotate")
13541 (set_attr "mode" "SI")])
13543 (define_expand "rotrhi3"
13544 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13545 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13546 (match_operand:QI 2 "nonmemory_operand" "")))
13547 (clobber (reg:CC FLAGS_REG))]
13548 "TARGET_HIMODE_MATH"
13549 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13551 (define_insn "*rotrhi3_one_bit"
13552 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13553 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13554 (match_operand:QI 2 "const1_operand" "")))
13555 (clobber (reg:CC FLAGS_REG))]
13556 "(TARGET_SHIFT1 || optimize_size)
13557 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13559 [(set_attr "type" "rotate")
13560 (set (attr "length")
13561 (if_then_else (match_operand 0 "register_operand" "")
13563 (const_string "*")))])
13565 (define_insn "*rotrhi3_1"
13566 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13567 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13568 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13569 (clobber (reg:CC FLAGS_REG))]
13570 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13572 ror{w}\t{%2, %0|%0, %2}
13573 ror{w}\t{%b2, %0|%0, %b2}"
13574 [(set_attr "type" "rotate")
13575 (set_attr "mode" "HI")])
13578 [(set (match_operand:HI 0 "register_operand" "")
13579 (rotatert:HI (match_dup 0) (const_int 8)))
13580 (clobber (reg:CC FLAGS_REG))]
13582 [(parallel [(set (strict_low_part (match_dup 0))
13583 (bswap:HI (match_dup 0)))
13584 (clobber (reg:CC FLAGS_REG))])]
13587 (define_expand "rotrqi3"
13588 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13589 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13590 (match_operand:QI 2 "nonmemory_operand" "")))
13591 (clobber (reg:CC FLAGS_REG))]
13592 "TARGET_QIMODE_MATH"
13593 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13595 (define_insn "*rotrqi3_1_one_bit"
13596 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13597 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13598 (match_operand:QI 2 "const1_operand" "")))
13599 (clobber (reg:CC FLAGS_REG))]
13600 "(TARGET_SHIFT1 || optimize_size)
13601 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13603 [(set_attr "type" "rotate")
13604 (set (attr "length")
13605 (if_then_else (match_operand 0 "register_operand" "")
13607 (const_string "*")))])
13609 (define_insn "*rotrqi3_1_one_bit_slp"
13610 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13611 (rotatert:QI (match_dup 0)
13612 (match_operand:QI 1 "const1_operand" "")))
13613 (clobber (reg:CC FLAGS_REG))]
13614 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13615 && (TARGET_SHIFT1 || optimize_size)"
13617 [(set_attr "type" "rotate1")
13618 (set (attr "length")
13619 (if_then_else (match_operand 0 "register_operand" "")
13621 (const_string "*")))])
13623 (define_insn "*rotrqi3_1"
13624 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13625 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13626 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13627 (clobber (reg:CC FLAGS_REG))]
13628 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13630 ror{b}\t{%2, %0|%0, %2}
13631 ror{b}\t{%b2, %0|%0, %b2}"
13632 [(set_attr "type" "rotate")
13633 (set_attr "mode" "QI")])
13635 (define_insn "*rotrqi3_1_slp"
13636 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13637 (rotatert:QI (match_dup 0)
13638 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13639 (clobber (reg:CC FLAGS_REG))]
13640 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13641 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13643 ror{b}\t{%1, %0|%0, %1}
13644 ror{b}\t{%b1, %0|%0, %b1}"
13645 [(set_attr "type" "rotate1")
13646 (set_attr "mode" "QI")])
13648 ;; Bit set / bit test instructions
13650 (define_expand "extv"
13651 [(set (match_operand:SI 0 "register_operand" "")
13652 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13653 (match_operand:SI 2 "const8_operand" "")
13654 (match_operand:SI 3 "const8_operand" "")))]
13657 /* Handle extractions from %ah et al. */
13658 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13661 /* From mips.md: extract_bit_field doesn't verify that our source
13662 matches the predicate, so check it again here. */
13663 if (! ext_register_operand (operands[1], VOIDmode))
13667 (define_expand "extzv"
13668 [(set (match_operand:SI 0 "register_operand" "")
13669 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13670 (match_operand:SI 2 "const8_operand" "")
13671 (match_operand:SI 3 "const8_operand" "")))]
13674 /* Handle extractions from %ah et al. */
13675 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13678 /* From mips.md: extract_bit_field doesn't verify that our source
13679 matches the predicate, so check it again here. */
13680 if (! ext_register_operand (operands[1], VOIDmode))
13684 (define_expand "insv"
13685 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13686 (match_operand 1 "const8_operand" "")
13687 (match_operand 2 "const8_operand" ""))
13688 (match_operand 3 "register_operand" ""))]
13691 /* Handle insertions to %ah et al. */
13692 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13695 /* From mips.md: insert_bit_field doesn't verify that our source
13696 matches the predicate, so check it again here. */
13697 if (! ext_register_operand (operands[0], VOIDmode))
13701 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13703 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13708 ;; %%% bts, btr, btc, bt.
13709 ;; In general these instructions are *slow* when applied to memory,
13710 ;; since they enforce atomic operation. When applied to registers,
13711 ;; it depends on the cpu implementation. They're never faster than
13712 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13713 ;; no point. But in 64-bit, we can't hold the relevant immediates
13714 ;; within the instruction itself, so operating on bits in the high
13715 ;; 32-bits of a register becomes easier.
13717 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13718 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13719 ;; negdf respectively, so they can never be disabled entirely.
13721 (define_insn "*btsq"
13722 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13724 (match_operand:DI 1 "const_0_to_63_operand" ""))
13726 (clobber (reg:CC FLAGS_REG))]
13727 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13729 [(set_attr "type" "alu1")])
13731 (define_insn "*btrq"
13732 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13734 (match_operand:DI 1 "const_0_to_63_operand" ""))
13736 (clobber (reg:CC FLAGS_REG))]
13737 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13739 [(set_attr "type" "alu1")])
13741 (define_insn "*btcq"
13742 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13744 (match_operand:DI 1 "const_0_to_63_operand" ""))
13745 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13746 (clobber (reg:CC FLAGS_REG))]
13747 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13749 [(set_attr "type" "alu1")])
13751 ;; Allow Nocona to avoid these instructions if a register is available.
13754 [(match_scratch:DI 2 "r")
13755 (parallel [(set (zero_extract:DI
13756 (match_operand:DI 0 "register_operand" "")
13758 (match_operand:DI 1 "const_0_to_63_operand" ""))
13760 (clobber (reg:CC FLAGS_REG))])]
13761 "TARGET_64BIT && !TARGET_USE_BT"
13764 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13767 if (HOST_BITS_PER_WIDE_INT >= 64)
13768 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13769 else if (i < HOST_BITS_PER_WIDE_INT)
13770 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13772 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13774 op1 = immed_double_const (lo, hi, DImode);
13777 emit_move_insn (operands[2], op1);
13781 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13786 [(match_scratch:DI 2 "r")
13787 (parallel [(set (zero_extract:DI
13788 (match_operand:DI 0 "register_operand" "")
13790 (match_operand:DI 1 "const_0_to_63_operand" ""))
13792 (clobber (reg:CC FLAGS_REG))])]
13793 "TARGET_64BIT && !TARGET_USE_BT"
13796 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13799 if (HOST_BITS_PER_WIDE_INT >= 64)
13800 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13801 else if (i < HOST_BITS_PER_WIDE_INT)
13802 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13804 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13806 op1 = immed_double_const (~lo, ~hi, DImode);
13809 emit_move_insn (operands[2], op1);
13813 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13818 [(match_scratch:DI 2 "r")
13819 (parallel [(set (zero_extract:DI
13820 (match_operand:DI 0 "register_operand" "")
13822 (match_operand:DI 1 "const_0_to_63_operand" ""))
13823 (not:DI (zero_extract:DI
13824 (match_dup 0) (const_int 1) (match_dup 1))))
13825 (clobber (reg:CC FLAGS_REG))])]
13826 "TARGET_64BIT && !TARGET_USE_BT"
13829 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13832 if (HOST_BITS_PER_WIDE_INT >= 64)
13833 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13834 else if (i < HOST_BITS_PER_WIDE_INT)
13835 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13837 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13839 op1 = immed_double_const (lo, hi, DImode);
13842 emit_move_insn (operands[2], op1);
13846 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13850 ;; Store-flag instructions.
13852 ;; For all sCOND expanders, also expand the compare or test insn that
13853 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13855 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13856 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13857 ;; way, which can later delete the movzx if only QImode is needed.
13859 (define_expand "s<code>"
13860 [(set (match_operand:QI 0 "register_operand" "")
13861 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13863 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13865 (define_expand "s<code>"
13866 [(set (match_operand:QI 0 "register_operand" "")
13867 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13868 "TARGET_80387 || TARGET_SSE"
13869 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13871 (define_insn "*setcc_1"
13872 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13873 (match_operator:QI 1 "ix86_comparison_operator"
13874 [(reg FLAGS_REG) (const_int 0)]))]
13877 [(set_attr "type" "setcc")
13878 (set_attr "mode" "QI")])
13880 (define_insn "*setcc_2"
13881 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13882 (match_operator:QI 1 "ix86_comparison_operator"
13883 [(reg FLAGS_REG) (const_int 0)]))]
13886 [(set_attr "type" "setcc")
13887 (set_attr "mode" "QI")])
13889 ;; In general it is not safe to assume too much about CCmode registers,
13890 ;; so simplify-rtx stops when it sees a second one. Under certain
13891 ;; conditions this is safe on x86, so help combine not create
13898 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13899 (ne:QI (match_operator 1 "ix86_comparison_operator"
13900 [(reg FLAGS_REG) (const_int 0)])
13903 [(set (match_dup 0) (match_dup 1))]
13905 PUT_MODE (operands[1], QImode);
13909 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13910 (ne:QI (match_operator 1 "ix86_comparison_operator"
13911 [(reg FLAGS_REG) (const_int 0)])
13914 [(set (match_dup 0) (match_dup 1))]
13916 PUT_MODE (operands[1], QImode);
13920 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13921 (eq:QI (match_operator 1 "ix86_comparison_operator"
13922 [(reg FLAGS_REG) (const_int 0)])
13925 [(set (match_dup 0) (match_dup 1))]
13927 rtx new_op1 = copy_rtx (operands[1]);
13928 operands[1] = new_op1;
13929 PUT_MODE (new_op1, QImode);
13930 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13931 GET_MODE (XEXP (new_op1, 0))));
13933 /* Make sure that (a) the CCmode we have for the flags is strong
13934 enough for the reversed compare or (b) we have a valid FP compare. */
13935 if (! ix86_comparison_operator (new_op1, VOIDmode))
13940 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13941 (eq:QI (match_operator 1 "ix86_comparison_operator"
13942 [(reg FLAGS_REG) (const_int 0)])
13945 [(set (match_dup 0) (match_dup 1))]
13947 rtx new_op1 = copy_rtx (operands[1]);
13948 operands[1] = new_op1;
13949 PUT_MODE (new_op1, QImode);
13950 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13951 GET_MODE (XEXP (new_op1, 0))));
13953 /* Make sure that (a) the CCmode we have for the flags is strong
13954 enough for the reversed compare or (b) we have a valid FP compare. */
13955 if (! ix86_comparison_operator (new_op1, VOIDmode))
13959 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13960 ;; subsequent logical operations are used to imitate conditional moves.
13961 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13964 (define_insn "*sse_setcc<mode>"
13965 [(set (match_operand:MODEF 0 "register_operand" "=x")
13966 (match_operator:MODEF 1 "sse_comparison_operator"
13967 [(match_operand:MODEF 2 "register_operand" "0")
13968 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13969 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13970 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13971 [(set_attr "type" "ssecmp")
13972 (set_attr "mode" "<MODE>")])
13974 (define_insn "*sse5_setcc<mode>"
13975 [(set (match_operand:MODEF 0 "register_operand" "=x")
13976 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13977 [(match_operand:MODEF 2 "register_operand" "x")
13978 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13980 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13981 [(set_attr "type" "sse4arg")
13982 (set_attr "mode" "<MODE>")])
13985 ;; Basic conditional jump instructions.
13986 ;; We ignore the overflow flag for signed branch instructions.
13988 ;; For all bCOND expanders, also expand the compare or test insn that
13989 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13991 (define_expand "b<code>"
13993 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13995 (label_ref (match_operand 0 ""))
13998 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14000 (define_expand "b<code>"
14002 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14004 (label_ref (match_operand 0 ""))
14006 "TARGET_80387 || TARGET_SSE_MATH"
14007 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14009 (define_insn "*jcc_1"
14011 (if_then_else (match_operator 1 "ix86_comparison_operator"
14012 [(reg FLAGS_REG) (const_int 0)])
14013 (label_ref (match_operand 0 "" ""))
14017 [(set_attr "type" "ibr")
14018 (set_attr "modrm" "0")
14019 (set (attr "length")
14020 (if_then_else (and (ge (minus (match_dup 0) (pc))
14022 (lt (minus (match_dup 0) (pc))
14027 (define_insn "*jcc_2"
14029 (if_then_else (match_operator 1 "ix86_comparison_operator"
14030 [(reg FLAGS_REG) (const_int 0)])
14032 (label_ref (match_operand 0 "" ""))))]
14035 [(set_attr "type" "ibr")
14036 (set_attr "modrm" "0")
14037 (set (attr "length")
14038 (if_then_else (and (ge (minus (match_dup 0) (pc))
14040 (lt (minus (match_dup 0) (pc))
14045 ;; In general it is not safe to assume too much about CCmode registers,
14046 ;; so simplify-rtx stops when it sees a second one. Under certain
14047 ;; conditions this is safe on x86, so help combine not create
14055 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14056 [(reg FLAGS_REG) (const_int 0)])
14058 (label_ref (match_operand 1 "" ""))
14062 (if_then_else (match_dup 0)
14063 (label_ref (match_dup 1))
14066 PUT_MODE (operands[0], VOIDmode);
14071 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14072 [(reg FLAGS_REG) (const_int 0)])
14074 (label_ref (match_operand 1 "" ""))
14078 (if_then_else (match_dup 0)
14079 (label_ref (match_dup 1))
14082 rtx new_op0 = copy_rtx (operands[0]);
14083 operands[0] = new_op0;
14084 PUT_MODE (new_op0, VOIDmode);
14085 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14086 GET_MODE (XEXP (new_op0, 0))));
14088 /* Make sure that (a) the CCmode we have for the flags is strong
14089 enough for the reversed compare or (b) we have a valid FP compare. */
14090 if (! ix86_comparison_operator (new_op0, VOIDmode))
14094 ;; Define combination compare-and-branch fp compare instructions to use
14095 ;; during early optimization. Splitting the operation apart early makes
14096 ;; for bad code when we want to reverse the operation.
14098 (define_insn "*fp_jcc_1_mixed"
14100 (if_then_else (match_operator 0 "comparison_operator"
14101 [(match_operand 1 "register_operand" "f,x")
14102 (match_operand 2 "nonimmediate_operand" "f,xm")])
14103 (label_ref (match_operand 3 "" ""))
14105 (clobber (reg:CCFP FPSR_REG))
14106 (clobber (reg:CCFP FLAGS_REG))]
14107 "TARGET_MIX_SSE_I387
14108 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14109 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14110 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14113 (define_insn "*fp_jcc_1_sse"
14115 (if_then_else (match_operator 0 "comparison_operator"
14116 [(match_operand 1 "register_operand" "x")
14117 (match_operand 2 "nonimmediate_operand" "xm")])
14118 (label_ref (match_operand 3 "" ""))
14120 (clobber (reg:CCFP FPSR_REG))
14121 (clobber (reg:CCFP FLAGS_REG))]
14123 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14124 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14125 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14128 (define_insn "*fp_jcc_1_387"
14130 (if_then_else (match_operator 0 "comparison_operator"
14131 [(match_operand 1 "register_operand" "f")
14132 (match_operand 2 "register_operand" "f")])
14133 (label_ref (match_operand 3 "" ""))
14135 (clobber (reg:CCFP FPSR_REG))
14136 (clobber (reg:CCFP FLAGS_REG))]
14137 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14139 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14140 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14143 (define_insn "*fp_jcc_2_mixed"
14145 (if_then_else (match_operator 0 "comparison_operator"
14146 [(match_operand 1 "register_operand" "f,x")
14147 (match_operand 2 "nonimmediate_operand" "f,xm")])
14149 (label_ref (match_operand 3 "" ""))))
14150 (clobber (reg:CCFP FPSR_REG))
14151 (clobber (reg:CCFP FLAGS_REG))]
14152 "TARGET_MIX_SSE_I387
14153 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14154 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14155 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14158 (define_insn "*fp_jcc_2_sse"
14160 (if_then_else (match_operator 0 "comparison_operator"
14161 [(match_operand 1 "register_operand" "x")
14162 (match_operand 2 "nonimmediate_operand" "xm")])
14164 (label_ref (match_operand 3 "" ""))))
14165 (clobber (reg:CCFP FPSR_REG))
14166 (clobber (reg:CCFP FLAGS_REG))]
14168 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14169 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14170 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14173 (define_insn "*fp_jcc_2_387"
14175 (if_then_else (match_operator 0 "comparison_operator"
14176 [(match_operand 1 "register_operand" "f")
14177 (match_operand 2 "register_operand" "f")])
14179 (label_ref (match_operand 3 "" ""))))
14180 (clobber (reg:CCFP FPSR_REG))
14181 (clobber (reg:CCFP FLAGS_REG))]
14182 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14184 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14185 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14188 (define_insn "*fp_jcc_3_387"
14190 (if_then_else (match_operator 0 "comparison_operator"
14191 [(match_operand 1 "register_operand" "f")
14192 (match_operand 2 "nonimmediate_operand" "fm")])
14193 (label_ref (match_operand 3 "" ""))
14195 (clobber (reg:CCFP FPSR_REG))
14196 (clobber (reg:CCFP FLAGS_REG))
14197 (clobber (match_scratch:HI 4 "=a"))]
14199 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14200 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14201 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14202 && SELECT_CC_MODE (GET_CODE (operands[0]),
14203 operands[1], operands[2]) == CCFPmode
14204 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14207 (define_insn "*fp_jcc_4_387"
14209 (if_then_else (match_operator 0 "comparison_operator"
14210 [(match_operand 1 "register_operand" "f")
14211 (match_operand 2 "nonimmediate_operand" "fm")])
14213 (label_ref (match_operand 3 "" ""))))
14214 (clobber (reg:CCFP FPSR_REG))
14215 (clobber (reg:CCFP FLAGS_REG))
14216 (clobber (match_scratch:HI 4 "=a"))]
14218 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14219 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14220 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14221 && SELECT_CC_MODE (GET_CODE (operands[0]),
14222 operands[1], operands[2]) == CCFPmode
14223 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14226 (define_insn "*fp_jcc_5_387"
14228 (if_then_else (match_operator 0 "comparison_operator"
14229 [(match_operand 1 "register_operand" "f")
14230 (match_operand 2 "register_operand" "f")])
14231 (label_ref (match_operand 3 "" ""))
14233 (clobber (reg:CCFP FPSR_REG))
14234 (clobber (reg:CCFP FLAGS_REG))
14235 (clobber (match_scratch:HI 4 "=a"))]
14236 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14237 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14238 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14241 (define_insn "*fp_jcc_6_387"
14243 (if_then_else (match_operator 0 "comparison_operator"
14244 [(match_operand 1 "register_operand" "f")
14245 (match_operand 2 "register_operand" "f")])
14247 (label_ref (match_operand 3 "" ""))))
14248 (clobber (reg:CCFP FPSR_REG))
14249 (clobber (reg:CCFP FLAGS_REG))
14250 (clobber (match_scratch:HI 4 "=a"))]
14251 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14252 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14253 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14256 (define_insn "*fp_jcc_7_387"
14258 (if_then_else (match_operator 0 "comparison_operator"
14259 [(match_operand 1 "register_operand" "f")
14260 (match_operand 2 "const0_operand" "X")])
14261 (label_ref (match_operand 3 "" ""))
14263 (clobber (reg:CCFP FPSR_REG))
14264 (clobber (reg:CCFP FLAGS_REG))
14265 (clobber (match_scratch:HI 4 "=a"))]
14266 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14267 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14268 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14269 && SELECT_CC_MODE (GET_CODE (operands[0]),
14270 operands[1], operands[2]) == CCFPmode
14271 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14274 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14275 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14276 ;; with a precedence over other operators and is always put in the first
14277 ;; place. Swap condition and operands to match ficom instruction.
14279 (define_insn "*fp_jcc_8<mode>_387"
14281 (if_then_else (match_operator 0 "comparison_operator"
14282 [(match_operator 1 "float_operator"
14283 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14284 (match_operand 3 "register_operand" "f,f")])
14285 (label_ref (match_operand 4 "" ""))
14287 (clobber (reg:CCFP FPSR_REG))
14288 (clobber (reg:CCFP FLAGS_REG))
14289 (clobber (match_scratch:HI 5 "=a,a"))]
14290 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14291 && TARGET_USE_<MODE>MODE_FIOP
14292 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14293 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14294 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14295 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14300 (if_then_else (match_operator 0 "comparison_operator"
14301 [(match_operand 1 "register_operand" "")
14302 (match_operand 2 "nonimmediate_operand" "")])
14303 (match_operand 3 "" "")
14304 (match_operand 4 "" "")))
14305 (clobber (reg:CCFP FPSR_REG))
14306 (clobber (reg:CCFP FLAGS_REG))]
14310 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14311 operands[3], operands[4], NULL_RTX, NULL_RTX);
14317 (if_then_else (match_operator 0 "comparison_operator"
14318 [(match_operand 1 "register_operand" "")
14319 (match_operand 2 "general_operand" "")])
14320 (match_operand 3 "" "")
14321 (match_operand 4 "" "")))
14322 (clobber (reg:CCFP FPSR_REG))
14323 (clobber (reg:CCFP FLAGS_REG))
14324 (clobber (match_scratch:HI 5 "=a"))]
14328 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14329 operands[3], operands[4], operands[5], NULL_RTX);
14335 (if_then_else (match_operator 0 "comparison_operator"
14336 [(match_operator 1 "float_operator"
14337 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14338 (match_operand 3 "register_operand" "")])
14339 (match_operand 4 "" "")
14340 (match_operand 5 "" "")))
14341 (clobber (reg:CCFP FPSR_REG))
14342 (clobber (reg:CCFP FLAGS_REG))
14343 (clobber (match_scratch:HI 6 "=a"))]
14347 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14348 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14349 operands[3], operands[7],
14350 operands[4], operands[5], operands[6], NULL_RTX);
14354 ;; %%% Kill this when reload knows how to do it.
14357 (if_then_else (match_operator 0 "comparison_operator"
14358 [(match_operator 1 "float_operator"
14359 [(match_operand:X87MODEI12 2 "register_operand" "")])
14360 (match_operand 3 "register_operand" "")])
14361 (match_operand 4 "" "")
14362 (match_operand 5 "" "")))
14363 (clobber (reg:CCFP FPSR_REG))
14364 (clobber (reg:CCFP FLAGS_REG))
14365 (clobber (match_scratch:HI 6 "=a"))]
14369 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14370 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14371 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14372 operands[3], operands[7],
14373 operands[4], operands[5], operands[6], operands[2]);
14377 ;; Unconditional and other jump instructions
14379 (define_insn "jump"
14381 (label_ref (match_operand 0 "" "")))]
14384 [(set_attr "type" "ibr")
14385 (set (attr "length")
14386 (if_then_else (and (ge (minus (match_dup 0) (pc))
14388 (lt (minus (match_dup 0) (pc))
14392 (set_attr "modrm" "0")])
14394 (define_expand "indirect_jump"
14395 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14399 (define_insn "*indirect_jump"
14400 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14403 [(set_attr "type" "ibr")
14404 (set_attr "length_immediate" "0")])
14406 (define_insn "*indirect_jump_rtx64"
14407 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14410 [(set_attr "type" "ibr")
14411 (set_attr "length_immediate" "0")])
14413 (define_expand "tablejump"
14414 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14415 (use (label_ref (match_operand 1 "" "")))])]
14418 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14419 relative. Convert the relative address to an absolute address. */
14423 enum rtx_code code;
14425 /* We can't use @GOTOFF for text labels on VxWorks;
14426 see gotoff_operand. */
14427 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14431 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14433 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14437 op1 = pic_offset_table_rtx;
14442 op0 = pic_offset_table_rtx;
14446 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14451 (define_insn "*tablejump_1"
14452 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14453 (use (label_ref (match_operand 1 "" "")))]
14456 [(set_attr "type" "ibr")
14457 (set_attr "length_immediate" "0")])
14459 (define_insn "*tablejump_1_rtx64"
14460 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14461 (use (label_ref (match_operand 1 "" "")))]
14464 [(set_attr "type" "ibr")
14465 (set_attr "length_immediate" "0")])
14467 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14470 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14471 (set (match_operand:QI 1 "register_operand" "")
14472 (match_operator:QI 2 "ix86_comparison_operator"
14473 [(reg FLAGS_REG) (const_int 0)]))
14474 (set (match_operand 3 "q_regs_operand" "")
14475 (zero_extend (match_dup 1)))]
14476 "(peep2_reg_dead_p (3, operands[1])
14477 || operands_match_p (operands[1], operands[3]))
14478 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14479 [(set (match_dup 4) (match_dup 0))
14480 (set (strict_low_part (match_dup 5))
14483 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14484 operands[5] = gen_lowpart (QImode, operands[3]);
14485 ix86_expand_clear (operands[3]);
14488 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14491 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14492 (set (match_operand:QI 1 "register_operand" "")
14493 (match_operator:QI 2 "ix86_comparison_operator"
14494 [(reg FLAGS_REG) (const_int 0)]))
14495 (parallel [(set (match_operand 3 "q_regs_operand" "")
14496 (zero_extend (match_dup 1)))
14497 (clobber (reg:CC FLAGS_REG))])]
14498 "(peep2_reg_dead_p (3, operands[1])
14499 || operands_match_p (operands[1], operands[3]))
14500 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14501 [(set (match_dup 4) (match_dup 0))
14502 (set (strict_low_part (match_dup 5))
14505 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14506 operands[5] = gen_lowpart (QImode, operands[3]);
14507 ix86_expand_clear (operands[3]);
14510 ;; Call instructions.
14512 ;; The predicates normally associated with named expanders are not properly
14513 ;; checked for calls. This is a bug in the generic code, but it isn't that
14514 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14516 ;; Call subroutine returning no value.
14518 (define_expand "call_pop"
14519 [(parallel [(call (match_operand:QI 0 "" "")
14520 (match_operand:SI 1 "" ""))
14521 (set (reg:SI SP_REG)
14522 (plus:SI (reg:SI SP_REG)
14523 (match_operand:SI 3 "" "")))])]
14526 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14530 (define_insn "*call_pop_0"
14531 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14532 (match_operand:SI 1 "" ""))
14533 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14534 (match_operand:SI 2 "immediate_operand" "")))]
14537 if (SIBLING_CALL_P (insn))
14540 return "call\t%P0";
14542 [(set_attr "type" "call")])
14544 (define_insn "*call_pop_1"
14545 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14546 (match_operand:SI 1 "" ""))
14547 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14548 (match_operand:SI 2 "immediate_operand" "i")))]
14551 if (constant_call_address_operand (operands[0], Pmode))
14553 if (SIBLING_CALL_P (insn))
14556 return "call\t%P0";
14558 if (SIBLING_CALL_P (insn))
14561 return "call\t%A0";
14563 [(set_attr "type" "call")])
14565 (define_expand "call"
14566 [(call (match_operand:QI 0 "" "")
14567 (match_operand 1 "" ""))
14568 (use (match_operand 2 "" ""))]
14571 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14575 (define_expand "sibcall"
14576 [(call (match_operand:QI 0 "" "")
14577 (match_operand 1 "" ""))
14578 (use (match_operand 2 "" ""))]
14581 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14585 (define_insn "*call_0"
14586 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14587 (match_operand 1 "" ""))]
14590 if (SIBLING_CALL_P (insn))
14593 return "call\t%P0";
14595 [(set_attr "type" "call")])
14597 (define_insn "*call_1"
14598 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14599 (match_operand 1 "" ""))]
14600 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14602 if (constant_call_address_operand (operands[0], Pmode))
14603 return "call\t%P0";
14604 return "call\t%A0";
14606 [(set_attr "type" "call")])
14608 (define_insn "*sibcall_1"
14609 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14610 (match_operand 1 "" ""))]
14611 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14613 if (constant_call_address_operand (operands[0], Pmode))
14617 [(set_attr "type" "call")])
14619 (define_insn "*call_1_rex64"
14620 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14621 (match_operand 1 "" ""))]
14622 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14623 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14625 if (constant_call_address_operand (operands[0], Pmode))
14626 return "call\t%P0";
14627 return "call\t%A0";
14629 [(set_attr "type" "call")])
14631 (define_insn "*call_1_rex64_large"
14632 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14633 (match_operand 1 "" ""))]
14634 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14636 [(set_attr "type" "call")])
14638 (define_insn "*sibcall_1_rex64"
14639 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14640 (match_operand 1 "" ""))]
14641 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14643 [(set_attr "type" "call")])
14645 (define_insn "*sibcall_1_rex64_v"
14646 [(call (mem:QI (reg:DI R11_REG))
14647 (match_operand 0 "" ""))]
14648 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14650 [(set_attr "type" "call")])
14653 ;; Call subroutine, returning value in operand 0
14655 (define_expand "call_value_pop"
14656 [(parallel [(set (match_operand 0 "" "")
14657 (call (match_operand:QI 1 "" "")
14658 (match_operand:SI 2 "" "")))
14659 (set (reg:SI SP_REG)
14660 (plus:SI (reg:SI SP_REG)
14661 (match_operand:SI 4 "" "")))])]
14664 ix86_expand_call (operands[0], operands[1], operands[2],
14665 operands[3], operands[4], 0);
14669 (define_expand "call_value"
14670 [(set (match_operand 0 "" "")
14671 (call (match_operand:QI 1 "" "")
14672 (match_operand:SI 2 "" "")))
14673 (use (match_operand:SI 3 "" ""))]
14674 ;; Operand 2 not used on the i386.
14677 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14681 (define_expand "sibcall_value"
14682 [(set (match_operand 0 "" "")
14683 (call (match_operand:QI 1 "" "")
14684 (match_operand:SI 2 "" "")))
14685 (use (match_operand:SI 3 "" ""))]
14686 ;; Operand 2 not used on the i386.
14689 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14693 ;; Call subroutine returning any type.
14695 (define_expand "untyped_call"
14696 [(parallel [(call (match_operand 0 "" "")
14698 (match_operand 1 "" "")
14699 (match_operand 2 "" "")])]
14704 /* In order to give reg-stack an easier job in validating two
14705 coprocessor registers as containing a possible return value,
14706 simply pretend the untyped call returns a complex long double
14709 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14710 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14711 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14714 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14716 rtx set = XVECEXP (operands[2], 0, i);
14717 emit_move_insn (SET_DEST (set), SET_SRC (set));
14720 /* The optimizer does not know that the call sets the function value
14721 registers we stored in the result block. We avoid problems by
14722 claiming that all hard registers are used and clobbered at this
14724 emit_insn (gen_blockage ());
14729 ;; Prologue and epilogue instructions
14731 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14732 ;; all of memory. This blocks insns from being moved across this point.
14734 (define_insn "blockage"
14735 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14738 [(set_attr "length" "0")])
14740 ;; As USE insns aren't meaningful after reload, this is used instead
14741 ;; to prevent deleting instructions setting registers for PIC code
14742 (define_insn "prologue_use"
14743 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14746 [(set_attr "length" "0")])
14748 ;; Insn emitted into the body of a function to return from a function.
14749 ;; This is only done if the function's epilogue is known to be simple.
14750 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14752 (define_expand "return"
14754 "ix86_can_use_return_insn_p ()"
14756 if (crtl->args.pops_args)
14758 rtx popc = GEN_INT (crtl->args.pops_args);
14759 emit_jump_insn (gen_return_pop_internal (popc));
14764 (define_insn "return_internal"
14768 [(set_attr "length" "1")
14769 (set_attr "length_immediate" "0")
14770 (set_attr "modrm" "0")])
14772 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14773 ;; instruction Athlon and K8 have.
14775 (define_insn "return_internal_long"
14777 (unspec [(const_int 0)] UNSPEC_REP)]
14780 [(set_attr "length" "1")
14781 (set_attr "length_immediate" "0")
14782 (set_attr "prefix_rep" "1")
14783 (set_attr "modrm" "0")])
14785 (define_insn "return_pop_internal"
14787 (use (match_operand:SI 0 "const_int_operand" ""))]
14790 [(set_attr "length" "3")
14791 (set_attr "length_immediate" "2")
14792 (set_attr "modrm" "0")])
14794 (define_insn "return_indirect_internal"
14796 (use (match_operand:SI 0 "register_operand" "r"))]
14799 [(set_attr "type" "ibr")
14800 (set_attr "length_immediate" "0")])
14806 [(set_attr "length" "1")
14807 (set_attr "length_immediate" "0")
14808 (set_attr "modrm" "0")])
14810 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14811 ;; branch prediction penalty for the third jump in a 16-byte
14814 (define_insn "align"
14815 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14818 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14819 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14821 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14822 The align insn is used to avoid 3 jump instructions in the row to improve
14823 branch prediction and the benefits hardly outweigh the cost of extra 8
14824 nops on the average inserted by full alignment pseudo operation. */
14828 [(set_attr "length" "16")])
14830 (define_expand "prologue"
14833 "ix86_expand_prologue (); DONE;")
14835 (define_insn "set_got"
14836 [(set (match_operand:SI 0 "register_operand" "=r")
14837 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14838 (clobber (reg:CC FLAGS_REG))]
14840 { return output_set_got (operands[0], NULL_RTX); }
14841 [(set_attr "type" "multi")
14842 (set_attr "length" "12")])
14844 (define_insn "set_got_labelled"
14845 [(set (match_operand:SI 0 "register_operand" "=r")
14846 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14848 (clobber (reg:CC FLAGS_REG))]
14850 { return output_set_got (operands[0], operands[1]); }
14851 [(set_attr "type" "multi")
14852 (set_attr "length" "12")])
14854 (define_insn "set_got_rex64"
14855 [(set (match_operand:DI 0 "register_operand" "=r")
14856 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14858 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14859 [(set_attr "type" "lea")
14860 (set_attr "length" "6")])
14862 (define_insn "set_rip_rex64"
14863 [(set (match_operand:DI 0 "register_operand" "=r")
14864 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14866 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14867 [(set_attr "type" "lea")
14868 (set_attr "length" "6")])
14870 (define_insn "set_got_offset_rex64"
14871 [(set (match_operand:DI 0 "register_operand" "=r")
14872 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14874 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14875 [(set_attr "type" "imov")
14876 (set_attr "length" "11")])
14878 (define_expand "epilogue"
14881 "ix86_expand_epilogue (1); DONE;")
14883 (define_expand "sibcall_epilogue"
14886 "ix86_expand_epilogue (0); DONE;")
14888 (define_expand "eh_return"
14889 [(use (match_operand 0 "register_operand" ""))]
14892 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14894 /* Tricky bit: we write the address of the handler to which we will
14895 be returning into someone else's stack frame, one word below the
14896 stack address we wish to restore. */
14897 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14898 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14899 tmp = gen_rtx_MEM (Pmode, tmp);
14900 emit_move_insn (tmp, ra);
14902 if (Pmode == SImode)
14903 emit_jump_insn (gen_eh_return_si (sa));
14905 emit_jump_insn (gen_eh_return_di (sa));
14910 (define_insn_and_split "eh_return_si"
14912 (unspec [(match_operand:SI 0 "register_operand" "c")]
14913 UNSPEC_EH_RETURN))]
14918 "ix86_expand_epilogue (2); DONE;")
14920 (define_insn_and_split "eh_return_di"
14922 (unspec [(match_operand:DI 0 "register_operand" "c")]
14923 UNSPEC_EH_RETURN))]
14928 "ix86_expand_epilogue (2); DONE;")
14930 (define_insn "leave"
14931 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14932 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14933 (clobber (mem:BLK (scratch)))]
14936 [(set_attr "type" "leave")])
14938 (define_insn "leave_rex64"
14939 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14940 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14941 (clobber (mem:BLK (scratch)))]
14944 [(set_attr "type" "leave")])
14946 (define_expand "ffssi2"
14948 [(set (match_operand:SI 0 "register_operand" "")
14949 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14950 (clobber (match_scratch:SI 2 ""))
14951 (clobber (reg:CC FLAGS_REG))])]
14956 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14961 (define_expand "ffs_cmove"
14962 [(set (match_dup 2) (const_int -1))
14963 (parallel [(set (reg:CCZ FLAGS_REG)
14964 (compare:CCZ (match_operand:SI 1 "register_operand" "")
14966 (set (match_operand:SI 0 "nonimmediate_operand" "")
14967 (ctz:SI (match_dup 1)))])
14968 (set (match_dup 0) (if_then_else:SI
14969 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14972 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14973 (clobber (reg:CC FLAGS_REG))])]
14975 "operands[2] = gen_reg_rtx (SImode);")
14977 (define_insn_and_split "*ffs_no_cmove"
14978 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14979 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14980 (clobber (match_scratch:SI 2 "=&q"))
14981 (clobber (reg:CC FLAGS_REG))]
14984 "&& reload_completed"
14985 [(parallel [(set (reg:CCZ FLAGS_REG)
14986 (compare:CCZ (match_dup 1) (const_int 0)))
14987 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14988 (set (strict_low_part (match_dup 3))
14989 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14990 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14991 (clobber (reg:CC FLAGS_REG))])
14992 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14993 (clobber (reg:CC FLAGS_REG))])
14994 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14995 (clobber (reg:CC FLAGS_REG))])]
14997 operands[3] = gen_lowpart (QImode, operands[2]);
14998 ix86_expand_clear (operands[2]);
15001 (define_insn "*ffssi_1"
15002 [(set (reg:CCZ FLAGS_REG)
15003 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15005 (set (match_operand:SI 0 "register_operand" "=r")
15006 (ctz:SI (match_dup 1)))]
15008 "bsf{l}\t{%1, %0|%0, %1}"
15009 [(set_attr "prefix_0f" "1")])
15011 (define_expand "ffsdi2"
15012 [(set (match_dup 2) (const_int -1))
15013 (parallel [(set (reg:CCZ FLAGS_REG)
15014 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15016 (set (match_operand:DI 0 "nonimmediate_operand" "")
15017 (ctz:DI (match_dup 1)))])
15018 (set (match_dup 0) (if_then_else:DI
15019 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15022 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15023 (clobber (reg:CC FLAGS_REG))])]
15025 "operands[2] = gen_reg_rtx (DImode);")
15027 (define_insn "*ffsdi_1"
15028 [(set (reg:CCZ FLAGS_REG)
15029 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15031 (set (match_operand:DI 0 "register_operand" "=r")
15032 (ctz:DI (match_dup 1)))]
15034 "bsf{q}\t{%1, %0|%0, %1}"
15035 [(set_attr "prefix_0f" "1")])
15037 (define_insn "ctzsi2"
15038 [(set (match_operand:SI 0 "register_operand" "=r")
15039 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15040 (clobber (reg:CC FLAGS_REG))]
15042 "bsf{l}\t{%1, %0|%0, %1}"
15043 [(set_attr "prefix_0f" "1")])
15045 (define_insn "ctzdi2"
15046 [(set (match_operand:DI 0 "register_operand" "=r")
15047 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15048 (clobber (reg:CC FLAGS_REG))]
15050 "bsf{q}\t{%1, %0|%0, %1}"
15051 [(set_attr "prefix_0f" "1")])
15053 (define_expand "clzsi2"
15055 [(set (match_operand:SI 0 "register_operand" "")
15056 (minus:SI (const_int 31)
15057 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15058 (clobber (reg:CC FLAGS_REG))])
15060 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15061 (clobber (reg:CC FLAGS_REG))])]
15066 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15071 (define_insn "clzsi2_abm"
15072 [(set (match_operand:SI 0 "register_operand" "=r")
15073 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15074 (clobber (reg:CC FLAGS_REG))]
15076 "lzcnt{l}\t{%1, %0|%0, %1}"
15077 [(set_attr "prefix_rep" "1")
15078 (set_attr "type" "bitmanip")
15079 (set_attr "mode" "SI")])
15081 (define_insn "*bsr"
15082 [(set (match_operand:SI 0 "register_operand" "=r")
15083 (minus:SI (const_int 31)
15084 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15085 (clobber (reg:CC FLAGS_REG))]
15087 "bsr{l}\t{%1, %0|%0, %1}"
15088 [(set_attr "prefix_0f" "1")
15089 (set_attr "mode" "SI")])
15091 (define_insn "popcountsi2"
15092 [(set (match_operand:SI 0 "register_operand" "=r")
15093 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15094 (clobber (reg:CC FLAGS_REG))]
15096 "popcnt{l}\t{%1, %0|%0, %1}"
15097 [(set_attr "prefix_rep" "1")
15098 (set_attr "type" "bitmanip")
15099 (set_attr "mode" "SI")])
15101 (define_insn "*popcountsi2_cmp"
15102 [(set (reg FLAGS_REG)
15104 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15106 (set (match_operand:SI 0 "register_operand" "=r")
15107 (popcount:SI (match_dup 1)))]
15108 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15109 "popcnt{l}\t{%1, %0|%0, %1}"
15110 [(set_attr "prefix_rep" "1")
15111 (set_attr "type" "bitmanip")
15112 (set_attr "mode" "SI")])
15114 (define_insn "*popcountsi2_cmp_zext"
15115 [(set (reg FLAGS_REG)
15117 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15119 (set (match_operand:DI 0 "register_operand" "=r")
15120 (zero_extend:DI(popcount:SI (match_dup 1))))]
15121 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15122 "popcnt{l}\t{%1, %0|%0, %1}"
15123 [(set_attr "prefix_rep" "1")
15124 (set_attr "type" "bitmanip")
15125 (set_attr "mode" "SI")])
15127 (define_expand "bswapsi2"
15128 [(set (match_operand:SI 0 "register_operand" "")
15129 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15134 rtx x = operands[0];
15136 emit_move_insn (x, operands[1]);
15137 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15138 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15139 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15144 (define_insn "*bswapsi_1"
15145 [(set (match_operand:SI 0 "register_operand" "=r")
15146 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15149 [(set_attr "prefix_0f" "1")
15150 (set_attr "length" "2")])
15152 (define_insn "*bswaphi_lowpart_1"
15153 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15154 (bswap:HI (match_dup 0)))
15155 (clobber (reg:CC FLAGS_REG))]
15156 "TARGET_USE_XCHGB || optimize_size"
15158 xchg{b}\t{%h0, %b0|%b0, %h0}
15159 rol{w}\t{$8, %0|%0, 8}"
15160 [(set_attr "length" "2,4")
15161 (set_attr "mode" "QI,HI")])
15163 (define_insn "bswaphi_lowpart"
15164 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15165 (bswap:HI (match_dup 0)))
15166 (clobber (reg:CC FLAGS_REG))]
15168 "rol{w}\t{$8, %0|%0, 8}"
15169 [(set_attr "length" "4")
15170 (set_attr "mode" "HI")])
15172 (define_insn "bswapdi2"
15173 [(set (match_operand:DI 0 "register_operand" "=r")
15174 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15177 [(set_attr "prefix_0f" "1")
15178 (set_attr "length" "3")])
15180 (define_expand "clzdi2"
15182 [(set (match_operand:DI 0 "register_operand" "")
15183 (minus:DI (const_int 63)
15184 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15185 (clobber (reg:CC FLAGS_REG))])
15187 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15188 (clobber (reg:CC FLAGS_REG))])]
15193 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15198 (define_insn "clzdi2_abm"
15199 [(set (match_operand:DI 0 "register_operand" "=r")
15200 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15201 (clobber (reg:CC FLAGS_REG))]
15202 "TARGET_64BIT && TARGET_ABM"
15203 "lzcnt{q}\t{%1, %0|%0, %1}"
15204 [(set_attr "prefix_rep" "1")
15205 (set_attr "type" "bitmanip")
15206 (set_attr "mode" "DI")])
15208 (define_insn "*bsr_rex64"
15209 [(set (match_operand:DI 0 "register_operand" "=r")
15210 (minus:DI (const_int 63)
15211 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15212 (clobber (reg:CC FLAGS_REG))]
15214 "bsr{q}\t{%1, %0|%0, %1}"
15215 [(set_attr "prefix_0f" "1")
15216 (set_attr "mode" "DI")])
15218 (define_insn "popcountdi2"
15219 [(set (match_operand:DI 0 "register_operand" "=r")
15220 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15221 (clobber (reg:CC FLAGS_REG))]
15222 "TARGET_64BIT && TARGET_POPCNT"
15223 "popcnt{q}\t{%1, %0|%0, %1}"
15224 [(set_attr "prefix_rep" "1")
15225 (set_attr "type" "bitmanip")
15226 (set_attr "mode" "DI")])
15228 (define_insn "*popcountdi2_cmp"
15229 [(set (reg FLAGS_REG)
15231 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15233 (set (match_operand:DI 0 "register_operand" "=r")
15234 (popcount:DI (match_dup 1)))]
15235 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15236 "popcnt{q}\t{%1, %0|%0, %1}"
15237 [(set_attr "prefix_rep" "1")
15238 (set_attr "type" "bitmanip")
15239 (set_attr "mode" "DI")])
15241 (define_expand "clzhi2"
15243 [(set (match_operand:HI 0 "register_operand" "")
15244 (minus:HI (const_int 15)
15245 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15246 (clobber (reg:CC FLAGS_REG))])
15248 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15249 (clobber (reg:CC FLAGS_REG))])]
15254 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15259 (define_insn "clzhi2_abm"
15260 [(set (match_operand:HI 0 "register_operand" "=r")
15261 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15262 (clobber (reg:CC FLAGS_REG))]
15264 "lzcnt{w}\t{%1, %0|%0, %1}"
15265 [(set_attr "prefix_rep" "1")
15266 (set_attr "type" "bitmanip")
15267 (set_attr "mode" "HI")])
15269 (define_insn "*bsrhi"
15270 [(set (match_operand:HI 0 "register_operand" "=r")
15271 (minus:HI (const_int 15)
15272 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15273 (clobber (reg:CC FLAGS_REG))]
15275 "bsr{w}\t{%1, %0|%0, %1}"
15276 [(set_attr "prefix_0f" "1")
15277 (set_attr "mode" "HI")])
15279 (define_insn "popcounthi2"
15280 [(set (match_operand:HI 0 "register_operand" "=r")
15281 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15282 (clobber (reg:CC FLAGS_REG))]
15284 "popcnt{w}\t{%1, %0|%0, %1}"
15285 [(set_attr "prefix_rep" "1")
15286 (set_attr "type" "bitmanip")
15287 (set_attr "mode" "HI")])
15289 (define_insn "*popcounthi2_cmp"
15290 [(set (reg FLAGS_REG)
15292 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15294 (set (match_operand:HI 0 "register_operand" "=r")
15295 (popcount:HI (match_dup 1)))]
15296 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15297 "popcnt{w}\t{%1, %0|%0, %1}"
15298 [(set_attr "prefix_rep" "1")
15299 (set_attr "type" "bitmanip")
15300 (set_attr "mode" "HI")])
15302 (define_expand "paritydi2"
15303 [(set (match_operand:DI 0 "register_operand" "")
15304 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15307 rtx scratch = gen_reg_rtx (QImode);
15310 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15311 NULL_RTX, operands[1]));
15313 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15314 gen_rtx_REG (CCmode, FLAGS_REG),
15316 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15319 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15322 rtx tmp = gen_reg_rtx (SImode);
15324 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15325 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15330 (define_insn_and_split "paritydi2_cmp"
15331 [(set (reg:CC FLAGS_REG)
15332 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15333 (clobber (match_scratch:DI 0 "=r"))
15334 (clobber (match_scratch:SI 1 "=&r"))
15335 (clobber (match_scratch:HI 2 "=Q"))]
15338 "&& reload_completed"
15340 [(set (match_dup 1)
15341 (xor:SI (match_dup 1) (match_dup 4)))
15342 (clobber (reg:CC FLAGS_REG))])
15344 [(set (reg:CC FLAGS_REG)
15345 (parity:CC (match_dup 1)))
15346 (clobber (match_dup 1))
15347 (clobber (match_dup 2))])]
15349 operands[4] = gen_lowpart (SImode, operands[3]);
15353 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15354 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15357 operands[1] = gen_highpart (SImode, operands[3]);
15360 (define_expand "paritysi2"
15361 [(set (match_operand:SI 0 "register_operand" "")
15362 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15365 rtx scratch = gen_reg_rtx (QImode);
15368 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15370 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15371 gen_rtx_REG (CCmode, FLAGS_REG),
15373 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15375 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15379 (define_insn_and_split "paritysi2_cmp"
15380 [(set (reg:CC FLAGS_REG)
15381 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15382 (clobber (match_scratch:SI 0 "=r"))
15383 (clobber (match_scratch:HI 1 "=&Q"))]
15386 "&& reload_completed"
15388 [(set (match_dup 1)
15389 (xor:HI (match_dup 1) (match_dup 3)))
15390 (clobber (reg:CC FLAGS_REG))])
15392 [(set (reg:CC FLAGS_REG)
15393 (parity:CC (match_dup 1)))
15394 (clobber (match_dup 1))])]
15396 operands[3] = gen_lowpart (HImode, operands[2]);
15398 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15399 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15402 (define_insn "*parityhi2_cmp"
15403 [(set (reg:CC FLAGS_REG)
15404 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15405 (clobber (match_scratch:HI 0 "=Q"))]
15407 "xor{b}\t{%h0, %b0|%b0, %h0}"
15408 [(set_attr "length" "2")
15409 (set_attr "mode" "HI")])
15411 (define_insn "*parityqi2_cmp"
15412 [(set (reg:CC FLAGS_REG)
15413 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15416 [(set_attr "length" "2")
15417 (set_attr "mode" "QI")])
15419 ;; Thread-local storage patterns for ELF.
15421 ;; Note that these code sequences must appear exactly as shown
15422 ;; in order to allow linker relaxation.
15424 (define_insn "*tls_global_dynamic_32_gnu"
15425 [(set (match_operand:SI 0 "register_operand" "=a")
15426 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15427 (match_operand:SI 2 "tls_symbolic_operand" "")
15428 (match_operand:SI 3 "call_insn_operand" "")]
15430 (clobber (match_scratch:SI 4 "=d"))
15431 (clobber (match_scratch:SI 5 "=c"))
15432 (clobber (reg:CC FLAGS_REG))]
15433 "!TARGET_64BIT && TARGET_GNU_TLS"
15434 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15435 [(set_attr "type" "multi")
15436 (set_attr "length" "12")])
15438 (define_insn "*tls_global_dynamic_32_sun"
15439 [(set (match_operand:SI 0 "register_operand" "=a")
15440 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15441 (match_operand:SI 2 "tls_symbolic_operand" "")
15442 (match_operand:SI 3 "call_insn_operand" "")]
15444 (clobber (match_scratch:SI 4 "=d"))
15445 (clobber (match_scratch:SI 5 "=c"))
15446 (clobber (reg:CC FLAGS_REG))]
15447 "!TARGET_64BIT && TARGET_SUN_TLS"
15448 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15449 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15450 [(set_attr "type" "multi")
15451 (set_attr "length" "14")])
15453 (define_expand "tls_global_dynamic_32"
15454 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15457 (match_operand:SI 1 "tls_symbolic_operand" "")
15460 (clobber (match_scratch:SI 4 ""))
15461 (clobber (match_scratch:SI 5 ""))
15462 (clobber (reg:CC FLAGS_REG))])]
15466 operands[2] = pic_offset_table_rtx;
15469 operands[2] = gen_reg_rtx (Pmode);
15470 emit_insn (gen_set_got (operands[2]));
15472 if (TARGET_GNU2_TLS)
15474 emit_insn (gen_tls_dynamic_gnu2_32
15475 (operands[0], operands[1], operands[2]));
15478 operands[3] = ix86_tls_get_addr ();
15481 (define_insn "*tls_global_dynamic_64"
15482 [(set (match_operand:DI 0 "register_operand" "=a")
15483 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15484 (match_operand:DI 3 "" "")))
15485 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15488 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15489 [(set_attr "type" "multi")
15490 (set_attr "length" "16")])
15492 (define_expand "tls_global_dynamic_64"
15493 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15494 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15495 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15499 if (TARGET_GNU2_TLS)
15501 emit_insn (gen_tls_dynamic_gnu2_64
15502 (operands[0], operands[1]));
15505 operands[2] = ix86_tls_get_addr ();
15508 (define_insn "*tls_local_dynamic_base_32_gnu"
15509 [(set (match_operand:SI 0 "register_operand" "=a")
15510 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15511 (match_operand:SI 2 "call_insn_operand" "")]
15512 UNSPEC_TLS_LD_BASE))
15513 (clobber (match_scratch:SI 3 "=d"))
15514 (clobber (match_scratch:SI 4 "=c"))
15515 (clobber (reg:CC FLAGS_REG))]
15516 "!TARGET_64BIT && TARGET_GNU_TLS"
15517 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15518 [(set_attr "type" "multi")
15519 (set_attr "length" "11")])
15521 (define_insn "*tls_local_dynamic_base_32_sun"
15522 [(set (match_operand:SI 0 "register_operand" "=a")
15523 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15524 (match_operand:SI 2 "call_insn_operand" "")]
15525 UNSPEC_TLS_LD_BASE))
15526 (clobber (match_scratch:SI 3 "=d"))
15527 (clobber (match_scratch:SI 4 "=c"))
15528 (clobber (reg:CC FLAGS_REG))]
15529 "!TARGET_64BIT && TARGET_SUN_TLS"
15530 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15531 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15532 [(set_attr "type" "multi")
15533 (set_attr "length" "13")])
15535 (define_expand "tls_local_dynamic_base_32"
15536 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15537 (unspec:SI [(match_dup 1) (match_dup 2)]
15538 UNSPEC_TLS_LD_BASE))
15539 (clobber (match_scratch:SI 3 ""))
15540 (clobber (match_scratch:SI 4 ""))
15541 (clobber (reg:CC FLAGS_REG))])]
15545 operands[1] = pic_offset_table_rtx;
15548 operands[1] = gen_reg_rtx (Pmode);
15549 emit_insn (gen_set_got (operands[1]));
15551 if (TARGET_GNU2_TLS)
15553 emit_insn (gen_tls_dynamic_gnu2_32
15554 (operands[0], ix86_tls_module_base (), operands[1]));
15557 operands[2] = ix86_tls_get_addr ();
15560 (define_insn "*tls_local_dynamic_base_64"
15561 [(set (match_operand:DI 0 "register_operand" "=a")
15562 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15563 (match_operand:DI 2 "" "")))
15564 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15566 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15567 [(set_attr "type" "multi")
15568 (set_attr "length" "12")])
15570 (define_expand "tls_local_dynamic_base_64"
15571 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15572 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15573 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15576 if (TARGET_GNU2_TLS)
15578 emit_insn (gen_tls_dynamic_gnu2_64
15579 (operands[0], ix86_tls_module_base ()));
15582 operands[1] = ix86_tls_get_addr ();
15585 ;; Local dynamic of a single variable is a lose. Show combine how
15586 ;; to convert that back to global dynamic.
15588 (define_insn_and_split "*tls_local_dynamic_32_once"
15589 [(set (match_operand:SI 0 "register_operand" "=a")
15590 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15591 (match_operand:SI 2 "call_insn_operand" "")]
15592 UNSPEC_TLS_LD_BASE)
15593 (const:SI (unspec:SI
15594 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15596 (clobber (match_scratch:SI 4 "=d"))
15597 (clobber (match_scratch:SI 5 "=c"))
15598 (clobber (reg:CC FLAGS_REG))]
15602 [(parallel [(set (match_dup 0)
15603 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15605 (clobber (match_dup 4))
15606 (clobber (match_dup 5))
15607 (clobber (reg:CC FLAGS_REG))])]
15610 ;; Load and add the thread base pointer from %gs:0.
15612 (define_insn "*load_tp_si"
15613 [(set (match_operand:SI 0 "register_operand" "=r")
15614 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15616 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15617 [(set_attr "type" "imov")
15618 (set_attr "modrm" "0")
15619 (set_attr "length" "7")
15620 (set_attr "memory" "load")
15621 (set_attr "imm_disp" "false")])
15623 (define_insn "*add_tp_si"
15624 [(set (match_operand:SI 0 "register_operand" "=r")
15625 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15626 (match_operand:SI 1 "register_operand" "0")))
15627 (clobber (reg:CC FLAGS_REG))]
15629 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15630 [(set_attr "type" "alu")
15631 (set_attr "modrm" "0")
15632 (set_attr "length" "7")
15633 (set_attr "memory" "load")
15634 (set_attr "imm_disp" "false")])
15636 (define_insn "*load_tp_di"
15637 [(set (match_operand:DI 0 "register_operand" "=r")
15638 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15640 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15641 [(set_attr "type" "imov")
15642 (set_attr "modrm" "0")
15643 (set_attr "length" "7")
15644 (set_attr "memory" "load")
15645 (set_attr "imm_disp" "false")])
15647 (define_insn "*add_tp_di"
15648 [(set (match_operand:DI 0 "register_operand" "=r")
15649 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15650 (match_operand:DI 1 "register_operand" "0")))
15651 (clobber (reg:CC FLAGS_REG))]
15653 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15654 [(set_attr "type" "alu")
15655 (set_attr "modrm" "0")
15656 (set_attr "length" "7")
15657 (set_attr "memory" "load")
15658 (set_attr "imm_disp" "false")])
15660 ;; GNU2 TLS patterns can be split.
15662 (define_expand "tls_dynamic_gnu2_32"
15663 [(set (match_dup 3)
15664 (plus:SI (match_operand:SI 2 "register_operand" "")
15666 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15669 [(set (match_operand:SI 0 "register_operand" "")
15670 (unspec:SI [(match_dup 1) (match_dup 3)
15671 (match_dup 2) (reg:SI SP_REG)]
15673 (clobber (reg:CC FLAGS_REG))])]
15674 "!TARGET_64BIT && TARGET_GNU2_TLS"
15676 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15677 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15680 (define_insn "*tls_dynamic_lea_32"
15681 [(set (match_operand:SI 0 "register_operand" "=r")
15682 (plus:SI (match_operand:SI 1 "register_operand" "b")
15684 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15685 UNSPEC_TLSDESC))))]
15686 "!TARGET_64BIT && TARGET_GNU2_TLS"
15687 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15688 [(set_attr "type" "lea")
15689 (set_attr "mode" "SI")
15690 (set_attr "length" "6")
15691 (set_attr "length_address" "4")])
15693 (define_insn "*tls_dynamic_call_32"
15694 [(set (match_operand:SI 0 "register_operand" "=a")
15695 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15696 (match_operand:SI 2 "register_operand" "0")
15697 ;; we have to make sure %ebx still points to the GOT
15698 (match_operand:SI 3 "register_operand" "b")
15701 (clobber (reg:CC FLAGS_REG))]
15702 "!TARGET_64BIT && TARGET_GNU2_TLS"
15703 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15704 [(set_attr "type" "call")
15705 (set_attr "length" "2")
15706 (set_attr "length_address" "0")])
15708 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15709 [(set (match_operand:SI 0 "register_operand" "=&a")
15711 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15712 (match_operand:SI 4 "" "")
15713 (match_operand:SI 2 "register_operand" "b")
15716 (const:SI (unspec:SI
15717 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15719 (clobber (reg:CC FLAGS_REG))]
15720 "!TARGET_64BIT && TARGET_GNU2_TLS"
15723 [(set (match_dup 0) (match_dup 5))]
15725 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15726 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15729 (define_expand "tls_dynamic_gnu2_64"
15730 [(set (match_dup 2)
15731 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15734 [(set (match_operand:DI 0 "register_operand" "")
15735 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15737 (clobber (reg:CC FLAGS_REG))])]
15738 "TARGET_64BIT && TARGET_GNU2_TLS"
15740 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15741 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15744 (define_insn "*tls_dynamic_lea_64"
15745 [(set (match_operand:DI 0 "register_operand" "=r")
15746 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15748 "TARGET_64BIT && TARGET_GNU2_TLS"
15749 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15750 [(set_attr "type" "lea")
15751 (set_attr "mode" "DI")
15752 (set_attr "length" "7")
15753 (set_attr "length_address" "4")])
15755 (define_insn "*tls_dynamic_call_64"
15756 [(set (match_operand:DI 0 "register_operand" "=a")
15757 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15758 (match_operand:DI 2 "register_operand" "0")
15761 (clobber (reg:CC FLAGS_REG))]
15762 "TARGET_64BIT && TARGET_GNU2_TLS"
15763 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15764 [(set_attr "type" "call")
15765 (set_attr "length" "2")
15766 (set_attr "length_address" "0")])
15768 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15769 [(set (match_operand:DI 0 "register_operand" "=&a")
15771 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15772 (match_operand:DI 3 "" "")
15775 (const:DI (unspec:DI
15776 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15778 (clobber (reg:CC FLAGS_REG))]
15779 "TARGET_64BIT && TARGET_GNU2_TLS"
15782 [(set (match_dup 0) (match_dup 4))]
15784 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15785 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15790 ;; These patterns match the binary 387 instructions for addM3, subM3,
15791 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15792 ;; SFmode. The first is the normal insn, the second the same insn but
15793 ;; with one operand a conversion, and the third the same insn but with
15794 ;; the other operand a conversion. The conversion may be SFmode or
15795 ;; SImode if the target mode DFmode, but only SImode if the target mode
15798 ;; Gcc is slightly more smart about handling normal two address instructions
15799 ;; so use special patterns for add and mull.
15801 (define_insn "*fop_sf_comm_mixed"
15802 [(set (match_operand:SF 0 "register_operand" "=f,x")
15803 (match_operator:SF 3 "binary_fp_operator"
15804 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15805 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15806 "TARGET_MIX_SSE_I387
15807 && COMMUTATIVE_ARITH_P (operands[3])
15808 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15809 "* return output_387_binary_op (insn, operands);"
15810 [(set (attr "type")
15811 (if_then_else (eq_attr "alternative" "1")
15812 (if_then_else (match_operand:SF 3 "mult_operator" "")
15813 (const_string "ssemul")
15814 (const_string "sseadd"))
15815 (if_then_else (match_operand:SF 3 "mult_operator" "")
15816 (const_string "fmul")
15817 (const_string "fop"))))
15818 (set_attr "mode" "SF")])
15820 (define_insn "*fop_sf_comm_sse"
15821 [(set (match_operand:SF 0 "register_operand" "=x")
15822 (match_operator:SF 3 "binary_fp_operator"
15823 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15824 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15826 && COMMUTATIVE_ARITH_P (operands[3])
15827 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15828 "* return output_387_binary_op (insn, operands);"
15829 [(set (attr "type")
15830 (if_then_else (match_operand:SF 3 "mult_operator" "")
15831 (const_string "ssemul")
15832 (const_string "sseadd")))
15833 (set_attr "mode" "SF")])
15835 (define_insn "*fop_sf_comm_i387"
15836 [(set (match_operand:SF 0 "register_operand" "=f")
15837 (match_operator:SF 3 "binary_fp_operator"
15838 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15839 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15841 && COMMUTATIVE_ARITH_P (operands[3])
15842 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15843 "* return output_387_binary_op (insn, operands);"
15844 [(set (attr "type")
15845 (if_then_else (match_operand:SF 3 "mult_operator" "")
15846 (const_string "fmul")
15847 (const_string "fop")))
15848 (set_attr "mode" "SF")])
15850 (define_insn "*fop_sf_1_mixed"
15851 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15852 (match_operator:SF 3 "binary_fp_operator"
15853 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15854 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15855 "TARGET_MIX_SSE_I387
15856 && !COMMUTATIVE_ARITH_P (operands[3])
15857 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15858 "* return output_387_binary_op (insn, operands);"
15859 [(set (attr "type")
15860 (cond [(and (eq_attr "alternative" "2")
15861 (match_operand:SF 3 "mult_operator" ""))
15862 (const_string "ssemul")
15863 (and (eq_attr "alternative" "2")
15864 (match_operand:SF 3 "div_operator" ""))
15865 (const_string "ssediv")
15866 (eq_attr "alternative" "2")
15867 (const_string "sseadd")
15868 (match_operand:SF 3 "mult_operator" "")
15869 (const_string "fmul")
15870 (match_operand:SF 3 "div_operator" "")
15871 (const_string "fdiv")
15873 (const_string "fop")))
15874 (set_attr "mode" "SF")])
15876 (define_insn "*rcpsf2_sse"
15877 [(set (match_operand:SF 0 "register_operand" "=x")
15878 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15881 "rcpss\t{%1, %0|%0, %1}"
15882 [(set_attr "type" "sse")
15883 (set_attr "mode" "SF")])
15885 (define_insn "*fop_sf_1_sse"
15886 [(set (match_operand:SF 0 "register_operand" "=x")
15887 (match_operator:SF 3 "binary_fp_operator"
15888 [(match_operand:SF 1 "register_operand" "0")
15889 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15891 && !COMMUTATIVE_ARITH_P (operands[3])"
15892 "* return output_387_binary_op (insn, operands);"
15893 [(set (attr "type")
15894 (cond [(match_operand:SF 3 "mult_operator" "")
15895 (const_string "ssemul")
15896 (match_operand:SF 3 "div_operator" "")
15897 (const_string "ssediv")
15899 (const_string "sseadd")))
15900 (set_attr "mode" "SF")])
15902 ;; This pattern is not fully shadowed by the pattern above.
15903 (define_insn "*fop_sf_1_i387"
15904 [(set (match_operand:SF 0 "register_operand" "=f,f")
15905 (match_operator:SF 3 "binary_fp_operator"
15906 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15907 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15908 "TARGET_80387 && !TARGET_SSE_MATH
15909 && !COMMUTATIVE_ARITH_P (operands[3])
15910 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15911 "* return output_387_binary_op (insn, operands);"
15912 [(set (attr "type")
15913 (cond [(match_operand:SF 3 "mult_operator" "")
15914 (const_string "fmul")
15915 (match_operand:SF 3 "div_operator" "")
15916 (const_string "fdiv")
15918 (const_string "fop")))
15919 (set_attr "mode" "SF")])
15921 ;; ??? Add SSE splitters for these!
15922 (define_insn "*fop_sf_2<mode>_i387"
15923 [(set (match_operand:SF 0 "register_operand" "=f,f")
15924 (match_operator:SF 3 "binary_fp_operator"
15925 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15926 (match_operand:SF 2 "register_operand" "0,0")]))]
15927 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15928 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15929 [(set (attr "type")
15930 (cond [(match_operand:SF 3 "mult_operator" "")
15931 (const_string "fmul")
15932 (match_operand:SF 3 "div_operator" "")
15933 (const_string "fdiv")
15935 (const_string "fop")))
15936 (set_attr "fp_int_src" "true")
15937 (set_attr "mode" "<MODE>")])
15939 (define_insn "*fop_sf_3<mode>_i387"
15940 [(set (match_operand:SF 0 "register_operand" "=f,f")
15941 (match_operator:SF 3 "binary_fp_operator"
15942 [(match_operand:SF 1 "register_operand" "0,0")
15943 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15944 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15945 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15946 [(set (attr "type")
15947 (cond [(match_operand:SF 3 "mult_operator" "")
15948 (const_string "fmul")
15949 (match_operand:SF 3 "div_operator" "")
15950 (const_string "fdiv")
15952 (const_string "fop")))
15953 (set_attr "fp_int_src" "true")
15954 (set_attr "mode" "<MODE>")])
15956 (define_insn "*fop_df_comm_mixed"
15957 [(set (match_operand:DF 0 "register_operand" "=f,x")
15958 (match_operator:DF 3 "binary_fp_operator"
15959 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15960 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15961 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15962 && COMMUTATIVE_ARITH_P (operands[3])
15963 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15964 "* return output_387_binary_op (insn, operands);"
15965 [(set (attr "type")
15966 (if_then_else (eq_attr "alternative" "1")
15967 (if_then_else (match_operand:DF 3 "mult_operator" "")
15968 (const_string "ssemul")
15969 (const_string "sseadd"))
15970 (if_then_else (match_operand:DF 3 "mult_operator" "")
15971 (const_string "fmul")
15972 (const_string "fop"))))
15973 (set_attr "mode" "DF")])
15975 (define_insn "*fop_df_comm_sse"
15976 [(set (match_operand:DF 0 "register_operand" "=x")
15977 (match_operator:DF 3 "binary_fp_operator"
15978 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15979 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15980 "TARGET_SSE2 && TARGET_SSE_MATH
15981 && COMMUTATIVE_ARITH_P (operands[3])
15982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15983 "* return output_387_binary_op (insn, operands);"
15984 [(set (attr "type")
15985 (if_then_else (match_operand:DF 3 "mult_operator" "")
15986 (const_string "ssemul")
15987 (const_string "sseadd")))
15988 (set_attr "mode" "DF")])
15990 (define_insn "*fop_df_comm_i387"
15991 [(set (match_operand:DF 0 "register_operand" "=f")
15992 (match_operator:DF 3 "binary_fp_operator"
15993 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15994 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15996 && COMMUTATIVE_ARITH_P (operands[3])
15997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15998 "* return output_387_binary_op (insn, operands);"
15999 [(set (attr "type")
16000 (if_then_else (match_operand:DF 3 "mult_operator" "")
16001 (const_string "fmul")
16002 (const_string "fop")))
16003 (set_attr "mode" "DF")])
16005 (define_insn "*fop_df_1_mixed"
16006 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16007 (match_operator:DF 3 "binary_fp_operator"
16008 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16009 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16010 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16011 && !COMMUTATIVE_ARITH_P (operands[3])
16012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16013 "* return output_387_binary_op (insn, operands);"
16014 [(set (attr "type")
16015 (cond [(and (eq_attr "alternative" "2")
16016 (match_operand:DF 3 "mult_operator" ""))
16017 (const_string "ssemul")
16018 (and (eq_attr "alternative" "2")
16019 (match_operand:DF 3 "div_operator" ""))
16020 (const_string "ssediv")
16021 (eq_attr "alternative" "2")
16022 (const_string "sseadd")
16023 (match_operand:DF 3 "mult_operator" "")
16024 (const_string "fmul")
16025 (match_operand:DF 3 "div_operator" "")
16026 (const_string "fdiv")
16028 (const_string "fop")))
16029 (set_attr "mode" "DF")])
16031 (define_insn "*fop_df_1_sse"
16032 [(set (match_operand:DF 0 "register_operand" "=x")
16033 (match_operator:DF 3 "binary_fp_operator"
16034 [(match_operand:DF 1 "register_operand" "0")
16035 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16036 "TARGET_SSE2 && TARGET_SSE_MATH
16037 && !COMMUTATIVE_ARITH_P (operands[3])"
16038 "* return output_387_binary_op (insn, operands);"
16039 [(set_attr "mode" "DF")
16041 (cond [(match_operand:DF 3 "mult_operator" "")
16042 (const_string "ssemul")
16043 (match_operand:DF 3 "div_operator" "")
16044 (const_string "ssediv")
16046 (const_string "sseadd")))])
16048 ;; This pattern is not fully shadowed by the pattern above.
16049 (define_insn "*fop_df_1_i387"
16050 [(set (match_operand:DF 0 "register_operand" "=f,f")
16051 (match_operator:DF 3 "binary_fp_operator"
16052 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16053 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16054 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16055 && !COMMUTATIVE_ARITH_P (operands[3])
16056 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16057 "* return output_387_binary_op (insn, operands);"
16058 [(set (attr "type")
16059 (cond [(match_operand:DF 3 "mult_operator" "")
16060 (const_string "fmul")
16061 (match_operand:DF 3 "div_operator" "")
16062 (const_string "fdiv")
16064 (const_string "fop")))
16065 (set_attr "mode" "DF")])
16067 ;; ??? Add SSE splitters for these!
16068 (define_insn "*fop_df_2<mode>_i387"
16069 [(set (match_operand:DF 0 "register_operand" "=f,f")
16070 (match_operator:DF 3 "binary_fp_operator"
16071 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16072 (match_operand:DF 2 "register_operand" "0,0")]))]
16073 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16074 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16075 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16076 [(set (attr "type")
16077 (cond [(match_operand:DF 3 "mult_operator" "")
16078 (const_string "fmul")
16079 (match_operand:DF 3 "div_operator" "")
16080 (const_string "fdiv")
16082 (const_string "fop")))
16083 (set_attr "fp_int_src" "true")
16084 (set_attr "mode" "<MODE>")])
16086 (define_insn "*fop_df_3<mode>_i387"
16087 [(set (match_operand:DF 0 "register_operand" "=f,f")
16088 (match_operator:DF 3 "binary_fp_operator"
16089 [(match_operand:DF 1 "register_operand" "0,0")
16090 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16091 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16092 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16093 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16094 [(set (attr "type")
16095 (cond [(match_operand:DF 3 "mult_operator" "")
16096 (const_string "fmul")
16097 (match_operand:DF 3 "div_operator" "")
16098 (const_string "fdiv")
16100 (const_string "fop")))
16101 (set_attr "fp_int_src" "true")
16102 (set_attr "mode" "<MODE>")])
16104 (define_insn "*fop_df_4_i387"
16105 [(set (match_operand:DF 0 "register_operand" "=f,f")
16106 (match_operator:DF 3 "binary_fp_operator"
16107 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16108 (match_operand:DF 2 "register_operand" "0,f")]))]
16109 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16111 "* return output_387_binary_op (insn, operands);"
16112 [(set (attr "type")
16113 (cond [(match_operand:DF 3 "mult_operator" "")
16114 (const_string "fmul")
16115 (match_operand:DF 3 "div_operator" "")
16116 (const_string "fdiv")
16118 (const_string "fop")))
16119 (set_attr "mode" "SF")])
16121 (define_insn "*fop_df_5_i387"
16122 [(set (match_operand:DF 0 "register_operand" "=f,f")
16123 (match_operator:DF 3 "binary_fp_operator"
16124 [(match_operand:DF 1 "register_operand" "0,f")
16126 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16127 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16128 "* return output_387_binary_op (insn, operands);"
16129 [(set (attr "type")
16130 (cond [(match_operand:DF 3 "mult_operator" "")
16131 (const_string "fmul")
16132 (match_operand:DF 3 "div_operator" "")
16133 (const_string "fdiv")
16135 (const_string "fop")))
16136 (set_attr "mode" "SF")])
16138 (define_insn "*fop_df_6_i387"
16139 [(set (match_operand:DF 0 "register_operand" "=f,f")
16140 (match_operator:DF 3 "binary_fp_operator"
16142 (match_operand:SF 1 "register_operand" "0,f"))
16144 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16145 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16146 "* return output_387_binary_op (insn, operands);"
16147 [(set (attr "type")
16148 (cond [(match_operand:DF 3 "mult_operator" "")
16149 (const_string "fmul")
16150 (match_operand:DF 3 "div_operator" "")
16151 (const_string "fdiv")
16153 (const_string "fop")))
16154 (set_attr "mode" "SF")])
16156 (define_insn "*fop_xf_comm_i387"
16157 [(set (match_operand:XF 0 "register_operand" "=f")
16158 (match_operator:XF 3 "binary_fp_operator"
16159 [(match_operand:XF 1 "register_operand" "%0")
16160 (match_operand:XF 2 "register_operand" "f")]))]
16162 && COMMUTATIVE_ARITH_P (operands[3])"
16163 "* return output_387_binary_op (insn, operands);"
16164 [(set (attr "type")
16165 (if_then_else (match_operand:XF 3 "mult_operator" "")
16166 (const_string "fmul")
16167 (const_string "fop")))
16168 (set_attr "mode" "XF")])
16170 (define_insn "*fop_xf_1_i387"
16171 [(set (match_operand:XF 0 "register_operand" "=f,f")
16172 (match_operator:XF 3 "binary_fp_operator"
16173 [(match_operand:XF 1 "register_operand" "0,f")
16174 (match_operand:XF 2 "register_operand" "f,0")]))]
16176 && !COMMUTATIVE_ARITH_P (operands[3])"
16177 "* return output_387_binary_op (insn, operands);"
16178 [(set (attr "type")
16179 (cond [(match_operand:XF 3 "mult_operator" "")
16180 (const_string "fmul")
16181 (match_operand:XF 3 "div_operator" "")
16182 (const_string "fdiv")
16184 (const_string "fop")))
16185 (set_attr "mode" "XF")])
16187 (define_insn "*fop_xf_2<mode>_i387"
16188 [(set (match_operand:XF 0 "register_operand" "=f,f")
16189 (match_operator:XF 3 "binary_fp_operator"
16190 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16191 (match_operand:XF 2 "register_operand" "0,0")]))]
16192 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16193 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16194 [(set (attr "type")
16195 (cond [(match_operand:XF 3 "mult_operator" "")
16196 (const_string "fmul")
16197 (match_operand:XF 3 "div_operator" "")
16198 (const_string "fdiv")
16200 (const_string "fop")))
16201 (set_attr "fp_int_src" "true")
16202 (set_attr "mode" "<MODE>")])
16204 (define_insn "*fop_xf_3<mode>_i387"
16205 [(set (match_operand:XF 0 "register_operand" "=f,f")
16206 (match_operator:XF 3 "binary_fp_operator"
16207 [(match_operand:XF 1 "register_operand" "0,0")
16208 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16209 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16210 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16211 [(set (attr "type")
16212 (cond [(match_operand:XF 3 "mult_operator" "")
16213 (const_string "fmul")
16214 (match_operand:XF 3 "div_operator" "")
16215 (const_string "fdiv")
16217 (const_string "fop")))
16218 (set_attr "fp_int_src" "true")
16219 (set_attr "mode" "<MODE>")])
16221 (define_insn "*fop_xf_4_i387"
16222 [(set (match_operand:XF 0 "register_operand" "=f,f")
16223 (match_operator:XF 3 "binary_fp_operator"
16225 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16226 (match_operand:XF 2 "register_operand" "0,f")]))]
16228 "* return output_387_binary_op (insn, operands);"
16229 [(set (attr "type")
16230 (cond [(match_operand:XF 3 "mult_operator" "")
16231 (const_string "fmul")
16232 (match_operand:XF 3 "div_operator" "")
16233 (const_string "fdiv")
16235 (const_string "fop")))
16236 (set_attr "mode" "SF")])
16238 (define_insn "*fop_xf_5_i387"
16239 [(set (match_operand:XF 0 "register_operand" "=f,f")
16240 (match_operator:XF 3 "binary_fp_operator"
16241 [(match_operand:XF 1 "register_operand" "0,f")
16243 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16245 "* return output_387_binary_op (insn, operands);"
16246 [(set (attr "type")
16247 (cond [(match_operand:XF 3 "mult_operator" "")
16248 (const_string "fmul")
16249 (match_operand:XF 3 "div_operator" "")
16250 (const_string "fdiv")
16252 (const_string "fop")))
16253 (set_attr "mode" "SF")])
16255 (define_insn "*fop_xf_6_i387"
16256 [(set (match_operand:XF 0 "register_operand" "=f,f")
16257 (match_operator:XF 3 "binary_fp_operator"
16259 (match_operand:MODEF 1 "register_operand" "0,f"))
16261 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16263 "* return output_387_binary_op (insn, operands);"
16264 [(set (attr "type")
16265 (cond [(match_operand:XF 3 "mult_operator" "")
16266 (const_string "fmul")
16267 (match_operand:XF 3 "div_operator" "")
16268 (const_string "fdiv")
16270 (const_string "fop")))
16271 (set_attr "mode" "SF")])
16274 [(set (match_operand 0 "register_operand" "")
16275 (match_operator 3 "binary_fp_operator"
16276 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16277 (match_operand 2 "register_operand" "")]))]
16279 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16282 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16283 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16284 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16285 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16286 GET_MODE (operands[3]),
16289 ix86_free_from_memory (GET_MODE (operands[1]));
16294 [(set (match_operand 0 "register_operand" "")
16295 (match_operator 3 "binary_fp_operator"
16296 [(match_operand 1 "register_operand" "")
16297 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16299 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16302 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16303 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16304 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16305 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16306 GET_MODE (operands[3]),
16309 ix86_free_from_memory (GET_MODE (operands[2]));
16313 ;; FPU special functions.
16315 ;; This pattern implements a no-op XFmode truncation for
16316 ;; all fancy i386 XFmode math functions.
16318 (define_insn "truncxf<mode>2_i387_noop_unspec"
16319 [(set (match_operand:MODEF 0 "register_operand" "=f")
16320 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16321 UNSPEC_TRUNC_NOOP))]
16322 "TARGET_USE_FANCY_MATH_387"
16323 "* return output_387_reg_move (insn, operands);"
16324 [(set_attr "type" "fmov")
16325 (set_attr "mode" "<MODE>")])
16327 (define_insn "sqrtxf2"
16328 [(set (match_operand:XF 0 "register_operand" "=f")
16329 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16330 "TARGET_USE_FANCY_MATH_387"
16332 [(set_attr "type" "fpspc")
16333 (set_attr "mode" "XF")
16334 (set_attr "athlon_decode" "direct")
16335 (set_attr "amdfam10_decode" "direct")])
16337 (define_insn "sqrt_extend<mode>xf2_i387"
16338 [(set (match_operand:XF 0 "register_operand" "=f")
16341 (match_operand:MODEF 1 "register_operand" "0"))))]
16342 "TARGET_USE_FANCY_MATH_387"
16344 [(set_attr "type" "fpspc")
16345 (set_attr "mode" "XF")
16346 (set_attr "athlon_decode" "direct")
16347 (set_attr "amdfam10_decode" "direct")])
16349 (define_insn "*rsqrtsf2_sse"
16350 [(set (match_operand:SF 0 "register_operand" "=x")
16351 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16354 "rsqrtss\t{%1, %0|%0, %1}"
16355 [(set_attr "type" "sse")
16356 (set_attr "mode" "SF")])
16358 (define_expand "rsqrtsf2"
16359 [(set (match_operand:SF 0 "register_operand" "")
16360 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16364 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16368 (define_insn "*sqrt<mode>2_sse"
16369 [(set (match_operand:MODEF 0 "register_operand" "=x")
16371 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16372 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16373 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16374 [(set_attr "type" "sse")
16375 (set_attr "mode" "<MODE>")
16376 (set_attr "athlon_decode" "*")
16377 (set_attr "amdfam10_decode" "*")])
16379 (define_expand "sqrt<mode>2"
16380 [(set (match_operand:MODEF 0 "register_operand" "")
16382 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16383 "TARGET_USE_FANCY_MATH_387
16384 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16386 if (<MODE>mode == SFmode
16387 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16388 && flag_finite_math_only && !flag_trapping_math
16389 && flag_unsafe_math_optimizations)
16391 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16395 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16397 rtx op0 = gen_reg_rtx (XFmode);
16398 rtx op1 = force_reg (<MODE>mode, operands[1]);
16400 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16401 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16406 (define_insn "fpremxf4_i387"
16407 [(set (match_operand:XF 0 "register_operand" "=f")
16408 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16409 (match_operand:XF 3 "register_operand" "1")]
16411 (set (match_operand:XF 1 "register_operand" "=u")
16412 (unspec:XF [(match_dup 2) (match_dup 3)]
16414 (set (reg:CCFP FPSR_REG)
16415 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16417 "TARGET_USE_FANCY_MATH_387"
16419 [(set_attr "type" "fpspc")
16420 (set_attr "mode" "XF")])
16422 (define_expand "fmodxf3"
16423 [(use (match_operand:XF 0 "register_operand" ""))
16424 (use (match_operand:XF 1 "general_operand" ""))
16425 (use (match_operand:XF 2 "general_operand" ""))]
16426 "TARGET_USE_FANCY_MATH_387"
16428 rtx label = gen_label_rtx ();
16430 rtx op1 = gen_reg_rtx (XFmode);
16431 rtx op2 = gen_reg_rtx (XFmode);
16433 emit_move_insn (op1, operands[1]);
16434 emit_move_insn (op2, operands[2]);
16436 emit_label (label);
16437 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16438 ix86_emit_fp_unordered_jump (label);
16439 LABEL_NUSES (label) = 1;
16441 emit_move_insn (operands[0], op1);
16445 (define_expand "fmod<mode>3"
16446 [(use (match_operand:MODEF 0 "register_operand" ""))
16447 (use (match_operand:MODEF 1 "general_operand" ""))
16448 (use (match_operand:MODEF 2 "general_operand" ""))]
16449 "TARGET_USE_FANCY_MATH_387"
16451 rtx label = gen_label_rtx ();
16453 rtx op1 = gen_reg_rtx (XFmode);
16454 rtx op2 = gen_reg_rtx (XFmode);
16456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16457 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16459 emit_label (label);
16460 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16461 ix86_emit_fp_unordered_jump (label);
16462 LABEL_NUSES (label) = 1;
16464 /* Truncate the result properly for strict SSE math. */
16465 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16466 && !TARGET_MIX_SSE_I387)
16467 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16469 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16474 (define_insn "fprem1xf4_i387"
16475 [(set (match_operand:XF 0 "register_operand" "=f")
16476 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16477 (match_operand:XF 3 "register_operand" "1")]
16479 (set (match_operand:XF 1 "register_operand" "=u")
16480 (unspec:XF [(match_dup 2) (match_dup 3)]
16482 (set (reg:CCFP FPSR_REG)
16483 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16485 "TARGET_USE_FANCY_MATH_387"
16487 [(set_attr "type" "fpspc")
16488 (set_attr "mode" "XF")])
16490 (define_expand "remainderxf3"
16491 [(use (match_operand:XF 0 "register_operand" ""))
16492 (use (match_operand:XF 1 "general_operand" ""))
16493 (use (match_operand:XF 2 "general_operand" ""))]
16494 "TARGET_USE_FANCY_MATH_387"
16496 rtx label = gen_label_rtx ();
16498 rtx op1 = gen_reg_rtx (XFmode);
16499 rtx op2 = gen_reg_rtx (XFmode);
16501 emit_move_insn (op1, operands[1]);
16502 emit_move_insn (op2, operands[2]);
16504 emit_label (label);
16505 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16506 ix86_emit_fp_unordered_jump (label);
16507 LABEL_NUSES (label) = 1;
16509 emit_move_insn (operands[0], op1);
16513 (define_expand "remainder<mode>3"
16514 [(use (match_operand:MODEF 0 "register_operand" ""))
16515 (use (match_operand:MODEF 1 "general_operand" ""))
16516 (use (match_operand:MODEF 2 "general_operand" ""))]
16517 "TARGET_USE_FANCY_MATH_387"
16519 rtx label = gen_label_rtx ();
16521 rtx op1 = gen_reg_rtx (XFmode);
16522 rtx op2 = gen_reg_rtx (XFmode);
16524 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16525 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16527 emit_label (label);
16529 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16530 ix86_emit_fp_unordered_jump (label);
16531 LABEL_NUSES (label) = 1;
16533 /* Truncate the result properly for strict SSE math. */
16534 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16535 && !TARGET_MIX_SSE_I387)
16536 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16538 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16543 (define_insn "*sinxf2_i387"
16544 [(set (match_operand:XF 0 "register_operand" "=f")
16545 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16546 "TARGET_USE_FANCY_MATH_387
16547 && flag_unsafe_math_optimizations"
16549 [(set_attr "type" "fpspc")
16550 (set_attr "mode" "XF")])
16552 (define_insn "*sin_extend<mode>xf2_i387"
16553 [(set (match_operand:XF 0 "register_operand" "=f")
16554 (unspec:XF [(float_extend:XF
16555 (match_operand:MODEF 1 "register_operand" "0"))]
16557 "TARGET_USE_FANCY_MATH_387
16558 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16559 || TARGET_MIX_SSE_I387)
16560 && flag_unsafe_math_optimizations"
16562 [(set_attr "type" "fpspc")
16563 (set_attr "mode" "XF")])
16565 (define_insn "*cosxf2_i387"
16566 [(set (match_operand:XF 0 "register_operand" "=f")
16567 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16568 "TARGET_USE_FANCY_MATH_387
16569 && flag_unsafe_math_optimizations"
16571 [(set_attr "type" "fpspc")
16572 (set_attr "mode" "XF")])
16574 (define_insn "*cos_extend<mode>xf2_i387"
16575 [(set (match_operand:XF 0 "register_operand" "=f")
16576 (unspec:XF [(float_extend:XF
16577 (match_operand:MODEF 1 "register_operand" "0"))]
16579 "TARGET_USE_FANCY_MATH_387
16580 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16581 || TARGET_MIX_SSE_I387)
16582 && flag_unsafe_math_optimizations"
16584 [(set_attr "type" "fpspc")
16585 (set_attr "mode" "XF")])
16587 ;; When sincos pattern is defined, sin and cos builtin functions will be
16588 ;; expanded to sincos pattern with one of its outputs left unused.
16589 ;; CSE pass will figure out if two sincos patterns can be combined,
16590 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16591 ;; depending on the unused output.
16593 (define_insn "sincosxf3"
16594 [(set (match_operand:XF 0 "register_operand" "=f")
16595 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16596 UNSPEC_SINCOS_COS))
16597 (set (match_operand:XF 1 "register_operand" "=u")
16598 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16599 "TARGET_USE_FANCY_MATH_387
16600 && flag_unsafe_math_optimizations"
16602 [(set_attr "type" "fpspc")
16603 (set_attr "mode" "XF")])
16606 [(set (match_operand:XF 0 "register_operand" "")
16607 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16608 UNSPEC_SINCOS_COS))
16609 (set (match_operand:XF 1 "register_operand" "")
16610 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16611 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16612 && !(reload_completed || reload_in_progress)"
16613 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16617 [(set (match_operand:XF 0 "register_operand" "")
16618 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16619 UNSPEC_SINCOS_COS))
16620 (set (match_operand:XF 1 "register_operand" "")
16621 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16622 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16623 && !(reload_completed || reload_in_progress)"
16624 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16627 (define_insn "sincos_extend<mode>xf3_i387"
16628 [(set (match_operand:XF 0 "register_operand" "=f")
16629 (unspec:XF [(float_extend:XF
16630 (match_operand:MODEF 2 "register_operand" "0"))]
16631 UNSPEC_SINCOS_COS))
16632 (set (match_operand:XF 1 "register_operand" "=u")
16633 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16634 "TARGET_USE_FANCY_MATH_387
16635 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16636 || TARGET_MIX_SSE_I387)
16637 && flag_unsafe_math_optimizations"
16639 [(set_attr "type" "fpspc")
16640 (set_attr "mode" "XF")])
16643 [(set (match_operand:XF 0 "register_operand" "")
16644 (unspec:XF [(float_extend:XF
16645 (match_operand:MODEF 2 "register_operand" ""))]
16646 UNSPEC_SINCOS_COS))
16647 (set (match_operand:XF 1 "register_operand" "")
16648 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16649 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16650 && !(reload_completed || reload_in_progress)"
16651 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16655 [(set (match_operand:XF 0 "register_operand" "")
16656 (unspec:XF [(float_extend:XF
16657 (match_operand:MODEF 2 "register_operand" ""))]
16658 UNSPEC_SINCOS_COS))
16659 (set (match_operand:XF 1 "register_operand" "")
16660 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16661 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16662 && !(reload_completed || reload_in_progress)"
16663 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16666 (define_expand "sincos<mode>3"
16667 [(use (match_operand:MODEF 0 "register_operand" ""))
16668 (use (match_operand:MODEF 1 "register_operand" ""))
16669 (use (match_operand:MODEF 2 "register_operand" ""))]
16670 "TARGET_USE_FANCY_MATH_387
16671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16672 || TARGET_MIX_SSE_I387)
16673 && flag_unsafe_math_optimizations"
16675 rtx op0 = gen_reg_rtx (XFmode);
16676 rtx op1 = gen_reg_rtx (XFmode);
16678 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16679 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16680 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16684 (define_insn "fptanxf4_i387"
16685 [(set (match_operand:XF 0 "register_operand" "=f")
16686 (match_operand:XF 3 "const_double_operand" "F"))
16687 (set (match_operand:XF 1 "register_operand" "=u")
16688 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16690 "TARGET_USE_FANCY_MATH_387
16691 && flag_unsafe_math_optimizations
16692 && standard_80387_constant_p (operands[3]) == 2"
16694 [(set_attr "type" "fpspc")
16695 (set_attr "mode" "XF")])
16697 (define_insn "fptan_extend<mode>xf4_i387"
16698 [(set (match_operand:MODEF 0 "register_operand" "=f")
16699 (match_operand:MODEF 3 "const_double_operand" "F"))
16700 (set (match_operand:XF 1 "register_operand" "=u")
16701 (unspec:XF [(float_extend:XF
16702 (match_operand:MODEF 2 "register_operand" "0"))]
16704 "TARGET_USE_FANCY_MATH_387
16705 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16706 || TARGET_MIX_SSE_I387)
16707 && flag_unsafe_math_optimizations
16708 && standard_80387_constant_p (operands[3]) == 2"
16710 [(set_attr "type" "fpspc")
16711 (set_attr "mode" "XF")])
16713 (define_expand "tanxf2"
16714 [(use (match_operand:XF 0 "register_operand" ""))
16715 (use (match_operand:XF 1 "register_operand" ""))]
16716 "TARGET_USE_FANCY_MATH_387
16717 && flag_unsafe_math_optimizations"
16719 rtx one = gen_reg_rtx (XFmode);
16720 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16722 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16726 (define_expand "tan<mode>2"
16727 [(use (match_operand:MODEF 0 "register_operand" ""))
16728 (use (match_operand:MODEF 1 "register_operand" ""))]
16729 "TARGET_USE_FANCY_MATH_387
16730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16731 || TARGET_MIX_SSE_I387)
16732 && flag_unsafe_math_optimizations"
16734 rtx op0 = gen_reg_rtx (XFmode);
16736 rtx one = gen_reg_rtx (<MODE>mode);
16737 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16739 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16740 operands[1], op2));
16741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16745 (define_insn "*fpatanxf3_i387"
16746 [(set (match_operand:XF 0 "register_operand" "=f")
16747 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16748 (match_operand:XF 2 "register_operand" "u")]
16750 (clobber (match_scratch:XF 3 "=2"))]
16751 "TARGET_USE_FANCY_MATH_387
16752 && flag_unsafe_math_optimizations"
16754 [(set_attr "type" "fpspc")
16755 (set_attr "mode" "XF")])
16757 (define_insn "fpatan_extend<mode>xf3_i387"
16758 [(set (match_operand:XF 0 "register_operand" "=f")
16759 (unspec:XF [(float_extend:XF
16760 (match_operand:MODEF 1 "register_operand" "0"))
16762 (match_operand:MODEF 2 "register_operand" "u"))]
16764 (clobber (match_scratch:XF 3 "=2"))]
16765 "TARGET_USE_FANCY_MATH_387
16766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16767 || TARGET_MIX_SSE_I387)
16768 && flag_unsafe_math_optimizations"
16770 [(set_attr "type" "fpspc")
16771 (set_attr "mode" "XF")])
16773 (define_expand "atan2xf3"
16774 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16775 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16776 (match_operand:XF 1 "register_operand" "")]
16778 (clobber (match_scratch:XF 3 ""))])]
16779 "TARGET_USE_FANCY_MATH_387
16780 && flag_unsafe_math_optimizations"
16783 (define_expand "atan2<mode>3"
16784 [(use (match_operand:MODEF 0 "register_operand" ""))
16785 (use (match_operand:MODEF 1 "register_operand" ""))
16786 (use (match_operand:MODEF 2 "register_operand" ""))]
16787 "TARGET_USE_FANCY_MATH_387
16788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16789 || TARGET_MIX_SSE_I387)
16790 && flag_unsafe_math_optimizations"
16792 rtx op0 = gen_reg_rtx (XFmode);
16794 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16799 (define_expand "atanxf2"
16800 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16801 (unspec:XF [(match_dup 2)
16802 (match_operand:XF 1 "register_operand" "")]
16804 (clobber (match_scratch:XF 3 ""))])]
16805 "TARGET_USE_FANCY_MATH_387
16806 && flag_unsafe_math_optimizations"
16808 operands[2] = gen_reg_rtx (XFmode);
16809 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16812 (define_expand "atan<mode>2"
16813 [(use (match_operand:MODEF 0 "register_operand" ""))
16814 (use (match_operand:MODEF 1 "register_operand" ""))]
16815 "TARGET_USE_FANCY_MATH_387
16816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16817 || TARGET_MIX_SSE_I387)
16818 && flag_unsafe_math_optimizations"
16820 rtx op0 = gen_reg_rtx (XFmode);
16822 rtx op2 = gen_reg_rtx (<MODE>mode);
16823 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16825 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16826 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16830 (define_expand "asinxf2"
16831 [(set (match_dup 2)
16832 (mult:XF (match_operand:XF 1 "register_operand" "")
16834 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16835 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16836 (parallel [(set (match_operand:XF 0 "register_operand" "")
16837 (unspec:XF [(match_dup 5) (match_dup 1)]
16839 (clobber (match_scratch:XF 6 ""))])]
16840 "TARGET_USE_FANCY_MATH_387
16841 && flag_unsafe_math_optimizations && !optimize_size"
16845 for (i = 2; i < 6; i++)
16846 operands[i] = gen_reg_rtx (XFmode);
16848 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16851 (define_expand "asin<mode>2"
16852 [(use (match_operand:MODEF 0 "register_operand" ""))
16853 (use (match_operand:MODEF 1 "general_operand" ""))]
16854 "TARGET_USE_FANCY_MATH_387
16855 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16856 || TARGET_MIX_SSE_I387)
16857 && flag_unsafe_math_optimizations && !optimize_size"
16859 rtx op0 = gen_reg_rtx (XFmode);
16860 rtx op1 = gen_reg_rtx (XFmode);
16862 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16863 emit_insn (gen_asinxf2 (op0, op1));
16864 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16868 (define_expand "acosxf2"
16869 [(set (match_dup 2)
16870 (mult:XF (match_operand:XF 1 "register_operand" "")
16872 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16873 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16874 (parallel [(set (match_operand:XF 0 "register_operand" "")
16875 (unspec:XF [(match_dup 1) (match_dup 5)]
16877 (clobber (match_scratch:XF 6 ""))])]
16878 "TARGET_USE_FANCY_MATH_387
16879 && flag_unsafe_math_optimizations && !optimize_size"
16883 for (i = 2; i < 6; i++)
16884 operands[i] = gen_reg_rtx (XFmode);
16886 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16889 (define_expand "acos<mode>2"
16890 [(use (match_operand:MODEF 0 "register_operand" ""))
16891 (use (match_operand:MODEF 1 "general_operand" ""))]
16892 "TARGET_USE_FANCY_MATH_387
16893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16894 || TARGET_MIX_SSE_I387)
16895 && flag_unsafe_math_optimizations && !optimize_size"
16897 rtx op0 = gen_reg_rtx (XFmode);
16898 rtx op1 = gen_reg_rtx (XFmode);
16900 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16901 emit_insn (gen_acosxf2 (op0, op1));
16902 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16906 (define_insn "fyl2xxf3_i387"
16907 [(set (match_operand:XF 0 "register_operand" "=f")
16908 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16909 (match_operand:XF 2 "register_operand" "u")]
16911 (clobber (match_scratch:XF 3 "=2"))]
16912 "TARGET_USE_FANCY_MATH_387
16913 && flag_unsafe_math_optimizations"
16915 [(set_attr "type" "fpspc")
16916 (set_attr "mode" "XF")])
16918 (define_insn "fyl2x_extend<mode>xf3_i387"
16919 [(set (match_operand:XF 0 "register_operand" "=f")
16920 (unspec:XF [(float_extend:XF
16921 (match_operand:MODEF 1 "register_operand" "0"))
16922 (match_operand:XF 2 "register_operand" "u")]
16924 (clobber (match_scratch:XF 3 "=2"))]
16925 "TARGET_USE_FANCY_MATH_387
16926 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16927 || TARGET_MIX_SSE_I387)
16928 && flag_unsafe_math_optimizations"
16930 [(set_attr "type" "fpspc")
16931 (set_attr "mode" "XF")])
16933 (define_expand "logxf2"
16934 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16935 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16936 (match_dup 2)] UNSPEC_FYL2X))
16937 (clobber (match_scratch:XF 3 ""))])]
16938 "TARGET_USE_FANCY_MATH_387
16939 && flag_unsafe_math_optimizations"
16941 operands[2] = gen_reg_rtx (XFmode);
16942 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16945 (define_expand "log<mode>2"
16946 [(use (match_operand:MODEF 0 "register_operand" ""))
16947 (use (match_operand:MODEF 1 "register_operand" ""))]
16948 "TARGET_USE_FANCY_MATH_387
16949 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16950 || TARGET_MIX_SSE_I387)
16951 && flag_unsafe_math_optimizations"
16953 rtx op0 = gen_reg_rtx (XFmode);
16955 rtx op2 = gen_reg_rtx (XFmode);
16956 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16958 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16959 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16963 (define_expand "log10xf2"
16964 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16965 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16966 (match_dup 2)] UNSPEC_FYL2X))
16967 (clobber (match_scratch:XF 3 ""))])]
16968 "TARGET_USE_FANCY_MATH_387
16969 && flag_unsafe_math_optimizations"
16971 operands[2] = gen_reg_rtx (XFmode);
16972 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16975 (define_expand "log10<mode>2"
16976 [(use (match_operand:MODEF 0 "register_operand" ""))
16977 (use (match_operand:MODEF 1 "register_operand" ""))]
16978 "TARGET_USE_FANCY_MATH_387
16979 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16980 || TARGET_MIX_SSE_I387)
16981 && flag_unsafe_math_optimizations"
16983 rtx op0 = gen_reg_rtx (XFmode);
16985 rtx op2 = gen_reg_rtx (XFmode);
16986 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16988 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16993 (define_expand "log2xf2"
16994 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16995 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16996 (match_dup 2)] UNSPEC_FYL2X))
16997 (clobber (match_scratch:XF 3 ""))])]
16998 "TARGET_USE_FANCY_MATH_387
16999 && flag_unsafe_math_optimizations"
17001 operands[2] = gen_reg_rtx (XFmode);
17002 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17005 (define_expand "log2<mode>2"
17006 [(use (match_operand:MODEF 0 "register_operand" ""))
17007 (use (match_operand:MODEF 1 "register_operand" ""))]
17008 "TARGET_USE_FANCY_MATH_387
17009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17010 || TARGET_MIX_SSE_I387)
17011 && flag_unsafe_math_optimizations"
17013 rtx op0 = gen_reg_rtx (XFmode);
17015 rtx op2 = gen_reg_rtx (XFmode);
17016 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17018 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17019 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17023 (define_insn "fyl2xp1xf3_i387"
17024 [(set (match_operand:XF 0 "register_operand" "=f")
17025 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17026 (match_operand:XF 2 "register_operand" "u")]
17028 (clobber (match_scratch:XF 3 "=2"))]
17029 "TARGET_USE_FANCY_MATH_387
17030 && flag_unsafe_math_optimizations"
17032 [(set_attr "type" "fpspc")
17033 (set_attr "mode" "XF")])
17035 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17036 [(set (match_operand:XF 0 "register_operand" "=f")
17037 (unspec:XF [(float_extend:XF
17038 (match_operand:MODEF 1 "register_operand" "0"))
17039 (match_operand:XF 2 "register_operand" "u")]
17041 (clobber (match_scratch:XF 3 "=2"))]
17042 "TARGET_USE_FANCY_MATH_387
17043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17044 || TARGET_MIX_SSE_I387)
17045 && flag_unsafe_math_optimizations"
17047 [(set_attr "type" "fpspc")
17048 (set_attr "mode" "XF")])
17050 (define_expand "log1pxf2"
17051 [(use (match_operand:XF 0 "register_operand" ""))
17052 (use (match_operand:XF 1 "register_operand" ""))]
17053 "TARGET_USE_FANCY_MATH_387
17054 && flag_unsafe_math_optimizations && !optimize_size"
17056 ix86_emit_i387_log1p (operands[0], operands[1]);
17060 (define_expand "log1p<mode>2"
17061 [(use (match_operand:MODEF 0 "register_operand" ""))
17062 (use (match_operand:MODEF 1 "register_operand" ""))]
17063 "TARGET_USE_FANCY_MATH_387
17064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17065 || TARGET_MIX_SSE_I387)
17066 && flag_unsafe_math_optimizations && !optimize_size"
17068 rtx op0 = gen_reg_rtx (XFmode);
17070 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17072 ix86_emit_i387_log1p (op0, operands[1]);
17073 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17077 (define_insn "fxtractxf3_i387"
17078 [(set (match_operand:XF 0 "register_operand" "=f")
17079 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17080 UNSPEC_XTRACT_FRACT))
17081 (set (match_operand:XF 1 "register_operand" "=u")
17082 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17083 "TARGET_USE_FANCY_MATH_387
17084 && flag_unsafe_math_optimizations"
17086 [(set_attr "type" "fpspc")
17087 (set_attr "mode" "XF")])
17089 (define_insn "fxtract_extend<mode>xf3_i387"
17090 [(set (match_operand:XF 0 "register_operand" "=f")
17091 (unspec:XF [(float_extend:XF
17092 (match_operand:MODEF 2 "register_operand" "0"))]
17093 UNSPEC_XTRACT_FRACT))
17094 (set (match_operand:XF 1 "register_operand" "=u")
17095 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17096 "TARGET_USE_FANCY_MATH_387
17097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17098 || TARGET_MIX_SSE_I387)
17099 && flag_unsafe_math_optimizations"
17101 [(set_attr "type" "fpspc")
17102 (set_attr "mode" "XF")])
17104 (define_expand "logbxf2"
17105 [(parallel [(set (match_dup 2)
17106 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17107 UNSPEC_XTRACT_FRACT))
17108 (set (match_operand:XF 0 "register_operand" "")
17109 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17110 "TARGET_USE_FANCY_MATH_387
17111 && flag_unsafe_math_optimizations"
17113 operands[2] = gen_reg_rtx (XFmode);
17116 (define_expand "logb<mode>2"
17117 [(use (match_operand:MODEF 0 "register_operand" ""))
17118 (use (match_operand:MODEF 1 "register_operand" ""))]
17119 "TARGET_USE_FANCY_MATH_387
17120 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17121 || TARGET_MIX_SSE_I387)
17122 && flag_unsafe_math_optimizations"
17124 rtx op0 = gen_reg_rtx (XFmode);
17125 rtx op1 = gen_reg_rtx (XFmode);
17127 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17128 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17132 (define_expand "ilogbxf2"
17133 [(use (match_operand:SI 0 "register_operand" ""))
17134 (use (match_operand:XF 1 "register_operand" ""))]
17135 "TARGET_USE_FANCY_MATH_387
17136 && flag_unsafe_math_optimizations && !optimize_size"
17138 rtx op0 = gen_reg_rtx (XFmode);
17139 rtx op1 = gen_reg_rtx (XFmode);
17141 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17142 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17146 (define_expand "ilogb<mode>2"
17147 [(use (match_operand:SI 0 "register_operand" ""))
17148 (use (match_operand:MODEF 1 "register_operand" ""))]
17149 "TARGET_USE_FANCY_MATH_387
17150 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17151 || TARGET_MIX_SSE_I387)
17152 && flag_unsafe_math_optimizations && !optimize_size"
17154 rtx op0 = gen_reg_rtx (XFmode);
17155 rtx op1 = gen_reg_rtx (XFmode);
17157 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17158 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17162 (define_insn "*f2xm1xf2_i387"
17163 [(set (match_operand:XF 0 "register_operand" "=f")
17164 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17166 "TARGET_USE_FANCY_MATH_387
17167 && flag_unsafe_math_optimizations"
17169 [(set_attr "type" "fpspc")
17170 (set_attr "mode" "XF")])
17172 (define_insn "*fscalexf4_i387"
17173 [(set (match_operand:XF 0 "register_operand" "=f")
17174 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17175 (match_operand:XF 3 "register_operand" "1")]
17176 UNSPEC_FSCALE_FRACT))
17177 (set (match_operand:XF 1 "register_operand" "=u")
17178 (unspec:XF [(match_dup 2) (match_dup 3)]
17179 UNSPEC_FSCALE_EXP))]
17180 "TARGET_USE_FANCY_MATH_387
17181 && flag_unsafe_math_optimizations"
17183 [(set_attr "type" "fpspc")
17184 (set_attr "mode" "XF")])
17186 (define_expand "expNcorexf3"
17187 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17188 (match_operand:XF 2 "register_operand" "")))
17189 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17190 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17191 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17192 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17193 (parallel [(set (match_operand:XF 0 "register_operand" "")
17194 (unspec:XF [(match_dup 8) (match_dup 4)]
17195 UNSPEC_FSCALE_FRACT))
17197 (unspec:XF [(match_dup 8) (match_dup 4)]
17198 UNSPEC_FSCALE_EXP))])]
17199 "TARGET_USE_FANCY_MATH_387
17200 && flag_unsafe_math_optimizations && !optimize_size"
17204 for (i = 3; i < 10; i++)
17205 operands[i] = gen_reg_rtx (XFmode);
17207 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17210 (define_expand "expxf2"
17211 [(use (match_operand:XF 0 "register_operand" ""))
17212 (use (match_operand:XF 1 "register_operand" ""))]
17213 "TARGET_USE_FANCY_MATH_387
17214 && flag_unsafe_math_optimizations && !optimize_size"
17216 rtx op2 = gen_reg_rtx (XFmode);
17217 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17219 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17223 (define_expand "exp<mode>2"
17224 [(use (match_operand:MODEF 0 "register_operand" ""))
17225 (use (match_operand:MODEF 1 "general_operand" ""))]
17226 "TARGET_USE_FANCY_MATH_387
17227 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17228 || TARGET_MIX_SSE_I387)
17229 && flag_unsafe_math_optimizations && !optimize_size"
17231 rtx op0 = gen_reg_rtx (XFmode);
17232 rtx op1 = gen_reg_rtx (XFmode);
17234 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17235 emit_insn (gen_expxf2 (op0, op1));
17236 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17240 (define_expand "exp10xf2"
17241 [(use (match_operand:XF 0 "register_operand" ""))
17242 (use (match_operand:XF 1 "register_operand" ""))]
17243 "TARGET_USE_FANCY_MATH_387
17244 && flag_unsafe_math_optimizations && !optimize_size"
17246 rtx op2 = gen_reg_rtx (XFmode);
17247 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17249 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17253 (define_expand "exp10<mode>2"
17254 [(use (match_operand:MODEF 0 "register_operand" ""))
17255 (use (match_operand:MODEF 1 "general_operand" ""))]
17256 "TARGET_USE_FANCY_MATH_387
17257 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17258 || TARGET_MIX_SSE_I387)
17259 && flag_unsafe_math_optimizations && !optimize_size"
17261 rtx op0 = gen_reg_rtx (XFmode);
17262 rtx op1 = gen_reg_rtx (XFmode);
17264 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17265 emit_insn (gen_exp10xf2 (op0, op1));
17266 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17270 (define_expand "exp2xf2"
17271 [(use (match_operand:XF 0 "register_operand" ""))
17272 (use (match_operand:XF 1 "register_operand" ""))]
17273 "TARGET_USE_FANCY_MATH_387
17274 && flag_unsafe_math_optimizations && !optimize_size"
17276 rtx op2 = gen_reg_rtx (XFmode);
17277 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17279 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17283 (define_expand "exp2<mode>2"
17284 [(use (match_operand:MODEF 0 "register_operand" ""))
17285 (use (match_operand:MODEF 1 "general_operand" ""))]
17286 "TARGET_USE_FANCY_MATH_387
17287 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17288 || TARGET_MIX_SSE_I387)
17289 && flag_unsafe_math_optimizations && !optimize_size"
17291 rtx op0 = gen_reg_rtx (XFmode);
17292 rtx op1 = gen_reg_rtx (XFmode);
17294 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17295 emit_insn (gen_exp2xf2 (op0, op1));
17296 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17300 (define_expand "expm1xf2"
17301 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17303 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17304 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17305 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17306 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17307 (parallel [(set (match_dup 7)
17308 (unspec:XF [(match_dup 6) (match_dup 4)]
17309 UNSPEC_FSCALE_FRACT))
17311 (unspec:XF [(match_dup 6) (match_dup 4)]
17312 UNSPEC_FSCALE_EXP))])
17313 (parallel [(set (match_dup 10)
17314 (unspec:XF [(match_dup 9) (match_dup 8)]
17315 UNSPEC_FSCALE_FRACT))
17316 (set (match_dup 11)
17317 (unspec:XF [(match_dup 9) (match_dup 8)]
17318 UNSPEC_FSCALE_EXP))])
17319 (set (match_dup 12) (minus:XF (match_dup 10)
17320 (float_extend:XF (match_dup 13))))
17321 (set (match_operand:XF 0 "register_operand" "")
17322 (plus:XF (match_dup 12) (match_dup 7)))]
17323 "TARGET_USE_FANCY_MATH_387
17324 && flag_unsafe_math_optimizations && !optimize_size"
17328 for (i = 2; i < 13; i++)
17329 operands[i] = gen_reg_rtx (XFmode);
17332 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17334 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17337 (define_expand "expm1<mode>2"
17338 [(use (match_operand:MODEF 0 "register_operand" ""))
17339 (use (match_operand:MODEF 1 "general_operand" ""))]
17340 "TARGET_USE_FANCY_MATH_387
17341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17342 || TARGET_MIX_SSE_I387)
17343 && flag_unsafe_math_optimizations && !optimize_size"
17345 rtx op0 = gen_reg_rtx (XFmode);
17346 rtx op1 = gen_reg_rtx (XFmode);
17348 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17349 emit_insn (gen_expm1xf2 (op0, op1));
17350 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17354 (define_expand "ldexpxf3"
17355 [(set (match_dup 3)
17356 (float:XF (match_operand:SI 2 "register_operand" "")))
17357 (parallel [(set (match_operand:XF 0 " register_operand" "")
17358 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17360 UNSPEC_FSCALE_FRACT))
17362 (unspec:XF [(match_dup 1) (match_dup 3)]
17363 UNSPEC_FSCALE_EXP))])]
17364 "TARGET_USE_FANCY_MATH_387
17365 && flag_unsafe_math_optimizations && !optimize_size"
17367 operands[3] = gen_reg_rtx (XFmode);
17368 operands[4] = gen_reg_rtx (XFmode);
17371 (define_expand "ldexp<mode>3"
17372 [(use (match_operand:MODEF 0 "register_operand" ""))
17373 (use (match_operand:MODEF 1 "general_operand" ""))
17374 (use (match_operand:SI 2 "register_operand" ""))]
17375 "TARGET_USE_FANCY_MATH_387
17376 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17377 || TARGET_MIX_SSE_I387)
17378 && flag_unsafe_math_optimizations && !optimize_size"
17380 rtx op0 = gen_reg_rtx (XFmode);
17381 rtx op1 = gen_reg_rtx (XFmode);
17383 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17384 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17385 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17389 (define_expand "scalbxf3"
17390 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17391 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17392 (match_operand:XF 2 "register_operand" "")]
17393 UNSPEC_FSCALE_FRACT))
17395 (unspec:XF [(match_dup 1) (match_dup 2)]
17396 UNSPEC_FSCALE_EXP))])]
17397 "TARGET_USE_FANCY_MATH_387
17398 && flag_unsafe_math_optimizations && !optimize_size"
17400 operands[3] = gen_reg_rtx (XFmode);
17403 (define_expand "scalb<mode>3"
17404 [(use (match_operand:MODEF 0 "register_operand" ""))
17405 (use (match_operand:MODEF 1 "general_operand" ""))
17406 (use (match_operand:MODEF 2 "register_operand" ""))]
17407 "TARGET_USE_FANCY_MATH_387
17408 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17409 || TARGET_MIX_SSE_I387)
17410 && flag_unsafe_math_optimizations && !optimize_size"
17412 rtx op0 = gen_reg_rtx (XFmode);
17413 rtx op1 = gen_reg_rtx (XFmode);
17414 rtx op2 = gen_reg_rtx (XFmode);
17416 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17417 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17418 emit_insn (gen_scalbxf3 (op0, op1, op2));
17419 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17424 (define_insn "sse4_1_round<mode>2"
17425 [(set (match_operand:MODEF 0 "register_operand" "=x")
17426 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17427 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17430 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17431 [(set_attr "type" "ssecvt")
17432 (set_attr "prefix_extra" "1")
17433 (set_attr "mode" "<MODE>")])
17435 (define_insn "rintxf2"
17436 [(set (match_operand:XF 0 "register_operand" "=f")
17437 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17439 "TARGET_USE_FANCY_MATH_387
17440 && flag_unsafe_math_optimizations"
17442 [(set_attr "type" "fpspc")
17443 (set_attr "mode" "XF")])
17445 (define_expand "rint<mode>2"
17446 [(use (match_operand:MODEF 0 "register_operand" ""))
17447 (use (match_operand:MODEF 1 "register_operand" ""))]
17448 "(TARGET_USE_FANCY_MATH_387
17449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17450 || TARGET_MIX_SSE_I387)
17451 && flag_unsafe_math_optimizations)
17452 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17453 && !flag_trapping_math
17454 && (TARGET_ROUND || !optimize_size))"
17456 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17457 && !flag_trapping_math
17458 && (TARGET_ROUND || !optimize_size))
17461 emit_insn (gen_sse4_1_round<mode>2
17462 (operands[0], operands[1], GEN_INT (0x04)));
17464 ix86_expand_rint (operand0, operand1);
17468 rtx op0 = gen_reg_rtx (XFmode);
17469 rtx op1 = gen_reg_rtx (XFmode);
17471 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17472 emit_insn (gen_rintxf2 (op0, op1));
17474 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17479 (define_expand "round<mode>2"
17480 [(match_operand:MODEF 0 "register_operand" "")
17481 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17482 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17483 && !flag_trapping_math && !flag_rounding_math
17486 if (TARGET_64BIT || (<MODE>mode != DFmode))
17487 ix86_expand_round (operand0, operand1);
17489 ix86_expand_rounddf_32 (operand0, operand1);
17493 (define_insn_and_split "*fistdi2_1"
17494 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17495 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17497 "TARGET_USE_FANCY_MATH_387
17498 && !(reload_completed || reload_in_progress)"
17503 if (memory_operand (operands[0], VOIDmode))
17504 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17507 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17508 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17513 [(set_attr "type" "fpspc")
17514 (set_attr "mode" "DI")])
17516 (define_insn "fistdi2"
17517 [(set (match_operand:DI 0 "memory_operand" "=m")
17518 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17520 (clobber (match_scratch:XF 2 "=&1f"))]
17521 "TARGET_USE_FANCY_MATH_387"
17522 "* return output_fix_trunc (insn, operands, 0);"
17523 [(set_attr "type" "fpspc")
17524 (set_attr "mode" "DI")])
17526 (define_insn "fistdi2_with_temp"
17527 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17528 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17530 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17531 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17532 "TARGET_USE_FANCY_MATH_387"
17534 [(set_attr "type" "fpspc")
17535 (set_attr "mode" "DI")])
17538 [(set (match_operand:DI 0 "register_operand" "")
17539 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17541 (clobber (match_operand:DI 2 "memory_operand" ""))
17542 (clobber (match_scratch 3 ""))]
17544 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17545 (clobber (match_dup 3))])
17546 (set (match_dup 0) (match_dup 2))]
17550 [(set (match_operand:DI 0 "memory_operand" "")
17551 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17553 (clobber (match_operand:DI 2 "memory_operand" ""))
17554 (clobber (match_scratch 3 ""))]
17556 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17557 (clobber (match_dup 3))])]
17560 (define_insn_and_split "*fist<mode>2_1"
17561 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17562 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17564 "TARGET_USE_FANCY_MATH_387
17565 && !(reload_completed || reload_in_progress)"
17570 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17571 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17575 [(set_attr "type" "fpspc")
17576 (set_attr "mode" "<MODE>")])
17578 (define_insn "fist<mode>2"
17579 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17580 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17582 "TARGET_USE_FANCY_MATH_387"
17583 "* return output_fix_trunc (insn, operands, 0);"
17584 [(set_attr "type" "fpspc")
17585 (set_attr "mode" "<MODE>")])
17587 (define_insn "fist<mode>2_with_temp"
17588 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17589 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17591 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17592 "TARGET_USE_FANCY_MATH_387"
17594 [(set_attr "type" "fpspc")
17595 (set_attr "mode" "<MODE>")])
17598 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17599 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17601 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17603 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17604 (set (match_dup 0) (match_dup 2))]
17608 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17609 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17611 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17613 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17616 (define_expand "lrintxf<mode>2"
17617 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17618 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17620 "TARGET_USE_FANCY_MATH_387"
17623 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17624 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17625 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17626 UNSPEC_FIX_NOTRUNC))]
17627 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17628 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17631 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17632 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17633 (match_operand:MODEF 1 "register_operand" "")]
17634 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17635 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17636 && !flag_trapping_math && !flag_rounding_math
17639 ix86_expand_lround (operand0, operand1);
17643 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17644 (define_insn_and_split "frndintxf2_floor"
17645 [(set (match_operand:XF 0 "register_operand" "")
17646 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17647 UNSPEC_FRNDINT_FLOOR))
17648 (clobber (reg:CC FLAGS_REG))]
17649 "TARGET_USE_FANCY_MATH_387
17650 && flag_unsafe_math_optimizations
17651 && !(reload_completed || reload_in_progress)"
17656 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17658 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17659 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17661 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17662 operands[2], operands[3]));
17665 [(set_attr "type" "frndint")
17666 (set_attr "i387_cw" "floor")
17667 (set_attr "mode" "XF")])
17669 (define_insn "frndintxf2_floor_i387"
17670 [(set (match_operand:XF 0 "register_operand" "=f")
17671 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17672 UNSPEC_FRNDINT_FLOOR))
17673 (use (match_operand:HI 2 "memory_operand" "m"))
17674 (use (match_operand:HI 3 "memory_operand" "m"))]
17675 "TARGET_USE_FANCY_MATH_387
17676 && flag_unsafe_math_optimizations"
17677 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17678 [(set_attr "type" "frndint")
17679 (set_attr "i387_cw" "floor")
17680 (set_attr "mode" "XF")])
17682 (define_expand "floorxf2"
17683 [(use (match_operand:XF 0 "register_operand" ""))
17684 (use (match_operand:XF 1 "register_operand" ""))]
17685 "TARGET_USE_FANCY_MATH_387
17686 && flag_unsafe_math_optimizations && !optimize_size"
17688 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17692 (define_expand "floor<mode>2"
17693 [(use (match_operand:MODEF 0 "register_operand" ""))
17694 (use (match_operand:MODEF 1 "register_operand" ""))]
17695 "(TARGET_USE_FANCY_MATH_387
17696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17697 || TARGET_MIX_SSE_I387)
17698 && flag_unsafe_math_optimizations && !optimize_size)
17699 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17700 && !flag_trapping_math
17701 && (TARGET_ROUND || !optimize_size))"
17703 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17704 && !flag_trapping_math
17705 && (TARGET_ROUND || !optimize_size))
17708 emit_insn (gen_sse4_1_round<mode>2
17709 (operands[0], operands[1], GEN_INT (0x01)));
17710 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17711 ix86_expand_floorceil (operand0, operand1, true);
17713 ix86_expand_floorceildf_32 (operand0, operand1, true);
17717 rtx op0 = gen_reg_rtx (XFmode);
17718 rtx op1 = gen_reg_rtx (XFmode);
17720 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17721 emit_insn (gen_frndintxf2_floor (op0, op1));
17723 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17728 (define_insn_and_split "*fist<mode>2_floor_1"
17729 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17730 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17731 UNSPEC_FIST_FLOOR))
17732 (clobber (reg:CC FLAGS_REG))]
17733 "TARGET_USE_FANCY_MATH_387
17734 && flag_unsafe_math_optimizations
17735 && !(reload_completed || reload_in_progress)"
17740 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17742 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17743 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17744 if (memory_operand (operands[0], VOIDmode))
17745 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17746 operands[2], operands[3]));
17749 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17750 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17751 operands[2], operands[3],
17756 [(set_attr "type" "fistp")
17757 (set_attr "i387_cw" "floor")
17758 (set_attr "mode" "<MODE>")])
17760 (define_insn "fistdi2_floor"
17761 [(set (match_operand:DI 0 "memory_operand" "=m")
17762 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17763 UNSPEC_FIST_FLOOR))
17764 (use (match_operand:HI 2 "memory_operand" "m"))
17765 (use (match_operand:HI 3 "memory_operand" "m"))
17766 (clobber (match_scratch:XF 4 "=&1f"))]
17767 "TARGET_USE_FANCY_MATH_387
17768 && flag_unsafe_math_optimizations"
17769 "* return output_fix_trunc (insn, operands, 0);"
17770 [(set_attr "type" "fistp")
17771 (set_attr "i387_cw" "floor")
17772 (set_attr "mode" "DI")])
17774 (define_insn "fistdi2_floor_with_temp"
17775 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17776 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17777 UNSPEC_FIST_FLOOR))
17778 (use (match_operand:HI 2 "memory_operand" "m,m"))
17779 (use (match_operand:HI 3 "memory_operand" "m,m"))
17780 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17781 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17782 "TARGET_USE_FANCY_MATH_387
17783 && flag_unsafe_math_optimizations"
17785 [(set_attr "type" "fistp")
17786 (set_attr "i387_cw" "floor")
17787 (set_attr "mode" "DI")])
17790 [(set (match_operand:DI 0 "register_operand" "")
17791 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17792 UNSPEC_FIST_FLOOR))
17793 (use (match_operand:HI 2 "memory_operand" ""))
17794 (use (match_operand:HI 3 "memory_operand" ""))
17795 (clobber (match_operand:DI 4 "memory_operand" ""))
17796 (clobber (match_scratch 5 ""))]
17798 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17799 (use (match_dup 2))
17800 (use (match_dup 3))
17801 (clobber (match_dup 5))])
17802 (set (match_dup 0) (match_dup 4))]
17806 [(set (match_operand:DI 0 "memory_operand" "")
17807 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17808 UNSPEC_FIST_FLOOR))
17809 (use (match_operand:HI 2 "memory_operand" ""))
17810 (use (match_operand:HI 3 "memory_operand" ""))
17811 (clobber (match_operand:DI 4 "memory_operand" ""))
17812 (clobber (match_scratch 5 ""))]
17814 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17815 (use (match_dup 2))
17816 (use (match_dup 3))
17817 (clobber (match_dup 5))])]
17820 (define_insn "fist<mode>2_floor"
17821 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17822 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17823 UNSPEC_FIST_FLOOR))
17824 (use (match_operand:HI 2 "memory_operand" "m"))
17825 (use (match_operand:HI 3 "memory_operand" "m"))]
17826 "TARGET_USE_FANCY_MATH_387
17827 && flag_unsafe_math_optimizations"
17828 "* return output_fix_trunc (insn, operands, 0);"
17829 [(set_attr "type" "fistp")
17830 (set_attr "i387_cw" "floor")
17831 (set_attr "mode" "<MODE>")])
17833 (define_insn "fist<mode>2_floor_with_temp"
17834 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17835 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17836 UNSPEC_FIST_FLOOR))
17837 (use (match_operand:HI 2 "memory_operand" "m,m"))
17838 (use (match_operand:HI 3 "memory_operand" "m,m"))
17839 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17840 "TARGET_USE_FANCY_MATH_387
17841 && flag_unsafe_math_optimizations"
17843 [(set_attr "type" "fistp")
17844 (set_attr "i387_cw" "floor")
17845 (set_attr "mode" "<MODE>")])
17848 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17849 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17850 UNSPEC_FIST_FLOOR))
17851 (use (match_operand:HI 2 "memory_operand" ""))
17852 (use (match_operand:HI 3 "memory_operand" ""))
17853 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17855 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17856 UNSPEC_FIST_FLOOR))
17857 (use (match_dup 2))
17858 (use (match_dup 3))])
17859 (set (match_dup 0) (match_dup 4))]
17863 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17864 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17865 UNSPEC_FIST_FLOOR))
17866 (use (match_operand:HI 2 "memory_operand" ""))
17867 (use (match_operand:HI 3 "memory_operand" ""))
17868 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17870 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17871 UNSPEC_FIST_FLOOR))
17872 (use (match_dup 2))
17873 (use (match_dup 3))])]
17876 (define_expand "lfloorxf<mode>2"
17877 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17878 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17879 UNSPEC_FIST_FLOOR))
17880 (clobber (reg:CC FLAGS_REG))])]
17881 "TARGET_USE_FANCY_MATH_387
17882 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17883 && flag_unsafe_math_optimizations"
17886 (define_expand "lfloor<mode>di2"
17887 [(match_operand:DI 0 "nonimmediate_operand" "")
17888 (match_operand:MODEF 1 "register_operand" "")]
17889 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17890 && !flag_trapping_math
17893 ix86_expand_lfloorceil (operand0, operand1, true);
17897 (define_expand "lfloor<mode>si2"
17898 [(match_operand:SI 0 "nonimmediate_operand" "")
17899 (match_operand:MODEF 1 "register_operand" "")]
17900 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17901 && !flag_trapping_math
17902 && (!optimize_size || !TARGET_64BIT)"
17904 ix86_expand_lfloorceil (operand0, operand1, true);
17908 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17909 (define_insn_and_split "frndintxf2_ceil"
17910 [(set (match_operand:XF 0 "register_operand" "")
17911 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17912 UNSPEC_FRNDINT_CEIL))
17913 (clobber (reg:CC FLAGS_REG))]
17914 "TARGET_USE_FANCY_MATH_387
17915 && flag_unsafe_math_optimizations
17916 && !(reload_completed || reload_in_progress)"
17921 ix86_optimize_mode_switching[I387_CEIL] = 1;
17923 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17924 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17926 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17927 operands[2], operands[3]));
17930 [(set_attr "type" "frndint")
17931 (set_attr "i387_cw" "ceil")
17932 (set_attr "mode" "XF")])
17934 (define_insn "frndintxf2_ceil_i387"
17935 [(set (match_operand:XF 0 "register_operand" "=f")
17936 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17937 UNSPEC_FRNDINT_CEIL))
17938 (use (match_operand:HI 2 "memory_operand" "m"))
17939 (use (match_operand:HI 3 "memory_operand" "m"))]
17940 "TARGET_USE_FANCY_MATH_387
17941 && flag_unsafe_math_optimizations"
17942 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17943 [(set_attr "type" "frndint")
17944 (set_attr "i387_cw" "ceil")
17945 (set_attr "mode" "XF")])
17947 (define_expand "ceilxf2"
17948 [(use (match_operand:XF 0 "register_operand" ""))
17949 (use (match_operand:XF 1 "register_operand" ""))]
17950 "TARGET_USE_FANCY_MATH_387
17951 && flag_unsafe_math_optimizations && !optimize_size"
17953 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17957 (define_expand "ceil<mode>2"
17958 [(use (match_operand:MODEF 0 "register_operand" ""))
17959 (use (match_operand:MODEF 1 "register_operand" ""))]
17960 "(TARGET_USE_FANCY_MATH_387
17961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17962 || TARGET_MIX_SSE_I387)
17963 && flag_unsafe_math_optimizations && !optimize_size)
17964 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17965 && !flag_trapping_math
17966 && (TARGET_ROUND || !optimize_size))"
17968 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17969 && !flag_trapping_math
17970 && (TARGET_ROUND || !optimize_size))
17973 emit_insn (gen_sse4_1_round<mode>2
17974 (operands[0], operands[1], GEN_INT (0x02)));
17975 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17976 ix86_expand_floorceil (operand0, operand1, false);
17978 ix86_expand_floorceildf_32 (operand0, operand1, false);
17982 rtx op0 = gen_reg_rtx (XFmode);
17983 rtx op1 = gen_reg_rtx (XFmode);
17985 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17986 emit_insn (gen_frndintxf2_ceil (op0, op1));
17988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17993 (define_insn_and_split "*fist<mode>2_ceil_1"
17994 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17995 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17997 (clobber (reg:CC FLAGS_REG))]
17998 "TARGET_USE_FANCY_MATH_387
17999 && flag_unsafe_math_optimizations
18000 && !(reload_completed || reload_in_progress)"
18005 ix86_optimize_mode_switching[I387_CEIL] = 1;
18007 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18008 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18009 if (memory_operand (operands[0], VOIDmode))
18010 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18011 operands[2], operands[3]));
18014 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18015 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18016 operands[2], operands[3],
18021 [(set_attr "type" "fistp")
18022 (set_attr "i387_cw" "ceil")
18023 (set_attr "mode" "<MODE>")])
18025 (define_insn "fistdi2_ceil"
18026 [(set (match_operand:DI 0 "memory_operand" "=m")
18027 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18029 (use (match_operand:HI 2 "memory_operand" "m"))
18030 (use (match_operand:HI 3 "memory_operand" "m"))
18031 (clobber (match_scratch:XF 4 "=&1f"))]
18032 "TARGET_USE_FANCY_MATH_387
18033 && flag_unsafe_math_optimizations"
18034 "* return output_fix_trunc (insn, operands, 0);"
18035 [(set_attr "type" "fistp")
18036 (set_attr "i387_cw" "ceil")
18037 (set_attr "mode" "DI")])
18039 (define_insn "fistdi2_ceil_with_temp"
18040 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18041 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18043 (use (match_operand:HI 2 "memory_operand" "m,m"))
18044 (use (match_operand:HI 3 "memory_operand" "m,m"))
18045 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18046 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18047 "TARGET_USE_FANCY_MATH_387
18048 && flag_unsafe_math_optimizations"
18050 [(set_attr "type" "fistp")
18051 (set_attr "i387_cw" "ceil")
18052 (set_attr "mode" "DI")])
18055 [(set (match_operand:DI 0 "register_operand" "")
18056 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18058 (use (match_operand:HI 2 "memory_operand" ""))
18059 (use (match_operand:HI 3 "memory_operand" ""))
18060 (clobber (match_operand:DI 4 "memory_operand" ""))
18061 (clobber (match_scratch 5 ""))]
18063 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18064 (use (match_dup 2))
18065 (use (match_dup 3))
18066 (clobber (match_dup 5))])
18067 (set (match_dup 0) (match_dup 4))]
18071 [(set (match_operand:DI 0 "memory_operand" "")
18072 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18074 (use (match_operand:HI 2 "memory_operand" ""))
18075 (use (match_operand:HI 3 "memory_operand" ""))
18076 (clobber (match_operand:DI 4 "memory_operand" ""))
18077 (clobber (match_scratch 5 ""))]
18079 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18080 (use (match_dup 2))
18081 (use (match_dup 3))
18082 (clobber (match_dup 5))])]
18085 (define_insn "fist<mode>2_ceil"
18086 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18087 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18089 (use (match_operand:HI 2 "memory_operand" "m"))
18090 (use (match_operand:HI 3 "memory_operand" "m"))]
18091 "TARGET_USE_FANCY_MATH_387
18092 && flag_unsafe_math_optimizations"
18093 "* return output_fix_trunc (insn, operands, 0);"
18094 [(set_attr "type" "fistp")
18095 (set_attr "i387_cw" "ceil")
18096 (set_attr "mode" "<MODE>")])
18098 (define_insn "fist<mode>2_ceil_with_temp"
18099 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18100 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18102 (use (match_operand:HI 2 "memory_operand" "m,m"))
18103 (use (match_operand:HI 3 "memory_operand" "m,m"))
18104 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18105 "TARGET_USE_FANCY_MATH_387
18106 && flag_unsafe_math_optimizations"
18108 [(set_attr "type" "fistp")
18109 (set_attr "i387_cw" "ceil")
18110 (set_attr "mode" "<MODE>")])
18113 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18114 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18116 (use (match_operand:HI 2 "memory_operand" ""))
18117 (use (match_operand:HI 3 "memory_operand" ""))
18118 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18120 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18122 (use (match_dup 2))
18123 (use (match_dup 3))])
18124 (set (match_dup 0) (match_dup 4))]
18128 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18129 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18131 (use (match_operand:HI 2 "memory_operand" ""))
18132 (use (match_operand:HI 3 "memory_operand" ""))
18133 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18135 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18137 (use (match_dup 2))
18138 (use (match_dup 3))])]
18141 (define_expand "lceilxf<mode>2"
18142 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18143 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18145 (clobber (reg:CC FLAGS_REG))])]
18146 "TARGET_USE_FANCY_MATH_387
18147 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18148 && flag_unsafe_math_optimizations"
18151 (define_expand "lceil<mode>di2"
18152 [(match_operand:DI 0 "nonimmediate_operand" "")
18153 (match_operand:MODEF 1 "register_operand" "")]
18154 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18155 && !flag_trapping_math"
18157 ix86_expand_lfloorceil (operand0, operand1, false);
18161 (define_expand "lceil<mode>si2"
18162 [(match_operand:SI 0 "nonimmediate_operand" "")
18163 (match_operand:MODEF 1 "register_operand" "")]
18164 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18165 && !flag_trapping_math"
18167 ix86_expand_lfloorceil (operand0, operand1, false);
18171 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18172 (define_insn_and_split "frndintxf2_trunc"
18173 [(set (match_operand:XF 0 "register_operand" "")
18174 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18175 UNSPEC_FRNDINT_TRUNC))
18176 (clobber (reg:CC FLAGS_REG))]
18177 "TARGET_USE_FANCY_MATH_387
18178 && flag_unsafe_math_optimizations
18179 && !(reload_completed || reload_in_progress)"
18184 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18186 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18187 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18189 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18190 operands[2], operands[3]));
18193 [(set_attr "type" "frndint")
18194 (set_attr "i387_cw" "trunc")
18195 (set_attr "mode" "XF")])
18197 (define_insn "frndintxf2_trunc_i387"
18198 [(set (match_operand:XF 0 "register_operand" "=f")
18199 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18200 UNSPEC_FRNDINT_TRUNC))
18201 (use (match_operand:HI 2 "memory_operand" "m"))
18202 (use (match_operand:HI 3 "memory_operand" "m"))]
18203 "TARGET_USE_FANCY_MATH_387
18204 && flag_unsafe_math_optimizations"
18205 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18206 [(set_attr "type" "frndint")
18207 (set_attr "i387_cw" "trunc")
18208 (set_attr "mode" "XF")])
18210 (define_expand "btruncxf2"
18211 [(use (match_operand:XF 0 "register_operand" ""))
18212 (use (match_operand:XF 1 "register_operand" ""))]
18213 "TARGET_USE_FANCY_MATH_387
18214 && flag_unsafe_math_optimizations && !optimize_size"
18216 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18220 (define_expand "btrunc<mode>2"
18221 [(use (match_operand:MODEF 0 "register_operand" ""))
18222 (use (match_operand:MODEF 1 "register_operand" ""))]
18223 "(TARGET_USE_FANCY_MATH_387
18224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18225 || TARGET_MIX_SSE_I387)
18226 && flag_unsafe_math_optimizations && !optimize_size)
18227 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18228 && !flag_trapping_math
18229 && (TARGET_ROUND || !optimize_size))"
18231 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18232 && !flag_trapping_math
18233 && (TARGET_ROUND || !optimize_size))
18236 emit_insn (gen_sse4_1_round<mode>2
18237 (operands[0], operands[1], GEN_INT (0x03)));
18238 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18239 ix86_expand_trunc (operand0, operand1);
18241 ix86_expand_truncdf_32 (operand0, operand1);
18245 rtx op0 = gen_reg_rtx (XFmode);
18246 rtx op1 = gen_reg_rtx (XFmode);
18248 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18249 emit_insn (gen_frndintxf2_trunc (op0, op1));
18251 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18256 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18257 (define_insn_and_split "frndintxf2_mask_pm"
18258 [(set (match_operand:XF 0 "register_operand" "")
18259 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18260 UNSPEC_FRNDINT_MASK_PM))
18261 (clobber (reg:CC FLAGS_REG))]
18262 "TARGET_USE_FANCY_MATH_387
18263 && flag_unsafe_math_optimizations
18264 && !(reload_completed || reload_in_progress)"
18269 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18271 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18272 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18274 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18275 operands[2], operands[3]));
18278 [(set_attr "type" "frndint")
18279 (set_attr "i387_cw" "mask_pm")
18280 (set_attr "mode" "XF")])
18282 (define_insn "frndintxf2_mask_pm_i387"
18283 [(set (match_operand:XF 0 "register_operand" "=f")
18284 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18285 UNSPEC_FRNDINT_MASK_PM))
18286 (use (match_operand:HI 2 "memory_operand" "m"))
18287 (use (match_operand:HI 3 "memory_operand" "m"))]
18288 "TARGET_USE_FANCY_MATH_387
18289 && flag_unsafe_math_optimizations"
18290 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18291 [(set_attr "type" "frndint")
18292 (set_attr "i387_cw" "mask_pm")
18293 (set_attr "mode" "XF")])
18295 (define_expand "nearbyintxf2"
18296 [(use (match_operand:XF 0 "register_operand" ""))
18297 (use (match_operand:XF 1 "register_operand" ""))]
18298 "TARGET_USE_FANCY_MATH_387
18299 && flag_unsafe_math_optimizations"
18301 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18306 (define_expand "nearbyint<mode>2"
18307 [(use (match_operand:MODEF 0 "register_operand" ""))
18308 (use (match_operand:MODEF 1 "register_operand" ""))]
18309 "TARGET_USE_FANCY_MATH_387
18310 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18311 || TARGET_MIX_SSE_I387)
18312 && flag_unsafe_math_optimizations"
18314 rtx op0 = gen_reg_rtx (XFmode);
18315 rtx op1 = gen_reg_rtx (XFmode);
18317 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18318 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18320 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18324 (define_insn "fxam<mode>2_i387"
18325 [(set (match_operand:HI 0 "register_operand" "=a")
18327 [(match_operand:X87MODEF 1 "register_operand" "f")]
18329 "TARGET_USE_FANCY_MATH_387"
18330 "fxam\n\tfnstsw\t%0"
18331 [(set_attr "type" "multi")
18332 (set_attr "unit" "i387")
18333 (set_attr "mode" "<MODE>")])
18335 (define_expand "isinf<mode>2"
18336 [(use (match_operand:SI 0 "register_operand" ""))
18337 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18338 "TARGET_USE_FANCY_MATH_387
18339 && TARGET_C99_FUNCTIONS
18340 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18342 rtx mask = GEN_INT (0x45);
18343 rtx val = GEN_INT (0x05);
18347 rtx scratch = gen_reg_rtx (HImode);
18348 rtx res = gen_reg_rtx (QImode);
18350 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18351 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18352 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18353 cond = gen_rtx_fmt_ee (EQ, QImode,
18354 gen_rtx_REG (CCmode, FLAGS_REG),
18356 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18357 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18361 (define_expand "signbit<mode>2"
18362 [(use (match_operand:SI 0 "register_operand" ""))
18363 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18364 "TARGET_USE_FANCY_MATH_387
18365 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18367 rtx mask = GEN_INT (0x0200);
18369 rtx scratch = gen_reg_rtx (HImode);
18371 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18372 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18376 ;; Block operation instructions
18379 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18382 [(set_attr "length" "1")
18383 (set_attr "length_immediate" "0")
18384 (set_attr "modrm" "0")])
18386 (define_expand "movmemsi"
18387 [(use (match_operand:BLK 0 "memory_operand" ""))
18388 (use (match_operand:BLK 1 "memory_operand" ""))
18389 (use (match_operand:SI 2 "nonmemory_operand" ""))
18390 (use (match_operand:SI 3 "const_int_operand" ""))
18391 (use (match_operand:SI 4 "const_int_operand" ""))
18392 (use (match_operand:SI 5 "const_int_operand" ""))]
18395 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18396 operands[4], operands[5]))
18402 (define_expand "movmemdi"
18403 [(use (match_operand:BLK 0 "memory_operand" ""))
18404 (use (match_operand:BLK 1 "memory_operand" ""))
18405 (use (match_operand:DI 2 "nonmemory_operand" ""))
18406 (use (match_operand:DI 3 "const_int_operand" ""))
18407 (use (match_operand:SI 4 "const_int_operand" ""))
18408 (use (match_operand:SI 5 "const_int_operand" ""))]
18411 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18412 operands[4], operands[5]))
18418 ;; Most CPUs don't like single string operations
18419 ;; Handle this case here to simplify previous expander.
18421 (define_expand "strmov"
18422 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18423 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18424 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18425 (clobber (reg:CC FLAGS_REG))])
18426 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18427 (clobber (reg:CC FLAGS_REG))])]
18430 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18432 /* If .md ever supports :P for Pmode, these can be directly
18433 in the pattern above. */
18434 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18435 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18437 /* Can't use this if the user has appropriated esi or edi. */
18438 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18439 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18441 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18442 operands[2], operands[3],
18443 operands[5], operands[6]));
18447 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18450 (define_expand "strmov_singleop"
18451 [(parallel [(set (match_operand 1 "memory_operand" "")
18452 (match_operand 3 "memory_operand" ""))
18453 (set (match_operand 0 "register_operand" "")
18454 (match_operand 4 "" ""))
18455 (set (match_operand 2 "register_operand" "")
18456 (match_operand 5 "" ""))])]
18457 "TARGET_SINGLE_STRINGOP || optimize_size"
18458 "ix86_current_function_needs_cld = 1;")
18460 (define_insn "*strmovdi_rex_1"
18461 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18462 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18463 (set (match_operand:DI 0 "register_operand" "=D")
18464 (plus:DI (match_dup 2)
18466 (set (match_operand:DI 1 "register_operand" "=S")
18467 (plus:DI (match_dup 3)
18469 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18471 [(set_attr "type" "str")
18472 (set_attr "mode" "DI")
18473 (set_attr "memory" "both")])
18475 (define_insn "*strmovsi_1"
18476 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18477 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18478 (set (match_operand:SI 0 "register_operand" "=D")
18479 (plus:SI (match_dup 2)
18481 (set (match_operand:SI 1 "register_operand" "=S")
18482 (plus:SI (match_dup 3)
18484 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18486 [(set_attr "type" "str")
18487 (set_attr "mode" "SI")
18488 (set_attr "memory" "both")])
18490 (define_insn "*strmovsi_rex_1"
18491 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18492 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18493 (set (match_operand:DI 0 "register_operand" "=D")
18494 (plus:DI (match_dup 2)
18496 (set (match_operand:DI 1 "register_operand" "=S")
18497 (plus:DI (match_dup 3)
18499 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18501 [(set_attr "type" "str")
18502 (set_attr "mode" "SI")
18503 (set_attr "memory" "both")])
18505 (define_insn "*strmovhi_1"
18506 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18507 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18508 (set (match_operand:SI 0 "register_operand" "=D")
18509 (plus:SI (match_dup 2)
18511 (set (match_operand:SI 1 "register_operand" "=S")
18512 (plus:SI (match_dup 3)
18514 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18516 [(set_attr "type" "str")
18517 (set_attr "memory" "both")
18518 (set_attr "mode" "HI")])
18520 (define_insn "*strmovhi_rex_1"
18521 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18522 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18523 (set (match_operand:DI 0 "register_operand" "=D")
18524 (plus:DI (match_dup 2)
18526 (set (match_operand:DI 1 "register_operand" "=S")
18527 (plus:DI (match_dup 3)
18529 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18531 [(set_attr "type" "str")
18532 (set_attr "memory" "both")
18533 (set_attr "mode" "HI")])
18535 (define_insn "*strmovqi_1"
18536 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18537 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18538 (set (match_operand:SI 0 "register_operand" "=D")
18539 (plus:SI (match_dup 2)
18541 (set (match_operand:SI 1 "register_operand" "=S")
18542 (plus:SI (match_dup 3)
18544 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18546 [(set_attr "type" "str")
18547 (set_attr "memory" "both")
18548 (set_attr "mode" "QI")])
18550 (define_insn "*strmovqi_rex_1"
18551 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18552 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18553 (set (match_operand:DI 0 "register_operand" "=D")
18554 (plus:DI (match_dup 2)
18556 (set (match_operand:DI 1 "register_operand" "=S")
18557 (plus:DI (match_dup 3)
18559 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18561 [(set_attr "type" "str")
18562 (set_attr "memory" "both")
18563 (set_attr "mode" "QI")])
18565 (define_expand "rep_mov"
18566 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18567 (set (match_operand 0 "register_operand" "")
18568 (match_operand 5 "" ""))
18569 (set (match_operand 2 "register_operand" "")
18570 (match_operand 6 "" ""))
18571 (set (match_operand 1 "memory_operand" "")
18572 (match_operand 3 "memory_operand" ""))
18573 (use (match_dup 4))])]
18575 "ix86_current_function_needs_cld = 1;")
18577 (define_insn "*rep_movdi_rex64"
18578 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18579 (set (match_operand:DI 0 "register_operand" "=D")
18580 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18582 (match_operand:DI 3 "register_operand" "0")))
18583 (set (match_operand:DI 1 "register_operand" "=S")
18584 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18585 (match_operand:DI 4 "register_operand" "1")))
18586 (set (mem:BLK (match_dup 3))
18587 (mem:BLK (match_dup 4)))
18588 (use (match_dup 5))]
18591 [(set_attr "type" "str")
18592 (set_attr "prefix_rep" "1")
18593 (set_attr "memory" "both")
18594 (set_attr "mode" "DI")])
18596 (define_insn "*rep_movsi"
18597 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18598 (set (match_operand:SI 0 "register_operand" "=D")
18599 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18601 (match_operand:SI 3 "register_operand" "0")))
18602 (set (match_operand:SI 1 "register_operand" "=S")
18603 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18604 (match_operand:SI 4 "register_operand" "1")))
18605 (set (mem:BLK (match_dup 3))
18606 (mem:BLK (match_dup 4)))
18607 (use (match_dup 5))]
18610 [(set_attr "type" "str")
18611 (set_attr "prefix_rep" "1")
18612 (set_attr "memory" "both")
18613 (set_attr "mode" "SI")])
18615 (define_insn "*rep_movsi_rex64"
18616 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18617 (set (match_operand:DI 0 "register_operand" "=D")
18618 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18620 (match_operand:DI 3 "register_operand" "0")))
18621 (set (match_operand:DI 1 "register_operand" "=S")
18622 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18623 (match_operand:DI 4 "register_operand" "1")))
18624 (set (mem:BLK (match_dup 3))
18625 (mem:BLK (match_dup 4)))
18626 (use (match_dup 5))]
18629 [(set_attr "type" "str")
18630 (set_attr "prefix_rep" "1")
18631 (set_attr "memory" "both")
18632 (set_attr "mode" "SI")])
18634 (define_insn "*rep_movqi"
18635 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18636 (set (match_operand:SI 0 "register_operand" "=D")
18637 (plus:SI (match_operand:SI 3 "register_operand" "0")
18638 (match_operand:SI 5 "register_operand" "2")))
18639 (set (match_operand:SI 1 "register_operand" "=S")
18640 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18641 (set (mem:BLK (match_dup 3))
18642 (mem:BLK (match_dup 4)))
18643 (use (match_dup 5))]
18646 [(set_attr "type" "str")
18647 (set_attr "prefix_rep" "1")
18648 (set_attr "memory" "both")
18649 (set_attr "mode" "SI")])
18651 (define_insn "*rep_movqi_rex64"
18652 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18653 (set (match_operand:DI 0 "register_operand" "=D")
18654 (plus:DI (match_operand:DI 3 "register_operand" "0")
18655 (match_operand:DI 5 "register_operand" "2")))
18656 (set (match_operand:DI 1 "register_operand" "=S")
18657 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18658 (set (mem:BLK (match_dup 3))
18659 (mem:BLK (match_dup 4)))
18660 (use (match_dup 5))]
18663 [(set_attr "type" "str")
18664 (set_attr "prefix_rep" "1")
18665 (set_attr "memory" "both")
18666 (set_attr "mode" "SI")])
18668 (define_expand "setmemsi"
18669 [(use (match_operand:BLK 0 "memory_operand" ""))
18670 (use (match_operand:SI 1 "nonmemory_operand" ""))
18671 (use (match_operand 2 "const_int_operand" ""))
18672 (use (match_operand 3 "const_int_operand" ""))
18673 (use (match_operand:SI 4 "const_int_operand" ""))
18674 (use (match_operand:SI 5 "const_int_operand" ""))]
18677 if (ix86_expand_setmem (operands[0], operands[1],
18678 operands[2], operands[3],
18679 operands[4], operands[5]))
18685 (define_expand "setmemdi"
18686 [(use (match_operand:BLK 0 "memory_operand" ""))
18687 (use (match_operand:DI 1 "nonmemory_operand" ""))
18688 (use (match_operand 2 "const_int_operand" ""))
18689 (use (match_operand 3 "const_int_operand" ""))
18690 (use (match_operand 4 "const_int_operand" ""))
18691 (use (match_operand 5 "const_int_operand" ""))]
18694 if (ix86_expand_setmem (operands[0], operands[1],
18695 operands[2], operands[3],
18696 operands[4], operands[5]))
18702 ;; Most CPUs don't like single string operations
18703 ;; Handle this case here to simplify previous expander.
18705 (define_expand "strset"
18706 [(set (match_operand 1 "memory_operand" "")
18707 (match_operand 2 "register_operand" ""))
18708 (parallel [(set (match_operand 0 "register_operand" "")
18710 (clobber (reg:CC FLAGS_REG))])]
18713 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18714 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18716 /* If .md ever supports :P for Pmode, this can be directly
18717 in the pattern above. */
18718 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18719 GEN_INT (GET_MODE_SIZE (GET_MODE
18721 if (TARGET_SINGLE_STRINGOP || optimize_size)
18723 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18729 (define_expand "strset_singleop"
18730 [(parallel [(set (match_operand 1 "memory_operand" "")
18731 (match_operand 2 "register_operand" ""))
18732 (set (match_operand 0 "register_operand" "")
18733 (match_operand 3 "" ""))])]
18734 "TARGET_SINGLE_STRINGOP || optimize_size"
18735 "ix86_current_function_needs_cld = 1;")
18737 (define_insn "*strsetdi_rex_1"
18738 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18739 (match_operand:DI 2 "register_operand" "a"))
18740 (set (match_operand:DI 0 "register_operand" "=D")
18741 (plus:DI (match_dup 1)
18743 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18745 [(set_attr "type" "str")
18746 (set_attr "memory" "store")
18747 (set_attr "mode" "DI")])
18749 (define_insn "*strsetsi_1"
18750 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18751 (match_operand:SI 2 "register_operand" "a"))
18752 (set (match_operand:SI 0 "register_operand" "=D")
18753 (plus:SI (match_dup 1)
18755 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18757 [(set_attr "type" "str")
18758 (set_attr "memory" "store")
18759 (set_attr "mode" "SI")])
18761 (define_insn "*strsetsi_rex_1"
18762 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18763 (match_operand:SI 2 "register_operand" "a"))
18764 (set (match_operand:DI 0 "register_operand" "=D")
18765 (plus:DI (match_dup 1)
18767 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18769 [(set_attr "type" "str")
18770 (set_attr "memory" "store")
18771 (set_attr "mode" "SI")])
18773 (define_insn "*strsethi_1"
18774 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18775 (match_operand:HI 2 "register_operand" "a"))
18776 (set (match_operand:SI 0 "register_operand" "=D")
18777 (plus:SI (match_dup 1)
18779 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18781 [(set_attr "type" "str")
18782 (set_attr "memory" "store")
18783 (set_attr "mode" "HI")])
18785 (define_insn "*strsethi_rex_1"
18786 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18787 (match_operand:HI 2 "register_operand" "a"))
18788 (set (match_operand:DI 0 "register_operand" "=D")
18789 (plus:DI (match_dup 1)
18791 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18793 [(set_attr "type" "str")
18794 (set_attr "memory" "store")
18795 (set_attr "mode" "HI")])
18797 (define_insn "*strsetqi_1"
18798 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18799 (match_operand:QI 2 "register_operand" "a"))
18800 (set (match_operand:SI 0 "register_operand" "=D")
18801 (plus:SI (match_dup 1)
18803 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18805 [(set_attr "type" "str")
18806 (set_attr "memory" "store")
18807 (set_attr "mode" "QI")])
18809 (define_insn "*strsetqi_rex_1"
18810 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18811 (match_operand:QI 2 "register_operand" "a"))
18812 (set (match_operand:DI 0 "register_operand" "=D")
18813 (plus:DI (match_dup 1)
18815 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18817 [(set_attr "type" "str")
18818 (set_attr "memory" "store")
18819 (set_attr "mode" "QI")])
18821 (define_expand "rep_stos"
18822 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18823 (set (match_operand 0 "register_operand" "")
18824 (match_operand 4 "" ""))
18825 (set (match_operand 2 "memory_operand" "") (const_int 0))
18826 (use (match_operand 3 "register_operand" ""))
18827 (use (match_dup 1))])]
18829 "ix86_current_function_needs_cld = 1;")
18831 (define_insn "*rep_stosdi_rex64"
18832 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18833 (set (match_operand:DI 0 "register_operand" "=D")
18834 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18836 (match_operand:DI 3 "register_operand" "0")))
18837 (set (mem:BLK (match_dup 3))
18839 (use (match_operand:DI 2 "register_operand" "a"))
18840 (use (match_dup 4))]
18843 [(set_attr "type" "str")
18844 (set_attr "prefix_rep" "1")
18845 (set_attr "memory" "store")
18846 (set_attr "mode" "DI")])
18848 (define_insn "*rep_stossi"
18849 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18850 (set (match_operand:SI 0 "register_operand" "=D")
18851 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18853 (match_operand:SI 3 "register_operand" "0")))
18854 (set (mem:BLK (match_dup 3))
18856 (use (match_operand:SI 2 "register_operand" "a"))
18857 (use (match_dup 4))]
18860 [(set_attr "type" "str")
18861 (set_attr "prefix_rep" "1")
18862 (set_attr "memory" "store")
18863 (set_attr "mode" "SI")])
18865 (define_insn "*rep_stossi_rex64"
18866 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18867 (set (match_operand:DI 0 "register_operand" "=D")
18868 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18870 (match_operand:DI 3 "register_operand" "0")))
18871 (set (mem:BLK (match_dup 3))
18873 (use (match_operand:SI 2 "register_operand" "a"))
18874 (use (match_dup 4))]
18877 [(set_attr "type" "str")
18878 (set_attr "prefix_rep" "1")
18879 (set_attr "memory" "store")
18880 (set_attr "mode" "SI")])
18882 (define_insn "*rep_stosqi"
18883 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18884 (set (match_operand:SI 0 "register_operand" "=D")
18885 (plus:SI (match_operand:SI 3 "register_operand" "0")
18886 (match_operand:SI 4 "register_operand" "1")))
18887 (set (mem:BLK (match_dup 3))
18889 (use (match_operand:QI 2 "register_operand" "a"))
18890 (use (match_dup 4))]
18893 [(set_attr "type" "str")
18894 (set_attr "prefix_rep" "1")
18895 (set_attr "memory" "store")
18896 (set_attr "mode" "QI")])
18898 (define_insn "*rep_stosqi_rex64"
18899 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18900 (set (match_operand:DI 0 "register_operand" "=D")
18901 (plus:DI (match_operand:DI 3 "register_operand" "0")
18902 (match_operand:DI 4 "register_operand" "1")))
18903 (set (mem:BLK (match_dup 3))
18905 (use (match_operand:QI 2 "register_operand" "a"))
18906 (use (match_dup 4))]
18909 [(set_attr "type" "str")
18910 (set_attr "prefix_rep" "1")
18911 (set_attr "memory" "store")
18912 (set_attr "mode" "QI")])
18914 (define_expand "cmpstrnsi"
18915 [(set (match_operand:SI 0 "register_operand" "")
18916 (compare:SI (match_operand:BLK 1 "general_operand" "")
18917 (match_operand:BLK 2 "general_operand" "")))
18918 (use (match_operand 3 "general_operand" ""))
18919 (use (match_operand 4 "immediate_operand" ""))]
18920 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18922 rtx addr1, addr2, out, outlow, count, countreg, align;
18924 /* Can't use this if the user has appropriated esi or edi. */
18925 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18930 out = gen_reg_rtx (SImode);
18932 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18933 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18934 if (addr1 != XEXP (operands[1], 0))
18935 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18936 if (addr2 != XEXP (operands[2], 0))
18937 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18939 count = operands[3];
18940 countreg = ix86_zero_extend_to_Pmode (count);
18942 /* %%% Iff we are testing strict equality, we can use known alignment
18943 to good advantage. This may be possible with combine, particularly
18944 once cc0 is dead. */
18945 align = operands[4];
18947 if (CONST_INT_P (count))
18949 if (INTVAL (count) == 0)
18951 emit_move_insn (operands[0], const0_rtx);
18954 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18955 operands[1], operands[2]));
18960 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18962 emit_insn (gen_cmpsi_1 (countreg, countreg));
18963 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18964 operands[1], operands[2]));
18967 outlow = gen_lowpart (QImode, out);
18968 emit_insn (gen_cmpintqi (outlow));
18969 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18971 if (operands[0] != out)
18972 emit_move_insn (operands[0], out);
18977 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18979 (define_expand "cmpintqi"
18980 [(set (match_dup 1)
18981 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18983 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18984 (parallel [(set (match_operand:QI 0 "register_operand" "")
18985 (minus:QI (match_dup 1)
18987 (clobber (reg:CC FLAGS_REG))])]
18989 "operands[1] = gen_reg_rtx (QImode);
18990 operands[2] = gen_reg_rtx (QImode);")
18992 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18993 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18995 (define_expand "cmpstrnqi_nz_1"
18996 [(parallel [(set (reg:CC FLAGS_REG)
18997 (compare:CC (match_operand 4 "memory_operand" "")
18998 (match_operand 5 "memory_operand" "")))
18999 (use (match_operand 2 "register_operand" ""))
19000 (use (match_operand:SI 3 "immediate_operand" ""))
19001 (clobber (match_operand 0 "register_operand" ""))
19002 (clobber (match_operand 1 "register_operand" ""))
19003 (clobber (match_dup 2))])]
19005 "ix86_current_function_needs_cld = 1;")
19007 (define_insn "*cmpstrnqi_nz_1"
19008 [(set (reg:CC FLAGS_REG)
19009 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19010 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19011 (use (match_operand:SI 6 "register_operand" "2"))
19012 (use (match_operand:SI 3 "immediate_operand" "i"))
19013 (clobber (match_operand:SI 0 "register_operand" "=S"))
19014 (clobber (match_operand:SI 1 "register_operand" "=D"))
19015 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19018 [(set_attr "type" "str")
19019 (set_attr "mode" "QI")
19020 (set_attr "prefix_rep" "1")])
19022 (define_insn "*cmpstrnqi_nz_rex_1"
19023 [(set (reg:CC FLAGS_REG)
19024 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19025 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19026 (use (match_operand:DI 6 "register_operand" "2"))
19027 (use (match_operand:SI 3 "immediate_operand" "i"))
19028 (clobber (match_operand:DI 0 "register_operand" "=S"))
19029 (clobber (match_operand:DI 1 "register_operand" "=D"))
19030 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19033 [(set_attr "type" "str")
19034 (set_attr "mode" "QI")
19035 (set_attr "prefix_rep" "1")])
19037 ;; The same, but the count is not known to not be zero.
19039 (define_expand "cmpstrnqi_1"
19040 [(parallel [(set (reg:CC FLAGS_REG)
19041 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19043 (compare:CC (match_operand 4 "memory_operand" "")
19044 (match_operand 5 "memory_operand" ""))
19046 (use (match_operand:SI 3 "immediate_operand" ""))
19047 (use (reg:CC FLAGS_REG))
19048 (clobber (match_operand 0 "register_operand" ""))
19049 (clobber (match_operand 1 "register_operand" ""))
19050 (clobber (match_dup 2))])]
19052 "ix86_current_function_needs_cld = 1;")
19054 (define_insn "*cmpstrnqi_1"
19055 [(set (reg:CC FLAGS_REG)
19056 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19058 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19059 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19061 (use (match_operand:SI 3 "immediate_operand" "i"))
19062 (use (reg:CC FLAGS_REG))
19063 (clobber (match_operand:SI 0 "register_operand" "=S"))
19064 (clobber (match_operand:SI 1 "register_operand" "=D"))
19065 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19068 [(set_attr "type" "str")
19069 (set_attr "mode" "QI")
19070 (set_attr "prefix_rep" "1")])
19072 (define_insn "*cmpstrnqi_rex_1"
19073 [(set (reg:CC FLAGS_REG)
19074 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19076 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19077 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19079 (use (match_operand:SI 3 "immediate_operand" "i"))
19080 (use (reg:CC FLAGS_REG))
19081 (clobber (match_operand:DI 0 "register_operand" "=S"))
19082 (clobber (match_operand:DI 1 "register_operand" "=D"))
19083 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19086 [(set_attr "type" "str")
19087 (set_attr "mode" "QI")
19088 (set_attr "prefix_rep" "1")])
19090 (define_expand "strlensi"
19091 [(set (match_operand:SI 0 "register_operand" "")
19092 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19093 (match_operand:QI 2 "immediate_operand" "")
19094 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19097 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19103 (define_expand "strlendi"
19104 [(set (match_operand:DI 0 "register_operand" "")
19105 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19106 (match_operand:QI 2 "immediate_operand" "")
19107 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19110 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19116 (define_expand "strlenqi_1"
19117 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19118 (clobber (match_operand 1 "register_operand" ""))
19119 (clobber (reg:CC FLAGS_REG))])]
19121 "ix86_current_function_needs_cld = 1;")
19123 (define_insn "*strlenqi_1"
19124 [(set (match_operand:SI 0 "register_operand" "=&c")
19125 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19126 (match_operand:QI 2 "register_operand" "a")
19127 (match_operand:SI 3 "immediate_operand" "i")
19128 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19129 (clobber (match_operand:SI 1 "register_operand" "=D"))
19130 (clobber (reg:CC FLAGS_REG))]
19133 [(set_attr "type" "str")
19134 (set_attr "mode" "QI")
19135 (set_attr "prefix_rep" "1")])
19137 (define_insn "*strlenqi_rex_1"
19138 [(set (match_operand:DI 0 "register_operand" "=&c")
19139 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19140 (match_operand:QI 2 "register_operand" "a")
19141 (match_operand:DI 3 "immediate_operand" "i")
19142 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19143 (clobber (match_operand:DI 1 "register_operand" "=D"))
19144 (clobber (reg:CC FLAGS_REG))]
19147 [(set_attr "type" "str")
19148 (set_attr "mode" "QI")
19149 (set_attr "prefix_rep" "1")])
19151 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19152 ;; handled in combine, but it is not currently up to the task.
19153 ;; When used for their truth value, the cmpstrn* expanders generate
19162 ;; The intermediate three instructions are unnecessary.
19164 ;; This one handles cmpstrn*_nz_1...
19167 (set (reg:CC FLAGS_REG)
19168 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19169 (mem:BLK (match_operand 5 "register_operand" ""))))
19170 (use (match_operand 6 "register_operand" ""))
19171 (use (match_operand:SI 3 "immediate_operand" ""))
19172 (clobber (match_operand 0 "register_operand" ""))
19173 (clobber (match_operand 1 "register_operand" ""))
19174 (clobber (match_operand 2 "register_operand" ""))])
19175 (set (match_operand:QI 7 "register_operand" "")
19176 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19177 (set (match_operand:QI 8 "register_operand" "")
19178 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19179 (set (reg FLAGS_REG)
19180 (compare (match_dup 7) (match_dup 8)))
19182 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19184 (set (reg:CC FLAGS_REG)
19185 (compare:CC (mem:BLK (match_dup 4))
19186 (mem:BLK (match_dup 5))))
19187 (use (match_dup 6))
19188 (use (match_dup 3))
19189 (clobber (match_dup 0))
19190 (clobber (match_dup 1))
19191 (clobber (match_dup 2))])]
19194 ;; ...and this one handles cmpstrn*_1.
19197 (set (reg:CC FLAGS_REG)
19198 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19200 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19201 (mem:BLK (match_operand 5 "register_operand" "")))
19203 (use (match_operand:SI 3 "immediate_operand" ""))
19204 (use (reg:CC FLAGS_REG))
19205 (clobber (match_operand 0 "register_operand" ""))
19206 (clobber (match_operand 1 "register_operand" ""))
19207 (clobber (match_operand 2 "register_operand" ""))])
19208 (set (match_operand:QI 7 "register_operand" "")
19209 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19210 (set (match_operand:QI 8 "register_operand" "")
19211 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19212 (set (reg FLAGS_REG)
19213 (compare (match_dup 7) (match_dup 8)))
19215 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19217 (set (reg:CC FLAGS_REG)
19218 (if_then_else:CC (ne (match_dup 6)
19220 (compare:CC (mem:BLK (match_dup 4))
19221 (mem:BLK (match_dup 5)))
19223 (use (match_dup 3))
19224 (use (reg:CC FLAGS_REG))
19225 (clobber (match_dup 0))
19226 (clobber (match_dup 1))
19227 (clobber (match_dup 2))])]
19232 ;; Conditional move instructions.
19234 (define_expand "movdicc"
19235 [(set (match_operand:DI 0 "register_operand" "")
19236 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19237 (match_operand:DI 2 "general_operand" "")
19238 (match_operand:DI 3 "general_operand" "")))]
19240 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19242 (define_insn "x86_movdicc_0_m1_rex64"
19243 [(set (match_operand:DI 0 "register_operand" "=r")
19244 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19247 (clobber (reg:CC FLAGS_REG))]
19250 ; Since we don't have the proper number of operands for an alu insn,
19251 ; fill in all the blanks.
19252 [(set_attr "type" "alu")
19253 (set_attr "pent_pair" "pu")
19254 (set_attr "memory" "none")
19255 (set_attr "imm_disp" "false")
19256 (set_attr "mode" "DI")
19257 (set_attr "length_immediate" "0")])
19259 (define_insn "*x86_movdicc_0_m1_se"
19260 [(set (match_operand:DI 0 "register_operand" "=r")
19261 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19264 (clobber (reg:CC FLAGS_REG))]
19267 [(set_attr "type" "alu")
19268 (set_attr "pent_pair" "pu")
19269 (set_attr "memory" "none")
19270 (set_attr "imm_disp" "false")
19271 (set_attr "mode" "DI")
19272 (set_attr "length_immediate" "0")])
19274 (define_insn "*movdicc_c_rex64"
19275 [(set (match_operand:DI 0 "register_operand" "=r,r")
19276 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19277 [(reg FLAGS_REG) (const_int 0)])
19278 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19279 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19280 "TARGET_64BIT && TARGET_CMOVE
19281 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19283 cmov%O2%C1\t{%2, %0|%0, %2}
19284 cmov%O2%c1\t{%3, %0|%0, %3}"
19285 [(set_attr "type" "icmov")
19286 (set_attr "mode" "DI")])
19288 (define_expand "movsicc"
19289 [(set (match_operand:SI 0 "register_operand" "")
19290 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19291 (match_operand:SI 2 "general_operand" "")
19292 (match_operand:SI 3 "general_operand" "")))]
19294 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19296 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19297 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19298 ;; So just document what we're doing explicitly.
19300 (define_insn "x86_movsicc_0_m1"
19301 [(set (match_operand:SI 0 "register_operand" "=r")
19302 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19305 (clobber (reg:CC FLAGS_REG))]
19308 ; Since we don't have the proper number of operands for an alu insn,
19309 ; fill in all the blanks.
19310 [(set_attr "type" "alu")
19311 (set_attr "pent_pair" "pu")
19312 (set_attr "memory" "none")
19313 (set_attr "imm_disp" "false")
19314 (set_attr "mode" "SI")
19315 (set_attr "length_immediate" "0")])
19317 (define_insn "*x86_movsicc_0_m1_se"
19318 [(set (match_operand:SI 0 "register_operand" "=r")
19319 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19322 (clobber (reg:CC FLAGS_REG))]
19325 [(set_attr "type" "alu")
19326 (set_attr "pent_pair" "pu")
19327 (set_attr "memory" "none")
19328 (set_attr "imm_disp" "false")
19329 (set_attr "mode" "SI")
19330 (set_attr "length_immediate" "0")])
19332 (define_insn "*movsicc_noc"
19333 [(set (match_operand:SI 0 "register_operand" "=r,r")
19334 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19335 [(reg FLAGS_REG) (const_int 0)])
19336 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19337 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19339 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19341 cmov%O2%C1\t{%2, %0|%0, %2}
19342 cmov%O2%c1\t{%3, %0|%0, %3}"
19343 [(set_attr "type" "icmov")
19344 (set_attr "mode" "SI")])
19346 (define_expand "movhicc"
19347 [(set (match_operand:HI 0 "register_operand" "")
19348 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19349 (match_operand:HI 2 "general_operand" "")
19350 (match_operand:HI 3 "general_operand" "")))]
19351 "TARGET_HIMODE_MATH"
19352 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19354 (define_insn "*movhicc_noc"
19355 [(set (match_operand:HI 0 "register_operand" "=r,r")
19356 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19357 [(reg FLAGS_REG) (const_int 0)])
19358 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19359 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19361 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19363 cmov%O2%C1\t{%2, %0|%0, %2}
19364 cmov%O2%c1\t{%3, %0|%0, %3}"
19365 [(set_attr "type" "icmov")
19366 (set_attr "mode" "HI")])
19368 (define_expand "movqicc"
19369 [(set (match_operand:QI 0 "register_operand" "")
19370 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19371 (match_operand:QI 2 "general_operand" "")
19372 (match_operand:QI 3 "general_operand" "")))]
19373 "TARGET_QIMODE_MATH"
19374 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19376 (define_insn_and_split "*movqicc_noc"
19377 [(set (match_operand:QI 0 "register_operand" "=r,r")
19378 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19379 [(match_operand 4 "flags_reg_operand" "")
19381 (match_operand:QI 2 "register_operand" "r,0")
19382 (match_operand:QI 3 "register_operand" "0,r")))]
19383 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19385 "&& reload_completed"
19386 [(set (match_dup 0)
19387 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19390 "operands[0] = gen_lowpart (SImode, operands[0]);
19391 operands[2] = gen_lowpart (SImode, operands[2]);
19392 operands[3] = gen_lowpart (SImode, operands[3]);"
19393 [(set_attr "type" "icmov")
19394 (set_attr "mode" "SI")])
19396 (define_expand "mov<mode>cc"
19397 [(set (match_operand:X87MODEF 0 "register_operand" "")
19398 (if_then_else:X87MODEF
19399 (match_operand 1 "comparison_operator" "")
19400 (match_operand:X87MODEF 2 "register_operand" "")
19401 (match_operand:X87MODEF 3 "register_operand" "")))]
19402 "(TARGET_80387 && TARGET_CMOVE)
19403 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19404 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19406 (define_insn "*movsfcc_1_387"
19407 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19408 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19409 [(reg FLAGS_REG) (const_int 0)])
19410 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19411 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19412 "TARGET_80387 && TARGET_CMOVE
19413 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19415 fcmov%F1\t{%2, %0|%0, %2}
19416 fcmov%f1\t{%3, %0|%0, %3}
19417 cmov%O2%C1\t{%2, %0|%0, %2}
19418 cmov%O2%c1\t{%3, %0|%0, %3}"
19419 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19420 (set_attr "mode" "SF,SF,SI,SI")])
19422 (define_insn "*movdfcc_1"
19423 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19424 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19425 [(reg FLAGS_REG) (const_int 0)])
19426 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19427 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19428 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19429 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19431 fcmov%F1\t{%2, %0|%0, %2}
19432 fcmov%f1\t{%3, %0|%0, %3}
19435 [(set_attr "type" "fcmov,fcmov,multi,multi")
19436 (set_attr "mode" "DF")])
19438 (define_insn "*movdfcc_1_rex64"
19439 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19440 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19441 [(reg FLAGS_REG) (const_int 0)])
19442 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19443 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19444 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19445 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19447 fcmov%F1\t{%2, %0|%0, %2}
19448 fcmov%f1\t{%3, %0|%0, %3}
19449 cmov%O2%C1\t{%2, %0|%0, %2}
19450 cmov%O2%c1\t{%3, %0|%0, %3}"
19451 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19452 (set_attr "mode" "DF")])
19455 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19456 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19457 [(match_operand 4 "flags_reg_operand" "")
19459 (match_operand:DF 2 "nonimmediate_operand" "")
19460 (match_operand:DF 3 "nonimmediate_operand" "")))]
19461 "!TARGET_64BIT && reload_completed"
19462 [(set (match_dup 2)
19463 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19467 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19470 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19471 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19473 (define_insn "*movxfcc_1"
19474 [(set (match_operand:XF 0 "register_operand" "=f,f")
19475 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19476 [(reg FLAGS_REG) (const_int 0)])
19477 (match_operand:XF 2 "register_operand" "f,0")
19478 (match_operand:XF 3 "register_operand" "0,f")))]
19479 "TARGET_80387 && TARGET_CMOVE"
19481 fcmov%F1\t{%2, %0|%0, %2}
19482 fcmov%f1\t{%3, %0|%0, %3}"
19483 [(set_attr "type" "fcmov")
19484 (set_attr "mode" "XF")])
19486 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19487 ;; the scalar versions to have only XMM registers as operands.
19489 ;; SSE5 conditional move
19490 (define_insn "*sse5_pcmov_<mode>"
19491 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19492 (if_then_else:MODEF
19493 (match_operand:MODEF 1 "register_operand" "x,0")
19494 (match_operand:MODEF 2 "register_operand" "0,x")
19495 (match_operand:MODEF 3 "register_operand" "x,x")))]
19496 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19497 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19498 [(set_attr "type" "sse4arg")])
19500 ;; These versions of the min/max patterns are intentionally ignorant of
19501 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19502 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19503 ;; are undefined in this condition, we're certain this is correct.
19505 (define_insn "<code><mode>3"
19506 [(set (match_operand:MODEF 0 "register_operand" "=x")
19508 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19509 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19510 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19511 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19512 [(set_attr "type" "sseadd")
19513 (set_attr "mode" "<MODE>")])
19515 ;; These versions of the min/max patterns implement exactly the operations
19516 ;; min = (op1 < op2 ? op1 : op2)
19517 ;; max = (!(op1 < op2) ? op1 : op2)
19518 ;; Their operands are not commutative, and thus they may be used in the
19519 ;; presence of -0.0 and NaN.
19521 (define_insn "*ieee_smin<mode>3"
19522 [(set (match_operand:MODEF 0 "register_operand" "=x")
19524 [(match_operand:MODEF 1 "register_operand" "0")
19525 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19527 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19528 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19529 [(set_attr "type" "sseadd")
19530 (set_attr "mode" "<MODE>")])
19532 (define_insn "*ieee_smax<mode>3"
19533 [(set (match_operand:MODEF 0 "register_operand" "=x")
19535 [(match_operand:MODEF 1 "register_operand" "0")
19536 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19538 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19539 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19540 [(set_attr "type" "sseadd")
19541 (set_attr "mode" "<MODE>")])
19543 ;; Make two stack loads independent:
19545 ;; fld %st(0) -> fld bb
19546 ;; fmul bb fmul %st(1), %st
19548 ;; Actually we only match the last two instructions for simplicity.
19550 [(set (match_operand 0 "fp_register_operand" "")
19551 (match_operand 1 "fp_register_operand" ""))
19553 (match_operator 2 "binary_fp_operator"
19555 (match_operand 3 "memory_operand" "")]))]
19556 "REGNO (operands[0]) != REGNO (operands[1])"
19557 [(set (match_dup 0) (match_dup 3))
19558 (set (match_dup 0) (match_dup 4))]
19560 ;; The % modifier is not operational anymore in peephole2's, so we have to
19561 ;; swap the operands manually in the case of addition and multiplication.
19562 "if (COMMUTATIVE_ARITH_P (operands[2]))
19563 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19564 operands[0], operands[1]);
19566 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19567 operands[1], operands[0]);")
19569 ;; Conditional addition patterns
19570 (define_expand "add<mode>cc"
19571 [(match_operand:SWI 0 "register_operand" "")
19572 (match_operand 1 "comparison_operator" "")
19573 (match_operand:SWI 2 "register_operand" "")
19574 (match_operand:SWI 3 "const_int_operand" "")]
19576 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19579 ;; Misc patterns (?)
19581 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19582 ;; Otherwise there will be nothing to keep
19584 ;; [(set (reg ebp) (reg esp))]
19585 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19586 ;; (clobber (eflags)]
19587 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19589 ;; in proper program order.
19590 (define_insn "pro_epilogue_adjust_stack_1"
19591 [(set (match_operand:SI 0 "register_operand" "=r,r")
19592 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19593 (match_operand:SI 2 "immediate_operand" "i,i")))
19594 (clobber (reg:CC FLAGS_REG))
19595 (clobber (mem:BLK (scratch)))]
19598 switch (get_attr_type (insn))
19601 return "mov{l}\t{%1, %0|%0, %1}";
19604 if (CONST_INT_P (operands[2])
19605 && (INTVAL (operands[2]) == 128
19606 || (INTVAL (operands[2]) < 0
19607 && INTVAL (operands[2]) != -128)))
19609 operands[2] = GEN_INT (-INTVAL (operands[2]));
19610 return "sub{l}\t{%2, %0|%0, %2}";
19612 return "add{l}\t{%2, %0|%0, %2}";
19615 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19616 return "lea{l}\t{%a2, %0|%0, %a2}";
19619 gcc_unreachable ();
19622 [(set (attr "type")
19623 (cond [(eq_attr "alternative" "0")
19624 (const_string "alu")
19625 (match_operand:SI 2 "const0_operand" "")
19626 (const_string "imov")
19628 (const_string "lea")))
19629 (set_attr "mode" "SI")])
19631 (define_insn "pro_epilogue_adjust_stack_rex64"
19632 [(set (match_operand:DI 0 "register_operand" "=r,r")
19633 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19634 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19635 (clobber (reg:CC FLAGS_REG))
19636 (clobber (mem:BLK (scratch)))]
19639 switch (get_attr_type (insn))
19642 return "mov{q}\t{%1, %0|%0, %1}";
19645 if (CONST_INT_P (operands[2])
19646 /* Avoid overflows. */
19647 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19648 && (INTVAL (operands[2]) == 128
19649 || (INTVAL (operands[2]) < 0
19650 && INTVAL (operands[2]) != -128)))
19652 operands[2] = GEN_INT (-INTVAL (operands[2]));
19653 return "sub{q}\t{%2, %0|%0, %2}";
19655 return "add{q}\t{%2, %0|%0, %2}";
19658 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19659 return "lea{q}\t{%a2, %0|%0, %a2}";
19662 gcc_unreachable ();
19665 [(set (attr "type")
19666 (cond [(eq_attr "alternative" "0")
19667 (const_string "alu")
19668 (match_operand:DI 2 "const0_operand" "")
19669 (const_string "imov")
19671 (const_string "lea")))
19672 (set_attr "mode" "DI")])
19674 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19675 [(set (match_operand:DI 0 "register_operand" "=r,r")
19676 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19677 (match_operand:DI 3 "immediate_operand" "i,i")))
19678 (use (match_operand:DI 2 "register_operand" "r,r"))
19679 (clobber (reg:CC FLAGS_REG))
19680 (clobber (mem:BLK (scratch)))]
19683 switch (get_attr_type (insn))
19686 return "add{q}\t{%2, %0|%0, %2}";
19689 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19690 return "lea{q}\t{%a2, %0|%0, %a2}";
19693 gcc_unreachable ();
19696 [(set_attr "type" "alu,lea")
19697 (set_attr "mode" "DI")])
19699 (define_insn "allocate_stack_worker_32"
19700 [(set (match_operand:SI 0 "register_operand" "+a")
19701 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19702 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19703 (clobber (reg:CC FLAGS_REG))]
19704 "!TARGET_64BIT && TARGET_STACK_PROBE"
19706 [(set_attr "type" "multi")
19707 (set_attr "length" "5")])
19709 (define_insn "allocate_stack_worker_64"
19710 [(set (match_operand:DI 0 "register_operand" "+a")
19711 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19712 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19713 (clobber (reg:DI R10_REG))
19714 (clobber (reg:DI R11_REG))
19715 (clobber (reg:CC FLAGS_REG))]
19716 "TARGET_64BIT && TARGET_STACK_PROBE"
19718 [(set_attr "type" "multi")
19719 (set_attr "length" "5")])
19721 (define_expand "allocate_stack"
19722 [(match_operand 0 "register_operand" "")
19723 (match_operand 1 "general_operand" "")]
19724 "TARGET_STACK_PROBE"
19728 #ifndef CHECK_STACK_LIMIT
19729 #define CHECK_STACK_LIMIT 0
19732 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19733 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19735 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19736 stack_pointer_rtx, 0, OPTAB_DIRECT);
19737 if (x != stack_pointer_rtx)
19738 emit_move_insn (stack_pointer_rtx, x);
19742 x = copy_to_mode_reg (Pmode, operands[1]);
19744 x = gen_allocate_stack_worker_64 (x);
19746 x = gen_allocate_stack_worker_32 (x);
19750 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19754 (define_expand "builtin_setjmp_receiver"
19755 [(label_ref (match_operand 0 "" ""))]
19756 "!TARGET_64BIT && flag_pic"
19761 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19762 rtx label_rtx = gen_label_rtx ();
19763 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19764 xops[0] = xops[1] = picreg;
19765 xops[2] = gen_rtx_CONST (SImode,
19766 gen_rtx_MINUS (SImode,
19767 gen_rtx_LABEL_REF (SImode, label_rtx),
19768 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19769 ix86_expand_binary_operator (MINUS, SImode, xops);
19772 emit_insn (gen_set_got (pic_offset_table_rtx));
19776 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19779 [(set (match_operand 0 "register_operand" "")
19780 (match_operator 3 "promotable_binary_operator"
19781 [(match_operand 1 "register_operand" "")
19782 (match_operand 2 "aligned_operand" "")]))
19783 (clobber (reg:CC FLAGS_REG))]
19784 "! TARGET_PARTIAL_REG_STALL && reload_completed
19785 && ((GET_MODE (operands[0]) == HImode
19786 && ((!optimize_size && !TARGET_FAST_PREFIX)
19787 /* ??? next two lines just !satisfies_constraint_K (...) */
19788 || !CONST_INT_P (operands[2])
19789 || satisfies_constraint_K (operands[2])))
19790 || (GET_MODE (operands[0]) == QImode
19791 && (TARGET_PROMOTE_QImode || optimize_size)))"
19792 [(parallel [(set (match_dup 0)
19793 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19794 (clobber (reg:CC FLAGS_REG))])]
19795 "operands[0] = gen_lowpart (SImode, operands[0]);
19796 operands[1] = gen_lowpart (SImode, operands[1]);
19797 if (GET_CODE (operands[3]) != ASHIFT)
19798 operands[2] = gen_lowpart (SImode, operands[2]);
19799 PUT_MODE (operands[3], SImode);")
19801 ; Promote the QImode tests, as i386 has encoding of the AND
19802 ; instruction with 32-bit sign-extended immediate and thus the
19803 ; instruction size is unchanged, except in the %eax case for
19804 ; which it is increased by one byte, hence the ! optimize_size.
19806 [(set (match_operand 0 "flags_reg_operand" "")
19807 (match_operator 2 "compare_operator"
19808 [(and (match_operand 3 "aligned_operand" "")
19809 (match_operand 4 "const_int_operand" ""))
19811 (set (match_operand 1 "register_operand" "")
19812 (and (match_dup 3) (match_dup 4)))]
19813 "! TARGET_PARTIAL_REG_STALL && reload_completed
19815 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19816 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19817 /* Ensure that the operand will remain sign-extended immediate. */
19818 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19819 [(parallel [(set (match_dup 0)
19820 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19823 (and:SI (match_dup 3) (match_dup 4)))])]
19826 = gen_int_mode (INTVAL (operands[4])
19827 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19828 operands[1] = gen_lowpart (SImode, operands[1]);
19829 operands[3] = gen_lowpart (SImode, operands[3]);
19832 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19833 ; the TEST instruction with 32-bit sign-extended immediate and thus
19834 ; the instruction size would at least double, which is not what we
19835 ; want even with ! optimize_size.
19837 [(set (match_operand 0 "flags_reg_operand" "")
19838 (match_operator 1 "compare_operator"
19839 [(and (match_operand:HI 2 "aligned_operand" "")
19840 (match_operand:HI 3 "const_int_operand" ""))
19842 "! TARGET_PARTIAL_REG_STALL && reload_completed
19843 && ! TARGET_FAST_PREFIX
19845 /* Ensure that the operand will remain sign-extended immediate. */
19846 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19847 [(set (match_dup 0)
19848 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19852 = gen_int_mode (INTVAL (operands[3])
19853 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19854 operands[2] = gen_lowpart (SImode, operands[2]);
19858 [(set (match_operand 0 "register_operand" "")
19859 (neg (match_operand 1 "register_operand" "")))
19860 (clobber (reg:CC FLAGS_REG))]
19861 "! TARGET_PARTIAL_REG_STALL && reload_completed
19862 && (GET_MODE (operands[0]) == HImode
19863 || (GET_MODE (operands[0]) == QImode
19864 && (TARGET_PROMOTE_QImode || optimize_size)))"
19865 [(parallel [(set (match_dup 0)
19866 (neg:SI (match_dup 1)))
19867 (clobber (reg:CC FLAGS_REG))])]
19868 "operands[0] = gen_lowpart (SImode, operands[0]);
19869 operands[1] = gen_lowpart (SImode, operands[1]);")
19872 [(set (match_operand 0 "register_operand" "")
19873 (not (match_operand 1 "register_operand" "")))]
19874 "! TARGET_PARTIAL_REG_STALL && reload_completed
19875 && (GET_MODE (operands[0]) == HImode
19876 || (GET_MODE (operands[0]) == QImode
19877 && (TARGET_PROMOTE_QImode || optimize_size)))"
19878 [(set (match_dup 0)
19879 (not:SI (match_dup 1)))]
19880 "operands[0] = gen_lowpart (SImode, operands[0]);
19881 operands[1] = gen_lowpart (SImode, operands[1]);")
19884 [(set (match_operand 0 "register_operand" "")
19885 (if_then_else (match_operator 1 "comparison_operator"
19886 [(reg FLAGS_REG) (const_int 0)])
19887 (match_operand 2 "register_operand" "")
19888 (match_operand 3 "register_operand" "")))]
19889 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19890 && (GET_MODE (operands[0]) == HImode
19891 || (GET_MODE (operands[0]) == QImode
19892 && (TARGET_PROMOTE_QImode || optimize_size)))"
19893 [(set (match_dup 0)
19894 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19895 "operands[0] = gen_lowpart (SImode, operands[0]);
19896 operands[2] = gen_lowpart (SImode, operands[2]);
19897 operands[3] = gen_lowpart (SImode, operands[3]);")
19900 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19901 ;; transform a complex memory operation into two memory to register operations.
19903 ;; Don't push memory operands
19905 [(set (match_operand:SI 0 "push_operand" "")
19906 (match_operand:SI 1 "memory_operand" ""))
19907 (match_scratch:SI 2 "r")]
19908 "!optimize_size && !TARGET_PUSH_MEMORY
19909 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19910 [(set (match_dup 2) (match_dup 1))
19911 (set (match_dup 0) (match_dup 2))]
19915 [(set (match_operand:DI 0 "push_operand" "")
19916 (match_operand:DI 1 "memory_operand" ""))
19917 (match_scratch:DI 2 "r")]
19918 "!optimize_size && !TARGET_PUSH_MEMORY
19919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920 [(set (match_dup 2) (match_dup 1))
19921 (set (match_dup 0) (match_dup 2))]
19924 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19927 [(set (match_operand:SF 0 "push_operand" "")
19928 (match_operand:SF 1 "memory_operand" ""))
19929 (match_scratch:SF 2 "r")]
19930 "!optimize_size && !TARGET_PUSH_MEMORY
19931 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19932 [(set (match_dup 2) (match_dup 1))
19933 (set (match_dup 0) (match_dup 2))]
19937 [(set (match_operand:HI 0 "push_operand" "")
19938 (match_operand:HI 1 "memory_operand" ""))
19939 (match_scratch:HI 2 "r")]
19940 "!optimize_size && !TARGET_PUSH_MEMORY
19941 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19942 [(set (match_dup 2) (match_dup 1))
19943 (set (match_dup 0) (match_dup 2))]
19947 [(set (match_operand:QI 0 "push_operand" "")
19948 (match_operand:QI 1 "memory_operand" ""))
19949 (match_scratch:QI 2 "q")]
19950 "!optimize_size && !TARGET_PUSH_MEMORY
19951 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19952 [(set (match_dup 2) (match_dup 1))
19953 (set (match_dup 0) (match_dup 2))]
19956 ;; Don't move an immediate directly to memory when the instruction
19959 [(match_scratch:SI 1 "r")
19960 (set (match_operand:SI 0 "memory_operand" "")
19963 && ! TARGET_USE_MOV0
19964 && TARGET_SPLIT_LONG_MOVES
19965 && get_attr_length (insn) >= ix86_cost->large_insn
19966 && peep2_regno_dead_p (0, FLAGS_REG)"
19967 [(parallel [(set (match_dup 1) (const_int 0))
19968 (clobber (reg:CC FLAGS_REG))])
19969 (set (match_dup 0) (match_dup 1))]
19973 [(match_scratch:HI 1 "r")
19974 (set (match_operand:HI 0 "memory_operand" "")
19977 && ! TARGET_USE_MOV0
19978 && TARGET_SPLIT_LONG_MOVES
19979 && get_attr_length (insn) >= ix86_cost->large_insn
19980 && peep2_regno_dead_p (0, FLAGS_REG)"
19981 [(parallel [(set (match_dup 2) (const_int 0))
19982 (clobber (reg:CC FLAGS_REG))])
19983 (set (match_dup 0) (match_dup 1))]
19984 "operands[2] = gen_lowpart (SImode, operands[1]);")
19987 [(match_scratch:QI 1 "q")
19988 (set (match_operand:QI 0 "memory_operand" "")
19991 && ! TARGET_USE_MOV0
19992 && TARGET_SPLIT_LONG_MOVES
19993 && get_attr_length (insn) >= ix86_cost->large_insn
19994 && peep2_regno_dead_p (0, FLAGS_REG)"
19995 [(parallel [(set (match_dup 2) (const_int 0))
19996 (clobber (reg:CC FLAGS_REG))])
19997 (set (match_dup 0) (match_dup 1))]
19998 "operands[2] = gen_lowpart (SImode, operands[1]);")
20001 [(match_scratch:SI 2 "r")
20002 (set (match_operand:SI 0 "memory_operand" "")
20003 (match_operand:SI 1 "immediate_operand" ""))]
20005 && TARGET_SPLIT_LONG_MOVES
20006 && get_attr_length (insn) >= ix86_cost->large_insn"
20007 [(set (match_dup 2) (match_dup 1))
20008 (set (match_dup 0) (match_dup 2))]
20012 [(match_scratch:HI 2 "r")
20013 (set (match_operand:HI 0 "memory_operand" "")
20014 (match_operand:HI 1 "immediate_operand" ""))]
20016 && TARGET_SPLIT_LONG_MOVES
20017 && get_attr_length (insn) >= ix86_cost->large_insn"
20018 [(set (match_dup 2) (match_dup 1))
20019 (set (match_dup 0) (match_dup 2))]
20023 [(match_scratch:QI 2 "q")
20024 (set (match_operand:QI 0 "memory_operand" "")
20025 (match_operand:QI 1 "immediate_operand" ""))]
20027 && TARGET_SPLIT_LONG_MOVES
20028 && get_attr_length (insn) >= ix86_cost->large_insn"
20029 [(set (match_dup 2) (match_dup 1))
20030 (set (match_dup 0) (match_dup 2))]
20033 ;; Don't compare memory with zero, load and use a test instead.
20035 [(set (match_operand 0 "flags_reg_operand" "")
20036 (match_operator 1 "compare_operator"
20037 [(match_operand:SI 2 "memory_operand" "")
20039 (match_scratch:SI 3 "r")]
20040 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20041 [(set (match_dup 3) (match_dup 2))
20042 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20045 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20046 ;; Don't split NOTs with a displacement operand, because resulting XOR
20047 ;; will not be pairable anyway.
20049 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20050 ;; represented using a modRM byte. The XOR replacement is long decoded,
20051 ;; so this split helps here as well.
20053 ;; Note: Can't do this as a regular split because we can't get proper
20054 ;; lifetime information then.
20057 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20058 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20060 && ((TARGET_NOT_UNPAIRABLE
20061 && (!MEM_P (operands[0])
20062 || !memory_displacement_operand (operands[0], SImode)))
20063 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20064 && peep2_regno_dead_p (0, FLAGS_REG)"
20065 [(parallel [(set (match_dup 0)
20066 (xor:SI (match_dup 1) (const_int -1)))
20067 (clobber (reg:CC FLAGS_REG))])]
20071 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20072 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20074 && ((TARGET_NOT_UNPAIRABLE
20075 && (!MEM_P (operands[0])
20076 || !memory_displacement_operand (operands[0], HImode)))
20077 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20078 && peep2_regno_dead_p (0, FLAGS_REG)"
20079 [(parallel [(set (match_dup 0)
20080 (xor:HI (match_dup 1) (const_int -1)))
20081 (clobber (reg:CC FLAGS_REG))])]
20085 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20086 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20088 && ((TARGET_NOT_UNPAIRABLE
20089 && (!MEM_P (operands[0])
20090 || !memory_displacement_operand (operands[0], QImode)))
20091 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20092 && peep2_regno_dead_p (0, FLAGS_REG)"
20093 [(parallel [(set (match_dup 0)
20094 (xor:QI (match_dup 1) (const_int -1)))
20095 (clobber (reg:CC FLAGS_REG))])]
20098 ;; Non pairable "test imm, reg" instructions can be translated to
20099 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20100 ;; byte opcode instead of two, have a short form for byte operands),
20101 ;; so do it for other CPUs as well. Given that the value was dead,
20102 ;; this should not create any new dependencies. Pass on the sub-word
20103 ;; versions if we're concerned about partial register stalls.
20106 [(set (match_operand 0 "flags_reg_operand" "")
20107 (match_operator 1 "compare_operator"
20108 [(and:SI (match_operand:SI 2 "register_operand" "")
20109 (match_operand:SI 3 "immediate_operand" ""))
20111 "ix86_match_ccmode (insn, CCNOmode)
20112 && (true_regnum (operands[2]) != AX_REG
20113 || satisfies_constraint_K (operands[3]))
20114 && peep2_reg_dead_p (1, operands[2])"
20116 [(set (match_dup 0)
20117 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20120 (and:SI (match_dup 2) (match_dup 3)))])]
20123 ;; We don't need to handle HImode case, because it will be promoted to SImode
20124 ;; on ! TARGET_PARTIAL_REG_STALL
20127 [(set (match_operand 0 "flags_reg_operand" "")
20128 (match_operator 1 "compare_operator"
20129 [(and:QI (match_operand:QI 2 "register_operand" "")
20130 (match_operand:QI 3 "immediate_operand" ""))
20132 "! TARGET_PARTIAL_REG_STALL
20133 && ix86_match_ccmode (insn, CCNOmode)
20134 && true_regnum (operands[2]) != AX_REG
20135 && peep2_reg_dead_p (1, operands[2])"
20137 [(set (match_dup 0)
20138 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20141 (and:QI (match_dup 2) (match_dup 3)))])]
20145 [(set (match_operand 0 "flags_reg_operand" "")
20146 (match_operator 1 "compare_operator"
20149 (match_operand 2 "ext_register_operand" "")
20152 (match_operand 3 "const_int_operand" ""))
20154 "! TARGET_PARTIAL_REG_STALL
20155 && ix86_match_ccmode (insn, CCNOmode)
20156 && true_regnum (operands[2]) != AX_REG
20157 && peep2_reg_dead_p (1, operands[2])"
20158 [(parallel [(set (match_dup 0)
20167 (set (zero_extract:SI (match_dup 2)
20178 ;; Don't do logical operations with memory inputs.
20180 [(match_scratch:SI 2 "r")
20181 (parallel [(set (match_operand:SI 0 "register_operand" "")
20182 (match_operator:SI 3 "arith_or_logical_operator"
20184 (match_operand:SI 1 "memory_operand" "")]))
20185 (clobber (reg:CC FLAGS_REG))])]
20186 "! optimize_size && ! TARGET_READ_MODIFY"
20187 [(set (match_dup 2) (match_dup 1))
20188 (parallel [(set (match_dup 0)
20189 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20190 (clobber (reg:CC FLAGS_REG))])]
20194 [(match_scratch:SI 2 "r")
20195 (parallel [(set (match_operand:SI 0 "register_operand" "")
20196 (match_operator:SI 3 "arith_or_logical_operator"
20197 [(match_operand:SI 1 "memory_operand" "")
20199 (clobber (reg:CC FLAGS_REG))])]
20200 "! optimize_size && ! TARGET_READ_MODIFY"
20201 [(set (match_dup 2) (match_dup 1))
20202 (parallel [(set (match_dup 0)
20203 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20204 (clobber (reg:CC FLAGS_REG))])]
20207 ; Don't do logical operations with memory outputs
20209 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20210 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20211 ; the same decoder scheduling characteristics as the original.
20214 [(match_scratch:SI 2 "r")
20215 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20216 (match_operator:SI 3 "arith_or_logical_operator"
20218 (match_operand:SI 1 "nonmemory_operand" "")]))
20219 (clobber (reg:CC FLAGS_REG))])]
20220 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20221 [(set (match_dup 2) (match_dup 0))
20222 (parallel [(set (match_dup 2)
20223 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20224 (clobber (reg:CC FLAGS_REG))])
20225 (set (match_dup 0) (match_dup 2))]
20229 [(match_scratch:SI 2 "r")
20230 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20231 (match_operator:SI 3 "arith_or_logical_operator"
20232 [(match_operand:SI 1 "nonmemory_operand" "")
20234 (clobber (reg:CC FLAGS_REG))])]
20235 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20236 [(set (match_dup 2) (match_dup 0))
20237 (parallel [(set (match_dup 2)
20238 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20239 (clobber (reg:CC FLAGS_REG))])
20240 (set (match_dup 0) (match_dup 2))]
20243 ;; Attempt to always use XOR for zeroing registers.
20245 [(set (match_operand 0 "register_operand" "")
20246 (match_operand 1 "const0_operand" ""))]
20247 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20248 && (! TARGET_USE_MOV0 || optimize_size)
20249 && GENERAL_REG_P (operands[0])
20250 && peep2_regno_dead_p (0, FLAGS_REG)"
20251 [(parallel [(set (match_dup 0) (const_int 0))
20252 (clobber (reg:CC FLAGS_REG))])]
20254 operands[0] = gen_lowpart (word_mode, operands[0]);
20258 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20260 "(GET_MODE (operands[0]) == QImode
20261 || GET_MODE (operands[0]) == HImode)
20262 && (! TARGET_USE_MOV0 || optimize_size)
20263 && peep2_regno_dead_p (0, FLAGS_REG)"
20264 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20265 (clobber (reg:CC FLAGS_REG))])])
20267 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20269 [(set (match_operand 0 "register_operand" "")
20271 "(GET_MODE (operands[0]) == HImode
20272 || GET_MODE (operands[0]) == SImode
20273 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20274 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20275 && peep2_regno_dead_p (0, FLAGS_REG)"
20276 [(parallel [(set (match_dup 0) (const_int -1))
20277 (clobber (reg:CC FLAGS_REG))])]
20278 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20281 ;; Attempt to convert simple leas to adds. These can be created by
20284 [(set (match_operand:SI 0 "register_operand" "")
20285 (plus:SI (match_dup 0)
20286 (match_operand:SI 1 "nonmemory_operand" "")))]
20287 "peep2_regno_dead_p (0, FLAGS_REG)"
20288 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20289 (clobber (reg:CC FLAGS_REG))])]
20293 [(set (match_operand:SI 0 "register_operand" "")
20294 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20295 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20296 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20297 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20298 (clobber (reg:CC FLAGS_REG))])]
20299 "operands[2] = gen_lowpart (SImode, operands[2]);")
20302 [(set (match_operand:DI 0 "register_operand" "")
20303 (plus:DI (match_dup 0)
20304 (match_operand:DI 1 "x86_64_general_operand" "")))]
20305 "peep2_regno_dead_p (0, FLAGS_REG)"
20306 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20307 (clobber (reg:CC FLAGS_REG))])]
20311 [(set (match_operand:SI 0 "register_operand" "")
20312 (mult:SI (match_dup 0)
20313 (match_operand:SI 1 "const_int_operand" "")))]
20314 "exact_log2 (INTVAL (operands[1])) >= 0
20315 && peep2_regno_dead_p (0, FLAGS_REG)"
20316 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20317 (clobber (reg:CC FLAGS_REG))])]
20318 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20321 [(set (match_operand:DI 0 "register_operand" "")
20322 (mult:DI (match_dup 0)
20323 (match_operand:DI 1 "const_int_operand" "")))]
20324 "exact_log2 (INTVAL (operands[1])) >= 0
20325 && peep2_regno_dead_p (0, FLAGS_REG)"
20326 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20327 (clobber (reg:CC FLAGS_REG))])]
20328 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20331 [(set (match_operand:SI 0 "register_operand" "")
20332 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20333 (match_operand:DI 2 "const_int_operand" "")) 0))]
20334 "exact_log2 (INTVAL (operands[2])) >= 0
20335 && REGNO (operands[0]) == REGNO (operands[1])
20336 && peep2_regno_dead_p (0, FLAGS_REG)"
20337 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20338 (clobber (reg:CC FLAGS_REG))])]
20339 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20341 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20342 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20343 ;; many CPUs it is also faster, since special hardware to avoid esp
20344 ;; dependencies is present.
20346 ;; While some of these conversions may be done using splitters, we use peepholes
20347 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20349 ;; Convert prologue esp subtractions to push.
20350 ;; We need register to push. In order to keep verify_flow_info happy we have
20352 ;; - use scratch and clobber it in order to avoid dependencies
20353 ;; - use already live register
20354 ;; We can't use the second way right now, since there is no reliable way how to
20355 ;; verify that given register is live. First choice will also most likely in
20356 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20357 ;; call clobbered registers are dead. We may want to use base pointer as an
20358 ;; alternative when no register is available later.
20361 [(match_scratch:SI 0 "r")
20362 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20363 (clobber (reg:CC FLAGS_REG))
20364 (clobber (mem:BLK (scratch)))])]
20365 "optimize_size || !TARGET_SUB_ESP_4"
20366 [(clobber (match_dup 0))
20367 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20368 (clobber (mem:BLK (scratch)))])])
20371 [(match_scratch:SI 0 "r")
20372 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20373 (clobber (reg:CC FLAGS_REG))
20374 (clobber (mem:BLK (scratch)))])]
20375 "optimize_size || !TARGET_SUB_ESP_8"
20376 [(clobber (match_dup 0))
20377 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20378 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20379 (clobber (mem:BLK (scratch)))])])
20381 ;; Convert esp subtractions to push.
20383 [(match_scratch:SI 0 "r")
20384 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20385 (clobber (reg:CC FLAGS_REG))])]
20386 "optimize_size || !TARGET_SUB_ESP_4"
20387 [(clobber (match_dup 0))
20388 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20391 [(match_scratch:SI 0 "r")
20392 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20393 (clobber (reg:CC FLAGS_REG))])]
20394 "optimize_size || !TARGET_SUB_ESP_8"
20395 [(clobber (match_dup 0))
20396 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20397 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20399 ;; Convert epilogue deallocator to pop.
20401 [(match_scratch:SI 0 "r")
20402 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20403 (clobber (reg:CC FLAGS_REG))
20404 (clobber (mem:BLK (scratch)))])]
20405 "optimize_size || !TARGET_ADD_ESP_4"
20406 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20407 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20408 (clobber (mem:BLK (scratch)))])]
20411 ;; Two pops case is tricky, since pop causes dependency on destination register.
20412 ;; We use two registers if available.
20414 [(match_scratch:SI 0 "r")
20415 (match_scratch:SI 1 "r")
20416 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20417 (clobber (reg:CC FLAGS_REG))
20418 (clobber (mem:BLK (scratch)))])]
20419 "optimize_size || !TARGET_ADD_ESP_8"
20420 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20421 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20422 (clobber (mem:BLK (scratch)))])
20423 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20424 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20428 [(match_scratch:SI 0 "r")
20429 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20430 (clobber (reg:CC FLAGS_REG))
20431 (clobber (mem:BLK (scratch)))])]
20433 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20434 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20435 (clobber (mem:BLK (scratch)))])
20436 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20437 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20440 ;; Convert esp additions to pop.
20442 [(match_scratch:SI 0 "r")
20443 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20444 (clobber (reg:CC FLAGS_REG))])]
20446 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20447 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20450 ;; Two pops case is tricky, since pop causes dependency on destination register.
20451 ;; We use two registers if available.
20453 [(match_scratch:SI 0 "r")
20454 (match_scratch:SI 1 "r")
20455 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20456 (clobber (reg:CC FLAGS_REG))])]
20458 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20459 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20460 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20461 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20465 [(match_scratch:SI 0 "r")
20466 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20467 (clobber (reg:CC FLAGS_REG))])]
20469 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20470 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20471 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20472 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20475 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20476 ;; required and register dies. Similarly for 128 to plus -128.
20478 [(set (match_operand 0 "flags_reg_operand" "")
20479 (match_operator 1 "compare_operator"
20480 [(match_operand 2 "register_operand" "")
20481 (match_operand 3 "const_int_operand" "")]))]
20482 "(INTVAL (operands[3]) == -1
20483 || INTVAL (operands[3]) == 1
20484 || INTVAL (operands[3]) == 128)
20485 && ix86_match_ccmode (insn, CCGCmode)
20486 && peep2_reg_dead_p (1, operands[2])"
20487 [(parallel [(set (match_dup 0)
20488 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20489 (clobber (match_dup 2))])]
20493 [(match_scratch:DI 0 "r")
20494 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20495 (clobber (reg:CC FLAGS_REG))
20496 (clobber (mem:BLK (scratch)))])]
20497 "optimize_size || !TARGET_SUB_ESP_4"
20498 [(clobber (match_dup 0))
20499 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20500 (clobber (mem:BLK (scratch)))])])
20503 [(match_scratch:DI 0 "r")
20504 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20505 (clobber (reg:CC FLAGS_REG))
20506 (clobber (mem:BLK (scratch)))])]
20507 "optimize_size || !TARGET_SUB_ESP_8"
20508 [(clobber (match_dup 0))
20509 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20510 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20511 (clobber (mem:BLK (scratch)))])])
20513 ;; Convert esp subtractions to push.
20515 [(match_scratch:DI 0 "r")
20516 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20517 (clobber (reg:CC FLAGS_REG))])]
20518 "optimize_size || !TARGET_SUB_ESP_4"
20519 [(clobber (match_dup 0))
20520 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20523 [(match_scratch:DI 0 "r")
20524 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20525 (clobber (reg:CC FLAGS_REG))])]
20526 "optimize_size || !TARGET_SUB_ESP_8"
20527 [(clobber (match_dup 0))
20528 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20529 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20531 ;; Convert epilogue deallocator to pop.
20533 [(match_scratch:DI 0 "r")
20534 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20535 (clobber (reg:CC FLAGS_REG))
20536 (clobber (mem:BLK (scratch)))])]
20537 "optimize_size || !TARGET_ADD_ESP_4"
20538 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20539 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20540 (clobber (mem:BLK (scratch)))])]
20543 ;; Two pops case is tricky, since pop causes dependency on destination register.
20544 ;; We use two registers if available.
20546 [(match_scratch:DI 0 "r")
20547 (match_scratch:DI 1 "r")
20548 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20549 (clobber (reg:CC FLAGS_REG))
20550 (clobber (mem:BLK (scratch)))])]
20551 "optimize_size || !TARGET_ADD_ESP_8"
20552 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20553 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20554 (clobber (mem:BLK (scratch)))])
20555 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20556 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20560 [(match_scratch:DI 0 "r")
20561 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20562 (clobber (reg:CC FLAGS_REG))
20563 (clobber (mem:BLK (scratch)))])]
20565 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20566 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20567 (clobber (mem:BLK (scratch)))])
20568 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20569 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20572 ;; Convert esp additions to pop.
20574 [(match_scratch:DI 0 "r")
20575 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20576 (clobber (reg:CC FLAGS_REG))])]
20578 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20579 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20582 ;; Two pops case is tricky, since pop causes dependency on destination register.
20583 ;; We use two registers if available.
20585 [(match_scratch:DI 0 "r")
20586 (match_scratch:DI 1 "r")
20587 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20588 (clobber (reg:CC FLAGS_REG))])]
20590 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20591 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20592 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20593 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20597 [(match_scratch:DI 0 "r")
20598 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20599 (clobber (reg:CC FLAGS_REG))])]
20601 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20602 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20603 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20604 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20607 ;; Convert imul by three, five and nine into lea
20610 [(set (match_operand:SI 0 "register_operand" "")
20611 (mult:SI (match_operand:SI 1 "register_operand" "")
20612 (match_operand:SI 2 "const_int_operand" "")))
20613 (clobber (reg:CC FLAGS_REG))])]
20614 "INTVAL (operands[2]) == 3
20615 || INTVAL (operands[2]) == 5
20616 || INTVAL (operands[2]) == 9"
20617 [(set (match_dup 0)
20618 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20620 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20624 [(set (match_operand:SI 0 "register_operand" "")
20625 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20626 (match_operand:SI 2 "const_int_operand" "")))
20627 (clobber (reg:CC FLAGS_REG))])]
20629 && (INTVAL (operands[2]) == 3
20630 || INTVAL (operands[2]) == 5
20631 || INTVAL (operands[2]) == 9)"
20632 [(set (match_dup 0) (match_dup 1))
20634 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20636 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20640 [(set (match_operand:DI 0 "register_operand" "")
20641 (mult:DI (match_operand:DI 1 "register_operand" "")
20642 (match_operand:DI 2 "const_int_operand" "")))
20643 (clobber (reg:CC FLAGS_REG))])]
20645 && (INTVAL (operands[2]) == 3
20646 || INTVAL (operands[2]) == 5
20647 || INTVAL (operands[2]) == 9)"
20648 [(set (match_dup 0)
20649 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20651 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20655 [(set (match_operand:DI 0 "register_operand" "")
20656 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20657 (match_operand:DI 2 "const_int_operand" "")))
20658 (clobber (reg:CC FLAGS_REG))])]
20661 && (INTVAL (operands[2]) == 3
20662 || INTVAL (operands[2]) == 5
20663 || INTVAL (operands[2]) == 9)"
20664 [(set (match_dup 0) (match_dup 1))
20666 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20668 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20670 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20671 ;; imul $32bit_imm, reg, reg is direct decoded.
20673 [(match_scratch:DI 3 "r")
20674 (parallel [(set (match_operand:DI 0 "register_operand" "")
20675 (mult:DI (match_operand:DI 1 "memory_operand" "")
20676 (match_operand:DI 2 "immediate_operand" "")))
20677 (clobber (reg:CC FLAGS_REG))])]
20678 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20679 && !satisfies_constraint_K (operands[2])"
20680 [(set (match_dup 3) (match_dup 1))
20681 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20682 (clobber (reg:CC FLAGS_REG))])]
20686 [(match_scratch:SI 3 "r")
20687 (parallel [(set (match_operand:SI 0 "register_operand" "")
20688 (mult:SI (match_operand:SI 1 "memory_operand" "")
20689 (match_operand:SI 2 "immediate_operand" "")))
20690 (clobber (reg:CC FLAGS_REG))])]
20691 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20692 && !satisfies_constraint_K (operands[2])"
20693 [(set (match_dup 3) (match_dup 1))
20694 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20695 (clobber (reg:CC FLAGS_REG))])]
20699 [(match_scratch:SI 3 "r")
20700 (parallel [(set (match_operand:DI 0 "register_operand" "")
20702 (mult:SI (match_operand:SI 1 "memory_operand" "")
20703 (match_operand:SI 2 "immediate_operand" ""))))
20704 (clobber (reg:CC FLAGS_REG))])]
20705 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20706 && !satisfies_constraint_K (operands[2])"
20707 [(set (match_dup 3) (match_dup 1))
20708 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20709 (clobber (reg:CC FLAGS_REG))])]
20712 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20713 ;; Convert it into imul reg, reg
20714 ;; It would be better to force assembler to encode instruction using long
20715 ;; immediate, but there is apparently no way to do so.
20717 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20718 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20719 (match_operand:DI 2 "const_int_operand" "")))
20720 (clobber (reg:CC FLAGS_REG))])
20721 (match_scratch:DI 3 "r")]
20722 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20723 && satisfies_constraint_K (operands[2])"
20724 [(set (match_dup 3) (match_dup 2))
20725 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20726 (clobber (reg:CC FLAGS_REG))])]
20728 if (!rtx_equal_p (operands[0], operands[1]))
20729 emit_move_insn (operands[0], operands[1]);
20733 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20734 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20735 (match_operand:SI 2 "const_int_operand" "")))
20736 (clobber (reg:CC FLAGS_REG))])
20737 (match_scratch:SI 3 "r")]
20738 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20739 && satisfies_constraint_K (operands[2])"
20740 [(set (match_dup 3) (match_dup 2))
20741 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20742 (clobber (reg:CC FLAGS_REG))])]
20744 if (!rtx_equal_p (operands[0], operands[1]))
20745 emit_move_insn (operands[0], operands[1]);
20749 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20750 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20751 (match_operand:HI 2 "immediate_operand" "")))
20752 (clobber (reg:CC FLAGS_REG))])
20753 (match_scratch:HI 3 "r")]
20754 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20755 [(set (match_dup 3) (match_dup 2))
20756 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20757 (clobber (reg:CC FLAGS_REG))])]
20759 if (!rtx_equal_p (operands[0], operands[1]))
20760 emit_move_insn (operands[0], operands[1]);
20763 ;; After splitting up read-modify operations, array accesses with memory
20764 ;; operands might end up in form:
20766 ;; movl 4(%esp), %edx
20768 ;; instead of pre-splitting:
20770 ;; addl 4(%esp), %eax
20772 ;; movl 4(%esp), %edx
20773 ;; leal (%edx,%eax,4), %eax
20776 [(parallel [(set (match_operand 0 "register_operand" "")
20777 (ashift (match_operand 1 "register_operand" "")
20778 (match_operand 2 "const_int_operand" "")))
20779 (clobber (reg:CC FLAGS_REG))])
20780 (set (match_operand 3 "register_operand")
20781 (match_operand 4 "x86_64_general_operand" ""))
20782 (parallel [(set (match_operand 5 "register_operand" "")
20783 (plus (match_operand 6 "register_operand" "")
20784 (match_operand 7 "register_operand" "")))
20785 (clobber (reg:CC FLAGS_REG))])]
20786 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20787 /* Validate MODE for lea. */
20788 && ((!TARGET_PARTIAL_REG_STALL
20789 && (GET_MODE (operands[0]) == QImode
20790 || GET_MODE (operands[0]) == HImode))
20791 || GET_MODE (operands[0]) == SImode
20792 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20793 /* We reorder load and the shift. */
20794 && !rtx_equal_p (operands[1], operands[3])
20795 && !reg_overlap_mentioned_p (operands[0], operands[4])
20796 /* Last PLUS must consist of operand 0 and 3. */
20797 && !rtx_equal_p (operands[0], operands[3])
20798 && (rtx_equal_p (operands[3], operands[6])
20799 || rtx_equal_p (operands[3], operands[7]))
20800 && (rtx_equal_p (operands[0], operands[6])
20801 || rtx_equal_p (operands[0], operands[7]))
20802 /* The intermediate operand 0 must die or be same as output. */
20803 && (rtx_equal_p (operands[0], operands[5])
20804 || peep2_reg_dead_p (3, operands[0]))"
20805 [(set (match_dup 3) (match_dup 4))
20806 (set (match_dup 0) (match_dup 1))]
20808 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20809 int scale = 1 << INTVAL (operands[2]);
20810 rtx index = gen_lowpart (Pmode, operands[1]);
20811 rtx base = gen_lowpart (Pmode, operands[3]);
20812 rtx dest = gen_lowpart (mode, operands[5]);
20814 operands[1] = gen_rtx_PLUS (Pmode, base,
20815 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20817 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20818 operands[0] = dest;
20821 ;; Call-value patterns last so that the wildcard operand does not
20822 ;; disrupt insn-recog's switch tables.
20824 (define_insn "*call_value_pop_0"
20825 [(set (match_operand 0 "" "")
20826 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20827 (match_operand:SI 2 "" "")))
20828 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20829 (match_operand:SI 3 "immediate_operand" "")))]
20832 if (SIBLING_CALL_P (insn))
20835 return "call\t%P1";
20837 [(set_attr "type" "callv")])
20839 (define_insn "*call_value_pop_1"
20840 [(set (match_operand 0 "" "")
20841 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20842 (match_operand:SI 2 "" "")))
20843 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20844 (match_operand:SI 3 "immediate_operand" "i")))]
20847 if (constant_call_address_operand (operands[1], Pmode))
20849 if (SIBLING_CALL_P (insn))
20852 return "call\t%P1";
20854 if (SIBLING_CALL_P (insn))
20857 return "call\t%A1";
20859 [(set_attr "type" "callv")])
20861 (define_insn "*call_value_0"
20862 [(set (match_operand 0 "" "")
20863 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20864 (match_operand:SI 2 "" "")))]
20867 if (SIBLING_CALL_P (insn))
20870 return "call\t%P1";
20872 [(set_attr "type" "callv")])
20874 (define_insn "*call_value_0_rex64"
20875 [(set (match_operand 0 "" "")
20876 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20877 (match_operand:DI 2 "const_int_operand" "")))]
20880 if (SIBLING_CALL_P (insn))
20883 return "call\t%P1";
20885 [(set_attr "type" "callv")])
20887 (define_insn "*call_value_1"
20888 [(set (match_operand 0 "" "")
20889 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20890 (match_operand:SI 2 "" "")))]
20891 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20893 if (constant_call_address_operand (operands[1], Pmode))
20894 return "call\t%P1";
20895 return "call\t%A1";
20897 [(set_attr "type" "callv")])
20899 (define_insn "*sibcall_value_1"
20900 [(set (match_operand 0 "" "")
20901 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20902 (match_operand:SI 2 "" "")))]
20903 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20905 if (constant_call_address_operand (operands[1], Pmode))
20909 [(set_attr "type" "callv")])
20911 (define_insn "*call_value_1_rex64"
20912 [(set (match_operand 0 "" "")
20913 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20914 (match_operand:DI 2 "" "")))]
20915 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20916 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20918 if (constant_call_address_operand (operands[1], Pmode))
20919 return "call\t%P1";
20920 return "call\t%A1";
20922 [(set_attr "type" "callv")])
20924 (define_insn "*call_value_1_rex64_large"
20925 [(set (match_operand 0 "" "")
20926 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20927 (match_operand:DI 2 "" "")))]
20928 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20930 [(set_attr "type" "callv")])
20932 (define_insn "*sibcall_value_1_rex64"
20933 [(set (match_operand 0 "" "")
20934 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20935 (match_operand:DI 2 "" "")))]
20936 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20938 [(set_attr "type" "callv")])
20940 (define_insn "*sibcall_value_1_rex64_v"
20941 [(set (match_operand 0 "" "")
20942 (call (mem:QI (reg:DI R11_REG))
20943 (match_operand:DI 1 "" "")))]
20944 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20946 [(set_attr "type" "callv")])
20948 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20949 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20950 ;; caught for use by garbage collectors and the like. Using an insn that
20951 ;; maps to SIGILL makes it more likely the program will rightfully die.
20952 ;; Keeping with tradition, "6" is in honor of #UD.
20953 (define_insn "trap"
20954 [(trap_if (const_int 1) (const_int 6))]
20956 { return ASM_SHORT "0x0b0f"; }
20957 [(set_attr "length" "2")])
20959 (define_expand "sse_prologue_save"
20960 [(parallel [(set (match_operand:BLK 0 "" "")
20961 (unspec:BLK [(reg:DI 21)
20968 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20969 (use (match_operand:DI 1 "register_operand" ""))
20970 (use (match_operand:DI 2 "immediate_operand" ""))
20971 (use (label_ref:DI (match_operand 3 "" "")))])]
20975 (define_insn "*sse_prologue_save_insn"
20976 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20977 (match_operand:DI 4 "const_int_operand" "n")))
20978 (unspec:BLK [(reg:DI 21)
20985 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20986 (use (match_operand:DI 1 "register_operand" "r"))
20987 (use (match_operand:DI 2 "const_int_operand" "i"))
20988 (use (label_ref:DI (match_operand 3 "" "X")))]
20990 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20991 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20994 operands[0] = gen_rtx_MEM (Pmode,
20995 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20996 output_asm_insn ("jmp\t%A1", operands);
20997 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20999 operands[4] = adjust_address (operands[0], DImode, i*16);
21000 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21001 PUT_MODE (operands[4], TImode);
21002 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21003 output_asm_insn ("rex", operands);
21004 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21006 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21007 CODE_LABEL_NUMBER (operands[3]));
21010 [(set_attr "type" "other")
21011 (set_attr "length_immediate" "0")
21012 (set_attr "length_address" "0")
21013 (set_attr "length" "34")
21014 (set_attr "memory" "store")
21015 (set_attr "modrm" "0")
21016 (set_attr "mode" "DI")])
21018 (define_expand "prefetch"
21019 [(prefetch (match_operand 0 "address_operand" "")
21020 (match_operand:SI 1 "const_int_operand" "")
21021 (match_operand:SI 2 "const_int_operand" ""))]
21022 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21024 int rw = INTVAL (operands[1]);
21025 int locality = INTVAL (operands[2]);
21027 gcc_assert (rw == 0 || rw == 1);
21028 gcc_assert (locality >= 0 && locality <= 3);
21029 gcc_assert (GET_MODE (operands[0]) == Pmode
21030 || GET_MODE (operands[0]) == VOIDmode);
21032 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21033 supported by SSE counterpart or the SSE prefetch is not available
21034 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21036 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21037 operands[2] = GEN_INT (3);
21039 operands[1] = const0_rtx;
21042 (define_insn "*prefetch_sse"
21043 [(prefetch (match_operand:SI 0 "address_operand" "p")
21045 (match_operand:SI 1 "const_int_operand" ""))]
21046 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21048 static const char * const patterns[4] = {
21049 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21052 int locality = INTVAL (operands[1]);
21053 gcc_assert (locality >= 0 && locality <= 3);
21055 return patterns[locality];
21057 [(set_attr "type" "sse")
21058 (set_attr "memory" "none")])
21060 (define_insn "*prefetch_sse_rex"
21061 [(prefetch (match_operand:DI 0 "address_operand" "p")
21063 (match_operand:SI 1 "const_int_operand" ""))]
21064 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21066 static const char * const patterns[4] = {
21067 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21070 int locality = INTVAL (operands[1]);
21071 gcc_assert (locality >= 0 && locality <= 3);
21073 return patterns[locality];
21075 [(set_attr "type" "sse")
21076 (set_attr "memory" "none")])
21078 (define_insn "*prefetch_3dnow"
21079 [(prefetch (match_operand:SI 0 "address_operand" "p")
21080 (match_operand:SI 1 "const_int_operand" "n")
21082 "TARGET_3DNOW && !TARGET_64BIT"
21084 if (INTVAL (operands[1]) == 0)
21085 return "prefetch\t%a0";
21087 return "prefetchw\t%a0";
21089 [(set_attr "type" "mmx")
21090 (set_attr "memory" "none")])
21092 (define_insn "*prefetch_3dnow_rex"
21093 [(prefetch (match_operand:DI 0 "address_operand" "p")
21094 (match_operand:SI 1 "const_int_operand" "n")
21096 "TARGET_3DNOW && TARGET_64BIT"
21098 if (INTVAL (operands[1]) == 0)
21099 return "prefetch\t%a0";
21101 return "prefetchw\t%a0";
21103 [(set_attr "type" "mmx")
21104 (set_attr "memory" "none")])
21106 (define_expand "stack_protect_set"
21107 [(match_operand 0 "memory_operand" "")
21108 (match_operand 1 "memory_operand" "")]
21111 #ifdef TARGET_THREAD_SSP_OFFSET
21113 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21114 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21116 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21117 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21120 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21122 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21127 (define_insn "stack_protect_set_si"
21128 [(set (match_operand:SI 0 "memory_operand" "=m")
21129 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21130 (set (match_scratch:SI 2 "=&r") (const_int 0))
21131 (clobber (reg:CC FLAGS_REG))]
21133 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21134 [(set_attr "type" "multi")])
21136 (define_insn "stack_protect_set_di"
21137 [(set (match_operand:DI 0 "memory_operand" "=m")
21138 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21139 (set (match_scratch:DI 2 "=&r") (const_int 0))
21140 (clobber (reg:CC FLAGS_REG))]
21142 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21143 [(set_attr "type" "multi")])
21145 (define_insn "stack_tls_protect_set_si"
21146 [(set (match_operand:SI 0 "memory_operand" "=m")
21147 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21148 (set (match_scratch:SI 2 "=&r") (const_int 0))
21149 (clobber (reg:CC FLAGS_REG))]
21151 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21152 [(set_attr "type" "multi")])
21154 (define_insn "stack_tls_protect_set_di"
21155 [(set (match_operand:DI 0 "memory_operand" "=m")
21156 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21157 (set (match_scratch:DI 2 "=&r") (const_int 0))
21158 (clobber (reg:CC FLAGS_REG))]
21161 /* The kernel uses a different segment register for performance reasons; a
21162 system call would not have to trash the userspace segment register,
21163 which would be expensive */
21164 if (ix86_cmodel != CM_KERNEL)
21165 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21167 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21169 [(set_attr "type" "multi")])
21171 (define_expand "stack_protect_test"
21172 [(match_operand 0 "memory_operand" "")
21173 (match_operand 1 "memory_operand" "")
21174 (match_operand 2 "" "")]
21177 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21178 ix86_compare_op0 = operands[0];
21179 ix86_compare_op1 = operands[1];
21180 ix86_compare_emitted = flags;
21182 #ifdef TARGET_THREAD_SSP_OFFSET
21184 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21185 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21187 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21188 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21191 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21193 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21195 emit_jump_insn (gen_beq (operands[2]));
21199 (define_insn "stack_protect_test_si"
21200 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21201 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21202 (match_operand:SI 2 "memory_operand" "m")]
21204 (clobber (match_scratch:SI 3 "=&r"))]
21206 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21207 [(set_attr "type" "multi")])
21209 (define_insn "stack_protect_test_di"
21210 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21211 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21212 (match_operand:DI 2 "memory_operand" "m")]
21214 (clobber (match_scratch:DI 3 "=&r"))]
21216 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21217 [(set_attr "type" "multi")])
21219 (define_insn "stack_tls_protect_test_si"
21220 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21221 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21222 (match_operand:SI 2 "const_int_operand" "i")]
21223 UNSPEC_SP_TLS_TEST))
21224 (clobber (match_scratch:SI 3 "=r"))]
21226 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21227 [(set_attr "type" "multi")])
21229 (define_insn "stack_tls_protect_test_di"
21230 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21231 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21232 (match_operand:DI 2 "const_int_operand" "i")]
21233 UNSPEC_SP_TLS_TEST))
21234 (clobber (match_scratch:DI 3 "=r"))]
21237 /* The kernel uses a different segment register for performance reasons; a
21238 system call would not have to trash the userspace segment register,
21239 which would be expensive */
21240 if (ix86_cmodel != CM_KERNEL)
21241 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21243 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21245 [(set_attr "type" "multi")])
21247 (define_mode_iterator CRC32MODE [QI HI SI])
21248 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21249 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21251 (define_insn "sse4_2_crc32<mode>"
21252 [(set (match_operand:SI 0 "register_operand" "=r")
21254 [(match_operand:SI 1 "register_operand" "0")
21255 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21258 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21259 [(set_attr "type" "sselog1")
21260 (set_attr "prefix_rep" "1")
21261 (set_attr "prefix_extra" "1")
21262 (set_attr "mode" "SI")])
21264 (define_insn "sse4_2_crc32di"
21265 [(set (match_operand:DI 0 "register_operand" "=r")
21267 [(match_operand:DI 1 "register_operand" "0")
21268 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21270 "TARGET_SSE4_2 && TARGET_64BIT"
21271 "crc32q\t{%2, %0|%0, %2}"
21272 [(set_attr "type" "sselog1")
21273 (set_attr "prefix_rep" "1")
21274 (set_attr "prefix_extra" "1")
21275 (set_attr "mode" "DI")])
21279 (include "sync.md")