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)
184 (UNSPEC_SSE5_ASHIFT 154)
185 (UNSPEC_SSE5_LSHIFT 155)
187 (UNSPEC_CVTPH2PS 157)
188 (UNSPEC_CVTPS2PH 158)
192 [(UNSPECV_BLOCKAGE 0)
193 (UNSPECV_STACK_PROBE 1)
202 (UNSPECV_CMPXCHG_1 10)
203 (UNSPECV_CMPXCHG_2 11)
206 (UNSPECV_PROLOGUE_USE 14)
209 ;; Constants to represent pcomtrue/pcomfalse variants
219 ;; Registers by name.
235 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
238 ;; In C guard expressions, put expressions which may be compile-time
239 ;; constants first. This allows for better optimization. For
240 ;; example, write "TARGET_64BIT && reload_completed", not
241 ;; "reload_completed && TARGET_64BIT".
244 ;; Processor type. This attribute must exactly match the processor_type
245 ;; enumeration in i386.h.
246 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
247 nocona,core2,generic32,generic64,amdfam10"
248 (const (symbol_ref "ix86_tune")))
250 ;; A basic instruction type. Refinements due to arguments to be
251 ;; provided in other attributes.
254 alu,alu1,negnot,imov,imovx,lea,
255 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
256 icmp,test,ibr,setcc,icmov,
257 push,pop,call,callv,leave,
259 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
260 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
261 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
263 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
264 (const_string "other"))
266 ;; Main data type used by the insn
268 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
269 (const_string "unknown"))
271 ;; The CPU unit operations uses.
272 (define_attr "unit" "integer,i387,sse,mmx,unknown"
273 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
274 (const_string "i387")
275 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
276 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
277 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
279 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
281 (eq_attr "type" "other")
282 (const_string "unknown")]
283 (const_string "integer")))
285 ;; The (bounding maximum) length of an instruction immediate.
286 (define_attr "length_immediate" ""
287 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
290 (eq_attr "unit" "i387,sse,mmx")
292 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
294 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
295 (eq_attr "type" "imov,test")
296 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
297 (eq_attr "type" "call")
298 (if_then_else (match_operand 0 "constant_call_address_operand" "")
301 (eq_attr "type" "callv")
302 (if_then_else (match_operand 1 "constant_call_address_operand" "")
305 ;; We don't know the size before shorten_branches. Expect
306 ;; the instruction to fit for better scheduling.
307 (eq_attr "type" "ibr")
310 (symbol_ref "/* Update immediate_length and other attributes! */
311 gcc_unreachable (),1")))
313 ;; The (bounding maximum) length of an instruction address.
314 (define_attr "length_address" ""
315 (cond [(eq_attr "type" "str,other,multi,fxch")
317 (and (eq_attr "type" "call")
318 (match_operand 0 "constant_call_address_operand" ""))
320 (and (eq_attr "type" "callv")
321 (match_operand 1 "constant_call_address_operand" ""))
324 (symbol_ref "ix86_attr_length_address_default (insn)")))
326 ;; Set when length prefix is used.
327 (define_attr "prefix_data16" ""
328 (if_then_else (ior (eq_attr "mode" "HI")
329 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
333 ;; Set when string REP prefix is used.
334 (define_attr "prefix_rep" ""
335 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
339 ;; Set when 0f opcode prefix is used.
340 (define_attr "prefix_0f" ""
342 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
343 (eq_attr "unit" "sse,mmx"))
347 ;; Set when REX opcode prefix is used.
348 (define_attr "prefix_rex" ""
349 (cond [(and (eq_attr "mode" "DI")
350 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
352 (and (eq_attr "mode" "QI")
353 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
356 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
362 ;; There are also additional prefixes in SSSE3.
363 (define_attr "prefix_extra" "" (const_int 0))
365 ;; Set when modrm byte is used.
366 (define_attr "modrm" ""
367 (cond [(eq_attr "type" "str,leave")
369 (eq_attr "unit" "i387")
371 (and (eq_attr "type" "incdec")
372 (ior (match_operand:SI 1 "register_operand" "")
373 (match_operand:HI 1 "register_operand" "")))
375 (and (eq_attr "type" "push")
376 (not (match_operand 1 "memory_operand" "")))
378 (and (eq_attr "type" "pop")
379 (not (match_operand 0 "memory_operand" "")))
381 (and (eq_attr "type" "imov")
382 (ior (and (match_operand 0 "register_operand" "")
383 (match_operand 1 "immediate_operand" ""))
384 (ior (and (match_operand 0 "ax_reg_operand" "")
385 (match_operand 1 "memory_displacement_only_operand" ""))
386 (and (match_operand 0 "memory_displacement_only_operand" "")
387 (match_operand 1 "ax_reg_operand" "")))))
389 (and (eq_attr "type" "call")
390 (match_operand 0 "constant_call_address_operand" ""))
392 (and (eq_attr "type" "callv")
393 (match_operand 1 "constant_call_address_operand" ""))
398 ;; The (bounding maximum) length of an instruction in bytes.
399 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
400 ;; Later we may want to split them and compute proper length as for
402 (define_attr "length" ""
403 (cond [(eq_attr "type" "other,multi,fistp,frndint")
405 (eq_attr "type" "fcmp")
407 (eq_attr "unit" "i387")
409 (plus (attr "prefix_data16")
410 (attr "length_address")))]
411 (plus (plus (attr "modrm")
412 (plus (attr "prefix_0f")
413 (plus (attr "prefix_rex")
414 (plus (attr "prefix_extra")
416 (plus (attr "prefix_rep")
417 (plus (attr "prefix_data16")
418 (plus (attr "length_immediate")
419 (attr "length_address")))))))
421 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
422 ;; `store' if there is a simple memory reference therein, or `unknown'
423 ;; if the instruction is complex.
425 (define_attr "memory" "none,load,store,both,unknown"
426 (cond [(eq_attr "type" "other,multi,str")
427 (const_string "unknown")
428 (eq_attr "type" "lea,fcmov,fpspc")
429 (const_string "none")
430 (eq_attr "type" "fistp,leave")
431 (const_string "both")
432 (eq_attr "type" "frndint")
433 (const_string "load")
434 (eq_attr "type" "push")
435 (if_then_else (match_operand 1 "memory_operand" "")
436 (const_string "both")
437 (const_string "store"))
438 (eq_attr "type" "pop")
439 (if_then_else (match_operand 0 "memory_operand" "")
440 (const_string "both")
441 (const_string "load"))
442 (eq_attr "type" "setcc")
443 (if_then_else (match_operand 0 "memory_operand" "")
444 (const_string "store")
445 (const_string "none"))
446 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
447 (if_then_else (ior (match_operand 0 "memory_operand" "")
448 (match_operand 1 "memory_operand" ""))
449 (const_string "load")
450 (const_string "none"))
451 (eq_attr "type" "ibr")
452 (if_then_else (match_operand 0 "memory_operand" "")
453 (const_string "load")
454 (const_string "none"))
455 (eq_attr "type" "call")
456 (if_then_else (match_operand 0 "constant_call_address_operand" "")
457 (const_string "none")
458 (const_string "load"))
459 (eq_attr "type" "callv")
460 (if_then_else (match_operand 1 "constant_call_address_operand" "")
461 (const_string "none")
462 (const_string "load"))
463 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
464 (match_operand 1 "memory_operand" ""))
465 (const_string "both")
466 (and (match_operand 0 "memory_operand" "")
467 (match_operand 1 "memory_operand" ""))
468 (const_string "both")
469 (match_operand 0 "memory_operand" "")
470 (const_string "store")
471 (match_operand 1 "memory_operand" "")
472 (const_string "load")
474 "!alu1,negnot,ishift1,
475 imov,imovx,icmp,test,bitmanip,
477 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
478 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
479 (match_operand 2 "memory_operand" ""))
480 (const_string "load")
481 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
482 (match_operand 3 "memory_operand" ""))
483 (const_string "load")
485 (const_string "none")))
487 ;; Indicates if an instruction has both an immediate and a displacement.
489 (define_attr "imm_disp" "false,true,unknown"
490 (cond [(eq_attr "type" "other,multi")
491 (const_string "unknown")
492 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
493 (and (match_operand 0 "memory_displacement_operand" "")
494 (match_operand 1 "immediate_operand" "")))
495 (const_string "true")
496 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
497 (and (match_operand 0 "memory_displacement_operand" "")
498 (match_operand 2 "immediate_operand" "")))
499 (const_string "true")
501 (const_string "false")))
503 ;; Indicates if an FP operation has an integer source.
505 (define_attr "fp_int_src" "false,true"
506 (const_string "false"))
508 ;; Defines rounding mode of an FP operation.
510 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
511 (const_string "any"))
513 ;; Describe a user's asm statement.
514 (define_asm_attributes
515 [(set_attr "length" "128")
516 (set_attr "type" "multi")])
518 (define_code_iterator plusminus [plus minus])
520 ;; Base name for define_insn and insn mnemonic.
521 (define_code_attr addsub [(plus "add") (minus "sub")])
523 ;; Mark commutative operators as such in constraints.
524 (define_code_attr comm [(plus "%") (minus "")])
526 ;; All single word integer modes.
527 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
529 ;; Instruction suffix for integer modes.
530 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
532 ;; Register class for integer modes.
533 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
535 ;; Immediate operand constraint for integer modes.
536 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
538 ;; General operand predicate for integer modes.
539 (define_mode_attr general_operand
540 [(QI "general_operand")
541 (HI "general_operand")
542 (SI "general_operand")
543 (DI "x86_64_general_operand")])
545 ;; SSE and x87 SFmode and DFmode floating point modes
546 (define_mode_iterator MODEF [SF DF])
548 ;; All x87 floating point modes
549 (define_mode_iterator X87MODEF [SF DF XF])
551 ;; All integer modes handled by x87 fisttp operator.
552 (define_mode_iterator X87MODEI [HI SI DI])
554 ;; All integer modes handled by integer x87 operators.
555 (define_mode_iterator X87MODEI12 [HI SI])
557 ;; All integer modes handled by SSE cvtts?2si* operators.
558 (define_mode_iterator SSEMODEI24 [SI DI])
560 ;; SSE asm suffix for floating point modes
561 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
563 ;; SSE vector mode corresponding to a scalar mode
564 (define_mode_attr ssevecmode
565 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
567 ;; Scheduling descriptions
569 (include "pentium.md")
572 (include "athlon.md")
576 ;; Operand and operator predicates and constraints
578 (include "predicates.md")
579 (include "constraints.md")
582 ;; Compare instructions.
584 ;; All compare insns have expanders that save the operands away without
585 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
586 ;; after the cmp) will actually emit the cmpM.
588 (define_expand "cmpti"
589 [(set (reg:CC FLAGS_REG)
590 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
591 (match_operand:TI 1 "x86_64_general_operand" "")))]
594 if (MEM_P (operands[0]) && MEM_P (operands[1]))
595 operands[0] = force_reg (TImode, operands[0]);
596 ix86_compare_op0 = operands[0];
597 ix86_compare_op1 = operands[1];
601 (define_expand "cmpdi"
602 [(set (reg:CC FLAGS_REG)
603 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
604 (match_operand:DI 1 "x86_64_general_operand" "")))]
607 if (MEM_P (operands[0]) && MEM_P (operands[1]))
608 operands[0] = force_reg (DImode, operands[0]);
609 ix86_compare_op0 = operands[0];
610 ix86_compare_op1 = operands[1];
614 (define_expand "cmpsi"
615 [(set (reg:CC FLAGS_REG)
616 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
617 (match_operand:SI 1 "general_operand" "")))]
620 if (MEM_P (operands[0]) && MEM_P (operands[1]))
621 operands[0] = force_reg (SImode, operands[0]);
622 ix86_compare_op0 = operands[0];
623 ix86_compare_op1 = operands[1];
627 (define_expand "cmphi"
628 [(set (reg:CC FLAGS_REG)
629 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
630 (match_operand:HI 1 "general_operand" "")))]
633 if (MEM_P (operands[0]) && MEM_P (operands[1]))
634 operands[0] = force_reg (HImode, operands[0]);
635 ix86_compare_op0 = operands[0];
636 ix86_compare_op1 = operands[1];
640 (define_expand "cmpqi"
641 [(set (reg:CC FLAGS_REG)
642 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
643 (match_operand:QI 1 "general_operand" "")))]
646 if (MEM_P (operands[0]) && MEM_P (operands[1]))
647 operands[0] = force_reg (QImode, operands[0]);
648 ix86_compare_op0 = operands[0];
649 ix86_compare_op1 = operands[1];
653 (define_insn "cmpdi_ccno_1_rex64"
654 [(set (reg FLAGS_REG)
655 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
656 (match_operand:DI 1 "const0_operand" "n,n")))]
657 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
660 cmp{q}\t{%1, %0|%0, %1}"
661 [(set_attr "type" "test,icmp")
662 (set_attr "length_immediate" "0,1")
663 (set_attr "mode" "DI")])
665 (define_insn "*cmpdi_minus_1_rex64"
666 [(set (reg FLAGS_REG)
667 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
668 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
670 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
671 "cmp{q}\t{%1, %0|%0, %1}"
672 [(set_attr "type" "icmp")
673 (set_attr "mode" "DI")])
675 (define_expand "cmpdi_1_rex64"
676 [(set (reg:CC FLAGS_REG)
677 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
678 (match_operand:DI 1 "general_operand" "")))]
682 (define_insn "cmpdi_1_insn_rex64"
683 [(set (reg FLAGS_REG)
684 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
685 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
686 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
687 "cmp{q}\t{%1, %0|%0, %1}"
688 [(set_attr "type" "icmp")
689 (set_attr "mode" "DI")])
692 (define_insn "*cmpsi_ccno_1"
693 [(set (reg FLAGS_REG)
694 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
695 (match_operand:SI 1 "const0_operand" "n,n")))]
696 "ix86_match_ccmode (insn, CCNOmode)"
699 cmp{l}\t{%1, %0|%0, %1}"
700 [(set_attr "type" "test,icmp")
701 (set_attr "length_immediate" "0,1")
702 (set_attr "mode" "SI")])
704 (define_insn "*cmpsi_minus_1"
705 [(set (reg FLAGS_REG)
706 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
707 (match_operand:SI 1 "general_operand" "ri,mr"))
709 "ix86_match_ccmode (insn, CCGOCmode)"
710 "cmp{l}\t{%1, %0|%0, %1}"
711 [(set_attr "type" "icmp")
712 (set_attr "mode" "SI")])
714 (define_expand "cmpsi_1"
715 [(set (reg:CC FLAGS_REG)
716 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
717 (match_operand:SI 1 "general_operand" "")))]
721 (define_insn "*cmpsi_1_insn"
722 [(set (reg FLAGS_REG)
723 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
724 (match_operand:SI 1 "general_operand" "ri,mr")))]
725 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
726 && ix86_match_ccmode (insn, CCmode)"
727 "cmp{l}\t{%1, %0|%0, %1}"
728 [(set_attr "type" "icmp")
729 (set_attr "mode" "SI")])
731 (define_insn "*cmphi_ccno_1"
732 [(set (reg FLAGS_REG)
733 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
734 (match_operand:HI 1 "const0_operand" "n,n")))]
735 "ix86_match_ccmode (insn, CCNOmode)"
738 cmp{w}\t{%1, %0|%0, %1}"
739 [(set_attr "type" "test,icmp")
740 (set_attr "length_immediate" "0,1")
741 (set_attr "mode" "HI")])
743 (define_insn "*cmphi_minus_1"
744 [(set (reg FLAGS_REG)
745 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
746 (match_operand:HI 1 "general_operand" "ri,mr"))
748 "ix86_match_ccmode (insn, CCGOCmode)"
749 "cmp{w}\t{%1, %0|%0, %1}"
750 [(set_attr "type" "icmp")
751 (set_attr "mode" "HI")])
753 (define_insn "*cmphi_1"
754 [(set (reg FLAGS_REG)
755 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
756 (match_operand:HI 1 "general_operand" "ri,mr")))]
757 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
758 && ix86_match_ccmode (insn, CCmode)"
759 "cmp{w}\t{%1, %0|%0, %1}"
760 [(set_attr "type" "icmp")
761 (set_attr "mode" "HI")])
763 (define_insn "*cmpqi_ccno_1"
764 [(set (reg FLAGS_REG)
765 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
766 (match_operand:QI 1 "const0_operand" "n,n")))]
767 "ix86_match_ccmode (insn, CCNOmode)"
770 cmp{b}\t{$0, %0|%0, 0}"
771 [(set_attr "type" "test,icmp")
772 (set_attr "length_immediate" "0,1")
773 (set_attr "mode" "QI")])
775 (define_insn "*cmpqi_1"
776 [(set (reg FLAGS_REG)
777 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
778 (match_operand:QI 1 "general_operand" "qi,mq")))]
779 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
780 && ix86_match_ccmode (insn, CCmode)"
781 "cmp{b}\t{%1, %0|%0, %1}"
782 [(set_attr "type" "icmp")
783 (set_attr "mode" "QI")])
785 (define_insn "*cmpqi_minus_1"
786 [(set (reg FLAGS_REG)
787 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
788 (match_operand:QI 1 "general_operand" "qi,mq"))
790 "ix86_match_ccmode (insn, CCGOCmode)"
791 "cmp{b}\t{%1, %0|%0, %1}"
792 [(set_attr "type" "icmp")
793 (set_attr "mode" "QI")])
795 (define_insn "*cmpqi_ext_1"
796 [(set (reg FLAGS_REG)
798 (match_operand:QI 0 "general_operand" "Qm")
801 (match_operand 1 "ext_register_operand" "Q")
804 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
805 "cmp{b}\t{%h1, %0|%0, %h1}"
806 [(set_attr "type" "icmp")
807 (set_attr "mode" "QI")])
809 (define_insn "*cmpqi_ext_1_rex64"
810 [(set (reg FLAGS_REG)
812 (match_operand:QI 0 "register_operand" "Q")
815 (match_operand 1 "ext_register_operand" "Q")
818 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
819 "cmp{b}\t{%h1, %0|%0, %h1}"
820 [(set_attr "type" "icmp")
821 (set_attr "mode" "QI")])
823 (define_insn "*cmpqi_ext_2"
824 [(set (reg FLAGS_REG)
828 (match_operand 0 "ext_register_operand" "Q")
831 (match_operand:QI 1 "const0_operand" "n")))]
832 "ix86_match_ccmode (insn, CCNOmode)"
834 [(set_attr "type" "test")
835 (set_attr "length_immediate" "0")
836 (set_attr "mode" "QI")])
838 (define_expand "cmpqi_ext_3"
839 [(set (reg:CC FLAGS_REG)
843 (match_operand 0 "ext_register_operand" "")
846 (match_operand:QI 1 "general_operand" "")))]
850 (define_insn "cmpqi_ext_3_insn"
851 [(set (reg FLAGS_REG)
855 (match_operand 0 "ext_register_operand" "Q")
858 (match_operand:QI 1 "general_operand" "Qmn")))]
859 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
860 "cmp{b}\t{%1, %h0|%h0, %1}"
861 [(set_attr "type" "icmp")
862 (set_attr "mode" "QI")])
864 (define_insn "cmpqi_ext_3_insn_rex64"
865 [(set (reg FLAGS_REG)
869 (match_operand 0 "ext_register_operand" "Q")
872 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
873 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
874 "cmp{b}\t{%1, %h0|%h0, %1}"
875 [(set_attr "type" "icmp")
876 (set_attr "mode" "QI")])
878 (define_insn "*cmpqi_ext_4"
879 [(set (reg FLAGS_REG)
883 (match_operand 0 "ext_register_operand" "Q")
888 (match_operand 1 "ext_register_operand" "Q")
891 "ix86_match_ccmode (insn, CCmode)"
892 "cmp{b}\t{%h1, %h0|%h0, %h1}"
893 [(set_attr "type" "icmp")
894 (set_attr "mode" "QI")])
896 ;; These implement float point compares.
897 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
898 ;; which would allow mix and match FP modes on the compares. Which is what
899 ;; the old patterns did, but with many more of them.
901 (define_expand "cmpxf"
902 [(set (reg:CC FLAGS_REG)
903 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
904 (match_operand:XF 1 "nonmemory_operand" "")))]
907 ix86_compare_op0 = operands[0];
908 ix86_compare_op1 = operands[1];
912 (define_expand "cmp<mode>"
913 [(set (reg:CC FLAGS_REG)
914 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
915 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
916 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
918 ix86_compare_op0 = operands[0];
919 ix86_compare_op1 = operands[1];
923 ;; FP compares, step 1:
924 ;; Set the FP condition codes.
926 ;; CCFPmode compare with exceptions
927 ;; CCFPUmode compare with no exceptions
929 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
930 ;; used to manage the reg stack popping would not be preserved.
932 (define_insn "*cmpfp_0"
933 [(set (match_operand:HI 0 "register_operand" "=a")
936 (match_operand 1 "register_operand" "f")
937 (match_operand 2 "const0_operand" "X"))]
939 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
940 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
941 "* return output_fp_compare (insn, operands, 0, 0);"
942 [(set_attr "type" "multi")
943 (set_attr "unit" "i387")
945 (cond [(match_operand:SF 1 "" "")
947 (match_operand:DF 1 "" "")
950 (const_string "XF")))])
952 (define_insn_and_split "*cmpfp_0_cc"
953 [(set (reg:CCFP FLAGS_REG)
955 (match_operand 1 "register_operand" "f")
956 (match_operand 2 "const0_operand" "X")))
957 (clobber (match_operand:HI 0 "register_operand" "=a"))]
958 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
959 && TARGET_SAHF && !TARGET_CMOVE
960 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
962 "&& reload_completed"
965 [(compare:CCFP (match_dup 1)(match_dup 2))]
967 (set (reg:CC FLAGS_REG)
968 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
970 [(set_attr "type" "multi")
971 (set_attr "unit" "i387")
973 (cond [(match_operand:SF 1 "" "")
975 (match_operand:DF 1 "" "")
978 (const_string "XF")))])
980 (define_insn "*cmpfp_xf"
981 [(set (match_operand:HI 0 "register_operand" "=a")
984 (match_operand:XF 1 "register_operand" "f")
985 (match_operand:XF 2 "register_operand" "f"))]
988 "* return output_fp_compare (insn, operands, 0, 0);"
989 [(set_attr "type" "multi")
990 (set_attr "unit" "i387")
991 (set_attr "mode" "XF")])
993 (define_insn_and_split "*cmpfp_xf_cc"
994 [(set (reg:CCFP FLAGS_REG)
996 (match_operand:XF 1 "register_operand" "f")
997 (match_operand:XF 2 "register_operand" "f")))
998 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1000 && TARGET_SAHF && !TARGET_CMOVE"
1002 "&& reload_completed"
1005 [(compare:CCFP (match_dup 1)(match_dup 2))]
1007 (set (reg:CC FLAGS_REG)
1008 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1010 [(set_attr "type" "multi")
1011 (set_attr "unit" "i387")
1012 (set_attr "mode" "XF")])
1014 (define_insn "*cmpfp_<mode>"
1015 [(set (match_operand:HI 0 "register_operand" "=a")
1018 (match_operand:MODEF 1 "register_operand" "f")
1019 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1022 "* return output_fp_compare (insn, operands, 0, 0);"
1023 [(set_attr "type" "multi")
1024 (set_attr "unit" "i387")
1025 (set_attr "mode" "<MODE>")])
1027 (define_insn_and_split "*cmpfp_<mode>_cc"
1028 [(set (reg:CCFP FLAGS_REG)
1030 (match_operand:MODEF 1 "register_operand" "f")
1031 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1032 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1034 && TARGET_SAHF && !TARGET_CMOVE"
1036 "&& reload_completed"
1039 [(compare:CCFP (match_dup 1)(match_dup 2))]
1041 (set (reg:CC FLAGS_REG)
1042 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1044 [(set_attr "type" "multi")
1045 (set_attr "unit" "i387")
1046 (set_attr "mode" "<MODE>")])
1048 (define_insn "*cmpfp_u"
1049 [(set (match_operand:HI 0 "register_operand" "=a")
1052 (match_operand 1 "register_operand" "f")
1053 (match_operand 2 "register_operand" "f"))]
1055 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1056 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1057 "* return output_fp_compare (insn, operands, 0, 1);"
1058 [(set_attr "type" "multi")
1059 (set_attr "unit" "i387")
1061 (cond [(match_operand:SF 1 "" "")
1063 (match_operand:DF 1 "" "")
1066 (const_string "XF")))])
1068 (define_insn_and_split "*cmpfp_u_cc"
1069 [(set (reg:CCFPU FLAGS_REG)
1071 (match_operand 1 "register_operand" "f")
1072 (match_operand 2 "register_operand" "f")))
1073 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1074 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1075 && TARGET_SAHF && !TARGET_CMOVE
1076 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078 "&& reload_completed"
1081 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1083 (set (reg:CC FLAGS_REG)
1084 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1086 [(set_attr "type" "multi")
1087 (set_attr "unit" "i387")
1089 (cond [(match_operand:SF 1 "" "")
1091 (match_operand:DF 1 "" "")
1094 (const_string "XF")))])
1096 (define_insn "*cmpfp_<mode>"
1097 [(set (match_operand:HI 0 "register_operand" "=a")
1100 (match_operand 1 "register_operand" "f")
1101 (match_operator 3 "float_operator"
1102 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1104 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1105 && TARGET_USE_<MODE>MODE_FIOP
1106 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1107 "* return output_fp_compare (insn, operands, 0, 0);"
1108 [(set_attr "type" "multi")
1109 (set_attr "unit" "i387")
1110 (set_attr "fp_int_src" "true")
1111 (set_attr "mode" "<MODE>")])
1113 (define_insn_and_split "*cmpfp_<mode>_cc"
1114 [(set (reg:CCFP FLAGS_REG)
1116 (match_operand 1 "register_operand" "f")
1117 (match_operator 3 "float_operator"
1118 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1119 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1120 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1121 && TARGET_SAHF && !TARGET_CMOVE
1122 && TARGET_USE_<MODE>MODE_FIOP
1123 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1125 "&& reload_completed"
1130 (match_op_dup 3 [(match_dup 2)]))]
1132 (set (reg:CC FLAGS_REG)
1133 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1135 [(set_attr "type" "multi")
1136 (set_attr "unit" "i387")
1137 (set_attr "fp_int_src" "true")
1138 (set_attr "mode" "<MODE>")])
1140 ;; FP compares, step 2
1141 ;; Move the fpsw to ax.
1143 (define_insn "x86_fnstsw_1"
1144 [(set (match_operand:HI 0 "register_operand" "=a")
1145 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1148 [(set_attr "length" "2")
1149 (set_attr "mode" "SI")
1150 (set_attr "unit" "i387")])
1152 ;; FP compares, step 3
1153 ;; Get ax into flags, general case.
1155 (define_insn "x86_sahf_1"
1156 [(set (reg:CC FLAGS_REG)
1157 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1161 #ifdef HAVE_AS_IX86_SAHF
1164 return ".byte\t0x9e";
1167 [(set_attr "length" "1")
1168 (set_attr "athlon_decode" "vector")
1169 (set_attr "amdfam10_decode" "direct")
1170 (set_attr "mode" "SI")])
1172 ;; Pentium Pro can do steps 1 through 3 in one go.
1173 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1174 (define_insn "*cmpfp_i_mixed"
1175 [(set (reg:CCFP FLAGS_REG)
1176 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1177 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1178 "TARGET_MIX_SSE_I387
1179 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1180 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1181 "* return output_fp_compare (insn, operands, 1, 0);"
1182 [(set_attr "type" "fcmp,ssecomi")
1184 (if_then_else (match_operand:SF 1 "" "")
1186 (const_string "DF")))
1187 (set_attr "athlon_decode" "vector")
1188 (set_attr "amdfam10_decode" "direct")])
1190 (define_insn "*cmpfp_i_sse"
1191 [(set (reg:CCFP FLAGS_REG)
1192 (compare:CCFP (match_operand 0 "register_operand" "x")
1193 (match_operand 1 "nonimmediate_operand" "xm")))]
1195 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1196 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1197 "* return output_fp_compare (insn, operands, 1, 0);"
1198 [(set_attr "type" "ssecomi")
1200 (if_then_else (match_operand:SF 1 "" "")
1202 (const_string "DF")))
1203 (set_attr "athlon_decode" "vector")
1204 (set_attr "amdfam10_decode" "direct")])
1206 (define_insn "*cmpfp_i_i387"
1207 [(set (reg:CCFP FLAGS_REG)
1208 (compare:CCFP (match_operand 0 "register_operand" "f")
1209 (match_operand 1 "register_operand" "f")))]
1210 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1212 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1213 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1214 "* return output_fp_compare (insn, operands, 1, 0);"
1215 [(set_attr "type" "fcmp")
1217 (cond [(match_operand:SF 1 "" "")
1219 (match_operand:DF 1 "" "")
1222 (const_string "XF")))
1223 (set_attr "athlon_decode" "vector")
1224 (set_attr "amdfam10_decode" "direct")])
1226 (define_insn "*cmpfp_iu_mixed"
1227 [(set (reg:CCFPU FLAGS_REG)
1228 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1229 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1230 "TARGET_MIX_SSE_I387
1231 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1232 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1233 "* return output_fp_compare (insn, operands, 1, 1);"
1234 [(set_attr "type" "fcmp,ssecomi")
1236 (if_then_else (match_operand:SF 1 "" "")
1238 (const_string "DF")))
1239 (set_attr "athlon_decode" "vector")
1240 (set_attr "amdfam10_decode" "direct")])
1242 (define_insn "*cmpfp_iu_sse"
1243 [(set (reg:CCFPU FLAGS_REG)
1244 (compare:CCFPU (match_operand 0 "register_operand" "x")
1245 (match_operand 1 "nonimmediate_operand" "xm")))]
1247 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1248 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1249 "* return output_fp_compare (insn, operands, 1, 1);"
1250 [(set_attr "type" "ssecomi")
1252 (if_then_else (match_operand:SF 1 "" "")
1254 (const_string "DF")))
1255 (set_attr "athlon_decode" "vector")
1256 (set_attr "amdfam10_decode" "direct")])
1258 (define_insn "*cmpfp_iu_387"
1259 [(set (reg:CCFPU FLAGS_REG)
1260 (compare:CCFPU (match_operand 0 "register_operand" "f")
1261 (match_operand 1 "register_operand" "f")))]
1262 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1264 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1265 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1266 "* return output_fp_compare (insn, operands, 1, 1);"
1267 [(set_attr "type" "fcmp")
1269 (cond [(match_operand:SF 1 "" "")
1271 (match_operand:DF 1 "" "")
1274 (const_string "XF")))
1275 (set_attr "athlon_decode" "vector")
1276 (set_attr "amdfam10_decode" "direct")])
1278 ;; Move instructions.
1280 ;; General case of fullword move.
1282 (define_expand "movsi"
1283 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1284 (match_operand:SI 1 "general_operand" ""))]
1286 "ix86_expand_move (SImode, operands); DONE;")
1288 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1291 ;; %%% We don't use a post-inc memory reference because x86 is not a
1292 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1293 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1294 ;; targets without our curiosities, and it is just as easy to represent
1295 ;; this differently.
1297 (define_insn "*pushsi2"
1298 [(set (match_operand:SI 0 "push_operand" "=<")
1299 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1302 [(set_attr "type" "push")
1303 (set_attr "mode" "SI")])
1305 ;; For 64BIT abi we always round up to 8 bytes.
1306 (define_insn "*pushsi2_rex64"
1307 [(set (match_operand:SI 0 "push_operand" "=X")
1308 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1311 [(set_attr "type" "push")
1312 (set_attr "mode" "SI")])
1314 (define_insn "*pushsi2_prologue"
1315 [(set (match_operand:SI 0 "push_operand" "=<")
1316 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1317 (clobber (mem:BLK (scratch)))]
1320 [(set_attr "type" "push")
1321 (set_attr "mode" "SI")])
1323 (define_insn "*popsi1_epilogue"
1324 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1325 (mem:SI (reg:SI SP_REG)))
1326 (set (reg:SI SP_REG)
1327 (plus:SI (reg:SI SP_REG) (const_int 4)))
1328 (clobber (mem:BLK (scratch)))]
1331 [(set_attr "type" "pop")
1332 (set_attr "mode" "SI")])
1334 (define_insn "popsi1"
1335 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1336 (mem:SI (reg:SI SP_REG)))
1337 (set (reg:SI SP_REG)
1338 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1341 [(set_attr "type" "pop")
1342 (set_attr "mode" "SI")])
1344 (define_insn "*movsi_xor"
1345 [(set (match_operand:SI 0 "register_operand" "=r")
1346 (match_operand:SI 1 "const0_operand" "i"))
1347 (clobber (reg:CC FLAGS_REG))]
1348 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1350 [(set_attr "type" "alu1")
1351 (set_attr "mode" "SI")
1352 (set_attr "length_immediate" "0")])
1354 (define_insn "*movsi_or"
1355 [(set (match_operand:SI 0 "register_operand" "=r")
1356 (match_operand:SI 1 "immediate_operand" "i"))
1357 (clobber (reg:CC FLAGS_REG))]
1359 && operands[1] == constm1_rtx
1360 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1362 operands[1] = constm1_rtx;
1363 return "or{l}\t{%1, %0|%0, %1}";
1365 [(set_attr "type" "alu1")
1366 (set_attr "mode" "SI")
1367 (set_attr "length_immediate" "1")])
1369 (define_insn "*movsi_1"
1370 [(set (match_operand:SI 0 "nonimmediate_operand"
1371 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1372 (match_operand:SI 1 "general_operand"
1373 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1374 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1376 switch (get_attr_type (insn))
1379 if (get_attr_mode (insn) == MODE_TI)
1380 return "pxor\t%0, %0";
1381 return "xorps\t%0, %0";
1384 switch (get_attr_mode (insn))
1387 return "movdqa\t{%1, %0|%0, %1}";
1389 return "movaps\t{%1, %0|%0, %1}";
1391 return "movd\t{%1, %0|%0, %1}";
1393 return "movss\t{%1, %0|%0, %1}";
1399 return "pxor\t%0, %0";
1402 if (get_attr_mode (insn) == MODE_DI)
1403 return "movq\t{%1, %0|%0, %1}";
1404 return "movd\t{%1, %0|%0, %1}";
1407 return "lea{l}\t{%1, %0|%0, %1}";
1410 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1411 return "mov{l}\t{%1, %0|%0, %1}";
1415 (cond [(eq_attr "alternative" "2")
1416 (const_string "mmxadd")
1417 (eq_attr "alternative" "3,4,5")
1418 (const_string "mmxmov")
1419 (eq_attr "alternative" "6")
1420 (const_string "sselog1")
1421 (eq_attr "alternative" "7,8,9,10,11")
1422 (const_string "ssemov")
1423 (match_operand:DI 1 "pic_32bit_operand" "")
1424 (const_string "lea")
1426 (const_string "imov")))
1428 (cond [(eq_attr "alternative" "2,3")
1430 (eq_attr "alternative" "6,7")
1432 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1433 (const_string "V4SF")
1434 (const_string "TI"))
1435 (and (eq_attr "alternative" "8,9,10,11")
1436 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1439 (const_string "SI")))])
1441 ;; Stores and loads of ax to arbitrary constant address.
1442 ;; We fake an second form of instruction to force reload to load address
1443 ;; into register when rax is not available
1444 (define_insn "*movabssi_1_rex64"
1445 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1446 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1447 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1449 movabs{l}\t{%1, %P0|%P0, %1}
1450 mov{l}\t{%1, %a0|%a0, %1}"
1451 [(set_attr "type" "imov")
1452 (set_attr "modrm" "0,*")
1453 (set_attr "length_address" "8,0")
1454 (set_attr "length_immediate" "0,*")
1455 (set_attr "memory" "store")
1456 (set_attr "mode" "SI")])
1458 (define_insn "*movabssi_2_rex64"
1459 [(set (match_operand:SI 0 "register_operand" "=a,r")
1460 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1461 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1463 movabs{l}\t{%P1, %0|%0, %P1}
1464 mov{l}\t{%a1, %0|%0, %a1}"
1465 [(set_attr "type" "imov")
1466 (set_attr "modrm" "0,*")
1467 (set_attr "length_address" "8,0")
1468 (set_attr "length_immediate" "0")
1469 (set_attr "memory" "load")
1470 (set_attr "mode" "SI")])
1472 (define_insn "*swapsi"
1473 [(set (match_operand:SI 0 "register_operand" "+r")
1474 (match_operand:SI 1 "register_operand" "+r"))
1479 [(set_attr "type" "imov")
1480 (set_attr "mode" "SI")
1481 (set_attr "pent_pair" "np")
1482 (set_attr "athlon_decode" "vector")
1483 (set_attr "amdfam10_decode" "double")])
1485 (define_expand "movhi"
1486 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1487 (match_operand:HI 1 "general_operand" ""))]
1489 "ix86_expand_move (HImode, operands); DONE;")
1491 (define_insn "*pushhi2"
1492 [(set (match_operand:HI 0 "push_operand" "=X")
1493 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1496 [(set_attr "type" "push")
1497 (set_attr "mode" "SI")])
1499 ;; For 64BIT abi we always round up to 8 bytes.
1500 (define_insn "*pushhi2_rex64"
1501 [(set (match_operand:HI 0 "push_operand" "=X")
1502 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1505 [(set_attr "type" "push")
1506 (set_attr "mode" "DI")])
1508 (define_insn "*movhi_1"
1509 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1510 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1513 switch (get_attr_type (insn))
1516 /* movzwl is faster than movw on p2 due to partial word stalls,
1517 though not as fast as an aligned movl. */
1518 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1520 if (get_attr_mode (insn) == MODE_SI)
1521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1523 return "mov{w}\t{%1, %0|%0, %1}";
1527 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1528 (const_string "imov")
1529 (and (eq_attr "alternative" "0")
1530 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532 (eq (symbol_ref "TARGET_HIMODE_MATH")
1534 (const_string "imov")
1535 (and (eq_attr "alternative" "1,2")
1536 (match_operand:HI 1 "aligned_operand" ""))
1537 (const_string "imov")
1538 (and (ne (symbol_ref "TARGET_MOVX")
1540 (eq_attr "alternative" "0,2"))
1541 (const_string "imovx")
1543 (const_string "imov")))
1545 (cond [(eq_attr "type" "imovx")
1547 (and (eq_attr "alternative" "1,2")
1548 (match_operand:HI 1 "aligned_operand" ""))
1550 (and (eq_attr "alternative" "0")
1551 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553 (eq (symbol_ref "TARGET_HIMODE_MATH")
1557 (const_string "HI")))])
1559 ;; Stores and loads of ax to arbitrary constant address.
1560 ;; We fake an second form of instruction to force reload to load address
1561 ;; into register when rax is not available
1562 (define_insn "*movabshi_1_rex64"
1563 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1564 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1565 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1567 movabs{w}\t{%1, %P0|%P0, %1}
1568 mov{w}\t{%1, %a0|%a0, %1}"
1569 [(set_attr "type" "imov")
1570 (set_attr "modrm" "0,*")
1571 (set_attr "length_address" "8,0")
1572 (set_attr "length_immediate" "0,*")
1573 (set_attr "memory" "store")
1574 (set_attr "mode" "HI")])
1576 (define_insn "*movabshi_2_rex64"
1577 [(set (match_operand:HI 0 "register_operand" "=a,r")
1578 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1579 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1581 movabs{w}\t{%P1, %0|%0, %P1}
1582 mov{w}\t{%a1, %0|%0, %a1}"
1583 [(set_attr "type" "imov")
1584 (set_attr "modrm" "0,*")
1585 (set_attr "length_address" "8,0")
1586 (set_attr "length_immediate" "0")
1587 (set_attr "memory" "load")
1588 (set_attr "mode" "HI")])
1590 (define_insn "*swaphi_1"
1591 [(set (match_operand:HI 0 "register_operand" "+r")
1592 (match_operand:HI 1 "register_operand" "+r"))
1595 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1597 [(set_attr "type" "imov")
1598 (set_attr "mode" "SI")
1599 (set_attr "pent_pair" "np")
1600 (set_attr "athlon_decode" "vector")
1601 (set_attr "amdfam10_decode" "double")])
1603 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1604 (define_insn "*swaphi_2"
1605 [(set (match_operand:HI 0 "register_operand" "+r")
1606 (match_operand:HI 1 "register_operand" "+r"))
1609 "TARGET_PARTIAL_REG_STALL"
1611 [(set_attr "type" "imov")
1612 (set_attr "mode" "HI")
1613 (set_attr "pent_pair" "np")
1614 (set_attr "athlon_decode" "vector")])
1616 (define_expand "movstricthi"
1617 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1618 (match_operand:HI 1 "general_operand" ""))]
1619 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1621 /* Don't generate memory->memory moves, go through a register */
1622 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1623 operands[1] = force_reg (HImode, operands[1]);
1626 (define_insn "*movstricthi_1"
1627 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1628 (match_operand:HI 1 "general_operand" "rn,m"))]
1629 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1630 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1631 "mov{w}\t{%1, %0|%0, %1}"
1632 [(set_attr "type" "imov")
1633 (set_attr "mode" "HI")])
1635 (define_insn "*movstricthi_xor"
1636 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1637 (match_operand:HI 1 "const0_operand" "i"))
1638 (clobber (reg:CC FLAGS_REG))]
1640 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1642 [(set_attr "type" "alu1")
1643 (set_attr "mode" "HI")
1644 (set_attr "length_immediate" "0")])
1646 (define_expand "movqi"
1647 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1648 (match_operand:QI 1 "general_operand" ""))]
1650 "ix86_expand_move (QImode, operands); DONE;")
1652 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1653 ;; "push a byte". But actually we use pushl, which has the effect
1654 ;; of rounding the amount pushed up to a word.
1656 (define_insn "*pushqi2"
1657 [(set (match_operand:QI 0 "push_operand" "=X")
1658 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1661 [(set_attr "type" "push")
1662 (set_attr "mode" "SI")])
1664 ;; For 64BIT abi we always round up to 8 bytes.
1665 (define_insn "*pushqi2_rex64"
1666 [(set (match_operand:QI 0 "push_operand" "=X")
1667 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1670 [(set_attr "type" "push")
1671 (set_attr "mode" "DI")])
1673 ;; Situation is quite tricky about when to choose full sized (SImode) move
1674 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1675 ;; partial register dependency machines (such as AMD Athlon), where QImode
1676 ;; moves issue extra dependency and for partial register stalls machines
1677 ;; that don't use QImode patterns (and QImode move cause stall on the next
1680 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1681 ;; register stall machines with, where we use QImode instructions, since
1682 ;; partial register stall can be caused there. Then we use movzx.
1683 (define_insn "*movqi_1"
1684 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1685 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1686 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1688 switch (get_attr_type (insn))
1691 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1692 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1694 if (get_attr_mode (insn) == MODE_SI)
1695 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1697 return "mov{b}\t{%1, %0|%0, %1}";
1701 (cond [(and (eq_attr "alternative" "5")
1702 (not (match_operand:QI 1 "aligned_operand" "")))
1703 (const_string "imovx")
1704 (ne (symbol_ref "optimize_size") (const_int 0))
1705 (const_string "imov")
1706 (and (eq_attr "alternative" "3")
1707 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1709 (eq (symbol_ref "TARGET_QIMODE_MATH")
1711 (const_string "imov")
1712 (eq_attr "alternative" "3,5")
1713 (const_string "imovx")
1714 (and (ne (symbol_ref "TARGET_MOVX")
1716 (eq_attr "alternative" "2"))
1717 (const_string "imovx")
1719 (const_string "imov")))
1721 (cond [(eq_attr "alternative" "3,4,5")
1723 (eq_attr "alternative" "6")
1725 (eq_attr "type" "imovx")
1727 (and (eq_attr "type" "imov")
1728 (and (eq_attr "alternative" "0,1")
1729 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1731 (and (eq (symbol_ref "optimize_size")
1733 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1736 ;; Avoid partial register stalls when not using QImode arithmetic
1737 (and (eq_attr "type" "imov")
1738 (and (eq_attr "alternative" "0,1")
1739 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1741 (eq (symbol_ref "TARGET_QIMODE_MATH")
1745 (const_string "QI")))])
1747 (define_expand "reload_outqi"
1748 [(parallel [(match_operand:QI 0 "" "=m")
1749 (match_operand:QI 1 "register_operand" "r")
1750 (match_operand:QI 2 "register_operand" "=&q")])]
1754 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1756 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1757 if (! q_regs_operand (op1, QImode))
1759 emit_insn (gen_movqi (op2, op1));
1762 emit_insn (gen_movqi (op0, op1));
1766 (define_insn "*swapqi_1"
1767 [(set (match_operand:QI 0 "register_operand" "+r")
1768 (match_operand:QI 1 "register_operand" "+r"))
1771 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1773 [(set_attr "type" "imov")
1774 (set_attr "mode" "SI")
1775 (set_attr "pent_pair" "np")
1776 (set_attr "athlon_decode" "vector")
1777 (set_attr "amdfam10_decode" "vector")])
1779 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1780 (define_insn "*swapqi_2"
1781 [(set (match_operand:QI 0 "register_operand" "+q")
1782 (match_operand:QI 1 "register_operand" "+q"))
1785 "TARGET_PARTIAL_REG_STALL"
1787 [(set_attr "type" "imov")
1788 (set_attr "mode" "QI")
1789 (set_attr "pent_pair" "np")
1790 (set_attr "athlon_decode" "vector")])
1792 (define_expand "movstrictqi"
1793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1794 (match_operand:QI 1 "general_operand" ""))]
1795 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1797 /* Don't generate memory->memory moves, go through a register. */
1798 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1799 operands[1] = force_reg (QImode, operands[1]);
1802 (define_insn "*movstrictqi_1"
1803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1804 (match_operand:QI 1 "general_operand" "*qn,m"))]
1805 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1806 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1807 "mov{b}\t{%1, %0|%0, %1}"
1808 [(set_attr "type" "imov")
1809 (set_attr "mode" "QI")])
1811 (define_insn "*movstrictqi_xor"
1812 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1813 (match_operand:QI 1 "const0_operand" "i"))
1814 (clobber (reg:CC FLAGS_REG))]
1815 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1817 [(set_attr "type" "alu1")
1818 (set_attr "mode" "QI")
1819 (set_attr "length_immediate" "0")])
1821 (define_insn "*movsi_extv_1"
1822 [(set (match_operand:SI 0 "register_operand" "=R")
1823 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1827 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1828 [(set_attr "type" "imovx")
1829 (set_attr "mode" "SI")])
1831 (define_insn "*movhi_extv_1"
1832 [(set (match_operand:HI 0 "register_operand" "=R")
1833 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1837 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1838 [(set_attr "type" "imovx")
1839 (set_attr "mode" "SI")])
1841 (define_insn "*movqi_extv_1"
1842 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1843 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1848 switch (get_attr_type (insn))
1851 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1853 return "mov{b}\t{%h1, %0|%0, %h1}";
1857 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1858 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1859 (ne (symbol_ref "TARGET_MOVX")
1861 (const_string "imovx")
1862 (const_string "imov")))
1864 (if_then_else (eq_attr "type" "imovx")
1866 (const_string "QI")))])
1868 (define_insn "*movqi_extv_1_rex64"
1869 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1870 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1875 switch (get_attr_type (insn))
1878 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1880 return "mov{b}\t{%h1, %0|%0, %h1}";
1884 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1885 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1886 (ne (symbol_ref "TARGET_MOVX")
1888 (const_string "imovx")
1889 (const_string "imov")))
1891 (if_then_else (eq_attr "type" "imovx")
1893 (const_string "QI")))])
1895 ;; Stores and loads of ax to arbitrary constant address.
1896 ;; We fake an second form of instruction to force reload to load address
1897 ;; into register when rax is not available
1898 (define_insn "*movabsqi_1_rex64"
1899 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1900 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1901 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1903 movabs{b}\t{%1, %P0|%P0, %1}
1904 mov{b}\t{%1, %a0|%a0, %1}"
1905 [(set_attr "type" "imov")
1906 (set_attr "modrm" "0,*")
1907 (set_attr "length_address" "8,0")
1908 (set_attr "length_immediate" "0,*")
1909 (set_attr "memory" "store")
1910 (set_attr "mode" "QI")])
1912 (define_insn "*movabsqi_2_rex64"
1913 [(set (match_operand:QI 0 "register_operand" "=a,r")
1914 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1915 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1917 movabs{b}\t{%P1, %0|%0, %P1}
1918 mov{b}\t{%a1, %0|%0, %a1}"
1919 [(set_attr "type" "imov")
1920 (set_attr "modrm" "0,*")
1921 (set_attr "length_address" "8,0")
1922 (set_attr "length_immediate" "0")
1923 (set_attr "memory" "load")
1924 (set_attr "mode" "QI")])
1926 (define_insn "*movdi_extzv_1"
1927 [(set (match_operand:DI 0 "register_operand" "=R")
1928 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1932 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1933 [(set_attr "type" "imovx")
1934 (set_attr "mode" "DI")])
1936 (define_insn "*movsi_extzv_1"
1937 [(set (match_operand:SI 0 "register_operand" "=R")
1938 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1942 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1943 [(set_attr "type" "imovx")
1944 (set_attr "mode" "SI")])
1946 (define_insn "*movqi_extzv_2"
1947 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1948 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1953 switch (get_attr_type (insn))
1956 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1958 return "mov{b}\t{%h1, %0|%0, %h1}";
1962 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1963 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1964 (ne (symbol_ref "TARGET_MOVX")
1966 (const_string "imovx")
1967 (const_string "imov")))
1969 (if_then_else (eq_attr "type" "imovx")
1971 (const_string "QI")))])
1973 (define_insn "*movqi_extzv_2_rex64"
1974 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1975 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1980 switch (get_attr_type (insn))
1983 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1985 return "mov{b}\t{%h1, %0|%0, %h1}";
1989 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1990 (ne (symbol_ref "TARGET_MOVX")
1992 (const_string "imovx")
1993 (const_string "imov")))
1995 (if_then_else (eq_attr "type" "imovx")
1997 (const_string "QI")))])
1999 (define_insn "movsi_insv_1"
2000 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2003 (match_operand:SI 1 "general_operand" "Qmn"))]
2005 "mov{b}\t{%b1, %h0|%h0, %b1}"
2006 [(set_attr "type" "imov")
2007 (set_attr "mode" "QI")])
2009 (define_insn "*movsi_insv_1_rex64"
2010 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2013 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2015 "mov{b}\t{%b1, %h0|%h0, %b1}"
2016 [(set_attr "type" "imov")
2017 (set_attr "mode" "QI")])
2019 (define_insn "movdi_insv_1_rex64"
2020 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2023 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2025 "mov{b}\t{%b1, %h0|%h0, %b1}"
2026 [(set_attr "type" "imov")
2027 (set_attr "mode" "QI")])
2029 (define_insn "*movqi_insv_2"
2030 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2033 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2036 "mov{b}\t{%h1, %h0|%h0, %h1}"
2037 [(set_attr "type" "imov")
2038 (set_attr "mode" "QI")])
2040 (define_expand "movdi"
2041 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2042 (match_operand:DI 1 "general_operand" ""))]
2044 "ix86_expand_move (DImode, operands); DONE;")
2046 (define_insn "*pushdi"
2047 [(set (match_operand:DI 0 "push_operand" "=<")
2048 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2052 (define_insn "*pushdi2_rex64"
2053 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2054 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2059 [(set_attr "type" "push,multi")
2060 (set_attr "mode" "DI")])
2062 ;; Convert impossible pushes of immediate to existing instructions.
2063 ;; First try to get scratch register and go through it. In case this
2064 ;; fails, push sign extended lower part first and then overwrite
2065 ;; upper part by 32bit move.
2067 [(match_scratch:DI 2 "r")
2068 (set (match_operand:DI 0 "push_operand" "")
2069 (match_operand:DI 1 "immediate_operand" ""))]
2070 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071 && !x86_64_immediate_operand (operands[1], DImode)"
2072 [(set (match_dup 2) (match_dup 1))
2073 (set (match_dup 0) (match_dup 2))]
2076 ;; We need to define this as both peepholer and splitter for case
2077 ;; peephole2 pass is not run.
2078 ;; "&& 1" is needed to keep it from matching the previous pattern.
2080 [(set (match_operand:DI 0 "push_operand" "")
2081 (match_operand:DI 1 "immediate_operand" ""))]
2082 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2083 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2084 [(set (match_dup 0) (match_dup 1))
2085 (set (match_dup 2) (match_dup 3))]
2086 "split_di (operands + 1, 1, operands + 2, operands + 3);
2087 operands[1] = gen_lowpart (DImode, operands[2]);
2088 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2093 [(set (match_operand:DI 0 "push_operand" "")
2094 (match_operand:DI 1 "immediate_operand" ""))]
2095 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2096 ? epilogue_completed : reload_completed)
2097 && !symbolic_operand (operands[1], DImode)
2098 && !x86_64_immediate_operand (operands[1], DImode)"
2099 [(set (match_dup 0) (match_dup 1))
2100 (set (match_dup 2) (match_dup 3))]
2101 "split_di (operands + 1, 1, operands + 2, operands + 3);
2102 operands[1] = gen_lowpart (DImode, operands[2]);
2103 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2107 (define_insn "*pushdi2_prologue_rex64"
2108 [(set (match_operand:DI 0 "push_operand" "=<")
2109 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2110 (clobber (mem:BLK (scratch)))]
2113 [(set_attr "type" "push")
2114 (set_attr "mode" "DI")])
2116 (define_insn "*popdi1_epilogue_rex64"
2117 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2118 (mem:DI (reg:DI SP_REG)))
2119 (set (reg:DI SP_REG)
2120 (plus:DI (reg:DI SP_REG) (const_int 8)))
2121 (clobber (mem:BLK (scratch)))]
2124 [(set_attr "type" "pop")
2125 (set_attr "mode" "DI")])
2127 (define_insn "popdi1"
2128 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2129 (mem:DI (reg:DI SP_REG)))
2130 (set (reg:DI SP_REG)
2131 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2134 [(set_attr "type" "pop")
2135 (set_attr "mode" "DI")])
2137 (define_insn "*movdi_xor_rex64"
2138 [(set (match_operand:DI 0 "register_operand" "=r")
2139 (match_operand:DI 1 "const0_operand" "i"))
2140 (clobber (reg:CC FLAGS_REG))]
2141 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2142 && reload_completed"
2144 [(set_attr "type" "alu1")
2145 (set_attr "mode" "SI")
2146 (set_attr "length_immediate" "0")])
2148 (define_insn "*movdi_or_rex64"
2149 [(set (match_operand:DI 0 "register_operand" "=r")
2150 (match_operand:DI 1 "const_int_operand" "i"))
2151 (clobber (reg:CC FLAGS_REG))]
2152 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2154 && operands[1] == constm1_rtx"
2156 operands[1] = constm1_rtx;
2157 return "or{q}\t{%1, %0|%0, %1}";
2159 [(set_attr "type" "alu1")
2160 (set_attr "mode" "DI")
2161 (set_attr "length_immediate" "1")])
2163 (define_insn "*movdi_2"
2164 [(set (match_operand:DI 0 "nonimmediate_operand"
2165 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2166 (match_operand:DI 1 "general_operand"
2167 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2168 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2173 movq\t{%1, %0|%0, %1}
2174 movq\t{%1, %0|%0, %1}
2176 movq\t{%1, %0|%0, %1}
2177 movdqa\t{%1, %0|%0, %1}
2178 movq\t{%1, %0|%0, %1}
2180 movlps\t{%1, %0|%0, %1}
2181 movaps\t{%1, %0|%0, %1}
2182 movlps\t{%1, %0|%0, %1}"
2183 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2184 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2187 [(set (match_operand:DI 0 "push_operand" "")
2188 (match_operand:DI 1 "general_operand" ""))]
2189 "!TARGET_64BIT && reload_completed
2190 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2192 "ix86_split_long_move (operands); DONE;")
2194 ;; %%% This multiword shite has got to go.
2196 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2197 (match_operand:DI 1 "general_operand" ""))]
2198 "!TARGET_64BIT && reload_completed
2199 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2200 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2202 "ix86_split_long_move (operands); DONE;")
2204 (define_insn "*movdi_1_rex64"
2205 [(set (match_operand:DI 0 "nonimmediate_operand"
2206 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2207 (match_operand:DI 1 "general_operand"
2208 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2209 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2211 switch (get_attr_type (insn))
2214 if (SSE_REG_P (operands[0]))
2215 return "movq2dq\t{%1, %0|%0, %1}";
2217 return "movdq2q\t{%1, %0|%0, %1}";
2220 if (get_attr_mode (insn) == MODE_TI)
2221 return "movdqa\t{%1, %0|%0, %1}";
2225 /* Moves from and into integer register is done using movd
2226 opcode with REX prefix. */
2227 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2228 return "movd\t{%1, %0|%0, %1}";
2229 return "movq\t{%1, %0|%0, %1}";
2233 return "pxor\t%0, %0";
2239 return "lea{q}\t{%a1, %0|%0, %a1}";
2242 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2243 if (get_attr_mode (insn) == MODE_SI)
2244 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2245 else if (which_alternative == 2)
2246 return "movabs{q}\t{%1, %0|%0, %1}";
2248 return "mov{q}\t{%1, %0|%0, %1}";
2252 (cond [(eq_attr "alternative" "5")
2253 (const_string "mmxadd")
2254 (eq_attr "alternative" "6,7,8,9,10")
2255 (const_string "mmxmov")
2256 (eq_attr "alternative" "11")
2257 (const_string "sselog1")
2258 (eq_attr "alternative" "12,13,14,15,16")
2259 (const_string "ssemov")
2260 (eq_attr "alternative" "17,18")
2261 (const_string "ssecvt")
2262 (eq_attr "alternative" "4")
2263 (const_string "multi")
2264 (match_operand:DI 1 "pic_32bit_operand" "")
2265 (const_string "lea")
2267 (const_string "imov")))
2268 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2269 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2272 ;; Stores and loads of ax to arbitrary constant address.
2273 ;; We fake an second form of instruction to force reload to load address
2274 ;; into register when rax is not available
2275 (define_insn "*movabsdi_1_rex64"
2276 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2277 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2278 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2280 movabs{q}\t{%1, %P0|%P0, %1}
2281 mov{q}\t{%1, %a0|%a0, %1}"
2282 [(set_attr "type" "imov")
2283 (set_attr "modrm" "0,*")
2284 (set_attr "length_address" "8,0")
2285 (set_attr "length_immediate" "0,*")
2286 (set_attr "memory" "store")
2287 (set_attr "mode" "DI")])
2289 (define_insn "*movabsdi_2_rex64"
2290 [(set (match_operand:DI 0 "register_operand" "=a,r")
2291 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2292 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2294 movabs{q}\t{%P1, %0|%0, %P1}
2295 mov{q}\t{%a1, %0|%0, %a1}"
2296 [(set_attr "type" "imov")
2297 (set_attr "modrm" "0,*")
2298 (set_attr "length_address" "8,0")
2299 (set_attr "length_immediate" "0")
2300 (set_attr "memory" "load")
2301 (set_attr "mode" "DI")])
2303 ;; Convert impossible stores of immediate to existing instructions.
2304 ;; First try to get scratch register and go through it. In case this
2305 ;; fails, move by 32bit parts.
2307 [(match_scratch:DI 2 "r")
2308 (set (match_operand:DI 0 "memory_operand" "")
2309 (match_operand:DI 1 "immediate_operand" ""))]
2310 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2311 && !x86_64_immediate_operand (operands[1], DImode)"
2312 [(set (match_dup 2) (match_dup 1))
2313 (set (match_dup 0) (match_dup 2))]
2316 ;; We need to define this as both peepholer and splitter for case
2317 ;; peephole2 pass is not run.
2318 ;; "&& 1" is needed to keep it from matching the previous pattern.
2320 [(set (match_operand:DI 0 "memory_operand" "")
2321 (match_operand:DI 1 "immediate_operand" ""))]
2322 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2323 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2324 [(set (match_dup 2) (match_dup 3))
2325 (set (match_dup 4) (match_dup 5))]
2326 "split_di (operands, 2, operands + 2, operands + 4);")
2329 [(set (match_operand:DI 0 "memory_operand" "")
2330 (match_operand:DI 1 "immediate_operand" ""))]
2331 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2332 ? epilogue_completed : reload_completed)
2333 && !symbolic_operand (operands[1], DImode)
2334 && !x86_64_immediate_operand (operands[1], DImode)"
2335 [(set (match_dup 2) (match_dup 3))
2336 (set (match_dup 4) (match_dup 5))]
2337 "split_di (operands, 2, operands + 2, operands + 4);")
2339 (define_insn "*swapdi_rex64"
2340 [(set (match_operand:DI 0 "register_operand" "+r")
2341 (match_operand:DI 1 "register_operand" "+r"))
2346 [(set_attr "type" "imov")
2347 (set_attr "mode" "DI")
2348 (set_attr "pent_pair" "np")
2349 (set_attr "athlon_decode" "vector")
2350 (set_attr "amdfam10_decode" "double")])
2352 (define_expand "movti"
2353 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2354 (match_operand:TI 1 "nonimmediate_operand" ""))]
2355 "TARGET_SSE || TARGET_64BIT"
2358 ix86_expand_move (TImode, operands);
2359 else if (push_operand (operands[0], TImode))
2360 ix86_expand_push (TImode, operands[1]);
2362 ix86_expand_vector_move (TImode, operands);
2366 (define_insn "*movti_internal"
2367 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2368 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2369 "TARGET_SSE && !TARGET_64BIT
2370 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2372 switch (which_alternative)
2375 if (get_attr_mode (insn) == MODE_V4SF)
2376 return "xorps\t%0, %0";
2378 return "pxor\t%0, %0";
2381 if (get_attr_mode (insn) == MODE_V4SF)
2382 return "movaps\t{%1, %0|%0, %1}";
2384 return "movdqa\t{%1, %0|%0, %1}";
2389 [(set_attr "type" "sselog1,ssemov,ssemov")
2391 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2392 (ne (symbol_ref "optimize_size") (const_int 0)))
2393 (const_string "V4SF")
2394 (and (eq_attr "alternative" "2")
2395 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2397 (const_string "V4SF")]
2398 (const_string "TI")))])
2400 (define_insn "*movti_rex64"
2401 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2402 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2404 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2406 switch (which_alternative)
2412 if (get_attr_mode (insn) == MODE_V4SF)
2413 return "xorps\t%0, %0";
2415 return "pxor\t%0, %0";
2418 if (get_attr_mode (insn) == MODE_V4SF)
2419 return "movaps\t{%1, %0|%0, %1}";
2421 return "movdqa\t{%1, %0|%0, %1}";
2426 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2428 (cond [(eq_attr "alternative" "2,3")
2430 (ne (symbol_ref "optimize_size")
2432 (const_string "V4SF")
2433 (const_string "TI"))
2434 (eq_attr "alternative" "4")
2436 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2438 (ne (symbol_ref "optimize_size")
2440 (const_string "V4SF")
2441 (const_string "TI"))]
2442 (const_string "DI")))])
2445 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2446 (match_operand:TI 1 "general_operand" ""))]
2447 "reload_completed && !SSE_REG_P (operands[0])
2448 && !SSE_REG_P (operands[1])"
2450 "ix86_split_long_move (operands); DONE;")
2452 ;; This expands to what emit_move_complex would generate if we didn't
2453 ;; have a movti pattern. Having this avoids problems with reload on
2454 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2455 ;; to have around all the time.
2456 (define_expand "movcdi"
2457 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2458 (match_operand:CDI 1 "general_operand" ""))]
2461 if (push_operand (operands[0], CDImode))
2462 emit_move_complex_push (CDImode, operands[0], operands[1]);
2464 emit_move_complex_parts (operands[0], operands[1]);
2468 (define_expand "movsf"
2469 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2470 (match_operand:SF 1 "general_operand" ""))]
2472 "ix86_expand_move (SFmode, operands); DONE;")
2474 (define_insn "*pushsf"
2475 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2476 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2479 /* Anything else should be already split before reg-stack. */
2480 gcc_assert (which_alternative == 1);
2481 return "push{l}\t%1";
2483 [(set_attr "type" "multi,push,multi")
2484 (set_attr "unit" "i387,*,*")
2485 (set_attr "mode" "SF,SI,SF")])
2487 (define_insn "*pushsf_rex64"
2488 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2489 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2492 /* Anything else should be already split before reg-stack. */
2493 gcc_assert (which_alternative == 1);
2494 return "push{q}\t%q1";
2496 [(set_attr "type" "multi,push,multi")
2497 (set_attr "unit" "i387,*,*")
2498 (set_attr "mode" "SF,DI,SF")])
2501 [(set (match_operand:SF 0 "push_operand" "")
2502 (match_operand:SF 1 "memory_operand" ""))]
2504 && MEM_P (operands[1])
2505 && (operands[2] = find_constant_src (insn))"
2510 ;; %%% Kill this when call knows how to work this out.
2512 [(set (match_operand:SF 0 "push_operand" "")
2513 (match_operand:SF 1 "any_fp_register_operand" ""))]
2515 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2516 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2519 [(set (match_operand:SF 0 "push_operand" "")
2520 (match_operand:SF 1 "any_fp_register_operand" ""))]
2522 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2523 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2525 (define_insn "*movsf_1"
2526 [(set (match_operand:SF 0 "nonimmediate_operand"
2527 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2528 (match_operand:SF 1 "general_operand"
2529 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2530 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2531 && (reload_in_progress || reload_completed
2532 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2533 || (!TARGET_SSE_MATH && optimize_size
2534 && standard_80387_constant_p (operands[1]))
2535 || GET_CODE (operands[1]) != CONST_DOUBLE
2536 || memory_operand (operands[0], SFmode))"
2538 switch (which_alternative)
2542 return output_387_reg_move (insn, operands);
2545 return standard_80387_constant_opcode (operands[1]);
2549 return "mov{l}\t{%1, %0|%0, %1}";
2551 if (get_attr_mode (insn) == MODE_TI)
2552 return "pxor\t%0, %0";
2554 return "xorps\t%0, %0";
2556 if (get_attr_mode (insn) == MODE_V4SF)
2557 return "movaps\t{%1, %0|%0, %1}";
2559 return "movss\t{%1, %0|%0, %1}";
2561 return "movss\t{%1, %0|%0, %1}";
2564 case 12: case 13: case 14: case 15:
2565 return "movd\t{%1, %0|%0, %1}";
2568 return "movq\t{%1, %0|%0, %1}";
2574 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2576 (cond [(eq_attr "alternative" "3,4,9,10")
2578 (eq_attr "alternative" "5")
2580 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2582 (ne (symbol_ref "TARGET_SSE2")
2584 (eq (symbol_ref "optimize_size")
2587 (const_string "V4SF"))
2588 /* For architectures resolving dependencies on
2589 whole SSE registers use APS move to break dependency
2590 chains, otherwise use short move to avoid extra work.
2592 Do the same for architectures resolving dependencies on
2593 the parts. While in DF mode it is better to always handle
2594 just register parts, the SF mode is different due to lack
2595 of instructions to load just part of the register. It is
2596 better to maintain the whole registers in single format
2597 to avoid problems on using packed logical operations. */
2598 (eq_attr "alternative" "6")
2600 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2604 (const_string "V4SF")
2605 (const_string "SF"))
2606 (eq_attr "alternative" "11")
2607 (const_string "DI")]
2608 (const_string "SF")))])
2610 (define_insn "*swapsf"
2611 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2612 (match_operand:SF 1 "fp_register_operand" "+f"))
2615 "reload_completed || TARGET_80387"
2617 if (STACK_TOP_P (operands[0]))
2622 [(set_attr "type" "fxch")
2623 (set_attr "mode" "SF")])
2625 (define_expand "movdf"
2626 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2627 (match_operand:DF 1 "general_operand" ""))]
2629 "ix86_expand_move (DFmode, operands); DONE;")
2631 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2632 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2633 ;; On the average, pushdf using integers can be still shorter. Allow this
2634 ;; pattern for optimize_size too.
2636 (define_insn "*pushdf_nointeger"
2637 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2638 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2639 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2641 /* This insn should be already split before reg-stack. */
2644 [(set_attr "type" "multi")
2645 (set_attr "unit" "i387,*,*,*")
2646 (set_attr "mode" "DF,SI,SI,DF")])
2648 (define_insn "*pushdf_integer"
2649 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2650 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2651 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2653 /* This insn should be already split before reg-stack. */
2656 [(set_attr "type" "multi")
2657 (set_attr "unit" "i387,*,*")
2658 (set_attr "mode" "DF,SI,DF")])
2660 ;; %%% Kill this when call knows how to work this out.
2662 [(set (match_operand:DF 0 "push_operand" "")
2663 (match_operand:DF 1 "any_fp_register_operand" ""))]
2664 "!TARGET_64BIT && reload_completed"
2665 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2666 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2670 [(set (match_operand:DF 0 "push_operand" "")
2671 (match_operand:DF 1 "any_fp_register_operand" ""))]
2672 "TARGET_64BIT && reload_completed"
2673 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2674 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2678 [(set (match_operand:DF 0 "push_operand" "")
2679 (match_operand:DF 1 "general_operand" ""))]
2682 "ix86_split_long_move (operands); DONE;")
2684 ;; Moving is usually shorter when only FP registers are used. This separate
2685 ;; movdf pattern avoids the use of integer registers for FP operations
2686 ;; when optimizing for size.
2688 (define_insn "*movdf_nointeger"
2689 [(set (match_operand:DF 0 "nonimmediate_operand"
2690 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2691 (match_operand:DF 1 "general_operand"
2692 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2693 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2694 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2695 && (reload_in_progress || reload_completed
2696 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2697 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2698 && !memory_operand (operands[0], DFmode)
2699 && standard_80387_constant_p (operands[1]))
2700 || GET_CODE (operands[1]) != CONST_DOUBLE
2702 || !TARGET_MEMORY_MISMATCH_STALL
2703 || reload_in_progress || reload_completed)
2704 && memory_operand (operands[0], DFmode)))"
2706 switch (which_alternative)
2710 return output_387_reg_move (insn, operands);
2713 return standard_80387_constant_opcode (operands[1]);
2719 switch (get_attr_mode (insn))
2722 return "xorps\t%0, %0";
2724 return "xorpd\t%0, %0";
2726 return "pxor\t%0, %0";
2733 switch (get_attr_mode (insn))
2736 return "movaps\t{%1, %0|%0, %1}";
2738 return "movapd\t{%1, %0|%0, %1}";
2740 return "movdqa\t{%1, %0|%0, %1}";
2742 return "movq\t{%1, %0|%0, %1}";
2744 return "movsd\t{%1, %0|%0, %1}";
2746 return "movlpd\t{%1, %0|%0, %1}";
2748 return "movlps\t{%1, %0|%0, %1}";
2757 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2759 (cond [(eq_attr "alternative" "0,1,2")
2761 (eq_attr "alternative" "3,4")
2764 /* For SSE1, we have many fewer alternatives. */
2765 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2766 (cond [(eq_attr "alternative" "5,6")
2767 (const_string "V4SF")
2769 (const_string "V2SF"))
2771 /* xorps is one byte shorter. */
2772 (eq_attr "alternative" "5")
2773 (cond [(ne (symbol_ref "optimize_size")
2775 (const_string "V4SF")
2776 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2780 (const_string "V2DF"))
2782 /* For architectures resolving dependencies on
2783 whole SSE registers use APD move to break dependency
2784 chains, otherwise use short move to avoid extra work.
2786 movaps encodes one byte shorter. */
2787 (eq_attr "alternative" "6")
2789 [(ne (symbol_ref "optimize_size")
2791 (const_string "V4SF")
2792 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2794 (const_string "V2DF")
2796 (const_string "DF"))
2797 /* For architectures resolving dependencies on register
2798 parts we may avoid extra work to zero out upper part
2800 (eq_attr "alternative" "7")
2802 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2804 (const_string "V1DF")
2805 (const_string "DF"))
2807 (const_string "DF")))])
2809 (define_insn "*movdf_integer_rex64"
2810 [(set (match_operand:DF 0 "nonimmediate_operand"
2811 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2812 (match_operand:DF 1 "general_operand"
2813 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2814 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2815 && (reload_in_progress || reload_completed
2816 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2817 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2818 && standard_80387_constant_p (operands[1]))
2819 || GET_CODE (operands[1]) != CONST_DOUBLE
2820 || memory_operand (operands[0], DFmode))"
2822 switch (which_alternative)
2826 return output_387_reg_move (insn, operands);
2829 return standard_80387_constant_opcode (operands[1]);
2836 switch (get_attr_mode (insn))
2839 return "xorps\t%0, %0";
2841 return "xorpd\t%0, %0";
2843 return "pxor\t%0, %0";
2850 switch (get_attr_mode (insn))
2853 return "movaps\t{%1, %0|%0, %1}";
2855 return "movapd\t{%1, %0|%0, %1}";
2857 return "movdqa\t{%1, %0|%0, %1}";
2859 return "movq\t{%1, %0|%0, %1}";
2861 return "movsd\t{%1, %0|%0, %1}";
2863 return "movlpd\t{%1, %0|%0, %1}";
2865 return "movlps\t{%1, %0|%0, %1}";
2872 return "movd\t{%1, %0|%0, %1}";
2878 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2880 (cond [(eq_attr "alternative" "0,1,2")
2882 (eq_attr "alternative" "3,4,9,10")
2885 /* For SSE1, we have many fewer alternatives. */
2886 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2887 (cond [(eq_attr "alternative" "5,6")
2888 (const_string "V4SF")
2890 (const_string "V2SF"))
2892 /* xorps is one byte shorter. */
2893 (eq_attr "alternative" "5")
2894 (cond [(ne (symbol_ref "optimize_size")
2896 (const_string "V4SF")
2897 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2901 (const_string "V2DF"))
2903 /* For architectures resolving dependencies on
2904 whole SSE registers use APD move to break dependency
2905 chains, otherwise use short move to avoid extra work.
2907 movaps encodes one byte shorter. */
2908 (eq_attr "alternative" "6")
2910 [(ne (symbol_ref "optimize_size")
2912 (const_string "V4SF")
2913 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2915 (const_string "V2DF")
2917 (const_string "DF"))
2918 /* For architectures resolving dependencies on register
2919 parts we may avoid extra work to zero out upper part
2921 (eq_attr "alternative" "7")
2923 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2925 (const_string "V1DF")
2926 (const_string "DF"))
2928 (const_string "DF")))])
2930 (define_insn "*movdf_integer"
2931 [(set (match_operand:DF 0 "nonimmediate_operand"
2932 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2933 (match_operand:DF 1 "general_operand"
2934 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2935 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2936 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2937 && (reload_in_progress || reload_completed
2938 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2939 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2940 && standard_80387_constant_p (operands[1]))
2941 || GET_CODE (operands[1]) != CONST_DOUBLE
2942 || memory_operand (operands[0], DFmode))"
2944 switch (which_alternative)
2948 return output_387_reg_move (insn, operands);
2951 return standard_80387_constant_opcode (operands[1]);
2958 switch (get_attr_mode (insn))
2961 return "xorps\t%0, %0";
2963 return "xorpd\t%0, %0";
2965 return "pxor\t%0, %0";
2972 switch (get_attr_mode (insn))
2975 return "movaps\t{%1, %0|%0, %1}";
2977 return "movapd\t{%1, %0|%0, %1}";
2979 return "movdqa\t{%1, %0|%0, %1}";
2981 return "movq\t{%1, %0|%0, %1}";
2983 return "movsd\t{%1, %0|%0, %1}";
2985 return "movlpd\t{%1, %0|%0, %1}";
2987 return "movlps\t{%1, %0|%0, %1}";
2996 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2998 (cond [(eq_attr "alternative" "0,1,2")
3000 (eq_attr "alternative" "3,4")
3003 /* For SSE1, we have many fewer alternatives. */
3004 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3005 (cond [(eq_attr "alternative" "5,6")
3006 (const_string "V4SF")
3008 (const_string "V2SF"))
3010 /* xorps is one byte shorter. */
3011 (eq_attr "alternative" "5")
3012 (cond [(ne (symbol_ref "optimize_size")
3014 (const_string "V4SF")
3015 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3019 (const_string "V2DF"))
3021 /* For architectures resolving dependencies on
3022 whole SSE registers use APD move to break dependency
3023 chains, otherwise use short move to avoid extra work.
3025 movaps encodes one byte shorter. */
3026 (eq_attr "alternative" "6")
3028 [(ne (symbol_ref "optimize_size")
3030 (const_string "V4SF")
3031 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3033 (const_string "V2DF")
3035 (const_string "DF"))
3036 /* For architectures resolving dependencies on register
3037 parts we may avoid extra work to zero out upper part
3039 (eq_attr "alternative" "7")
3041 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3043 (const_string "V1DF")
3044 (const_string "DF"))
3046 (const_string "DF")))])
3049 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3050 (match_operand:DF 1 "general_operand" ""))]
3052 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3053 && ! (ANY_FP_REG_P (operands[0]) ||
3054 (GET_CODE (operands[0]) == SUBREG
3055 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3056 && ! (ANY_FP_REG_P (operands[1]) ||
3057 (GET_CODE (operands[1]) == SUBREG
3058 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3060 "ix86_split_long_move (operands); DONE;")
3062 (define_insn "*swapdf"
3063 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3064 (match_operand:DF 1 "fp_register_operand" "+f"))
3067 "reload_completed || TARGET_80387"
3069 if (STACK_TOP_P (operands[0]))
3074 [(set_attr "type" "fxch")
3075 (set_attr "mode" "DF")])
3077 (define_expand "movxf"
3078 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3079 (match_operand:XF 1 "general_operand" ""))]
3081 "ix86_expand_move (XFmode, operands); DONE;")
3083 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3084 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3085 ;; Pushing using integer instructions is longer except for constants
3086 ;; and direct memory references.
3087 ;; (assuming that any given constant is pushed only once, but this ought to be
3088 ;; handled elsewhere).
3090 (define_insn "*pushxf_nointeger"
3091 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3092 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3095 /* This insn should be already split before reg-stack. */
3098 [(set_attr "type" "multi")
3099 (set_attr "unit" "i387,*,*")
3100 (set_attr "mode" "XF,SI,SI")])
3102 (define_insn "*pushxf_integer"
3103 [(set (match_operand:XF 0 "push_operand" "=<,<")
3104 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3107 /* This insn should be already split before reg-stack. */
3110 [(set_attr "type" "multi")
3111 (set_attr "unit" "i387,*")
3112 (set_attr "mode" "XF,SI")])
3115 [(set (match_operand 0 "push_operand" "")
3116 (match_operand 1 "general_operand" ""))]
3118 && (GET_MODE (operands[0]) == XFmode
3119 || GET_MODE (operands[0]) == DFmode)
3120 && !ANY_FP_REG_P (operands[1])"
3122 "ix86_split_long_move (operands); DONE;")
3125 [(set (match_operand:XF 0 "push_operand" "")
3126 (match_operand:XF 1 "any_fp_register_operand" ""))]
3128 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3129 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3130 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3133 [(set (match_operand:XF 0 "push_operand" "")
3134 (match_operand:XF 1 "any_fp_register_operand" ""))]
3136 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3137 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3138 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3140 ;; Do not use integer registers when optimizing for size
3141 (define_insn "*movxf_nointeger"
3142 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3143 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3145 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3146 && (reload_in_progress || reload_completed
3147 || (optimize_size && standard_80387_constant_p (operands[1]))
3148 || GET_CODE (operands[1]) != CONST_DOUBLE
3149 || memory_operand (operands[0], XFmode))"
3151 switch (which_alternative)
3155 return output_387_reg_move (insn, operands);
3158 return standard_80387_constant_opcode (operands[1]);
3166 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3167 (set_attr "mode" "XF,XF,XF,SI,SI")])
3169 (define_insn "*movxf_integer"
3170 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3171 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3173 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3174 && (reload_in_progress || reload_completed
3175 || (optimize_size && standard_80387_constant_p (operands[1]))
3176 || GET_CODE (operands[1]) != CONST_DOUBLE
3177 || memory_operand (operands[0], XFmode))"
3179 switch (which_alternative)
3183 return output_387_reg_move (insn, operands);
3186 return standard_80387_constant_opcode (operands[1]);
3195 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3196 (set_attr "mode" "XF,XF,XF,SI,SI")])
3198 (define_expand "movtf"
3199 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3200 (match_operand:TF 1 "nonimmediate_operand" ""))]
3203 ix86_expand_move (TFmode, operands);
3207 (define_insn "*movtf_internal"
3208 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3209 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3211 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3213 switch (which_alternative)
3217 if (get_attr_mode (insn) == MODE_V4SF)
3218 return "movaps\t{%1, %0|%0, %1}";
3220 return "movdqa\t{%1, %0|%0, %1}";
3222 if (get_attr_mode (insn) == MODE_V4SF)
3223 return "xorps\t%0, %0";
3225 return "pxor\t%0, %0";
3233 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3235 (cond [(eq_attr "alternative" "0,2")
3237 (ne (symbol_ref "optimize_size")
3239 (const_string "V4SF")
3240 (const_string "TI"))
3241 (eq_attr "alternative" "1")
3243 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3245 (ne (symbol_ref "optimize_size")
3247 (const_string "V4SF")
3248 (const_string "TI"))]
3249 (const_string "DI")))])
3252 [(set (match_operand 0 "nonimmediate_operand" "")
3253 (match_operand 1 "general_operand" ""))]
3255 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3256 && GET_MODE (operands[0]) == XFmode
3257 && ! (ANY_FP_REG_P (operands[0]) ||
3258 (GET_CODE (operands[0]) == SUBREG
3259 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3260 && ! (ANY_FP_REG_P (operands[1]) ||
3261 (GET_CODE (operands[1]) == SUBREG
3262 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3264 "ix86_split_long_move (operands); DONE;")
3267 [(set (match_operand 0 "register_operand" "")
3268 (match_operand 1 "memory_operand" ""))]
3270 && MEM_P (operands[1])
3271 && (GET_MODE (operands[0]) == TFmode
3272 || GET_MODE (operands[0]) == XFmode
3273 || GET_MODE (operands[0]) == SFmode
3274 || GET_MODE (operands[0]) == DFmode)
3275 && (operands[2] = find_constant_src (insn))"
3276 [(set (match_dup 0) (match_dup 2))]
3278 rtx c = operands[2];
3279 rtx r = operands[0];
3281 if (GET_CODE (r) == SUBREG)
3286 if (!standard_sse_constant_p (c))
3289 else if (FP_REG_P (r))
3291 if (!standard_80387_constant_p (c))
3294 else if (MMX_REG_P (r))
3299 [(set (match_operand 0 "register_operand" "")
3300 (float_extend (match_operand 1 "memory_operand" "")))]
3302 && MEM_P (operands[1])
3303 && (GET_MODE (operands[0]) == TFmode
3304 || GET_MODE (operands[0]) == XFmode
3305 || GET_MODE (operands[0]) == SFmode
3306 || GET_MODE (operands[0]) == DFmode)
3307 && (operands[2] = find_constant_src (insn))"
3308 [(set (match_dup 0) (match_dup 2))]
3310 rtx c = operands[2];
3311 rtx r = operands[0];
3313 if (GET_CODE (r) == SUBREG)
3318 if (!standard_sse_constant_p (c))
3321 else if (FP_REG_P (r))
3323 if (!standard_80387_constant_p (c))
3326 else if (MMX_REG_P (r))
3330 (define_insn "swapxf"
3331 [(set (match_operand:XF 0 "register_operand" "+f")
3332 (match_operand:XF 1 "register_operand" "+f"))
3337 if (STACK_TOP_P (operands[0]))
3342 [(set_attr "type" "fxch")
3343 (set_attr "mode" "XF")])
3345 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3347 [(set (match_operand:X87MODEF 0 "register_operand" "")
3348 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3349 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3350 && (standard_80387_constant_p (operands[1]) == 8
3351 || standard_80387_constant_p (operands[1]) == 9)"
3352 [(set (match_dup 0)(match_dup 1))
3354 (neg:X87MODEF (match_dup 0)))]
3358 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3359 if (real_isnegzero (&r))
3360 operands[1] = CONST0_RTX (<MODE>mode);
3362 operands[1] = CONST1_RTX (<MODE>mode);
3366 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3367 (match_operand:TF 1 "general_operand" ""))]
3369 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3371 "ix86_split_long_move (operands); DONE;")
3373 ;; Zero extension instructions
3375 (define_expand "zero_extendhisi2"
3376 [(set (match_operand:SI 0 "register_operand" "")
3377 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3380 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3382 operands[1] = force_reg (HImode, operands[1]);
3383 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3388 (define_insn "zero_extendhisi2_and"
3389 [(set (match_operand:SI 0 "register_operand" "=r")
3390 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3391 (clobber (reg:CC FLAGS_REG))]
3392 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3394 [(set_attr "type" "alu1")
3395 (set_attr "mode" "SI")])
3398 [(set (match_operand:SI 0 "register_operand" "")
3399 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3400 (clobber (reg:CC FLAGS_REG))]
3401 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3402 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3403 (clobber (reg:CC FLAGS_REG))])]
3406 (define_insn "*zero_extendhisi2_movzwl"
3407 [(set (match_operand:SI 0 "register_operand" "=r")
3408 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3409 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3410 "movz{wl|x}\t{%1, %0|%0, %1}"
3411 [(set_attr "type" "imovx")
3412 (set_attr "mode" "SI")])
3414 (define_expand "zero_extendqihi2"
3416 [(set (match_operand:HI 0 "register_operand" "")
3417 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3418 (clobber (reg:CC FLAGS_REG))])]
3422 (define_insn "*zero_extendqihi2_and"
3423 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3424 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3425 (clobber (reg:CC FLAGS_REG))]
3426 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3428 [(set_attr "type" "alu1")
3429 (set_attr "mode" "HI")])
3431 (define_insn "*zero_extendqihi2_movzbw_and"
3432 [(set (match_operand:HI 0 "register_operand" "=r,r")
3433 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3434 (clobber (reg:CC FLAGS_REG))]
3435 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3437 [(set_attr "type" "imovx,alu1")
3438 (set_attr "mode" "HI")])
3440 ; zero extend to SImode here to avoid partial register stalls
3441 (define_insn "*zero_extendqihi2_movzbl"
3442 [(set (match_operand:HI 0 "register_operand" "=r")
3443 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3444 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3445 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3446 [(set_attr "type" "imovx")
3447 (set_attr "mode" "SI")])
3449 ;; For the movzbw case strip only the clobber
3451 [(set (match_operand:HI 0 "register_operand" "")
3452 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3453 (clobber (reg:CC FLAGS_REG))]
3455 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3456 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3457 [(set (match_operand:HI 0 "register_operand" "")
3458 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3460 ;; When source and destination does not overlap, clear destination
3461 ;; first and then do the movb
3463 [(set (match_operand:HI 0 "register_operand" "")
3464 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3465 (clobber (reg:CC FLAGS_REG))]
3467 && ANY_QI_REG_P (operands[0])
3468 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3469 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3470 [(set (match_dup 0) (const_int 0))
3471 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3472 "operands[2] = gen_lowpart (QImode, operands[0]);")
3474 ;; Rest is handled by single and.
3476 [(set (match_operand:HI 0 "register_operand" "")
3477 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3478 (clobber (reg:CC FLAGS_REG))]
3480 && true_regnum (operands[0]) == true_regnum (operands[1])"
3481 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3482 (clobber (reg:CC FLAGS_REG))])]
3485 (define_expand "zero_extendqisi2"
3487 [(set (match_operand:SI 0 "register_operand" "")
3488 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3489 (clobber (reg:CC FLAGS_REG))])]
3493 (define_insn "*zero_extendqisi2_and"
3494 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3495 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3496 (clobber (reg:CC FLAGS_REG))]
3497 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3499 [(set_attr "type" "alu1")
3500 (set_attr "mode" "SI")])
3502 (define_insn "*zero_extendqisi2_movzbw_and"
3503 [(set (match_operand:SI 0 "register_operand" "=r,r")
3504 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3505 (clobber (reg:CC FLAGS_REG))]
3506 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3508 [(set_attr "type" "imovx,alu1")
3509 (set_attr "mode" "SI")])
3511 (define_insn "*zero_extendqisi2_movzbw"
3512 [(set (match_operand:SI 0 "register_operand" "=r")
3513 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3514 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3515 "movz{bl|x}\t{%1, %0|%0, %1}"
3516 [(set_attr "type" "imovx")
3517 (set_attr "mode" "SI")])
3519 ;; For the movzbl case strip only the clobber
3521 [(set (match_operand:SI 0 "register_operand" "")
3522 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3523 (clobber (reg:CC FLAGS_REG))]
3525 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3526 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3528 (zero_extend:SI (match_dup 1)))])
3530 ;; When source and destination does not overlap, clear destination
3531 ;; first and then do the movb
3533 [(set (match_operand:SI 0 "register_operand" "")
3534 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3535 (clobber (reg:CC FLAGS_REG))]
3537 && ANY_QI_REG_P (operands[0])
3538 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3539 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3540 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3541 [(set (match_dup 0) (const_int 0))
3542 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3543 "operands[2] = gen_lowpart (QImode, operands[0]);")
3545 ;; Rest is handled by single and.
3547 [(set (match_operand:SI 0 "register_operand" "")
3548 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3549 (clobber (reg:CC FLAGS_REG))]
3551 && true_regnum (operands[0]) == true_regnum (operands[1])"
3552 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3553 (clobber (reg:CC FLAGS_REG))])]
3556 ;; %%% Kill me once multi-word ops are sane.
3557 (define_expand "zero_extendsidi2"
3558 [(set (match_operand:DI 0 "register_operand" "")
3559 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3564 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3569 (define_insn "zero_extendsidi2_32"
3570 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3572 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3573 (clobber (reg:CC FLAGS_REG))]
3579 movd\t{%1, %0|%0, %1}
3580 movd\t{%1, %0|%0, %1}
3581 movd\t{%1, %0|%0, %1}
3582 movd\t{%1, %0|%0, %1}"
3583 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3584 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3586 (define_insn "zero_extendsidi2_rex64"
3587 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3589 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3592 mov\t{%k1, %k0|%k0, %k1}
3594 movd\t{%1, %0|%0, %1}
3595 movd\t{%1, %0|%0, %1}
3596 movd\t{%1, %0|%0, %1}
3597 movd\t{%1, %0|%0, %1}"
3598 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3599 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3602 [(set (match_operand:DI 0 "memory_operand" "")
3603 (zero_extend:DI (match_dup 0)))]
3605 [(set (match_dup 4) (const_int 0))]
3606 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3609 [(set (match_operand:DI 0 "register_operand" "")
3610 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3611 (clobber (reg:CC FLAGS_REG))]
3612 "!TARGET_64BIT && reload_completed
3613 && true_regnum (operands[0]) == true_regnum (operands[1])"
3614 [(set (match_dup 4) (const_int 0))]
3615 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3618 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3619 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3620 (clobber (reg:CC FLAGS_REG))]
3621 "!TARGET_64BIT && reload_completed
3622 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3623 [(set (match_dup 3) (match_dup 1))
3624 (set (match_dup 4) (const_int 0))]
3625 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3627 (define_insn "zero_extendhidi2"
3628 [(set (match_operand:DI 0 "register_operand" "=r")
3629 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3631 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3632 [(set_attr "type" "imovx")
3633 (set_attr "mode" "DI")])
3635 (define_insn "zero_extendqidi2"
3636 [(set (match_operand:DI 0 "register_operand" "=r")
3637 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3639 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3640 [(set_attr "type" "imovx")
3641 (set_attr "mode" "DI")])
3643 ;; Sign extension instructions
3645 (define_expand "extendsidi2"
3646 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3647 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3648 (clobber (reg:CC FLAGS_REG))
3649 (clobber (match_scratch:SI 2 ""))])]
3654 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3659 (define_insn "*extendsidi2_1"
3660 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3661 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3662 (clobber (reg:CC FLAGS_REG))
3663 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3667 (define_insn "extendsidi2_rex64"
3668 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3669 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3673 movs{lq|x}\t{%1,%0|%0, %1}"
3674 [(set_attr "type" "imovx")
3675 (set_attr "mode" "DI")
3676 (set_attr "prefix_0f" "0")
3677 (set_attr "modrm" "0,1")])
3679 (define_insn "extendhidi2"
3680 [(set (match_operand:DI 0 "register_operand" "=r")
3681 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683 "movs{wq|x}\t{%1,%0|%0, %1}"
3684 [(set_attr "type" "imovx")
3685 (set_attr "mode" "DI")])
3687 (define_insn "extendqidi2"
3688 [(set (match_operand:DI 0 "register_operand" "=r")
3689 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3691 "movs{bq|x}\t{%1,%0|%0, %1}"
3692 [(set_attr "type" "imovx")
3693 (set_attr "mode" "DI")])
3695 ;; Extend to memory case when source register does die.
3697 [(set (match_operand:DI 0 "memory_operand" "")
3698 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3699 (clobber (reg:CC FLAGS_REG))
3700 (clobber (match_operand:SI 2 "register_operand" ""))]
3702 && dead_or_set_p (insn, operands[1])
3703 && !reg_mentioned_p (operands[1], operands[0]))"
3704 [(set (match_dup 3) (match_dup 1))
3705 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3706 (clobber (reg:CC FLAGS_REG))])
3707 (set (match_dup 4) (match_dup 1))]
3708 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3710 ;; Extend to memory case when source register does not die.
3712 [(set (match_operand:DI 0 "memory_operand" "")
3713 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3714 (clobber (reg:CC FLAGS_REG))
3715 (clobber (match_operand:SI 2 "register_operand" ""))]
3719 split_di (&operands[0], 1, &operands[3], &operands[4]);
3721 emit_move_insn (operands[3], operands[1]);
3723 /* Generate a cltd if possible and doing so it profitable. */
3724 if ((optimize_size || TARGET_USE_CLTD)
3725 && true_regnum (operands[1]) == AX_REG
3726 && true_regnum (operands[2]) == DX_REG)
3728 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3732 emit_move_insn (operands[2], operands[1]);
3733 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3735 emit_move_insn (operands[4], operands[2]);
3739 ;; Extend to register case. Optimize case where source and destination
3740 ;; registers match and cases where we can use cltd.
3742 [(set (match_operand:DI 0 "register_operand" "")
3743 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3744 (clobber (reg:CC FLAGS_REG))
3745 (clobber (match_scratch:SI 2 ""))]
3749 split_di (&operands[0], 1, &operands[3], &operands[4]);
3751 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3752 emit_move_insn (operands[3], operands[1]);
3754 /* Generate a cltd if possible and doing so it profitable. */
3755 if ((optimize_size || TARGET_USE_CLTD)
3756 && true_regnum (operands[3]) == AX_REG)
3758 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3762 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3763 emit_move_insn (operands[4], operands[1]);
3765 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3769 (define_insn "extendhisi2"
3770 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3771 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3774 switch (get_attr_prefix_0f (insn))
3777 return "{cwtl|cwde}";
3779 return "movs{wl|x}\t{%1,%0|%0, %1}";
3782 [(set_attr "type" "imovx")
3783 (set_attr "mode" "SI")
3784 (set (attr "prefix_0f")
3785 ;; movsx is short decodable while cwtl is vector decoded.
3786 (if_then_else (and (eq_attr "cpu" "!k6")
3787 (eq_attr "alternative" "0"))
3789 (const_string "1")))
3791 (if_then_else (eq_attr "prefix_0f" "0")
3793 (const_string "1")))])
3795 (define_insn "*extendhisi2_zext"
3796 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3798 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3801 switch (get_attr_prefix_0f (insn))
3804 return "{cwtl|cwde}";
3806 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3809 [(set_attr "type" "imovx")
3810 (set_attr "mode" "SI")
3811 (set (attr "prefix_0f")
3812 ;; movsx is short decodable while cwtl is vector decoded.
3813 (if_then_else (and (eq_attr "cpu" "!k6")
3814 (eq_attr "alternative" "0"))
3816 (const_string "1")))
3818 (if_then_else (eq_attr "prefix_0f" "0")
3820 (const_string "1")))])
3822 (define_insn "extendqihi2"
3823 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3824 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3827 switch (get_attr_prefix_0f (insn))
3830 return "{cbtw|cbw}";
3832 return "movs{bw|x}\t{%1,%0|%0, %1}";
3835 [(set_attr "type" "imovx")
3836 (set_attr "mode" "HI")
3837 (set (attr "prefix_0f")
3838 ;; movsx is short decodable while cwtl is vector decoded.
3839 (if_then_else (and (eq_attr "cpu" "!k6")
3840 (eq_attr "alternative" "0"))
3842 (const_string "1")))
3844 (if_then_else (eq_attr "prefix_0f" "0")
3846 (const_string "1")))])
3848 (define_insn "extendqisi2"
3849 [(set (match_operand:SI 0 "register_operand" "=r")
3850 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3852 "movs{bl|x}\t{%1,%0|%0, %1}"
3853 [(set_attr "type" "imovx")
3854 (set_attr "mode" "SI")])
3856 (define_insn "*extendqisi2_zext"
3857 [(set (match_operand:DI 0 "register_operand" "=r")
3859 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3861 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3862 [(set_attr "type" "imovx")
3863 (set_attr "mode" "SI")])
3865 ;; Conversions between float and double.
3867 ;; These are all no-ops in the model used for the 80387. So just
3870 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3871 (define_insn "*dummy_extendsfdf2"
3872 [(set (match_operand:DF 0 "push_operand" "=<")
3873 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3878 [(set (match_operand:DF 0 "push_operand" "")
3879 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3881 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3882 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3885 [(set (match_operand:DF 0 "push_operand" "")
3886 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3888 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3889 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3891 (define_insn "*dummy_extendsfxf2"
3892 [(set (match_operand:XF 0 "push_operand" "=<")
3893 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3898 [(set (match_operand:XF 0 "push_operand" "")
3899 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3901 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3902 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3903 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3906 [(set (match_operand:XF 0 "push_operand" "")
3907 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3909 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3910 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3911 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3914 [(set (match_operand:XF 0 "push_operand" "")
3915 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3917 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3918 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3919 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3922 [(set (match_operand:XF 0 "push_operand" "")
3923 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3925 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3926 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3927 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3929 (define_expand "extendsfdf2"
3930 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3931 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3932 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3934 /* ??? Needed for compress_float_constant since all fp constants
3935 are LEGITIMATE_CONSTANT_P. */
3936 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3938 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3939 && standard_80387_constant_p (operands[1]) > 0)
3941 operands[1] = simplify_const_unary_operation
3942 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3943 emit_move_insn_1 (operands[0], operands[1]);
3946 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3950 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3952 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3954 We do the conversion post reload to avoid producing of 128bit spills
3955 that might lead to ICE on 32bit target. The sequence unlikely combine
3958 [(set (match_operand:DF 0 "register_operand" "")
3960 (match_operand:SF 1 "nonimmediate_operand" "")))]
3961 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3962 && reload_completed && SSE_REG_P (operands[0])"
3967 (parallel [(const_int 0) (const_int 1)]))))]
3969 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3970 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3971 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3972 Try to avoid move when unpacking can be done in source. */
3973 if (REG_P (operands[1]))
3975 /* If it is unsafe to overwrite upper half of source, we need
3976 to move to destination and unpack there. */
3977 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3978 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3979 && true_regnum (operands[0]) != true_regnum (operands[1]))
3981 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3982 emit_move_insn (tmp, operands[1]);
3985 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3986 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3989 emit_insn (gen_vec_setv4sf_0 (operands[3],
3990 CONST0_RTX (V4SFmode), operands[1]));
3993 (define_insn "*extendsfdf2_mixed"
3994 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3996 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3997 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3999 switch (which_alternative)
4003 return output_387_reg_move (insn, operands);
4006 return "cvtss2sd\t{%1, %0|%0, %1}";
4012 [(set_attr "type" "fmov,fmov,ssecvt")
4013 (set_attr "mode" "SF,XF,DF")])
4015 (define_insn "*extendsfdf2_sse"
4016 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4017 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4018 "TARGET_SSE2 && TARGET_SSE_MATH"
4019 "cvtss2sd\t{%1, %0|%0, %1}"
4020 [(set_attr "type" "ssecvt")
4021 (set_attr "mode" "DF")])
4023 (define_insn "*extendsfdf2_i387"
4024 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4025 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4027 "* return output_387_reg_move (insn, operands);"
4028 [(set_attr "type" "fmov")
4029 (set_attr "mode" "SF,XF")])
4031 (define_expand "extend<mode>xf2"
4032 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4033 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4036 /* ??? Needed for compress_float_constant since all fp constants
4037 are LEGITIMATE_CONSTANT_P. */
4038 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4040 if (standard_80387_constant_p (operands[1]) > 0)
4042 operands[1] = simplify_const_unary_operation
4043 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4044 emit_move_insn_1 (operands[0], operands[1]);
4047 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4051 (define_insn "*extend<mode>xf2_i387"
4052 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4054 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4056 "* return output_387_reg_move (insn, operands);"
4057 [(set_attr "type" "fmov")
4058 (set_attr "mode" "<MODE>,XF")])
4060 ;; %%% This seems bad bad news.
4061 ;; This cannot output into an f-reg because there is no way to be sure
4062 ;; of truncating in that case. Otherwise this is just like a simple move
4063 ;; insn. So we pretend we can output to a reg in order to get better
4064 ;; register preferencing, but we really use a stack slot.
4066 ;; Conversion from DFmode to SFmode.
4068 (define_expand "truncdfsf2"
4069 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4071 (match_operand:DF 1 "nonimmediate_operand" "")))]
4072 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4074 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4076 else if (flag_unsafe_math_optimizations)
4080 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4081 rtx temp = assign_386_stack_local (SFmode, slot);
4082 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4087 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4089 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4091 We do the conversion post reload to avoid producing of 128bit spills
4092 that might lead to ICE on 32bit target. The sequence unlikely combine
4095 [(set (match_operand:SF 0 "register_operand" "")
4097 (match_operand:DF 1 "nonimmediate_operand" "")))]
4098 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4099 && reload_completed && SSE_REG_P (operands[0])"
4102 (float_truncate:V2SF
4106 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4107 operands[3] = CONST0_RTX (V2SFmode);
4108 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4109 /* Use movsd for loading from memory, unpcklpd for registers.
4110 Try to avoid move when unpacking can be done in source, or SSE3
4111 movddup is available. */
4112 if (REG_P (operands[1]))
4115 && true_regnum (operands[0]) != true_regnum (operands[1])
4116 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4117 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4119 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4120 emit_move_insn (tmp, operands[1]);
4123 else if (!TARGET_SSE3)
4124 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4125 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4128 emit_insn (gen_sse2_loadlpd (operands[4],
4129 CONST0_RTX (V2DFmode), operands[1]));
4132 (define_expand "truncdfsf2_with_temp"
4133 [(parallel [(set (match_operand:SF 0 "" "")
4134 (float_truncate:SF (match_operand:DF 1 "" "")))
4135 (clobber (match_operand:SF 2 "" ""))])]
4138 (define_insn "*truncdfsf_fast_mixed"
4139 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4141 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4142 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4144 switch (which_alternative)
4148 return output_387_reg_move (insn, operands);
4150 return "cvtsd2ss\t{%1, %0|%0, %1}";
4155 [(set_attr "type" "fmov,fmov,ssecvt")
4156 (set_attr "mode" "SF")])
4158 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4159 ;; because nothing we do here is unsafe.
4160 (define_insn "*truncdfsf_fast_sse"
4161 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4163 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4164 "TARGET_SSE2 && TARGET_SSE_MATH"
4165 "cvtsd2ss\t{%1, %0|%0, %1}"
4166 [(set_attr "type" "ssecvt")
4167 (set_attr "mode" "SF")])
4169 (define_insn "*truncdfsf_fast_i387"
4170 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4172 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4173 "TARGET_80387 && flag_unsafe_math_optimizations"
4174 "* return output_387_reg_move (insn, operands);"
4175 [(set_attr "type" "fmov")
4176 (set_attr "mode" "SF")])
4178 (define_insn "*truncdfsf_mixed"
4179 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4181 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4182 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4183 "TARGET_MIX_SSE_I387"
4185 switch (which_alternative)
4188 return output_387_reg_move (insn, operands);
4193 return "cvtsd2ss\t{%1, %0|%0, %1}";
4198 [(set_attr "type" "fmov,multi,ssecvt")
4199 (set_attr "unit" "*,i387,*")
4200 (set_attr "mode" "SF")])
4202 (define_insn "*truncdfsf_i387"
4203 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4205 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4206 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4209 switch (which_alternative)
4212 return output_387_reg_move (insn, operands);
4220 [(set_attr "type" "fmov,multi")
4221 (set_attr "unit" "*,i387")
4222 (set_attr "mode" "SF")])
4224 (define_insn "*truncdfsf2_i387_1"
4225 [(set (match_operand:SF 0 "memory_operand" "=m")
4227 (match_operand:DF 1 "register_operand" "f")))]
4229 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4230 && !TARGET_MIX_SSE_I387"
4231 "* return output_387_reg_move (insn, operands);"
4232 [(set_attr "type" "fmov")
4233 (set_attr "mode" "SF")])
4236 [(set (match_operand:SF 0 "register_operand" "")
4238 (match_operand:DF 1 "fp_register_operand" "")))
4239 (clobber (match_operand 2 "" ""))]
4241 [(set (match_dup 2) (match_dup 1))
4242 (set (match_dup 0) (match_dup 2))]
4244 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4247 ;; Conversion from XFmode to {SF,DF}mode
4249 (define_expand "truncxf<mode>2"
4250 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4251 (float_truncate:MODEF
4252 (match_operand:XF 1 "register_operand" "")))
4253 (clobber (match_dup 2))])]
4256 if (flag_unsafe_math_optimizations)
4258 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4259 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4260 if (reg != operands[0])
4261 emit_move_insn (operands[0], reg);
4266 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4267 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4271 (define_insn "*truncxfsf2_mixed"
4272 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4274 (match_operand:XF 1 "register_operand" "f,f")))
4275 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4278 gcc_assert (!which_alternative);
4279 return output_387_reg_move (insn, operands);
4281 [(set_attr "type" "fmov,multi")
4282 (set_attr "unit" "*,i387")
4283 (set_attr "mode" "SF")])
4285 (define_insn "*truncxfdf2_mixed"
4286 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4288 (match_operand:XF 1 "register_operand" "f,f")))
4289 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4292 gcc_assert (!which_alternative);
4293 return output_387_reg_move (insn, operands);
4295 [(set_attr "type" "fmov,multi")
4296 (set_attr "unit" "*,i387")
4297 (set_attr "mode" "DF")])
4299 (define_insn "truncxf<mode>2_i387_noop"
4300 [(set (match_operand:MODEF 0 "register_operand" "=f")
4301 (float_truncate:MODEF
4302 (match_operand:XF 1 "register_operand" "f")))]
4303 "TARGET_80387 && flag_unsafe_math_optimizations"
4304 "* return output_387_reg_move (insn, operands);"
4305 [(set_attr "type" "fmov")
4306 (set_attr "mode" "<MODE>")])
4308 (define_insn "*truncxf<mode>2_i387"
4309 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4310 (float_truncate:MODEF
4311 (match_operand:XF 1 "register_operand" "f")))]
4313 "* return output_387_reg_move (insn, operands);"
4314 [(set_attr "type" "fmov")
4315 (set_attr "mode" "<MODE>")])
4318 [(set (match_operand:MODEF 0 "register_operand" "")
4319 (float_truncate:MODEF
4320 (match_operand:XF 1 "register_operand" "")))
4321 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4322 "TARGET_80387 && reload_completed"
4323 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4324 (set (match_dup 0) (match_dup 2))]
4328 [(set (match_operand:MODEF 0 "memory_operand" "")
4329 (float_truncate:MODEF
4330 (match_operand:XF 1 "register_operand" "")))
4331 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4333 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4336 ;; Signed conversion to DImode.
4338 (define_expand "fix_truncxfdi2"
4339 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4340 (fix:DI (match_operand:XF 1 "register_operand" "")))
4341 (clobber (reg:CC FLAGS_REG))])]
4346 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4351 (define_expand "fix_trunc<mode>di2"
4352 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4353 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4354 (clobber (reg:CC FLAGS_REG))])]
4355 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4358 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4360 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4363 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4365 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4366 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4367 if (out != operands[0])
4368 emit_move_insn (operands[0], out);
4373 ;; Signed conversion to SImode.
4375 (define_expand "fix_truncxfsi2"
4376 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4377 (fix:SI (match_operand:XF 1 "register_operand" "")))
4378 (clobber (reg:CC FLAGS_REG))])]
4383 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4388 (define_expand "fix_trunc<mode>si2"
4389 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4390 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4391 (clobber (reg:CC FLAGS_REG))])]
4392 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4395 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4397 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4400 if (SSE_FLOAT_MODE_P (<MODE>mode))
4402 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4403 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4404 if (out != operands[0])
4405 emit_move_insn (operands[0], out);
4410 ;; Signed conversion to HImode.
4412 (define_expand "fix_trunc<mode>hi2"
4413 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4414 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4415 (clobber (reg:CC FLAGS_REG))])]
4417 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4421 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4426 ;; Unsigned conversion to SImode.
4428 (define_expand "fixuns_trunc<mode>si2"
4430 [(set (match_operand:SI 0 "register_operand" "")
4432 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4434 (clobber (match_scratch:<ssevecmode> 3 ""))
4435 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4436 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4438 enum machine_mode mode = <MODE>mode;
4439 enum machine_mode vecmode = <ssevecmode>mode;
4440 REAL_VALUE_TYPE TWO31r;
4443 real_ldexp (&TWO31r, &dconst1, 31);
4444 two31 = const_double_from_real_value (TWO31r, mode);
4445 two31 = ix86_build_const_vector (mode, true, two31);
4446 operands[2] = force_reg (vecmode, two31);
4449 (define_insn_and_split "*fixuns_trunc<mode>_1"
4450 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4452 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4453 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4454 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4455 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4456 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4458 "&& reload_completed"
4461 ix86_split_convert_uns_si_sse (operands);
4465 ;; Unsigned conversion to HImode.
4466 ;; Without these patterns, we'll try the unsigned SI conversion which
4467 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4469 (define_expand "fixuns_trunc<mode>hi2"
4471 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4472 (set (match_operand:HI 0 "nonimmediate_operand" "")
4473 (subreg:HI (match_dup 2) 0))]
4474 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4475 "operands[2] = gen_reg_rtx (SImode);")
4477 ;; When SSE is available, it is always faster to use it!
4478 (define_insn "fix_trunc<mode>di_sse"
4479 [(set (match_operand:DI 0 "register_operand" "=r,r")
4480 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4481 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4482 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4483 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4484 [(set_attr "type" "sseicvt")
4485 (set_attr "mode" "<MODE>")
4486 (set_attr "athlon_decode" "double,vector")
4487 (set_attr "amdfam10_decode" "double,double")])
4489 (define_insn "fix_trunc<mode>si_sse"
4490 [(set (match_operand:SI 0 "register_operand" "=r,r")
4491 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4492 "SSE_FLOAT_MODE_P (<MODE>mode)
4493 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4494 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4495 [(set_attr "type" "sseicvt")
4496 (set_attr "mode" "<MODE>")
4497 (set_attr "athlon_decode" "double,vector")
4498 (set_attr "amdfam10_decode" "double,double")])
4500 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4502 [(set (match_operand:MODEF 0 "register_operand" "")
4503 (match_operand:MODEF 1 "memory_operand" ""))
4504 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4505 (fix:SSEMODEI24 (match_dup 0)))]
4506 "TARGET_SHORTEN_X87_SSE
4507 && peep2_reg_dead_p (2, operands[0])"
4508 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4511 ;; Avoid vector decoded forms of the instruction.
4513 [(match_scratch:DF 2 "Y2")
4514 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4515 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4516 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4517 [(set (match_dup 2) (match_dup 1))
4518 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4522 [(match_scratch:SF 2 "x")
4523 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4524 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4525 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4526 [(set (match_dup 2) (match_dup 1))
4527 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4530 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4531 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4532 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4533 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && (TARGET_64BIT || <MODE>mode != DImode))
4538 && !(reload_completed || reload_in_progress)"
4543 if (memory_operand (operands[0], VOIDmode))
4544 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4547 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4548 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4554 [(set_attr "type" "fisttp")
4555 (set_attr "mode" "<MODE>")])
4557 (define_insn "fix_trunc<mode>_i387_fisttp"
4558 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4559 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4560 (clobber (match_scratch:XF 2 "=&1f"))]
4561 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && (TARGET_64BIT || <MODE>mode != DImode))
4565 && TARGET_SSE_MATH)"
4566 "* return output_fix_trunc (insn, operands, 1);"
4567 [(set_attr "type" "fisttp")
4568 (set_attr "mode" "<MODE>")])
4570 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4571 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4572 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4573 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4574 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4575 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4577 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4578 && (TARGET_64BIT || <MODE>mode != DImode))
4579 && TARGET_SSE_MATH)"
4581 [(set_attr "type" "fisttp")
4582 (set_attr "mode" "<MODE>")])
4585 [(set (match_operand:X87MODEI 0 "register_operand" "")
4586 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4587 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4588 (clobber (match_scratch 3 ""))]
4590 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4591 (clobber (match_dup 3))])
4592 (set (match_dup 0) (match_dup 2))]
4596 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4597 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4598 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4599 (clobber (match_scratch 3 ""))]
4601 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4602 (clobber (match_dup 3))])]
4605 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4606 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4607 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4608 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4609 ;; function in i386.c.
4610 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4611 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4612 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4613 (clobber (reg:CC FLAGS_REG))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && (TARGET_64BIT || <MODE>mode != DImode))
4618 && !(reload_completed || reload_in_progress)"
4623 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4625 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4626 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4627 if (memory_operand (operands[0], VOIDmode))
4628 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4629 operands[2], operands[3]));
4632 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4633 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4634 operands[2], operands[3],
4639 [(set_attr "type" "fistp")
4640 (set_attr "i387_cw" "trunc")
4641 (set_attr "mode" "<MODE>")])
4643 (define_insn "fix_truncdi_i387"
4644 [(set (match_operand:DI 0 "memory_operand" "=m")
4645 (fix:DI (match_operand 1 "register_operand" "f")))
4646 (use (match_operand:HI 2 "memory_operand" "m"))
4647 (use (match_operand:HI 3 "memory_operand" "m"))
4648 (clobber (match_scratch:XF 4 "=&1f"))]
4649 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4651 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4652 "* return output_fix_trunc (insn, operands, 0);"
4653 [(set_attr "type" "fistp")
4654 (set_attr "i387_cw" "trunc")
4655 (set_attr "mode" "DI")])
4657 (define_insn "fix_truncdi_i387_with_temp"
4658 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4659 (fix:DI (match_operand 1 "register_operand" "f,f")))
4660 (use (match_operand:HI 2 "memory_operand" "m,m"))
4661 (use (match_operand:HI 3 "memory_operand" "m,m"))
4662 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4663 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4664 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4666 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4668 [(set_attr "type" "fistp")
4669 (set_attr "i387_cw" "trunc")
4670 (set_attr "mode" "DI")])
4673 [(set (match_operand:DI 0 "register_operand" "")
4674 (fix:DI (match_operand 1 "register_operand" "")))
4675 (use (match_operand:HI 2 "memory_operand" ""))
4676 (use (match_operand:HI 3 "memory_operand" ""))
4677 (clobber (match_operand:DI 4 "memory_operand" ""))
4678 (clobber (match_scratch 5 ""))]
4680 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4683 (clobber (match_dup 5))])
4684 (set (match_dup 0) (match_dup 4))]
4688 [(set (match_operand:DI 0 "memory_operand" "")
4689 (fix:DI (match_operand 1 "register_operand" "")))
4690 (use (match_operand:HI 2 "memory_operand" ""))
4691 (use (match_operand:HI 3 "memory_operand" ""))
4692 (clobber (match_operand:DI 4 "memory_operand" ""))
4693 (clobber (match_scratch 5 ""))]
4695 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4698 (clobber (match_dup 5))])]
4701 (define_insn "fix_trunc<mode>_i387"
4702 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4703 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4704 (use (match_operand:HI 2 "memory_operand" "m"))
4705 (use (match_operand:HI 3 "memory_operand" "m"))]
4706 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4708 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4709 "* return output_fix_trunc (insn, operands, 0);"
4710 [(set_attr "type" "fistp")
4711 (set_attr "i387_cw" "trunc")
4712 (set_attr "mode" "<MODE>")])
4714 (define_insn "fix_trunc<mode>_i387_with_temp"
4715 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4716 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4717 (use (match_operand:HI 2 "memory_operand" "m,m"))
4718 (use (match_operand:HI 3 "memory_operand" "m,m"))
4719 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4720 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4722 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4724 [(set_attr "type" "fistp")
4725 (set_attr "i387_cw" "trunc")
4726 (set_attr "mode" "<MODE>")])
4729 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4730 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4731 (use (match_operand:HI 2 "memory_operand" ""))
4732 (use (match_operand:HI 3 "memory_operand" ""))
4733 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4735 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4737 (use (match_dup 3))])
4738 (set (match_dup 0) (match_dup 4))]
4742 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4743 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4744 (use (match_operand:HI 2 "memory_operand" ""))
4745 (use (match_operand:HI 3 "memory_operand" ""))
4746 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4748 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4750 (use (match_dup 3))])]
4753 (define_insn "x86_fnstcw_1"
4754 [(set (match_operand:HI 0 "memory_operand" "=m")
4755 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4758 [(set_attr "length" "2")
4759 (set_attr "mode" "HI")
4760 (set_attr "unit" "i387")])
4762 (define_insn "x86_fldcw_1"
4763 [(set (reg:HI FPCR_REG)
4764 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4767 [(set_attr "length" "2")
4768 (set_attr "mode" "HI")
4769 (set_attr "unit" "i387")
4770 (set_attr "athlon_decode" "vector")
4771 (set_attr "amdfam10_decode" "vector")])
4773 ;; Conversion between fixed point and floating point.
4775 ;; Even though we only accept memory inputs, the backend _really_
4776 ;; wants to be able to do this between registers.
4778 (define_expand "floathi<mode>2"
4779 [(set (match_operand:MODEF 0 "register_operand" "")
4780 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4781 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4783 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4786 (gen_floatsi<mode>2 (operands[0],
4787 convert_to_mode (SImode, operands[1], 0)));
4792 (define_insn "*floathi<mode>2_i387"
4793 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4795 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4798 || TARGET_MIX_SSE_I387)"
4802 [(set_attr "type" "fmov,multi")
4803 (set_attr "mode" "<MODE>")
4804 (set_attr "unit" "*,i387")
4805 (set_attr "fp_int_src" "true")])
4807 (define_expand "floatsi<mode>2"
4808 [(set (match_operand:MODEF 0 "register_operand" "")
4809 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4810 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4812 /* When we use vector converts, we can't have input in memory. */
4813 if (GET_MODE (operands[0]) == DFmode
4814 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4815 && SSE_FLOAT_MODE_P (DFmode))
4816 operands[1] = force_reg (SImode, operands[1]);
4817 else if (GET_MODE (operands[0]) == SFmode
4818 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4819 && SSE_FLOAT_MODE_P (SFmode))
4821 /* When !flag_trapping_math, we handle SImode->SFmode vector
4822 conversions same way as SImode->DFmode.
4824 For flat_trapping_math we can't safely use vector conversion without
4825 clearing upper half, otherwise precision exception might occur.
4826 However we can still generate the common sequence converting value
4827 from general register to XMM register as:
4833 because we know that movd clears the upper half.
4835 Sadly in this case we can't rely on reload moving the value to XMM
4836 register, since we need to know if upper half is OK, so we need
4837 to do reloading by hand. We force operand to memory unless target
4838 supports inter unit moves. */
4839 if (!flag_trapping_math)
4840 operands[1] = force_reg (SImode, operands[1]);
4841 else if (!MEM_P (operands[1]))
4843 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4844 rtx tmp = assign_386_stack_local (SImode, slot);
4845 emit_move_insn (tmp, operands[1]);
4849 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4850 !TARGET_INTER_UNIT_CONVERSIONS
4851 It is necessary for the patterns to not accept nonmemory operands
4852 as we would optimize out later. */
4853 else if (!TARGET_INTER_UNIT_CONVERSIONS
4854 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4856 && !MEM_P (operands[1]))
4858 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4859 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4860 emit_move_insn (tmp, operands[1]);
4865 (define_insn "*floatsisf2_mixed_vector"
4866 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4867 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4868 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4869 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4871 cvtdq2ps\t{%1, %0|%0, %1}
4874 [(set_attr "type" "sseicvt,fmov,multi")
4875 (set_attr "mode" "SF")
4876 (set_attr "unit" "*,i387,*")
4877 (set_attr "athlon_decode" "double,*,*")
4878 (set_attr "amdfam10_decode" "double,*,*")
4879 (set_attr "fp_int_src" "false,true,true")])
4881 (define_insn "*floatsisf2_mixed"
4882 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4883 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4884 "TARGET_MIX_SSE_I387
4885 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4890 cvtsi2ss\t{%1, %0|%0, %1}
4891 cvtsi2ss\t{%1, %0|%0, %1}"
4892 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4893 (set_attr "mode" "SF")
4894 (set_attr "unit" "*,i387,*,*")
4895 (set_attr "athlon_decode" "*,*,vector,double")
4896 (set_attr "amdfam10_decode" "*,*,vector,double")
4897 (set_attr "fp_int_src" "true")])
4899 (define_insn "*floatsisf2_mixed_memory"
4900 [(set (match_operand:SF 0 "register_operand" "=f,x")
4901 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4902 "TARGET_MIX_SSE_I387
4903 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4906 cvtsi2ss\t{%1, %0|%0, %1}"
4907 [(set_attr "type" "fmov,sseicvt")
4908 (set_attr "mode" "SF")
4909 (set_attr "athlon_decode" "*,double")
4910 (set_attr "amdfam10_decode" "*,double")
4911 (set_attr "fp_int_src" "true")])
4913 (define_insn "*floatsisf2_sse_vector_nointernunit"
4914 [(set (match_operand:SF 0 "register_operand" "=x")
4915 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4916 "TARGET_SSE_MATH && flag_trapping_math
4917 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4918 && !TARGET_INTER_UNIT_MOVES"
4920 [(set_attr "type" "multi")])
4922 (define_insn "*floatsisf2_sse_vector_internunit"
4923 [(set (match_operand:SF 0 "register_operand" "=x,x")
4924 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4925 "TARGET_SSE_MATH && flag_trapping_math
4926 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4927 && TARGET_INTER_UNIT_MOVES"
4929 [(set_attr "type" "multi")])
4932 [(set (match_operand:SF 0 "register_operand" "")
4933 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4935 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4936 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4937 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4939 (float:V4SF (match_dup 2)))]
4941 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4942 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4943 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4947 [(set (match_operand:SF 0 "register_operand" "")
4948 (float:SF (match_operand:SI 1 "register_operand" "")))]
4950 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4951 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4952 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4954 (float:V4SF (match_dup 2)))]
4956 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4957 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4960 (define_insn "*floatsisf2_sse_vector"
4961 [(set (match_operand:SF 0 "register_operand" "=x")
4962 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4963 "TARGET_SSE_MATH && !flag_trapping_math
4964 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4965 && !TARGET_INTER_UNIT_MOVES"
4966 "cvtdq2ps\t{%1, %0|%0, %1}"
4967 [(set_attr "type" "sseicvt")
4968 (set_attr "mode" "SF")
4969 (set_attr "athlon_decode" "double")
4970 (set_attr "amdfam10_decode" "double")
4971 (set_attr "fp_int_src" "true")])
4973 (define_insn "*floatsisf2_sse"
4974 [(set (match_operand:SF 0 "register_operand" "=x,x")
4975 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4977 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4979 "cvtsi2ss\t{%1, %0|%0, %1}"
4980 [(set_attr "type" "sseicvt")
4981 (set_attr "mode" "SF")
4982 (set_attr "athlon_decode" "vector,double")
4983 (set_attr "amdfam10_decode" "vector,double")
4984 (set_attr "fp_int_src" "true")])
4986 (define_insn "*floatsisf2_sse_memory"
4987 [(set (match_operand:SF 0 "register_operand" "=x")
4988 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4990 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4991 "cvtsi2ss\t{%1, %0|%0, %1}"
4992 [(set_attr "type" "sseicvt")
4993 (set_attr "mode" "SF")
4994 (set_attr "athlon_decode" "double")
4995 (set_attr "amdfam10_decode" "double")
4996 (set_attr "fp_int_src" "true")])
4998 (define_insn "*floatsidf2_mixed_vector"
4999 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
5000 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
5001 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5002 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5004 cvtdq2pd\t{%1, %0|%0, %1}
5007 [(set_attr "type" "sseicvt,fmov,multi")
5008 (set_attr "mode" "V2DF,DF,DF")
5009 (set_attr "unit" "*,*,i387")
5010 (set_attr "athlon_decode" "double,*,*")
5011 (set_attr "amdfam10_decode" "double,*,*")
5012 (set_attr "fp_int_src" "false,true,true")])
5014 (define_insn "*floatsidf2_mixed"
5015 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5016 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5017 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5018 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5023 cvtsi2sd\t{%1, %0|%0, %1}
5024 cvtsi2sd\t{%1, %0|%0, %1}
5025 cvtdq2pd\t{%1, %0|%0, %1}"
5026 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5027 (set_attr "mode" "DF,DF,DF,DF,V2DF")
5028 (set_attr "unit" "*,i387,*,*,*")
5029 (set_attr "athlon_decode" "*,*,double,direct,double")
5030 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5031 (set_attr "fp_int_src" "true,true,true,true,false")])
5033 (define_insn "*floatsidf2_mixed_memory"
5034 [(set (match_operand:DF 0 "register_operand" "=f,x")
5035 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5036 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5037 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5040 cvtsi2sd\t{%1, %0|%0, %1}"
5041 [(set_attr "type" "fmov,sseicvt")
5042 (set_attr "mode" "DF")
5043 (set_attr "athlon_decode" "*,direct")
5044 (set_attr "amdfam10_decode" "*,double")
5045 (set_attr "fp_int_src" "true")])
5047 (define_insn "*floatsidf2_sse_vector"
5048 [(set (match_operand:DF 0 "register_operand" "=x")
5049 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5050 "TARGET_SSE2 && TARGET_SSE_MATH
5051 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5052 "cvtdq2pd\t{%1, %0|%0, %1}"
5053 [(set_attr "type" "sseicvt")
5054 (set_attr "mode" "V2DF")
5055 (set_attr "athlon_decode" "double")
5056 (set_attr "amdfam10_decode" "double")
5057 (set_attr "fp_int_src" "true")])
5060 [(set (match_operand:DF 0 "register_operand" "")
5061 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5062 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5063 && SSE_REG_P (operands[0])"
5068 (parallel [(const_int 0) (const_int 1)]))))]
5070 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5071 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5072 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5075 (define_insn "*floatsidf2_sse"
5076 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5077 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5078 "TARGET_SSE2 && TARGET_SSE_MATH
5079 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5082 cvtsi2sd\t{%1, %0|%0, %1}
5083 cvtsi2sd\t{%1, %0|%0, %1}
5084 cvtdq2pd\t{%1, %0|%0, %1}"
5085 [(set_attr "type" "sseicvt")
5086 (set_attr "mode" "DF,DF,V2DF")
5087 (set_attr "athlon_decode" "double,direct,double")
5088 (set_attr "amdfam10_decode" "vector,double,double")
5089 (set_attr "fp_int_src" "true")])
5091 (define_insn "*floatsidf2_memory"
5092 [(set (match_operand:DF 0 "register_operand" "=x")
5093 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5094 "TARGET_SSE2 && TARGET_SSE_MATH
5095 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5097 "cvtsi2sd\t{%1, %0|%0, %1}"
5098 [(set_attr "type" "sseicvt")
5099 (set_attr "mode" "DF")
5100 (set_attr "athlon_decode" "direct")
5101 (set_attr "amdfam10_decode" "double")
5102 (set_attr "fp_int_src" "true")])
5104 (define_insn "*floatsi<mode>2_i387"
5105 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5107 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5109 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5113 [(set_attr "type" "fmov,multi")
5114 (set_attr "mode" "<MODE>")
5115 (set_attr "unit" "*,i387")
5116 (set_attr "fp_int_src" "true")])
5118 (define_expand "floatdisf2"
5119 [(set (match_operand:SF 0 "register_operand" "")
5120 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5121 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5123 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5124 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5126 && !MEM_P (operands[1]))
5128 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5129 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5130 emit_move_insn (tmp, operands[1]);
5135 (define_insn "*floatdisf2_mixed"
5136 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5137 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5138 "TARGET_64BIT && TARGET_MIX_SSE_I387
5139 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5143 cvtsi2ss{q}\t{%1, %0|%0, %1}
5144 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5145 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5146 (set_attr "mode" "SF")
5147 (set_attr "unit" "*,i387,*,*")
5148 (set_attr "athlon_decode" "*,*,vector,double")
5149 (set_attr "amdfam10_decode" "*,*,vector,double")
5150 (set_attr "fp_int_src" "true")])
5152 (define_insn "*floatdisf2_mixed"
5153 [(set (match_operand:SF 0 "register_operand" "=f,x")
5154 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5155 "TARGET_64BIT && TARGET_MIX_SSE_I387
5156 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5159 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5160 [(set_attr "type" "fmov,sseicvt")
5161 (set_attr "mode" "SF")
5162 (set_attr "athlon_decode" "*,double")
5163 (set_attr "amdfam10_decode" "*,double")
5164 (set_attr "fp_int_src" "true")])
5166 (define_insn "*floatdisf2_sse"
5167 [(set (match_operand:SF 0 "register_operand" "=x,x")
5168 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5169 "TARGET_64BIT && TARGET_SSE_MATH
5170 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5171 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5172 [(set_attr "type" "sseicvt")
5173 (set_attr "mode" "SF")
5174 (set_attr "athlon_decode" "vector,double")
5175 (set_attr "amdfam10_decode" "vector,double")
5176 (set_attr "fp_int_src" "true")])
5178 (define_insn "*floatdisf2_memory"
5179 [(set (match_operand:SF 0 "register_operand" "=x")
5180 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5181 "TARGET_64BIT && TARGET_SSE_MATH
5182 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5183 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5184 [(set_attr "type" "sseicvt")
5185 (set_attr "mode" "SF")
5186 (set_attr "athlon_decode" "double")
5187 (set_attr "amdfam10_decode" "double")
5188 (set_attr "fp_int_src" "true")])
5190 (define_expand "floatdidf2"
5191 [(set (match_operand:DF 0 "register_operand" "")
5192 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5193 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5195 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5197 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5200 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5201 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5203 && !MEM_P (operands[1]))
5205 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5206 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5207 emit_move_insn (tmp, operands[1]);
5212 (define_insn "*floatdidf2_mixed"
5213 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5214 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5215 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5216 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5220 cvtsi2sd{q}\t{%1, %0|%0, %1}
5221 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5222 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5223 (set_attr "mode" "DF")
5224 (set_attr "unit" "*,i387,*,*")
5225 (set_attr "athlon_decode" "*,*,double,direct")
5226 (set_attr "amdfam10_decode" "*,*,vector,double")
5227 (set_attr "fp_int_src" "true")])
5229 (define_insn "*floatdidf2_mixed_memory"
5230 [(set (match_operand:DF 0 "register_operand" "=f,x")
5231 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5232 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5233 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5236 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5237 [(set_attr "type" "fmov,sseicvt")
5238 (set_attr "mode" "DF")
5239 (set_attr "athlon_decode" "*,direct")
5240 (set_attr "amdfam10_decode" "*,double")
5241 (set_attr "fp_int_src" "true")])
5243 (define_insn "*floatdidf2_sse"
5244 [(set (match_operand:DF 0 "register_operand" "=x,x")
5245 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5246 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5247 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5248 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5249 [(set_attr "type" "sseicvt")
5250 (set_attr "mode" "DF")
5251 (set_attr "athlon_decode" "double,direct")
5252 (set_attr "amdfam10_decode" "vector,double")
5253 (set_attr "fp_int_src" "true")])
5255 (define_insn "*floatdidf2_sse_memory"
5256 [(set (match_operand:DF 0 "register_operand" "=x")
5257 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5258 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5259 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5260 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5261 [(set_attr "type" "sseicvt")
5262 (set_attr "mode" "DF")
5263 (set_attr "athlon_decode" "direct")
5264 (set_attr "amdfam10_decode" "double")
5265 (set_attr "fp_int_src" "true")])
5267 (define_insn "*floatdi<mode>2_i387"
5268 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5270 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5272 && (!TARGET_SSE_MATH || !TARGET_64BIT
5273 || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5277 [(set_attr "type" "fmov,multi")
5278 (set_attr "mode" "<MODE>")
5279 (set_attr "unit" "*,i387")
5280 (set_attr "fp_int_src" "true")])
5282 (define_insn "float<mode>xf2"
5283 [(set (match_operand:XF 0 "register_operand" "=f,f")
5284 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5289 [(set_attr "type" "fmov,multi")
5290 (set_attr "mode" "XF")
5291 (set_attr "unit" "*,i387")
5292 (set_attr "fp_int_src" "true")])
5294 ;; %%% Kill these when reload knows how to do it.
5296 [(set (match_operand 0 "fp_register_operand" "")
5297 (float (match_operand 1 "register_operand" "")))]
5299 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5302 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5303 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5304 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5305 ix86_free_from_memory (GET_MODE (operands[1]));
5309 (define_expand "floatunssi<mode>2"
5310 [(use (match_operand:MODEF 0 "register_operand" ""))
5311 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5312 "!TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5314 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5318 (define_expand "floatunsdisf2"
5319 [(use (match_operand:SF 0 "register_operand" ""))
5320 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5321 "TARGET_64BIT && TARGET_SSE_MATH"
5322 "x86_emit_floatuns (operands); DONE;")
5324 (define_expand "floatunsdidf2"
5325 [(use (match_operand:DF 0 "register_operand" ""))
5326 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5327 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5328 && TARGET_SSE2 && TARGET_SSE_MATH"
5331 x86_emit_floatuns (operands);
5333 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5339 ;; %%% splits for addditi3
5341 (define_expand "addti3"
5342 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5343 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5344 (match_operand:TI 2 "x86_64_general_operand" "")))
5345 (clobber (reg:CC FLAGS_REG))]
5347 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5349 (define_insn "*addti3_1"
5350 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5351 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5352 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5353 (clobber (reg:CC FLAGS_REG))]
5354 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5358 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5359 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5360 (match_operand:TI 2 "x86_64_general_operand" "")))
5361 (clobber (reg:CC FLAGS_REG))]
5362 "TARGET_64BIT && reload_completed"
5363 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5365 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5366 (parallel [(set (match_dup 3)
5367 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5370 (clobber (reg:CC FLAGS_REG))])]
5371 "split_ti (operands+0, 1, operands+0, operands+3);
5372 split_ti (operands+1, 1, operands+1, operands+4);
5373 split_ti (operands+2, 1, operands+2, operands+5);")
5375 ;; %%% splits for addsidi3
5376 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5377 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5378 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5380 (define_expand "adddi3"
5381 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5382 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5383 (match_operand:DI 2 "x86_64_general_operand" "")))
5384 (clobber (reg:CC FLAGS_REG))]
5386 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5388 (define_insn "*adddi3_1"
5389 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5390 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5391 (match_operand:DI 2 "general_operand" "roiF,riF")))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5398 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5399 (match_operand:DI 2 "general_operand" "")))
5400 (clobber (reg:CC FLAGS_REG))]
5401 "!TARGET_64BIT && reload_completed"
5402 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5404 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5405 (parallel [(set (match_dup 3)
5406 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5409 (clobber (reg:CC FLAGS_REG))])]
5410 "split_di (operands+0, 1, operands+0, operands+3);
5411 split_di (operands+1, 1, operands+1, operands+4);
5412 split_di (operands+2, 1, operands+2, operands+5);")
5414 (define_insn "adddi3_carry_rex64"
5415 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5416 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5417 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5418 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5419 (clobber (reg:CC FLAGS_REG))]
5420 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5421 "adc{q}\t{%2, %0|%0, %2}"
5422 [(set_attr "type" "alu")
5423 (set_attr "pent_pair" "pu")
5424 (set_attr "mode" "DI")])
5426 (define_insn "*adddi3_cc_rex64"
5427 [(set (reg:CC FLAGS_REG)
5428 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5429 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5431 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5432 (plus:DI (match_dup 1) (match_dup 2)))]
5433 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5434 "add{q}\t{%2, %0|%0, %2}"
5435 [(set_attr "type" "alu")
5436 (set_attr "mode" "DI")])
5438 (define_insn "*<addsub><mode>3_cc_overflow"
5439 [(set (reg:CCC FLAGS_REG)
5442 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5443 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5445 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5446 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5447 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5448 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5449 [(set_attr "type" "alu")
5450 (set_attr "mode" "<MODE>")])
5452 (define_insn "*add<mode>3_cconly_overflow"
5453 [(set (reg:CCC FLAGS_REG)
5455 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5456 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5458 (clobber (match_scratch:SWI 0 "=<r>"))]
5459 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5460 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5461 [(set_attr "type" "alu")
5462 (set_attr "mode" "<MODE>")])
5464 (define_insn "*sub<mode>3_cconly_overflow"
5465 [(set (reg:CCC FLAGS_REG)
5467 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5468 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5471 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5472 [(set_attr "type" "icmp")
5473 (set_attr "mode" "<MODE>")])
5475 (define_insn "*<addsub>si3_zext_cc_overflow"
5476 [(set (reg:CCC FLAGS_REG)
5478 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5479 (match_operand:SI 2 "general_operand" "g"))
5481 (set (match_operand:DI 0 "register_operand" "=r")
5482 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5483 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5484 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5485 [(set_attr "type" "alu")
5486 (set_attr "mode" "SI")])
5488 (define_insn "addqi3_carry"
5489 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5490 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5491 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5492 (match_operand:QI 2 "general_operand" "qi,qm")))
5493 (clobber (reg:CC FLAGS_REG))]
5494 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5495 "adc{b}\t{%2, %0|%0, %2}"
5496 [(set_attr "type" "alu")
5497 (set_attr "pent_pair" "pu")
5498 (set_attr "mode" "QI")])
5500 (define_insn "addhi3_carry"
5501 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5502 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5503 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5504 (match_operand:HI 2 "general_operand" "ri,rm")))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5507 "adc{w}\t{%2, %0|%0, %2}"
5508 [(set_attr "type" "alu")
5509 (set_attr "pent_pair" "pu")
5510 (set_attr "mode" "HI")])
5512 (define_insn "addsi3_carry"
5513 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5514 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5515 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5516 (match_operand:SI 2 "general_operand" "ri,rm")))
5517 (clobber (reg:CC FLAGS_REG))]
5518 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5519 "adc{l}\t{%2, %0|%0, %2}"
5520 [(set_attr "type" "alu")
5521 (set_attr "pent_pair" "pu")
5522 (set_attr "mode" "SI")])
5524 (define_insn "*addsi3_carry_zext"
5525 [(set (match_operand:DI 0 "register_operand" "=r")
5527 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5528 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5529 (match_operand:SI 2 "general_operand" "g"))))
5530 (clobber (reg:CC FLAGS_REG))]
5531 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5532 "adc{l}\t{%2, %k0|%k0, %2}"
5533 [(set_attr "type" "alu")
5534 (set_attr "pent_pair" "pu")
5535 (set_attr "mode" "SI")])
5537 (define_insn "*addsi3_cc"
5538 [(set (reg:CC FLAGS_REG)
5539 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5540 (match_operand:SI 2 "general_operand" "ri,rm")]
5542 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5543 (plus:SI (match_dup 1) (match_dup 2)))]
5544 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5545 "add{l}\t{%2, %0|%0, %2}"
5546 [(set_attr "type" "alu")
5547 (set_attr "mode" "SI")])
5549 (define_insn "addqi3_cc"
5550 [(set (reg:CC FLAGS_REG)
5551 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5552 (match_operand:QI 2 "general_operand" "qi,qm")]
5554 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5555 (plus:QI (match_dup 1) (match_dup 2)))]
5556 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5557 "add{b}\t{%2, %0|%0, %2}"
5558 [(set_attr "type" "alu")
5559 (set_attr "mode" "QI")])
5561 (define_expand "addsi3"
5562 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5563 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5564 (match_operand:SI 2 "general_operand" "")))
5565 (clobber (reg:CC FLAGS_REG))])]
5567 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5569 (define_insn "*lea_1"
5570 [(set (match_operand:SI 0 "register_operand" "=r")
5571 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5573 "lea{l}\t{%a1, %0|%0, %a1}"
5574 [(set_attr "type" "lea")
5575 (set_attr "mode" "SI")])
5577 (define_insn "*lea_1_rex64"
5578 [(set (match_operand:SI 0 "register_operand" "=r")
5579 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5581 "lea{l}\t{%a1, %0|%0, %a1}"
5582 [(set_attr "type" "lea")
5583 (set_attr "mode" "SI")])
5585 (define_insn "*lea_1_zext"
5586 [(set (match_operand:DI 0 "register_operand" "=r")
5588 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5590 "lea{l}\t{%a1, %k0|%k0, %a1}"
5591 [(set_attr "type" "lea")
5592 (set_attr "mode" "SI")])
5594 (define_insn "*lea_2_rex64"
5595 [(set (match_operand:DI 0 "register_operand" "=r")
5596 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5598 "lea{q}\t{%a1, %0|%0, %a1}"
5599 [(set_attr "type" "lea")
5600 (set_attr "mode" "DI")])
5602 ;; The lea patterns for non-Pmodes needs to be matched by several
5603 ;; insns converted to real lea by splitters.
5605 (define_insn_and_split "*lea_general_1"
5606 [(set (match_operand 0 "register_operand" "=r")
5607 (plus (plus (match_operand 1 "index_register_operand" "l")
5608 (match_operand 2 "register_operand" "r"))
5609 (match_operand 3 "immediate_operand" "i")))]
5610 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5611 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5612 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5613 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5614 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5615 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5616 || GET_MODE (operands[3]) == VOIDmode)"
5618 "&& reload_completed"
5622 operands[0] = gen_lowpart (SImode, operands[0]);
5623 operands[1] = gen_lowpart (Pmode, operands[1]);
5624 operands[2] = gen_lowpart (Pmode, operands[2]);
5625 operands[3] = gen_lowpart (Pmode, operands[3]);
5626 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5628 if (Pmode != SImode)
5629 pat = gen_rtx_SUBREG (SImode, pat, 0);
5630 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5633 [(set_attr "type" "lea")
5634 (set_attr "mode" "SI")])
5636 (define_insn_and_split "*lea_general_1_zext"
5637 [(set (match_operand:DI 0 "register_operand" "=r")
5639 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5640 (match_operand:SI 2 "register_operand" "r"))
5641 (match_operand:SI 3 "immediate_operand" "i"))))]
5644 "&& reload_completed"
5646 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5648 (match_dup 3)) 0)))]
5650 operands[1] = gen_lowpart (Pmode, operands[1]);
5651 operands[2] = gen_lowpart (Pmode, operands[2]);
5652 operands[3] = gen_lowpart (Pmode, operands[3]);
5654 [(set_attr "type" "lea")
5655 (set_attr "mode" "SI")])
5657 (define_insn_and_split "*lea_general_2"
5658 [(set (match_operand 0 "register_operand" "=r")
5659 (plus (mult (match_operand 1 "index_register_operand" "l")
5660 (match_operand 2 "const248_operand" "i"))
5661 (match_operand 3 "nonmemory_operand" "ri")))]
5662 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5663 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5664 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5665 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5666 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5667 || GET_MODE (operands[3]) == VOIDmode)"
5669 "&& reload_completed"
5673 operands[0] = gen_lowpart (SImode, operands[0]);
5674 operands[1] = gen_lowpart (Pmode, operands[1]);
5675 operands[3] = gen_lowpart (Pmode, operands[3]);
5676 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5678 if (Pmode != SImode)
5679 pat = gen_rtx_SUBREG (SImode, pat, 0);
5680 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5683 [(set_attr "type" "lea")
5684 (set_attr "mode" "SI")])
5686 (define_insn_and_split "*lea_general_2_zext"
5687 [(set (match_operand:DI 0 "register_operand" "=r")
5689 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5690 (match_operand:SI 2 "const248_operand" "n"))
5691 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5694 "&& reload_completed"
5696 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5698 (match_dup 3)) 0)))]
5700 operands[1] = gen_lowpart (Pmode, operands[1]);
5701 operands[3] = gen_lowpart (Pmode, operands[3]);
5703 [(set_attr "type" "lea")
5704 (set_attr "mode" "SI")])
5706 (define_insn_and_split "*lea_general_3"
5707 [(set (match_operand 0 "register_operand" "=r")
5708 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5709 (match_operand 2 "const248_operand" "i"))
5710 (match_operand 3 "register_operand" "r"))
5711 (match_operand 4 "immediate_operand" "i")))]
5712 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5713 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5714 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5715 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5716 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5718 "&& reload_completed"
5722 operands[0] = gen_lowpart (SImode, operands[0]);
5723 operands[1] = gen_lowpart (Pmode, operands[1]);
5724 operands[3] = gen_lowpart (Pmode, operands[3]);
5725 operands[4] = gen_lowpart (Pmode, operands[4]);
5726 pat = gen_rtx_PLUS (Pmode,
5727 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5731 if (Pmode != SImode)
5732 pat = gen_rtx_SUBREG (SImode, pat, 0);
5733 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5736 [(set_attr "type" "lea")
5737 (set_attr "mode" "SI")])
5739 (define_insn_and_split "*lea_general_3_zext"
5740 [(set (match_operand:DI 0 "register_operand" "=r")
5742 (plus:SI (plus:SI (mult:SI
5743 (match_operand:SI 1 "index_register_operand" "l")
5744 (match_operand:SI 2 "const248_operand" "n"))
5745 (match_operand:SI 3 "register_operand" "r"))
5746 (match_operand:SI 4 "immediate_operand" "i"))))]
5749 "&& reload_completed"
5751 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5754 (match_dup 4)) 0)))]
5756 operands[1] = gen_lowpart (Pmode, operands[1]);
5757 operands[3] = gen_lowpart (Pmode, operands[3]);
5758 operands[4] = gen_lowpart (Pmode, operands[4]);
5760 [(set_attr "type" "lea")
5761 (set_attr "mode" "SI")])
5763 (define_insn "*adddi_1_rex64"
5764 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5765 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5766 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5770 switch (get_attr_type (insn))
5773 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5774 return "lea{q}\t{%a2, %0|%0, %a2}";
5777 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778 if (operands[2] == const1_rtx)
5779 return "inc{q}\t%0";
5782 gcc_assert (operands[2] == constm1_rtx);
5783 return "dec{q}\t%0";
5787 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5791 if (CONST_INT_P (operands[2])
5792 /* Avoid overflows. */
5793 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5794 && (INTVAL (operands[2]) == 128
5795 || (INTVAL (operands[2]) < 0
5796 && INTVAL (operands[2]) != -128)))
5798 operands[2] = GEN_INT (-INTVAL (operands[2]));
5799 return "sub{q}\t{%2, %0|%0, %2}";
5801 return "add{q}\t{%2, %0|%0, %2}";
5805 (cond [(eq_attr "alternative" "2")
5806 (const_string "lea")
5807 ; Current assemblers are broken and do not allow @GOTOFF in
5808 ; ought but a memory context.
5809 (match_operand:DI 2 "pic_symbolic_operand" "")
5810 (const_string "lea")
5811 (match_operand:DI 2 "incdec_operand" "")
5812 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "DI")])
5817 ;; Convert lea to the lea pattern to avoid flags dependency.
5819 [(set (match_operand:DI 0 "register_operand" "")
5820 (plus:DI (match_operand:DI 1 "register_operand" "")
5821 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5822 (clobber (reg:CC FLAGS_REG))]
5823 "TARGET_64BIT && reload_completed
5824 && true_regnum (operands[0]) != true_regnum (operands[1])"
5826 (plus:DI (match_dup 1)
5830 (define_insn "*adddi_2_rex64"
5831 [(set (reg FLAGS_REG)
5833 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5834 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5836 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5837 (plus:DI (match_dup 1) (match_dup 2)))]
5838 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5839 && ix86_binary_operator_ok (PLUS, DImode, operands)
5840 /* Current assemblers are broken and do not allow @GOTOFF in
5841 ought but a memory context. */
5842 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5844 switch (get_attr_type (insn))
5847 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5848 if (operands[2] == const1_rtx)
5849 return "inc{q}\t%0";
5852 gcc_assert (operands[2] == constm1_rtx);
5853 return "dec{q}\t%0";
5857 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5858 /* ???? We ought to handle there the 32bit case too
5859 - do we need new constraint? */
5860 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5861 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5862 if (CONST_INT_P (operands[2])
5863 /* Avoid overflows. */
5864 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5865 && (INTVAL (operands[2]) == 128
5866 || (INTVAL (operands[2]) < 0
5867 && INTVAL (operands[2]) != -128)))
5869 operands[2] = GEN_INT (-INTVAL (operands[2]));
5870 return "sub{q}\t{%2, %0|%0, %2}";
5872 return "add{q}\t{%2, %0|%0, %2}";
5876 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5877 (const_string "incdec")
5878 (const_string "alu")))
5879 (set_attr "mode" "DI")])
5881 (define_insn "*adddi_3_rex64"
5882 [(set (reg FLAGS_REG)
5883 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5884 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5885 (clobber (match_scratch:DI 0 "=r"))]
5887 && ix86_match_ccmode (insn, CCZmode)
5888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5889 /* Current assemblers are broken and do not allow @GOTOFF in
5890 ought but a memory context. */
5891 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5893 switch (get_attr_type (insn))
5896 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5897 if (operands[2] == const1_rtx)
5898 return "inc{q}\t%0";
5901 gcc_assert (operands[2] == constm1_rtx);
5902 return "dec{q}\t%0";
5906 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5907 /* ???? We ought to handle there the 32bit case too
5908 - do we need new constraint? */
5909 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5910 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5911 if (CONST_INT_P (operands[2])
5912 /* Avoid overflows. */
5913 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5914 && (INTVAL (operands[2]) == 128
5915 || (INTVAL (operands[2]) < 0
5916 && INTVAL (operands[2]) != -128)))
5918 operands[2] = GEN_INT (-INTVAL (operands[2]));
5919 return "sub{q}\t{%2, %0|%0, %2}";
5921 return "add{q}\t{%2, %0|%0, %2}";
5925 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5926 (const_string "incdec")
5927 (const_string "alu")))
5928 (set_attr "mode" "DI")])
5930 ; For comparisons against 1, -1 and 128, we may generate better code
5931 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5932 ; is matched then. We can't accept general immediate, because for
5933 ; case of overflows, the result is messed up.
5934 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5936 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5937 ; only for comparisons not depending on it.
5938 (define_insn "*adddi_4_rex64"
5939 [(set (reg FLAGS_REG)
5940 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5941 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5942 (clobber (match_scratch:DI 0 "=rm"))]
5944 && ix86_match_ccmode (insn, CCGCmode)"
5946 switch (get_attr_type (insn))
5949 if (operands[2] == constm1_rtx)
5950 return "inc{q}\t%0";
5953 gcc_assert (operands[2] == const1_rtx);
5954 return "dec{q}\t%0";
5958 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5959 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5960 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5961 if ((INTVAL (operands[2]) == -128
5962 || (INTVAL (operands[2]) > 0
5963 && INTVAL (operands[2]) != 128))
5964 /* Avoid overflows. */
5965 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5966 return "sub{q}\t{%2, %0|%0, %2}";
5967 operands[2] = GEN_INT (-INTVAL (operands[2]));
5968 return "add{q}\t{%2, %0|%0, %2}";
5972 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5973 (const_string "incdec")
5974 (const_string "alu")))
5975 (set_attr "mode" "DI")])
5977 (define_insn "*adddi_5_rex64"
5978 [(set (reg FLAGS_REG)
5980 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5981 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5983 (clobber (match_scratch:DI 0 "=r"))]
5985 && ix86_match_ccmode (insn, CCGOCmode)
5986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5987 /* Current assemblers are broken and do not allow @GOTOFF in
5988 ought but a memory context. */
5989 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5991 switch (get_attr_type (insn))
5994 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995 if (operands[2] == const1_rtx)
5996 return "inc{q}\t%0";
5999 gcc_assert (operands[2] == constm1_rtx);
6000 return "dec{q}\t%0";
6004 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (CONST_INT_P (operands[2])
6008 /* Avoid overflows. */
6009 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6010 && (INTVAL (operands[2]) == 128
6011 || (INTVAL (operands[2]) < 0
6012 && INTVAL (operands[2]) != -128)))
6014 operands[2] = GEN_INT (-INTVAL (operands[2]));
6015 return "sub{q}\t{%2, %0|%0, %2}";
6017 return "add{q}\t{%2, %0|%0, %2}";
6021 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6022 (const_string "incdec")
6023 (const_string "alu")))
6024 (set_attr "mode" "DI")])
6027 (define_insn "*addsi_1"
6028 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6029 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6030 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6031 (clobber (reg:CC FLAGS_REG))]
6032 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6034 switch (get_attr_type (insn))
6037 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6038 return "lea{l}\t{%a2, %0|%0, %a2}";
6041 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6042 if (operands[2] == const1_rtx)
6043 return "inc{l}\t%0";
6046 gcc_assert (operands[2] == constm1_rtx);
6047 return "dec{l}\t%0";
6051 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6053 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6055 if (CONST_INT_P (operands[2])
6056 && (INTVAL (operands[2]) == 128
6057 || (INTVAL (operands[2]) < 0
6058 && INTVAL (operands[2]) != -128)))
6060 operands[2] = GEN_INT (-INTVAL (operands[2]));
6061 return "sub{l}\t{%2, %0|%0, %2}";
6063 return "add{l}\t{%2, %0|%0, %2}";
6067 (cond [(eq_attr "alternative" "2")
6068 (const_string "lea")
6069 ; Current assemblers are broken and do not allow @GOTOFF in
6070 ; ought but a memory context.
6071 (match_operand:SI 2 "pic_symbolic_operand" "")
6072 (const_string "lea")
6073 (match_operand:SI 2 "incdec_operand" "")
6074 (const_string "incdec")
6076 (const_string "alu")))
6077 (set_attr "mode" "SI")])
6079 ;; Convert lea to the lea pattern to avoid flags dependency.
6081 [(set (match_operand 0 "register_operand" "")
6082 (plus (match_operand 1 "register_operand" "")
6083 (match_operand 2 "nonmemory_operand" "")))
6084 (clobber (reg:CC FLAGS_REG))]
6086 && true_regnum (operands[0]) != true_regnum (operands[1])"
6090 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6091 may confuse gen_lowpart. */
6092 if (GET_MODE (operands[0]) != Pmode)
6094 operands[1] = gen_lowpart (Pmode, operands[1]);
6095 operands[2] = gen_lowpart (Pmode, operands[2]);
6097 operands[0] = gen_lowpart (SImode, operands[0]);
6098 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6099 if (Pmode != SImode)
6100 pat = gen_rtx_SUBREG (SImode, pat, 0);
6101 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6105 ;; It may seem that nonimmediate operand is proper one for operand 1.
6106 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6107 ;; we take care in ix86_binary_operator_ok to not allow two memory
6108 ;; operands so proper swapping will be done in reload. This allow
6109 ;; patterns constructed from addsi_1 to match.
6110 (define_insn "addsi_1_zext"
6111 [(set (match_operand:DI 0 "register_operand" "=r,r")
6113 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6114 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6115 (clobber (reg:CC FLAGS_REG))]
6116 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6118 switch (get_attr_type (insn))
6121 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6122 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6125 if (operands[2] == const1_rtx)
6126 return "inc{l}\t%k0";
6129 gcc_assert (operands[2] == constm1_rtx);
6130 return "dec{l}\t%k0";
6134 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6135 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6136 if (CONST_INT_P (operands[2])
6137 && (INTVAL (operands[2]) == 128
6138 || (INTVAL (operands[2]) < 0
6139 && INTVAL (operands[2]) != -128)))
6141 operands[2] = GEN_INT (-INTVAL (operands[2]));
6142 return "sub{l}\t{%2, %k0|%k0, %2}";
6144 return "add{l}\t{%2, %k0|%k0, %2}";
6148 (cond [(eq_attr "alternative" "1")
6149 (const_string "lea")
6150 ; Current assemblers are broken and do not allow @GOTOFF in
6151 ; ought but a memory context.
6152 (match_operand:SI 2 "pic_symbolic_operand" "")
6153 (const_string "lea")
6154 (match_operand:SI 2 "incdec_operand" "")
6155 (const_string "incdec")
6157 (const_string "alu")))
6158 (set_attr "mode" "SI")])
6160 ;; Convert lea to the lea pattern to avoid flags dependency.
6162 [(set (match_operand:DI 0 "register_operand" "")
6164 (plus:SI (match_operand:SI 1 "register_operand" "")
6165 (match_operand:SI 2 "nonmemory_operand" ""))))
6166 (clobber (reg:CC FLAGS_REG))]
6167 "TARGET_64BIT && reload_completed
6168 && true_regnum (operands[0]) != true_regnum (operands[1])"
6170 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6172 operands[1] = gen_lowpart (Pmode, operands[1]);
6173 operands[2] = gen_lowpart (Pmode, operands[2]);
6176 (define_insn "*addsi_2"
6177 [(set (reg FLAGS_REG)
6179 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6180 (match_operand:SI 2 "general_operand" "rmni,rni"))
6182 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6183 (plus:SI (match_dup 1) (match_dup 2)))]
6184 "ix86_match_ccmode (insn, CCGOCmode)
6185 && ix86_binary_operator_ok (PLUS, SImode, operands)
6186 /* Current assemblers are broken and do not allow @GOTOFF in
6187 ought but a memory context. */
6188 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6190 switch (get_attr_type (insn))
6193 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6194 if (operands[2] == const1_rtx)
6195 return "inc{l}\t%0";
6198 gcc_assert (operands[2] == constm1_rtx);
6199 return "dec{l}\t%0";
6203 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 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6219 (const_string "incdec")
6220 (const_string "alu")))
6221 (set_attr "mode" "SI")])
6223 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6224 (define_insn "*addsi_2_zext"
6225 [(set (reg FLAGS_REG)
6227 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6228 (match_operand:SI 2 "general_operand" "rmni"))
6230 (set (match_operand:DI 0 "register_operand" "=r")
6231 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6232 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6233 && ix86_binary_operator_ok (PLUS, SImode, operands)
6234 /* Current assemblers are broken and do not allow @GOTOFF in
6235 ought but a memory context. */
6236 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6238 switch (get_attr_type (insn))
6241 if (operands[2] == const1_rtx)
6242 return "inc{l}\t%k0";
6245 gcc_assert (operands[2] == constm1_rtx);
6246 return "dec{l}\t%k0";
6250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6251 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6252 if (CONST_INT_P (operands[2])
6253 && (INTVAL (operands[2]) == 128
6254 || (INTVAL (operands[2]) < 0
6255 && INTVAL (operands[2]) != -128)))
6257 operands[2] = GEN_INT (-INTVAL (operands[2]));
6258 return "sub{l}\t{%2, %k0|%k0, %2}";
6260 return "add{l}\t{%2, %k0|%k0, %2}";
6264 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6265 (const_string "incdec")
6266 (const_string "alu")))
6267 (set_attr "mode" "SI")])
6269 (define_insn "*addsi_3"
6270 [(set (reg FLAGS_REG)
6271 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6272 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6273 (clobber (match_scratch:SI 0 "=r"))]
6274 "ix86_match_ccmode (insn, CCZmode)
6275 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6276 /* Current assemblers are broken and do not allow @GOTOFF in
6277 ought but a memory context. */
6278 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6280 switch (get_attr_type (insn))
6283 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6284 if (operands[2] == const1_rtx)
6285 return "inc{l}\t%0";
6288 gcc_assert (operands[2] == constm1_rtx);
6289 return "dec{l}\t%0";
6293 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6294 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6295 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6296 if (CONST_INT_P (operands[2])
6297 && (INTVAL (operands[2]) == 128
6298 || (INTVAL (operands[2]) < 0
6299 && INTVAL (operands[2]) != -128)))
6301 operands[2] = GEN_INT (-INTVAL (operands[2]));
6302 return "sub{l}\t{%2, %0|%0, %2}";
6304 return "add{l}\t{%2, %0|%0, %2}";
6308 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6309 (const_string "incdec")
6310 (const_string "alu")))
6311 (set_attr "mode" "SI")])
6313 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6314 (define_insn "*addsi_3_zext"
6315 [(set (reg FLAGS_REG)
6316 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6317 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6318 (set (match_operand:DI 0 "register_operand" "=r")
6319 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6320 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6321 && ix86_binary_operator_ok (PLUS, SImode, operands)
6322 /* Current assemblers are broken and do not allow @GOTOFF in
6323 ought but a memory context. */
6324 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6326 switch (get_attr_type (insn))
6329 if (operands[2] == const1_rtx)
6330 return "inc{l}\t%k0";
6333 gcc_assert (operands[2] == constm1_rtx);
6334 return "dec{l}\t%k0";
6338 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6339 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6340 if (CONST_INT_P (operands[2])
6341 && (INTVAL (operands[2]) == 128
6342 || (INTVAL (operands[2]) < 0
6343 && INTVAL (operands[2]) != -128)))
6345 operands[2] = GEN_INT (-INTVAL (operands[2]));
6346 return "sub{l}\t{%2, %k0|%k0, %2}";
6348 return "add{l}\t{%2, %k0|%k0, %2}";
6352 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6353 (const_string "incdec")
6354 (const_string "alu")))
6355 (set_attr "mode" "SI")])
6357 ; For comparisons against 1, -1 and 128, we may generate better code
6358 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6359 ; is matched then. We can't accept general immediate, because for
6360 ; case of overflows, the result is messed up.
6361 ; This pattern also don't hold of 0x80000000, since the value overflows
6363 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6364 ; only for comparisons not depending on it.
6365 (define_insn "*addsi_4"
6366 [(set (reg FLAGS_REG)
6367 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6368 (match_operand:SI 2 "const_int_operand" "n")))
6369 (clobber (match_scratch:SI 0 "=rm"))]
6370 "ix86_match_ccmode (insn, CCGCmode)
6371 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6373 switch (get_attr_type (insn))
6376 if (operands[2] == constm1_rtx)
6377 return "inc{l}\t%0";
6380 gcc_assert (operands[2] == const1_rtx);
6381 return "dec{l}\t%0";
6385 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6386 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6387 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6388 if ((INTVAL (operands[2]) == -128
6389 || (INTVAL (operands[2]) > 0
6390 && INTVAL (operands[2]) != 128)))
6391 return "sub{l}\t{%2, %0|%0, %2}";
6392 operands[2] = GEN_INT (-INTVAL (operands[2]));
6393 return "add{l}\t{%2, %0|%0, %2}";
6397 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6398 (const_string "incdec")
6399 (const_string "alu")))
6400 (set_attr "mode" "SI")])
6402 (define_insn "*addsi_5"
6403 [(set (reg FLAGS_REG)
6405 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6406 (match_operand:SI 2 "general_operand" "rmni"))
6408 (clobber (match_scratch:SI 0 "=r"))]
6409 "ix86_match_ccmode (insn, CCGOCmode)
6410 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6411 /* Current assemblers are broken and do not allow @GOTOFF in
6412 ought but a memory context. */
6413 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6415 switch (get_attr_type (insn))
6418 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6419 if (operands[2] == const1_rtx)
6420 return "inc{l}\t%0";
6423 gcc_assert (operands[2] == constm1_rtx);
6424 return "dec{l}\t%0";
6428 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6429 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6430 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6431 if (CONST_INT_P (operands[2])
6432 && (INTVAL (operands[2]) == 128
6433 || (INTVAL (operands[2]) < 0
6434 && INTVAL (operands[2]) != -128)))
6436 operands[2] = GEN_INT (-INTVAL (operands[2]));
6437 return "sub{l}\t{%2, %0|%0, %2}";
6439 return "add{l}\t{%2, %0|%0, %2}";
6443 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6444 (const_string "incdec")
6445 (const_string "alu")))
6446 (set_attr "mode" "SI")])
6448 (define_expand "addhi3"
6449 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6450 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6451 (match_operand:HI 2 "general_operand" "")))
6452 (clobber (reg:CC FLAGS_REG))])]
6453 "TARGET_HIMODE_MATH"
6454 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6456 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6457 ;; type optimizations enabled by define-splits. This is not important
6458 ;; for PII, and in fact harmful because of partial register stalls.
6460 (define_insn "*addhi_1_lea"
6461 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6462 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6463 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6464 (clobber (reg:CC FLAGS_REG))]
6465 "!TARGET_PARTIAL_REG_STALL
6466 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6468 switch (get_attr_type (insn))
6473 if (operands[2] == const1_rtx)
6474 return "inc{w}\t%0";
6477 gcc_assert (operands[2] == constm1_rtx);
6478 return "dec{w}\t%0";
6482 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6483 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6484 if (CONST_INT_P (operands[2])
6485 && (INTVAL (operands[2]) == 128
6486 || (INTVAL (operands[2]) < 0
6487 && INTVAL (operands[2]) != -128)))
6489 operands[2] = GEN_INT (-INTVAL (operands[2]));
6490 return "sub{w}\t{%2, %0|%0, %2}";
6492 return "add{w}\t{%2, %0|%0, %2}";
6496 (if_then_else (eq_attr "alternative" "2")
6497 (const_string "lea")
6498 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6499 (const_string "incdec")
6500 (const_string "alu"))))
6501 (set_attr "mode" "HI,HI,SI")])
6503 (define_insn "*addhi_1"
6504 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6505 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6506 (match_operand:HI 2 "general_operand" "ri,rm")))
6507 (clobber (reg:CC FLAGS_REG))]
6508 "TARGET_PARTIAL_REG_STALL
6509 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6511 switch (get_attr_type (insn))
6514 if (operands[2] == const1_rtx)
6515 return "inc{w}\t%0";
6518 gcc_assert (operands[2] == constm1_rtx);
6519 return "dec{w}\t%0";
6523 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6524 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6525 if (CONST_INT_P (operands[2])
6526 && (INTVAL (operands[2]) == 128
6527 || (INTVAL (operands[2]) < 0
6528 && INTVAL (operands[2]) != -128)))
6530 operands[2] = GEN_INT (-INTVAL (operands[2]));
6531 return "sub{w}\t{%2, %0|%0, %2}";
6533 return "add{w}\t{%2, %0|%0, %2}";
6537 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6538 (const_string "incdec")
6539 (const_string "alu")))
6540 (set_attr "mode" "HI")])
6542 (define_insn "*addhi_2"
6543 [(set (reg FLAGS_REG)
6545 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6546 (match_operand:HI 2 "general_operand" "rmni,rni"))
6548 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6549 (plus:HI (match_dup 1) (match_dup 2)))]
6550 "ix86_match_ccmode (insn, CCGOCmode)
6551 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6553 switch (get_attr_type (insn))
6556 if (operands[2] == const1_rtx)
6557 return "inc{w}\t%0";
6560 gcc_assert (operands[2] == constm1_rtx);
6561 return "dec{w}\t%0";
6565 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6566 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6567 if (CONST_INT_P (operands[2])
6568 && (INTVAL (operands[2]) == 128
6569 || (INTVAL (operands[2]) < 0
6570 && INTVAL (operands[2]) != -128)))
6572 operands[2] = GEN_INT (-INTVAL (operands[2]));
6573 return "sub{w}\t{%2, %0|%0, %2}";
6575 return "add{w}\t{%2, %0|%0, %2}";
6579 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6580 (const_string "incdec")
6581 (const_string "alu")))
6582 (set_attr "mode" "HI")])
6584 (define_insn "*addhi_3"
6585 [(set (reg FLAGS_REG)
6586 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6587 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6588 (clobber (match_scratch:HI 0 "=r"))]
6589 "ix86_match_ccmode (insn, CCZmode)
6590 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6592 switch (get_attr_type (insn))
6595 if (operands[2] == const1_rtx)
6596 return "inc{w}\t%0";
6599 gcc_assert (operands[2] == constm1_rtx);
6600 return "dec{w}\t%0";
6604 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6606 if (CONST_INT_P (operands[2])
6607 && (INTVAL (operands[2]) == 128
6608 || (INTVAL (operands[2]) < 0
6609 && INTVAL (operands[2]) != -128)))
6611 operands[2] = GEN_INT (-INTVAL (operands[2]));
6612 return "sub{w}\t{%2, %0|%0, %2}";
6614 return "add{w}\t{%2, %0|%0, %2}";
6618 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6619 (const_string "incdec")
6620 (const_string "alu")))
6621 (set_attr "mode" "HI")])
6623 ; See comments above addsi_4 for details.
6624 (define_insn "*addhi_4"
6625 [(set (reg FLAGS_REG)
6626 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6627 (match_operand:HI 2 "const_int_operand" "n")))
6628 (clobber (match_scratch:HI 0 "=rm"))]
6629 "ix86_match_ccmode (insn, CCGCmode)
6630 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6632 switch (get_attr_type (insn))
6635 if (operands[2] == constm1_rtx)
6636 return "inc{w}\t%0";
6639 gcc_assert (operands[2] == const1_rtx);
6640 return "dec{w}\t%0";
6644 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6645 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6646 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6647 if ((INTVAL (operands[2]) == -128
6648 || (INTVAL (operands[2]) > 0
6649 && INTVAL (operands[2]) != 128)))
6650 return "sub{w}\t{%2, %0|%0, %2}";
6651 operands[2] = GEN_INT (-INTVAL (operands[2]));
6652 return "add{w}\t{%2, %0|%0, %2}";
6656 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6657 (const_string "incdec")
6658 (const_string "alu")))
6659 (set_attr "mode" "SI")])
6662 (define_insn "*addhi_5"
6663 [(set (reg FLAGS_REG)
6665 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6666 (match_operand:HI 2 "general_operand" "rmni"))
6668 (clobber (match_scratch:HI 0 "=r"))]
6669 "ix86_match_ccmode (insn, CCGOCmode)
6670 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6672 switch (get_attr_type (insn))
6675 if (operands[2] == const1_rtx)
6676 return "inc{w}\t%0";
6679 gcc_assert (operands[2] == constm1_rtx);
6680 return "dec{w}\t%0";
6684 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6685 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6686 if (CONST_INT_P (operands[2])
6687 && (INTVAL (operands[2]) == 128
6688 || (INTVAL (operands[2]) < 0
6689 && INTVAL (operands[2]) != -128)))
6691 operands[2] = GEN_INT (-INTVAL (operands[2]));
6692 return "sub{w}\t{%2, %0|%0, %2}";
6694 return "add{w}\t{%2, %0|%0, %2}";
6698 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6699 (const_string "incdec")
6700 (const_string "alu")))
6701 (set_attr "mode" "HI")])
6703 (define_expand "addqi3"
6704 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6705 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6706 (match_operand:QI 2 "general_operand" "")))
6707 (clobber (reg:CC FLAGS_REG))])]
6708 "TARGET_QIMODE_MATH"
6709 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6711 ;; %%% Potential partial reg stall on alternative 2. What to do?
6712 (define_insn "*addqi_1_lea"
6713 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6714 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6715 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6716 (clobber (reg:CC FLAGS_REG))]
6717 "!TARGET_PARTIAL_REG_STALL
6718 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6720 int widen = (which_alternative == 2);
6721 switch (get_attr_type (insn))
6726 if (operands[2] == const1_rtx)
6727 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6730 gcc_assert (operands[2] == constm1_rtx);
6731 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6735 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6736 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6737 if (CONST_INT_P (operands[2])
6738 && (INTVAL (operands[2]) == 128
6739 || (INTVAL (operands[2]) < 0
6740 && INTVAL (operands[2]) != -128)))
6742 operands[2] = GEN_INT (-INTVAL (operands[2]));
6744 return "sub{l}\t{%2, %k0|%k0, %2}";
6746 return "sub{b}\t{%2, %0|%0, %2}";
6749 return "add{l}\t{%k2, %k0|%k0, %k2}";
6751 return "add{b}\t{%2, %0|%0, %2}";
6755 (if_then_else (eq_attr "alternative" "3")
6756 (const_string "lea")
6757 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6758 (const_string "incdec")
6759 (const_string "alu"))))
6760 (set_attr "mode" "QI,QI,SI,SI")])
6762 (define_insn "*addqi_1"
6763 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6764 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6765 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6766 (clobber (reg:CC FLAGS_REG))]
6767 "TARGET_PARTIAL_REG_STALL
6768 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6770 int widen = (which_alternative == 2);
6771 switch (get_attr_type (insn))
6774 if (operands[2] == const1_rtx)
6775 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6778 gcc_assert (operands[2] == constm1_rtx);
6779 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6783 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6784 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6785 if (CONST_INT_P (operands[2])
6786 && (INTVAL (operands[2]) == 128
6787 || (INTVAL (operands[2]) < 0
6788 && INTVAL (operands[2]) != -128)))
6790 operands[2] = GEN_INT (-INTVAL (operands[2]));
6792 return "sub{l}\t{%2, %k0|%k0, %2}";
6794 return "sub{b}\t{%2, %0|%0, %2}";
6797 return "add{l}\t{%k2, %k0|%k0, %k2}";
6799 return "add{b}\t{%2, %0|%0, %2}";
6803 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6804 (const_string "incdec")
6805 (const_string "alu")))
6806 (set_attr "mode" "QI,QI,SI")])
6808 (define_insn "*addqi_1_slp"
6809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6810 (plus:QI (match_dup 0)
6811 (match_operand:QI 1 "general_operand" "qn,qnm")))
6812 (clobber (reg:CC FLAGS_REG))]
6813 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6816 switch (get_attr_type (insn))
6819 if (operands[1] == const1_rtx)
6820 return "inc{b}\t%0";
6823 gcc_assert (operands[1] == constm1_rtx);
6824 return "dec{b}\t%0";
6828 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6829 if (CONST_INT_P (operands[1])
6830 && INTVAL (operands[1]) < 0)
6832 operands[1] = GEN_INT (-INTVAL (operands[1]));
6833 return "sub{b}\t{%1, %0|%0, %1}";
6835 return "add{b}\t{%1, %0|%0, %1}";
6839 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6840 (const_string "incdec")
6841 (const_string "alu1")))
6842 (set (attr "memory")
6843 (if_then_else (match_operand 1 "memory_operand" "")
6844 (const_string "load")
6845 (const_string "none")))
6846 (set_attr "mode" "QI")])
6848 (define_insn "*addqi_2"
6849 [(set (reg FLAGS_REG)
6851 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6852 (match_operand:QI 2 "general_operand" "qmni,qni"))
6854 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6855 (plus:QI (match_dup 1) (match_dup 2)))]
6856 "ix86_match_ccmode (insn, CCGOCmode)
6857 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6859 switch (get_attr_type (insn))
6862 if (operands[2] == const1_rtx)
6863 return "inc{b}\t%0";
6866 gcc_assert (operands[2] == constm1_rtx
6867 || (CONST_INT_P (operands[2])
6868 && INTVAL (operands[2]) == 255));
6869 return "dec{b}\t%0";
6873 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6874 if (CONST_INT_P (operands[2])
6875 && INTVAL (operands[2]) < 0)
6877 operands[2] = GEN_INT (-INTVAL (operands[2]));
6878 return "sub{b}\t{%2, %0|%0, %2}";
6880 return "add{b}\t{%2, %0|%0, %2}";
6884 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6885 (const_string "incdec")
6886 (const_string "alu")))
6887 (set_attr "mode" "QI")])
6889 (define_insn "*addqi_3"
6890 [(set (reg FLAGS_REG)
6891 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6892 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6893 (clobber (match_scratch:QI 0 "=q"))]
6894 "ix86_match_ccmode (insn, CCZmode)
6895 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6897 switch (get_attr_type (insn))
6900 if (operands[2] == const1_rtx)
6901 return "inc{b}\t%0";
6904 gcc_assert (operands[2] == constm1_rtx
6905 || (CONST_INT_P (operands[2])
6906 && INTVAL (operands[2]) == 255));
6907 return "dec{b}\t%0";
6911 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6912 if (CONST_INT_P (operands[2])
6913 && INTVAL (operands[2]) < 0)
6915 operands[2] = GEN_INT (-INTVAL (operands[2]));
6916 return "sub{b}\t{%2, %0|%0, %2}";
6918 return "add{b}\t{%2, %0|%0, %2}";
6922 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6923 (const_string "incdec")
6924 (const_string "alu")))
6925 (set_attr "mode" "QI")])
6927 ; See comments above addsi_4 for details.
6928 (define_insn "*addqi_4"
6929 [(set (reg FLAGS_REG)
6930 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6931 (match_operand:QI 2 "const_int_operand" "n")))
6932 (clobber (match_scratch:QI 0 "=qm"))]
6933 "ix86_match_ccmode (insn, CCGCmode)
6934 && (INTVAL (operands[2]) & 0xff) != 0x80"
6936 switch (get_attr_type (insn))
6939 if (operands[2] == constm1_rtx
6940 || (CONST_INT_P (operands[2])
6941 && INTVAL (operands[2]) == 255))
6942 return "inc{b}\t%0";
6945 gcc_assert (operands[2] == const1_rtx);
6946 return "dec{b}\t%0";
6950 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6951 if (INTVAL (operands[2]) < 0)
6953 operands[2] = GEN_INT (-INTVAL (operands[2]));
6954 return "add{b}\t{%2, %0|%0, %2}";
6956 return "sub{b}\t{%2, %0|%0, %2}";
6960 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6961 (const_string "incdec")
6962 (const_string "alu")))
6963 (set_attr "mode" "QI")])
6966 (define_insn "*addqi_5"
6967 [(set (reg FLAGS_REG)
6969 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6970 (match_operand:QI 2 "general_operand" "qmni"))
6972 (clobber (match_scratch:QI 0 "=q"))]
6973 "ix86_match_ccmode (insn, CCGOCmode)
6974 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6976 switch (get_attr_type (insn))
6979 if (operands[2] == const1_rtx)
6980 return "inc{b}\t%0";
6983 gcc_assert (operands[2] == constm1_rtx
6984 || (CONST_INT_P (operands[2])
6985 && INTVAL (operands[2]) == 255));
6986 return "dec{b}\t%0";
6990 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6991 if (CONST_INT_P (operands[2])
6992 && INTVAL (operands[2]) < 0)
6994 operands[2] = GEN_INT (-INTVAL (operands[2]));
6995 return "sub{b}\t{%2, %0|%0, %2}";
6997 return "add{b}\t{%2, %0|%0, %2}";
7001 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7002 (const_string "incdec")
7003 (const_string "alu")))
7004 (set_attr "mode" "QI")])
7007 (define_insn "addqi_ext_1"
7008 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7013 (match_operand 1 "ext_register_operand" "0")
7016 (match_operand:QI 2 "general_operand" "Qmn")))
7017 (clobber (reg:CC FLAGS_REG))]
7020 switch (get_attr_type (insn))
7023 if (operands[2] == const1_rtx)
7024 return "inc{b}\t%h0";
7027 gcc_assert (operands[2] == constm1_rtx
7028 || (CONST_INT_P (operands[2])
7029 && INTVAL (operands[2]) == 255));
7030 return "dec{b}\t%h0";
7034 return "add{b}\t{%2, %h0|%h0, %2}";
7038 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7039 (const_string "incdec")
7040 (const_string "alu")))
7041 (set_attr "mode" "QI")])
7043 (define_insn "*addqi_ext_1_rex64"
7044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7049 (match_operand 1 "ext_register_operand" "0")
7052 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7053 (clobber (reg:CC FLAGS_REG))]
7056 switch (get_attr_type (insn))
7059 if (operands[2] == const1_rtx)
7060 return "inc{b}\t%h0";
7063 gcc_assert (operands[2] == constm1_rtx
7064 || (CONST_INT_P (operands[2])
7065 && INTVAL (operands[2]) == 255));
7066 return "dec{b}\t%h0";
7070 return "add{b}\t{%2, %h0|%h0, %2}";
7074 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7075 (const_string "incdec")
7076 (const_string "alu")))
7077 (set_attr "mode" "QI")])
7079 (define_insn "*addqi_ext_2"
7080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7085 (match_operand 1 "ext_register_operand" "%0")
7089 (match_operand 2 "ext_register_operand" "Q")
7092 (clobber (reg:CC FLAGS_REG))]
7094 "add{b}\t{%h2, %h0|%h0, %h2}"
7095 [(set_attr "type" "alu")
7096 (set_attr "mode" "QI")])
7098 ;; The patterns that match these are at the end of this file.
7100 (define_expand "addxf3"
7101 [(set (match_operand:XF 0 "register_operand" "")
7102 (plus:XF (match_operand:XF 1 "register_operand" "")
7103 (match_operand:XF 2 "register_operand" "")))]
7107 (define_expand "add<mode>3"
7108 [(set (match_operand:MODEF 0 "register_operand" "")
7109 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7110 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7111 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7114 ;; Subtract instructions
7116 ;; %%% splits for subditi3
7118 (define_expand "subti3"
7119 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7120 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7121 (match_operand:TI 2 "x86_64_general_operand" "")))
7122 (clobber (reg:CC FLAGS_REG))])]
7124 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7126 (define_insn "*subti3_1"
7127 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7128 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7129 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7130 (clobber (reg:CC FLAGS_REG))]
7131 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7135 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7136 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7137 (match_operand:TI 2 "x86_64_general_operand" "")))
7138 (clobber (reg:CC FLAGS_REG))]
7139 "TARGET_64BIT && reload_completed"
7140 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7141 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7142 (parallel [(set (match_dup 3)
7143 (minus:DI (match_dup 4)
7144 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7146 (clobber (reg:CC FLAGS_REG))])]
7147 "split_ti (operands+0, 1, operands+0, operands+3);
7148 split_ti (operands+1, 1, operands+1, operands+4);
7149 split_ti (operands+2, 1, operands+2, operands+5);")
7151 ;; %%% splits for subsidi3
7153 (define_expand "subdi3"
7154 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7155 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7156 (match_operand:DI 2 "x86_64_general_operand" "")))
7157 (clobber (reg:CC FLAGS_REG))])]
7159 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7161 (define_insn "*subdi3_1"
7162 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7163 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7164 (match_operand:DI 2 "general_operand" "roiF,riF")))
7165 (clobber (reg:CC FLAGS_REG))]
7166 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7170 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7171 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7172 (match_operand:DI 2 "general_operand" "")))
7173 (clobber (reg:CC FLAGS_REG))]
7174 "!TARGET_64BIT && reload_completed"
7175 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7176 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7177 (parallel [(set (match_dup 3)
7178 (minus:SI (match_dup 4)
7179 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7181 (clobber (reg:CC FLAGS_REG))])]
7182 "split_di (operands+0, 1, operands+0, operands+3);
7183 split_di (operands+1, 1, operands+1, operands+4);
7184 split_di (operands+2, 1, operands+2, operands+5);")
7186 (define_insn "subdi3_carry_rex64"
7187 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7188 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7189 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7190 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7191 (clobber (reg:CC FLAGS_REG))]
7192 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7193 "sbb{q}\t{%2, %0|%0, %2}"
7194 [(set_attr "type" "alu")
7195 (set_attr "pent_pair" "pu")
7196 (set_attr "mode" "DI")])
7198 (define_insn "*subdi_1_rex64"
7199 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7200 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7201 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7202 (clobber (reg:CC FLAGS_REG))]
7203 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7204 "sub{q}\t{%2, %0|%0, %2}"
7205 [(set_attr "type" "alu")
7206 (set_attr "mode" "DI")])
7208 (define_insn "*subdi_2_rex64"
7209 [(set (reg FLAGS_REG)
7211 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7212 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7214 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7215 (minus:DI (match_dup 1) (match_dup 2)))]
7216 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7217 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7218 "sub{q}\t{%2, %0|%0, %2}"
7219 [(set_attr "type" "alu")
7220 (set_attr "mode" "DI")])
7222 (define_insn "*subdi_3_rex63"
7223 [(set (reg FLAGS_REG)
7224 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7225 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7226 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7227 (minus:DI (match_dup 1) (match_dup 2)))]
7228 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7229 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7230 "sub{q}\t{%2, %0|%0, %2}"
7231 [(set_attr "type" "alu")
7232 (set_attr "mode" "DI")])
7234 (define_insn "subqi3_carry"
7235 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7236 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7237 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7238 (match_operand:QI 2 "general_operand" "qi,qm"))))
7239 (clobber (reg:CC FLAGS_REG))]
7240 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7241 "sbb{b}\t{%2, %0|%0, %2}"
7242 [(set_attr "type" "alu")
7243 (set_attr "pent_pair" "pu")
7244 (set_attr "mode" "QI")])
7246 (define_insn "subhi3_carry"
7247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7248 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7249 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7250 (match_operand:HI 2 "general_operand" "ri,rm"))))
7251 (clobber (reg:CC FLAGS_REG))]
7252 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7253 "sbb{w}\t{%2, %0|%0, %2}"
7254 [(set_attr "type" "alu")
7255 (set_attr "pent_pair" "pu")
7256 (set_attr "mode" "HI")])
7258 (define_insn "subsi3_carry"
7259 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7260 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7261 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7262 (match_operand:SI 2 "general_operand" "ri,rm"))))
7263 (clobber (reg:CC FLAGS_REG))]
7264 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7265 "sbb{l}\t{%2, %0|%0, %2}"
7266 [(set_attr "type" "alu")
7267 (set_attr "pent_pair" "pu")
7268 (set_attr "mode" "SI")])
7270 (define_insn "subsi3_carry_zext"
7271 [(set (match_operand:DI 0 "register_operand" "=r")
7273 (minus:SI (match_operand:SI 1 "register_operand" "0")
7274 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7275 (match_operand:SI 2 "general_operand" "g")))))
7276 (clobber (reg:CC FLAGS_REG))]
7277 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7278 "sbb{l}\t{%2, %k0|%k0, %2}"
7279 [(set_attr "type" "alu")
7280 (set_attr "pent_pair" "pu")
7281 (set_attr "mode" "SI")])
7283 (define_expand "subsi3"
7284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7285 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7286 (match_operand:SI 2 "general_operand" "")))
7287 (clobber (reg:CC FLAGS_REG))])]
7289 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7291 (define_insn "*subsi_1"
7292 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7293 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7294 (match_operand:SI 2 "general_operand" "ri,rm")))
7295 (clobber (reg:CC FLAGS_REG))]
7296 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7297 "sub{l}\t{%2, %0|%0, %2}"
7298 [(set_attr "type" "alu")
7299 (set_attr "mode" "SI")])
7301 (define_insn "*subsi_1_zext"
7302 [(set (match_operand:DI 0 "register_operand" "=r")
7304 (minus:SI (match_operand:SI 1 "register_operand" "0")
7305 (match_operand:SI 2 "general_operand" "g"))))
7306 (clobber (reg:CC FLAGS_REG))]
7307 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7308 "sub{l}\t{%2, %k0|%k0, %2}"
7309 [(set_attr "type" "alu")
7310 (set_attr "mode" "SI")])
7312 (define_insn "*subsi_2"
7313 [(set (reg FLAGS_REG)
7315 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7316 (match_operand:SI 2 "general_operand" "ri,rm"))
7318 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7319 (minus:SI (match_dup 1) (match_dup 2)))]
7320 "ix86_match_ccmode (insn, CCGOCmode)
7321 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7322 "sub{l}\t{%2, %0|%0, %2}"
7323 [(set_attr "type" "alu")
7324 (set_attr "mode" "SI")])
7326 (define_insn "*subsi_2_zext"
7327 [(set (reg FLAGS_REG)
7329 (minus:SI (match_operand:SI 1 "register_operand" "0")
7330 (match_operand:SI 2 "general_operand" "g"))
7332 (set (match_operand:DI 0 "register_operand" "=r")
7334 (minus:SI (match_dup 1)
7336 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7337 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7338 "sub{l}\t{%2, %k0|%k0, %2}"
7339 [(set_attr "type" "alu")
7340 (set_attr "mode" "SI")])
7342 (define_insn "*subsi_3"
7343 [(set (reg FLAGS_REG)
7344 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7345 (match_operand:SI 2 "general_operand" "ri,rm")))
7346 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7347 (minus:SI (match_dup 1) (match_dup 2)))]
7348 "ix86_match_ccmode (insn, CCmode)
7349 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7350 "sub{l}\t{%2, %0|%0, %2}"
7351 [(set_attr "type" "alu")
7352 (set_attr "mode" "SI")])
7354 (define_insn "*subsi_3_zext"
7355 [(set (reg FLAGS_REG)
7356 (compare (match_operand:SI 1 "register_operand" "0")
7357 (match_operand:SI 2 "general_operand" "g")))
7358 (set (match_operand:DI 0 "register_operand" "=r")
7360 (minus:SI (match_dup 1)
7362 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7363 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7364 "sub{l}\t{%2, %1|%1, %2}"
7365 [(set_attr "type" "alu")
7366 (set_attr "mode" "DI")])
7368 (define_expand "subhi3"
7369 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7370 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7371 (match_operand:HI 2 "general_operand" "")))
7372 (clobber (reg:CC FLAGS_REG))])]
7373 "TARGET_HIMODE_MATH"
7374 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7376 (define_insn "*subhi_1"
7377 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7378 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7379 (match_operand:HI 2 "general_operand" "ri,rm")))
7380 (clobber (reg:CC FLAGS_REG))]
7381 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7382 "sub{w}\t{%2, %0|%0, %2}"
7383 [(set_attr "type" "alu")
7384 (set_attr "mode" "HI")])
7386 (define_insn "*subhi_2"
7387 [(set (reg FLAGS_REG)
7389 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7390 (match_operand:HI 2 "general_operand" "ri,rm"))
7392 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7393 (minus:HI (match_dup 1) (match_dup 2)))]
7394 "ix86_match_ccmode (insn, CCGOCmode)
7395 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7396 "sub{w}\t{%2, %0|%0, %2}"
7397 [(set_attr "type" "alu")
7398 (set_attr "mode" "HI")])
7400 (define_insn "*subhi_3"
7401 [(set (reg FLAGS_REG)
7402 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7403 (match_operand:HI 2 "general_operand" "ri,rm")))
7404 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7405 (minus:HI (match_dup 1) (match_dup 2)))]
7406 "ix86_match_ccmode (insn, CCmode)
7407 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7408 "sub{w}\t{%2, %0|%0, %2}"
7409 [(set_attr "type" "alu")
7410 (set_attr "mode" "HI")])
7412 (define_expand "subqi3"
7413 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7414 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7415 (match_operand:QI 2 "general_operand" "")))
7416 (clobber (reg:CC FLAGS_REG))])]
7417 "TARGET_QIMODE_MATH"
7418 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7420 (define_insn "*subqi_1"
7421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7422 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7423 (match_operand:QI 2 "general_operand" "qn,qmn")))
7424 (clobber (reg:CC FLAGS_REG))]
7425 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7426 "sub{b}\t{%2, %0|%0, %2}"
7427 [(set_attr "type" "alu")
7428 (set_attr "mode" "QI")])
7430 (define_insn "*subqi_1_slp"
7431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7432 (minus:QI (match_dup 0)
7433 (match_operand:QI 1 "general_operand" "qn,qmn")))
7434 (clobber (reg:CC FLAGS_REG))]
7435 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7436 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7437 "sub{b}\t{%1, %0|%0, %1}"
7438 [(set_attr "type" "alu1")
7439 (set_attr "mode" "QI")])
7441 (define_insn "*subqi_2"
7442 [(set (reg FLAGS_REG)
7444 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7445 (match_operand:QI 2 "general_operand" "qi,qm"))
7447 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7448 (minus:HI (match_dup 1) (match_dup 2)))]
7449 "ix86_match_ccmode (insn, CCGOCmode)
7450 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7451 "sub{b}\t{%2, %0|%0, %2}"
7452 [(set_attr "type" "alu")
7453 (set_attr "mode" "QI")])
7455 (define_insn "*subqi_3"
7456 [(set (reg FLAGS_REG)
7457 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7458 (match_operand:QI 2 "general_operand" "qi,qm")))
7459 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7460 (minus:HI (match_dup 1) (match_dup 2)))]
7461 "ix86_match_ccmode (insn, CCmode)
7462 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7463 "sub{b}\t{%2, %0|%0, %2}"
7464 [(set_attr "type" "alu")
7465 (set_attr "mode" "QI")])
7467 ;; The patterns that match these are at the end of this file.
7469 (define_expand "subxf3"
7470 [(set (match_operand:XF 0 "register_operand" "")
7471 (minus:XF (match_operand:XF 1 "register_operand" "")
7472 (match_operand:XF 2 "register_operand" "")))]
7476 (define_expand "sub<mode>3"
7477 [(set (match_operand:MODEF 0 "register_operand" "")
7478 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7479 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7480 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7483 ;; Multiply instructions
7485 (define_expand "muldi3"
7486 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7487 (mult:DI (match_operand:DI 1 "register_operand" "")
7488 (match_operand:DI 2 "x86_64_general_operand" "")))
7489 (clobber (reg:CC FLAGS_REG))])]
7494 ;; IMUL reg64, reg64, imm8 Direct
7495 ;; IMUL reg64, mem64, imm8 VectorPath
7496 ;; IMUL reg64, reg64, imm32 Direct
7497 ;; IMUL reg64, mem64, imm32 VectorPath
7498 ;; IMUL reg64, reg64 Direct
7499 ;; IMUL reg64, mem64 Direct
7501 (define_insn "*muldi3_1_rex64"
7502 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7503 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7504 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7505 (clobber (reg:CC FLAGS_REG))]
7507 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7509 imul{q}\t{%2, %1, %0|%0, %1, %2}
7510 imul{q}\t{%2, %1, %0|%0, %1, %2}
7511 imul{q}\t{%2, %0|%0, %2}"
7512 [(set_attr "type" "imul")
7513 (set_attr "prefix_0f" "0,0,1")
7514 (set (attr "athlon_decode")
7515 (cond [(eq_attr "cpu" "athlon")
7516 (const_string "vector")
7517 (eq_attr "alternative" "1")
7518 (const_string "vector")
7519 (and (eq_attr "alternative" "2")
7520 (match_operand 1 "memory_operand" ""))
7521 (const_string "vector")]
7522 (const_string "direct")))
7523 (set (attr "amdfam10_decode")
7524 (cond [(and (eq_attr "alternative" "0,1")
7525 (match_operand 1 "memory_operand" ""))
7526 (const_string "vector")]
7527 (const_string "direct")))
7528 (set_attr "mode" "DI")])
7530 (define_expand "mulsi3"
7531 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7532 (mult:SI (match_operand:SI 1 "register_operand" "")
7533 (match_operand:SI 2 "general_operand" "")))
7534 (clobber (reg:CC FLAGS_REG))])]
7539 ;; IMUL reg32, reg32, imm8 Direct
7540 ;; IMUL reg32, mem32, imm8 VectorPath
7541 ;; IMUL reg32, reg32, imm32 Direct
7542 ;; IMUL reg32, mem32, imm32 VectorPath
7543 ;; IMUL reg32, reg32 Direct
7544 ;; IMUL reg32, mem32 Direct
7546 (define_insn "*mulsi3_1"
7547 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7548 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7549 (match_operand:SI 2 "general_operand" "K,i,mr")))
7550 (clobber (reg:CC FLAGS_REG))]
7551 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7553 imul{l}\t{%2, %1, %0|%0, %1, %2}
7554 imul{l}\t{%2, %1, %0|%0, %1, %2}
7555 imul{l}\t{%2, %0|%0, %2}"
7556 [(set_attr "type" "imul")
7557 (set_attr "prefix_0f" "0,0,1")
7558 (set (attr "athlon_decode")
7559 (cond [(eq_attr "cpu" "athlon")
7560 (const_string "vector")
7561 (eq_attr "alternative" "1")
7562 (const_string "vector")
7563 (and (eq_attr "alternative" "2")
7564 (match_operand 1 "memory_operand" ""))
7565 (const_string "vector")]
7566 (const_string "direct")))
7567 (set (attr "amdfam10_decode")
7568 (cond [(and (eq_attr "alternative" "0,1")
7569 (match_operand 1 "memory_operand" ""))
7570 (const_string "vector")]
7571 (const_string "direct")))
7572 (set_attr "mode" "SI")])
7574 (define_insn "*mulsi3_1_zext"
7575 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7577 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7578 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7579 (clobber (reg:CC FLAGS_REG))]
7581 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7583 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7584 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7585 imul{l}\t{%2, %k0|%k0, %2}"
7586 [(set_attr "type" "imul")
7587 (set_attr "prefix_0f" "0,0,1")
7588 (set (attr "athlon_decode")
7589 (cond [(eq_attr "cpu" "athlon")
7590 (const_string "vector")
7591 (eq_attr "alternative" "1")
7592 (const_string "vector")
7593 (and (eq_attr "alternative" "2")
7594 (match_operand 1 "memory_operand" ""))
7595 (const_string "vector")]
7596 (const_string "direct")))
7597 (set (attr "amdfam10_decode")
7598 (cond [(and (eq_attr "alternative" "0,1")
7599 (match_operand 1 "memory_operand" ""))
7600 (const_string "vector")]
7601 (const_string "direct")))
7602 (set_attr "mode" "SI")])
7604 (define_expand "mulhi3"
7605 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7606 (mult:HI (match_operand:HI 1 "register_operand" "")
7607 (match_operand:HI 2 "general_operand" "")))
7608 (clobber (reg:CC FLAGS_REG))])]
7609 "TARGET_HIMODE_MATH"
7613 ;; IMUL reg16, reg16, imm8 VectorPath
7614 ;; IMUL reg16, mem16, imm8 VectorPath
7615 ;; IMUL reg16, reg16, imm16 VectorPath
7616 ;; IMUL reg16, mem16, imm16 VectorPath
7617 ;; IMUL reg16, reg16 Direct
7618 ;; IMUL reg16, mem16 Direct
7619 (define_insn "*mulhi3_1"
7620 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7621 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7622 (match_operand:HI 2 "general_operand" "K,i,mr")))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7626 imul{w}\t{%2, %1, %0|%0, %1, %2}
7627 imul{w}\t{%2, %1, %0|%0, %1, %2}
7628 imul{w}\t{%2, %0|%0, %2}"
7629 [(set_attr "type" "imul")
7630 (set_attr "prefix_0f" "0,0,1")
7631 (set (attr "athlon_decode")
7632 (cond [(eq_attr "cpu" "athlon")
7633 (const_string "vector")
7634 (eq_attr "alternative" "1,2")
7635 (const_string "vector")]
7636 (const_string "direct")))
7637 (set (attr "amdfam10_decode")
7638 (cond [(eq_attr "alternative" "0,1")
7639 (const_string "vector")]
7640 (const_string "direct")))
7641 (set_attr "mode" "HI")])
7643 (define_expand "mulqi3"
7644 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7645 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7646 (match_operand:QI 2 "register_operand" "")))
7647 (clobber (reg:CC FLAGS_REG))])]
7648 "TARGET_QIMODE_MATH"
7655 (define_insn "*mulqi3_1"
7656 [(set (match_operand:QI 0 "register_operand" "=a")
7657 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7658 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7659 (clobber (reg:CC FLAGS_REG))]
7661 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663 [(set_attr "type" "imul")
7664 (set_attr "length_immediate" "0")
7665 (set (attr "athlon_decode")
7666 (if_then_else (eq_attr "cpu" "athlon")
7667 (const_string "vector")
7668 (const_string "direct")))
7669 (set_attr "amdfam10_decode" "direct")
7670 (set_attr "mode" "QI")])
7672 (define_expand "umulqihi3"
7673 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7674 (mult:HI (zero_extend:HI
7675 (match_operand:QI 1 "nonimmediate_operand" ""))
7677 (match_operand:QI 2 "register_operand" ""))))
7678 (clobber (reg:CC FLAGS_REG))])]
7679 "TARGET_QIMODE_MATH"
7682 (define_insn "*umulqihi3_1"
7683 [(set (match_operand:HI 0 "register_operand" "=a")
7684 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7685 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7686 (clobber (reg:CC FLAGS_REG))]
7688 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7690 [(set_attr "type" "imul")
7691 (set_attr "length_immediate" "0")
7692 (set (attr "athlon_decode")
7693 (if_then_else (eq_attr "cpu" "athlon")
7694 (const_string "vector")
7695 (const_string "direct")))
7696 (set_attr "amdfam10_decode" "direct")
7697 (set_attr "mode" "QI")])
7699 (define_expand "mulqihi3"
7700 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7701 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7702 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7703 (clobber (reg:CC FLAGS_REG))])]
7704 "TARGET_QIMODE_MATH"
7707 (define_insn "*mulqihi3_insn"
7708 [(set (match_operand:HI 0 "register_operand" "=a")
7709 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7710 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7711 (clobber (reg:CC FLAGS_REG))]
7713 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7715 [(set_attr "type" "imul")
7716 (set_attr "length_immediate" "0")
7717 (set (attr "athlon_decode")
7718 (if_then_else (eq_attr "cpu" "athlon")
7719 (const_string "vector")
7720 (const_string "direct")))
7721 (set_attr "amdfam10_decode" "direct")
7722 (set_attr "mode" "QI")])
7724 (define_expand "umulditi3"
7725 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7726 (mult:TI (zero_extend:TI
7727 (match_operand:DI 1 "nonimmediate_operand" ""))
7729 (match_operand:DI 2 "register_operand" ""))))
7730 (clobber (reg:CC FLAGS_REG))])]
7734 (define_insn "*umulditi3_insn"
7735 [(set (match_operand:TI 0 "register_operand" "=A")
7736 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7737 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7738 (clobber (reg:CC FLAGS_REG))]
7740 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7742 [(set_attr "type" "imul")
7743 (set_attr "length_immediate" "0")
7744 (set (attr "athlon_decode")
7745 (if_then_else (eq_attr "cpu" "athlon")
7746 (const_string "vector")
7747 (const_string "double")))
7748 (set_attr "amdfam10_decode" "double")
7749 (set_attr "mode" "DI")])
7751 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7752 (define_expand "umulsidi3"
7753 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7754 (mult:DI (zero_extend:DI
7755 (match_operand:SI 1 "nonimmediate_operand" ""))
7757 (match_operand:SI 2 "register_operand" ""))))
7758 (clobber (reg:CC FLAGS_REG))])]
7762 (define_insn "*umulsidi3_insn"
7763 [(set (match_operand:DI 0 "register_operand" "=A")
7764 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7765 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7766 (clobber (reg:CC FLAGS_REG))]
7768 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7770 [(set_attr "type" "imul")
7771 (set_attr "length_immediate" "0")
7772 (set (attr "athlon_decode")
7773 (if_then_else (eq_attr "cpu" "athlon")
7774 (const_string "vector")
7775 (const_string "double")))
7776 (set_attr "amdfam10_decode" "double")
7777 (set_attr "mode" "SI")])
7779 (define_expand "mulditi3"
7780 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7781 (mult:TI (sign_extend:TI
7782 (match_operand:DI 1 "nonimmediate_operand" ""))
7784 (match_operand:DI 2 "register_operand" ""))))
7785 (clobber (reg:CC FLAGS_REG))])]
7789 (define_insn "*mulditi3_insn"
7790 [(set (match_operand:TI 0 "register_operand" "=A")
7791 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7792 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7793 (clobber (reg:CC FLAGS_REG))]
7795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7797 [(set_attr "type" "imul")
7798 (set_attr "length_immediate" "0")
7799 (set (attr "athlon_decode")
7800 (if_then_else (eq_attr "cpu" "athlon")
7801 (const_string "vector")
7802 (const_string "double")))
7803 (set_attr "amdfam10_decode" "double")
7804 (set_attr "mode" "DI")])
7806 (define_expand "mulsidi3"
7807 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7808 (mult:DI (sign_extend:DI
7809 (match_operand:SI 1 "nonimmediate_operand" ""))
7811 (match_operand:SI 2 "register_operand" ""))))
7812 (clobber (reg:CC FLAGS_REG))])]
7816 (define_insn "*mulsidi3_insn"
7817 [(set (match_operand:DI 0 "register_operand" "=A")
7818 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7819 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7820 (clobber (reg:CC FLAGS_REG))]
7822 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7824 [(set_attr "type" "imul")
7825 (set_attr "length_immediate" "0")
7826 (set (attr "athlon_decode")
7827 (if_then_else (eq_attr "cpu" "athlon")
7828 (const_string "vector")
7829 (const_string "double")))
7830 (set_attr "amdfam10_decode" "double")
7831 (set_attr "mode" "SI")])
7833 (define_expand "umuldi3_highpart"
7834 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7837 (mult:TI (zero_extend:TI
7838 (match_operand:DI 1 "nonimmediate_operand" ""))
7840 (match_operand:DI 2 "register_operand" "")))
7842 (clobber (match_scratch:DI 3 ""))
7843 (clobber (reg:CC FLAGS_REG))])]
7847 (define_insn "*umuldi3_highpart_rex64"
7848 [(set (match_operand:DI 0 "register_operand" "=d")
7851 (mult:TI (zero_extend:TI
7852 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7854 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7856 (clobber (match_scratch:DI 3 "=1"))
7857 (clobber (reg:CC FLAGS_REG))]
7859 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7861 [(set_attr "type" "imul")
7862 (set_attr "length_immediate" "0")
7863 (set (attr "athlon_decode")
7864 (if_then_else (eq_attr "cpu" "athlon")
7865 (const_string "vector")
7866 (const_string "double")))
7867 (set_attr "amdfam10_decode" "double")
7868 (set_attr "mode" "DI")])
7870 (define_expand "umulsi3_highpart"
7871 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7874 (mult:DI (zero_extend:DI
7875 (match_operand:SI 1 "nonimmediate_operand" ""))
7877 (match_operand:SI 2 "register_operand" "")))
7879 (clobber (match_scratch:SI 3 ""))
7880 (clobber (reg:CC FLAGS_REG))])]
7884 (define_insn "*umulsi3_highpart_insn"
7885 [(set (match_operand:SI 0 "register_operand" "=d")
7888 (mult:DI (zero_extend:DI
7889 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7891 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7893 (clobber (match_scratch:SI 3 "=1"))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7897 [(set_attr "type" "imul")
7898 (set_attr "length_immediate" "0")
7899 (set (attr "athlon_decode")
7900 (if_then_else (eq_attr "cpu" "athlon")
7901 (const_string "vector")
7902 (const_string "double")))
7903 (set_attr "amdfam10_decode" "double")
7904 (set_attr "mode" "SI")])
7906 (define_insn "*umulsi3_highpart_zext"
7907 [(set (match_operand:DI 0 "register_operand" "=d")
7908 (zero_extend:DI (truncate:SI
7910 (mult:DI (zero_extend:DI
7911 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7913 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7915 (clobber (match_scratch:SI 3 "=1"))
7916 (clobber (reg:CC FLAGS_REG))]
7918 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7920 [(set_attr "type" "imul")
7921 (set_attr "length_immediate" "0")
7922 (set (attr "athlon_decode")
7923 (if_then_else (eq_attr "cpu" "athlon")
7924 (const_string "vector")
7925 (const_string "double")))
7926 (set_attr "amdfam10_decode" "double")
7927 (set_attr "mode" "SI")])
7929 (define_expand "smuldi3_highpart"
7930 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7933 (mult:TI (sign_extend:TI
7934 (match_operand:DI 1 "nonimmediate_operand" ""))
7936 (match_operand:DI 2 "register_operand" "")))
7938 (clobber (match_scratch:DI 3 ""))
7939 (clobber (reg:CC FLAGS_REG))])]
7943 (define_insn "*smuldi3_highpart_rex64"
7944 [(set (match_operand:DI 0 "register_operand" "=d")
7947 (mult:TI (sign_extend:TI
7948 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7950 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7952 (clobber (match_scratch:DI 3 "=1"))
7953 (clobber (reg:CC FLAGS_REG))]
7955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7957 [(set_attr "type" "imul")
7958 (set (attr "athlon_decode")
7959 (if_then_else (eq_attr "cpu" "athlon")
7960 (const_string "vector")
7961 (const_string "double")))
7962 (set_attr "amdfam10_decode" "double")
7963 (set_attr "mode" "DI")])
7965 (define_expand "smulsi3_highpart"
7966 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7969 (mult:DI (sign_extend:DI
7970 (match_operand:SI 1 "nonimmediate_operand" ""))
7972 (match_operand:SI 2 "register_operand" "")))
7974 (clobber (match_scratch:SI 3 ""))
7975 (clobber (reg:CC FLAGS_REG))])]
7979 (define_insn "*smulsi3_highpart_insn"
7980 [(set (match_operand:SI 0 "register_operand" "=d")
7983 (mult:DI (sign_extend:DI
7984 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7986 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7988 (clobber (match_scratch:SI 3 "=1"))
7989 (clobber (reg:CC FLAGS_REG))]
7990 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7992 [(set_attr "type" "imul")
7993 (set (attr "athlon_decode")
7994 (if_then_else (eq_attr "cpu" "athlon")
7995 (const_string "vector")
7996 (const_string "double")))
7997 (set_attr "amdfam10_decode" "double")
7998 (set_attr "mode" "SI")])
8000 (define_insn "*smulsi3_highpart_zext"
8001 [(set (match_operand:DI 0 "register_operand" "=d")
8002 (zero_extend:DI (truncate:SI
8004 (mult:DI (sign_extend:DI
8005 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8007 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8009 (clobber (match_scratch:SI 3 "=1"))
8010 (clobber (reg:CC FLAGS_REG))]
8012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8014 [(set_attr "type" "imul")
8015 (set (attr "athlon_decode")
8016 (if_then_else (eq_attr "cpu" "athlon")
8017 (const_string "vector")
8018 (const_string "double")))
8019 (set_attr "amdfam10_decode" "double")
8020 (set_attr "mode" "SI")])
8022 ;; The patterns that match these are at the end of this file.
8024 (define_expand "mulxf3"
8025 [(set (match_operand:XF 0 "register_operand" "")
8026 (mult:XF (match_operand:XF 1 "register_operand" "")
8027 (match_operand:XF 2 "register_operand" "")))]
8031 (define_expand "mul<mode>3"
8032 [(set (match_operand:MODEF 0 "register_operand" "")
8033 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8034 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8035 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8038 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8041 ;; Divide instructions
8043 (define_insn "divqi3"
8044 [(set (match_operand:QI 0 "register_operand" "=a")
8045 (div:QI (match_operand:HI 1 "register_operand" "0")
8046 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8047 (clobber (reg:CC FLAGS_REG))]
8048 "TARGET_QIMODE_MATH"
8050 [(set_attr "type" "idiv")
8051 (set_attr "mode" "QI")])
8053 (define_insn "udivqi3"
8054 [(set (match_operand:QI 0 "register_operand" "=a")
8055 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8056 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8057 (clobber (reg:CC FLAGS_REG))]
8058 "TARGET_QIMODE_MATH"
8060 [(set_attr "type" "idiv")
8061 (set_attr "mode" "QI")])
8063 ;; The patterns that match these are at the end of this file.
8065 (define_expand "divxf3"
8066 [(set (match_operand:XF 0 "register_operand" "")
8067 (div:XF (match_operand:XF 1 "register_operand" "")
8068 (match_operand:XF 2 "register_operand" "")))]
8072 (define_expand "divdf3"
8073 [(set (match_operand:DF 0 "register_operand" "")
8074 (div:DF (match_operand:DF 1 "register_operand" "")
8075 (match_operand:DF 2 "nonimmediate_operand" "")))]
8076 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8079 (define_expand "divsf3"
8080 [(set (match_operand:SF 0 "register_operand" "")
8081 (div:SF (match_operand:SF 1 "register_operand" "")
8082 (match_operand:SF 2 "nonimmediate_operand" "")))]
8083 "TARGET_80387 || TARGET_SSE_MATH"
8085 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8086 && flag_finite_math_only && !flag_trapping_math
8087 && flag_unsafe_math_optimizations)
8089 ix86_emit_swdivsf (operands[0], operands[1],
8090 operands[2], SFmode);
8095 ;; Remainder instructions.
8097 (define_expand "divmoddi4"
8098 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8099 (div:DI (match_operand:DI 1 "register_operand" "")
8100 (match_operand:DI 2 "nonimmediate_operand" "")))
8101 (set (match_operand:DI 3 "register_operand" "")
8102 (mod:DI (match_dup 1) (match_dup 2)))
8103 (clobber (reg:CC FLAGS_REG))])]
8107 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8108 ;; Penalize eax case slightly because it results in worse scheduling
8110 (define_insn "*divmoddi4_nocltd_rex64"
8111 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8112 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8113 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8114 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8115 (mod:DI (match_dup 2) (match_dup 3)))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8119 [(set_attr "type" "multi")])
8121 (define_insn "*divmoddi4_cltd_rex64"
8122 [(set (match_operand:DI 0 "register_operand" "=a")
8123 (div:DI (match_operand:DI 2 "register_operand" "a")
8124 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8125 (set (match_operand:DI 1 "register_operand" "=&d")
8126 (mod:DI (match_dup 2) (match_dup 3)))
8127 (clobber (reg:CC FLAGS_REG))]
8128 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8130 [(set_attr "type" "multi")])
8132 (define_insn "*divmoddi_noext_rex64"
8133 [(set (match_operand:DI 0 "register_operand" "=a")
8134 (div:DI (match_operand:DI 1 "register_operand" "0")
8135 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8136 (set (match_operand:DI 3 "register_operand" "=d")
8137 (mod:DI (match_dup 1) (match_dup 2)))
8138 (use (match_operand:DI 4 "register_operand" "3"))
8139 (clobber (reg:CC FLAGS_REG))]
8142 [(set_attr "type" "idiv")
8143 (set_attr "mode" "DI")])
8146 [(set (match_operand:DI 0 "register_operand" "")
8147 (div:DI (match_operand:DI 1 "register_operand" "")
8148 (match_operand:DI 2 "nonimmediate_operand" "")))
8149 (set (match_operand:DI 3 "register_operand" "")
8150 (mod:DI (match_dup 1) (match_dup 2)))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "TARGET_64BIT && reload_completed"
8153 [(parallel [(set (match_dup 3)
8154 (ashiftrt:DI (match_dup 4) (const_int 63)))
8155 (clobber (reg:CC FLAGS_REG))])
8156 (parallel [(set (match_dup 0)
8157 (div:DI (reg:DI 0) (match_dup 2)))
8159 (mod:DI (reg:DI 0) (match_dup 2)))
8161 (clobber (reg:CC FLAGS_REG))])]
8163 /* Avoid use of cltd in favor of a mov+shift. */
8164 if (!TARGET_USE_CLTD && !optimize_size)
8166 if (true_regnum (operands[1]))
8167 emit_move_insn (operands[0], operands[1]);
8169 emit_move_insn (operands[3], operands[1]);
8170 operands[4] = operands[3];
8174 gcc_assert (!true_regnum (operands[1]));
8175 operands[4] = operands[1];
8180 (define_expand "divmodsi4"
8181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8182 (div:SI (match_operand:SI 1 "register_operand" "")
8183 (match_operand:SI 2 "nonimmediate_operand" "")))
8184 (set (match_operand:SI 3 "register_operand" "")
8185 (mod:SI (match_dup 1) (match_dup 2)))
8186 (clobber (reg:CC FLAGS_REG))])]
8190 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8191 ;; Penalize eax case slightly because it results in worse scheduling
8193 (define_insn "*divmodsi4_nocltd"
8194 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8195 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8196 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8197 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8198 (mod:SI (match_dup 2) (match_dup 3)))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "!optimize_size && !TARGET_USE_CLTD"
8202 [(set_attr "type" "multi")])
8204 (define_insn "*divmodsi4_cltd"
8205 [(set (match_operand:SI 0 "register_operand" "=a")
8206 (div:SI (match_operand:SI 2 "register_operand" "a")
8207 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8208 (set (match_operand:SI 1 "register_operand" "=&d")
8209 (mod:SI (match_dup 2) (match_dup 3)))
8210 (clobber (reg:CC FLAGS_REG))]
8211 "optimize_size || TARGET_USE_CLTD"
8213 [(set_attr "type" "multi")])
8215 (define_insn "*divmodsi_noext"
8216 [(set (match_operand:SI 0 "register_operand" "=a")
8217 (div:SI (match_operand:SI 1 "register_operand" "0")
8218 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8219 (set (match_operand:SI 3 "register_operand" "=d")
8220 (mod:SI (match_dup 1) (match_dup 2)))
8221 (use (match_operand:SI 4 "register_operand" "3"))
8222 (clobber (reg:CC FLAGS_REG))]
8225 [(set_attr "type" "idiv")
8226 (set_attr "mode" "SI")])
8229 [(set (match_operand:SI 0 "register_operand" "")
8230 (div:SI (match_operand:SI 1 "register_operand" "")
8231 (match_operand:SI 2 "nonimmediate_operand" "")))
8232 (set (match_operand:SI 3 "register_operand" "")
8233 (mod:SI (match_dup 1) (match_dup 2)))
8234 (clobber (reg:CC FLAGS_REG))]
8236 [(parallel [(set (match_dup 3)
8237 (ashiftrt:SI (match_dup 4) (const_int 31)))
8238 (clobber (reg:CC FLAGS_REG))])
8239 (parallel [(set (match_dup 0)
8240 (div:SI (reg:SI 0) (match_dup 2)))
8242 (mod:SI (reg:SI 0) (match_dup 2)))
8244 (clobber (reg:CC FLAGS_REG))])]
8246 /* Avoid use of cltd in favor of a mov+shift. */
8247 if (!TARGET_USE_CLTD && !optimize_size)
8249 if (true_regnum (operands[1]))
8250 emit_move_insn (operands[0], operands[1]);
8252 emit_move_insn (operands[3], operands[1]);
8253 operands[4] = operands[3];
8257 gcc_assert (!true_regnum (operands[1]));
8258 operands[4] = operands[1];
8262 (define_insn "divmodhi4"
8263 [(set (match_operand:HI 0 "register_operand" "=a")
8264 (div:HI (match_operand:HI 1 "register_operand" "0")
8265 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8266 (set (match_operand:HI 3 "register_operand" "=&d")
8267 (mod:HI (match_dup 1) (match_dup 2)))
8268 (clobber (reg:CC FLAGS_REG))]
8269 "TARGET_HIMODE_MATH"
8271 [(set_attr "type" "multi")
8272 (set_attr "length_immediate" "0")
8273 (set_attr "mode" "SI")])
8275 (define_insn "udivmoddi4"
8276 [(set (match_operand:DI 0 "register_operand" "=a")
8277 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8278 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8279 (set (match_operand:DI 3 "register_operand" "=&d")
8280 (umod:DI (match_dup 1) (match_dup 2)))
8281 (clobber (reg:CC FLAGS_REG))]
8283 "xor{q}\t%3, %3\;div{q}\t%2"
8284 [(set_attr "type" "multi")
8285 (set_attr "length_immediate" "0")
8286 (set_attr "mode" "DI")])
8288 (define_insn "*udivmoddi4_noext"
8289 [(set (match_operand:DI 0 "register_operand" "=a")
8290 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8291 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8292 (set (match_operand:DI 3 "register_operand" "=d")
8293 (umod:DI (match_dup 1) (match_dup 2)))
8295 (clobber (reg:CC FLAGS_REG))]
8298 [(set_attr "type" "idiv")
8299 (set_attr "mode" "DI")])
8302 [(set (match_operand:DI 0 "register_operand" "")
8303 (udiv:DI (match_operand:DI 1 "register_operand" "")
8304 (match_operand:DI 2 "nonimmediate_operand" "")))
8305 (set (match_operand:DI 3 "register_operand" "")
8306 (umod:DI (match_dup 1) (match_dup 2)))
8307 (clobber (reg:CC FLAGS_REG))]
8308 "TARGET_64BIT && reload_completed"
8309 [(set (match_dup 3) (const_int 0))
8310 (parallel [(set (match_dup 0)
8311 (udiv:DI (match_dup 1) (match_dup 2)))
8313 (umod:DI (match_dup 1) (match_dup 2)))
8315 (clobber (reg:CC FLAGS_REG))])]
8318 (define_insn "udivmodsi4"
8319 [(set (match_operand:SI 0 "register_operand" "=a")
8320 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8321 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8322 (set (match_operand:SI 3 "register_operand" "=&d")
8323 (umod:SI (match_dup 1) (match_dup 2)))
8324 (clobber (reg:CC FLAGS_REG))]
8326 "xor{l}\t%3, %3\;div{l}\t%2"
8327 [(set_attr "type" "multi")
8328 (set_attr "length_immediate" "0")
8329 (set_attr "mode" "SI")])
8331 (define_insn "*udivmodsi4_noext"
8332 [(set (match_operand:SI 0 "register_operand" "=a")
8333 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8334 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8335 (set (match_operand:SI 3 "register_operand" "=d")
8336 (umod:SI (match_dup 1) (match_dup 2)))
8338 (clobber (reg:CC FLAGS_REG))]
8341 [(set_attr "type" "idiv")
8342 (set_attr "mode" "SI")])
8345 [(set (match_operand:SI 0 "register_operand" "")
8346 (udiv:SI (match_operand:SI 1 "register_operand" "")
8347 (match_operand:SI 2 "nonimmediate_operand" "")))
8348 (set (match_operand:SI 3 "register_operand" "")
8349 (umod:SI (match_dup 1) (match_dup 2)))
8350 (clobber (reg:CC FLAGS_REG))]
8352 [(set (match_dup 3) (const_int 0))
8353 (parallel [(set (match_dup 0)
8354 (udiv:SI (match_dup 1) (match_dup 2)))
8356 (umod:SI (match_dup 1) (match_dup 2)))
8358 (clobber (reg:CC FLAGS_REG))])]
8361 (define_expand "udivmodhi4"
8362 [(set (match_dup 4) (const_int 0))
8363 (parallel [(set (match_operand:HI 0 "register_operand" "")
8364 (udiv:HI (match_operand:HI 1 "register_operand" "")
8365 (match_operand:HI 2 "nonimmediate_operand" "")))
8366 (set (match_operand:HI 3 "register_operand" "")
8367 (umod:HI (match_dup 1) (match_dup 2)))
8369 (clobber (reg:CC FLAGS_REG))])]
8370 "TARGET_HIMODE_MATH"
8371 "operands[4] = gen_reg_rtx (HImode);")
8373 (define_insn "*udivmodhi_noext"
8374 [(set (match_operand:HI 0 "register_operand" "=a")
8375 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8376 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8377 (set (match_operand:HI 3 "register_operand" "=d")
8378 (umod:HI (match_dup 1) (match_dup 2)))
8379 (use (match_operand:HI 4 "register_operand" "3"))
8380 (clobber (reg:CC FLAGS_REG))]
8383 [(set_attr "type" "idiv")
8384 (set_attr "mode" "HI")])
8386 ;; We cannot use div/idiv for double division, because it causes
8387 ;; "division by zero" on the overflow and that's not what we expect
8388 ;; from truncate. Because true (non truncating) double division is
8389 ;; never generated, we can't create this insn anyway.
8392 ; [(set (match_operand:SI 0 "register_operand" "=a")
8394 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8396 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8397 ; (set (match_operand:SI 3 "register_operand" "=d")
8399 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8400 ; (clobber (reg:CC FLAGS_REG))]
8402 ; "div{l}\t{%2, %0|%0, %2}"
8403 ; [(set_attr "type" "idiv")])
8405 ;;- Logical AND instructions
8407 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8408 ;; Note that this excludes ah.
8410 (define_insn "*testdi_1_rex64"
8411 [(set (reg FLAGS_REG)
8413 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8414 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8416 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8419 test{l}\t{%k1, %k0|%k0, %k1}
8420 test{l}\t{%k1, %k0|%k0, %k1}
8421 test{q}\t{%1, %0|%0, %1}
8422 test{q}\t{%1, %0|%0, %1}
8423 test{q}\t{%1, %0|%0, %1}"
8424 [(set_attr "type" "test")
8425 (set_attr "modrm" "0,1,0,1,1")
8426 (set_attr "mode" "SI,SI,DI,DI,DI")
8427 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8429 (define_insn "testsi_1"
8430 [(set (reg FLAGS_REG)
8432 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8433 (match_operand:SI 1 "general_operand" "in,in,rin"))
8435 "ix86_match_ccmode (insn, CCNOmode)
8436 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8437 "test{l}\t{%1, %0|%0, %1}"
8438 [(set_attr "type" "test")
8439 (set_attr "modrm" "0,1,1")
8440 (set_attr "mode" "SI")
8441 (set_attr "pent_pair" "uv,np,uv")])
8443 (define_expand "testsi_ccno_1"
8444 [(set (reg:CCNO FLAGS_REG)
8446 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8447 (match_operand:SI 1 "nonmemory_operand" ""))
8452 (define_insn "*testhi_1"
8453 [(set (reg FLAGS_REG)
8454 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8455 (match_operand:HI 1 "general_operand" "n,n,rn"))
8457 "ix86_match_ccmode (insn, CCNOmode)
8458 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8459 "test{w}\t{%1, %0|%0, %1}"
8460 [(set_attr "type" "test")
8461 (set_attr "modrm" "0,1,1")
8462 (set_attr "mode" "HI")
8463 (set_attr "pent_pair" "uv,np,uv")])
8465 (define_expand "testqi_ccz_1"
8466 [(set (reg:CCZ FLAGS_REG)
8467 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8468 (match_operand:QI 1 "nonmemory_operand" ""))
8473 (define_insn "*testqi_1_maybe_si"
8474 [(set (reg FLAGS_REG)
8477 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8478 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8480 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8481 && ix86_match_ccmode (insn,
8482 CONST_INT_P (operands[1])
8483 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8485 if (which_alternative == 3)
8487 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8488 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8489 return "test{l}\t{%1, %k0|%k0, %1}";
8491 return "test{b}\t{%1, %0|%0, %1}";
8493 [(set_attr "type" "test")
8494 (set_attr "modrm" "0,1,1,1")
8495 (set_attr "mode" "QI,QI,QI,SI")
8496 (set_attr "pent_pair" "uv,np,uv,np")])
8498 (define_insn "*testqi_1"
8499 [(set (reg FLAGS_REG)
8502 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8503 (match_operand:QI 1 "general_operand" "n,n,qn"))
8505 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8506 && ix86_match_ccmode (insn, CCNOmode)"
8507 "test{b}\t{%1, %0|%0, %1}"
8508 [(set_attr "type" "test")
8509 (set_attr "modrm" "0,1,1")
8510 (set_attr "mode" "QI")
8511 (set_attr "pent_pair" "uv,np,uv")])
8513 (define_expand "testqi_ext_ccno_0"
8514 [(set (reg:CCNO FLAGS_REG)
8518 (match_operand 0 "ext_register_operand" "")
8521 (match_operand 1 "const_int_operand" ""))
8526 (define_insn "*testqi_ext_0"
8527 [(set (reg FLAGS_REG)
8531 (match_operand 0 "ext_register_operand" "Q")
8534 (match_operand 1 "const_int_operand" "n"))
8536 "ix86_match_ccmode (insn, CCNOmode)"
8537 "test{b}\t{%1, %h0|%h0, %1}"
8538 [(set_attr "type" "test")
8539 (set_attr "mode" "QI")
8540 (set_attr "length_immediate" "1")
8541 (set_attr "pent_pair" "np")])
8543 (define_insn "*testqi_ext_1"
8544 [(set (reg FLAGS_REG)
8548 (match_operand 0 "ext_register_operand" "Q")
8552 (match_operand:QI 1 "general_operand" "Qm")))
8554 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8555 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8556 "test{b}\t{%1, %h0|%h0, %1}"
8557 [(set_attr "type" "test")
8558 (set_attr "mode" "QI")])
8560 (define_insn "*testqi_ext_1_rex64"
8561 [(set (reg FLAGS_REG)
8565 (match_operand 0 "ext_register_operand" "Q")
8569 (match_operand:QI 1 "register_operand" "Q")))
8571 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8572 "test{b}\t{%1, %h0|%h0, %1}"
8573 [(set_attr "type" "test")
8574 (set_attr "mode" "QI")])
8576 (define_insn "*testqi_ext_2"
8577 [(set (reg FLAGS_REG)
8581 (match_operand 0 "ext_register_operand" "Q")
8585 (match_operand 1 "ext_register_operand" "Q")
8589 "ix86_match_ccmode (insn, CCNOmode)"
8590 "test{b}\t{%h1, %h0|%h0, %h1}"
8591 [(set_attr "type" "test")
8592 (set_attr "mode" "QI")])
8594 ;; Combine likes to form bit extractions for some tests. Humor it.
8595 (define_insn "*testqi_ext_3"
8596 [(set (reg FLAGS_REG)
8597 (compare (zero_extract:SI
8598 (match_operand 0 "nonimmediate_operand" "rm")
8599 (match_operand:SI 1 "const_int_operand" "")
8600 (match_operand:SI 2 "const_int_operand" ""))
8602 "ix86_match_ccmode (insn, CCNOmode)
8603 && INTVAL (operands[1]) > 0
8604 && INTVAL (operands[2]) >= 0
8605 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8606 && (GET_MODE (operands[0]) == SImode
8607 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8608 || GET_MODE (operands[0]) == HImode
8609 || GET_MODE (operands[0]) == QImode)"
8612 (define_insn "*testqi_ext_3_rex64"
8613 [(set (reg FLAGS_REG)
8614 (compare (zero_extract:DI
8615 (match_operand 0 "nonimmediate_operand" "rm")
8616 (match_operand:DI 1 "const_int_operand" "")
8617 (match_operand:DI 2 "const_int_operand" ""))
8620 && ix86_match_ccmode (insn, CCNOmode)
8621 && INTVAL (operands[1]) > 0
8622 && INTVAL (operands[2]) >= 0
8623 /* Ensure that resulting mask is zero or sign extended operand. */
8624 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8625 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8626 && INTVAL (operands[1]) > 32))
8627 && (GET_MODE (operands[0]) == SImode
8628 || GET_MODE (operands[0]) == DImode
8629 || GET_MODE (operands[0]) == HImode
8630 || GET_MODE (operands[0]) == QImode)"
8634 [(set (match_operand 0 "flags_reg_operand" "")
8635 (match_operator 1 "compare_operator"
8637 (match_operand 2 "nonimmediate_operand" "")
8638 (match_operand 3 "const_int_operand" "")
8639 (match_operand 4 "const_int_operand" ""))
8641 "ix86_match_ccmode (insn, CCNOmode)"
8642 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8644 rtx val = operands[2];
8645 HOST_WIDE_INT len = INTVAL (operands[3]);
8646 HOST_WIDE_INT pos = INTVAL (operands[4]);
8648 enum machine_mode mode, submode;
8650 mode = GET_MODE (val);
8653 /* ??? Combine likes to put non-volatile mem extractions in QImode
8654 no matter the size of the test. So find a mode that works. */
8655 if (! MEM_VOLATILE_P (val))
8657 mode = smallest_mode_for_size (pos + len, MODE_INT);
8658 val = adjust_address (val, mode, 0);
8661 else if (GET_CODE (val) == SUBREG
8662 && (submode = GET_MODE (SUBREG_REG (val)),
8663 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8664 && pos + len <= GET_MODE_BITSIZE (submode))
8666 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8668 val = SUBREG_REG (val);
8670 else if (mode == HImode && pos + len <= 8)
8672 /* Small HImode tests can be converted to QImode. */
8674 val = gen_lowpart (QImode, val);
8677 if (len == HOST_BITS_PER_WIDE_INT)
8680 mask = ((HOST_WIDE_INT)1 << len) - 1;
8683 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8686 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8687 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8688 ;; this is relatively important trick.
8689 ;; Do the conversion only post-reload to avoid limiting of the register class
8692 [(set (match_operand 0 "flags_reg_operand" "")
8693 (match_operator 1 "compare_operator"
8694 [(and (match_operand 2 "register_operand" "")
8695 (match_operand 3 "const_int_operand" ""))
8698 && QI_REG_P (operands[2])
8699 && GET_MODE (operands[2]) != QImode
8700 && ((ix86_match_ccmode (insn, CCZmode)
8701 && !(INTVAL (operands[3]) & ~(255 << 8)))
8702 || (ix86_match_ccmode (insn, CCNOmode)
8703 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8706 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8709 "operands[2] = gen_lowpart (SImode, operands[2]);
8710 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8713 [(set (match_operand 0 "flags_reg_operand" "")
8714 (match_operator 1 "compare_operator"
8715 [(and (match_operand 2 "nonimmediate_operand" "")
8716 (match_operand 3 "const_int_operand" ""))
8719 && GET_MODE (operands[2]) != QImode
8720 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8721 && ((ix86_match_ccmode (insn, CCZmode)
8722 && !(INTVAL (operands[3]) & ~255))
8723 || (ix86_match_ccmode (insn, CCNOmode)
8724 && !(INTVAL (operands[3]) & ~127)))"
8726 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8728 "operands[2] = gen_lowpart (QImode, operands[2]);
8729 operands[3] = gen_lowpart (QImode, operands[3]);")
8732 ;; %%% This used to optimize known byte-wide and operations to memory,
8733 ;; and sometimes to QImode registers. If this is considered useful,
8734 ;; it should be done with splitters.
8736 (define_expand "anddi3"
8737 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8738 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8739 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8740 (clobber (reg:CC FLAGS_REG))]
8742 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8744 (define_insn "*anddi_1_rex64"
8745 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8746 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8747 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8748 (clobber (reg:CC FLAGS_REG))]
8749 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8751 switch (get_attr_type (insn))
8755 enum machine_mode mode;
8757 gcc_assert (CONST_INT_P (operands[2]));
8758 if (INTVAL (operands[2]) == 0xff)
8762 gcc_assert (INTVAL (operands[2]) == 0xffff);
8766 operands[1] = gen_lowpart (mode, operands[1]);
8768 return "movz{bq|x}\t{%1,%0|%0, %1}";
8770 return "movz{wq|x}\t{%1,%0|%0, %1}";
8774 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8775 if (get_attr_mode (insn) == MODE_SI)
8776 return "and{l}\t{%k2, %k0|%k0, %k2}";
8778 return "and{q}\t{%2, %0|%0, %2}";
8781 [(set_attr "type" "alu,alu,alu,imovx")
8782 (set_attr "length_immediate" "*,*,*,0")
8783 (set_attr "mode" "SI,DI,DI,DI")])
8785 (define_insn "*anddi_2"
8786 [(set (reg FLAGS_REG)
8787 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8788 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8790 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8791 (and:DI (match_dup 1) (match_dup 2)))]
8792 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8793 && ix86_binary_operator_ok (AND, DImode, operands)"
8795 and{l}\t{%k2, %k0|%k0, %k2}
8796 and{q}\t{%2, %0|%0, %2}
8797 and{q}\t{%2, %0|%0, %2}"
8798 [(set_attr "type" "alu")
8799 (set_attr "mode" "SI,DI,DI")])
8801 (define_expand "andsi3"
8802 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8803 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8804 (match_operand:SI 2 "general_operand" "")))
8805 (clobber (reg:CC FLAGS_REG))]
8807 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8809 (define_insn "*andsi_1"
8810 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8811 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8812 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8813 (clobber (reg:CC FLAGS_REG))]
8814 "ix86_binary_operator_ok (AND, SImode, operands)"
8816 switch (get_attr_type (insn))
8820 enum machine_mode mode;
8822 gcc_assert (CONST_INT_P (operands[2]));
8823 if (INTVAL (operands[2]) == 0xff)
8827 gcc_assert (INTVAL (operands[2]) == 0xffff);
8831 operands[1] = gen_lowpart (mode, operands[1]);
8833 return "movz{bl|x}\t{%1,%0|%0, %1}";
8835 return "movz{wl|x}\t{%1,%0|%0, %1}";
8839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8840 return "and{l}\t{%2, %0|%0, %2}";
8843 [(set_attr "type" "alu,alu,imovx")
8844 (set_attr "length_immediate" "*,*,0")
8845 (set_attr "mode" "SI")])
8848 [(set (match_operand 0 "register_operand" "")
8850 (const_int -65536)))
8851 (clobber (reg:CC FLAGS_REG))]
8852 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8853 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8854 "operands[1] = gen_lowpart (HImode, operands[0]);")
8857 [(set (match_operand 0 "ext_register_operand" "")
8860 (clobber (reg:CC FLAGS_REG))]
8861 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8862 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8863 "operands[1] = gen_lowpart (QImode, operands[0]);")
8866 [(set (match_operand 0 "ext_register_operand" "")
8868 (const_int -65281)))
8869 (clobber (reg:CC FLAGS_REG))]
8870 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8871 [(parallel [(set (zero_extract:SI (match_dup 0)
8875 (zero_extract:SI (match_dup 0)
8878 (zero_extract:SI (match_dup 0)
8881 (clobber (reg:CC FLAGS_REG))])]
8882 "operands[0] = gen_lowpart (SImode, operands[0]);")
8884 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8885 (define_insn "*andsi_1_zext"
8886 [(set (match_operand:DI 0 "register_operand" "=r")
8888 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8889 (match_operand:SI 2 "general_operand" "g"))))
8890 (clobber (reg:CC FLAGS_REG))]
8891 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8892 "and{l}\t{%2, %k0|%k0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "mode" "SI")])
8896 (define_insn "*andsi_2"
8897 [(set (reg FLAGS_REG)
8898 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8899 (match_operand:SI 2 "general_operand" "g,ri"))
8901 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8902 (and:SI (match_dup 1) (match_dup 2)))]
8903 "ix86_match_ccmode (insn, CCNOmode)
8904 && ix86_binary_operator_ok (AND, SImode, operands)"
8905 "and{l}\t{%2, %0|%0, %2}"
8906 [(set_attr "type" "alu")
8907 (set_attr "mode" "SI")])
8909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8910 (define_insn "*andsi_2_zext"
8911 [(set (reg FLAGS_REG)
8912 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8913 (match_operand:SI 2 "general_operand" "g"))
8915 (set (match_operand:DI 0 "register_operand" "=r")
8916 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8917 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8918 && ix86_binary_operator_ok (AND, SImode, operands)"
8919 "and{l}\t{%2, %k0|%k0, %2}"
8920 [(set_attr "type" "alu")
8921 (set_attr "mode" "SI")])
8923 (define_expand "andhi3"
8924 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8925 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8926 (match_operand:HI 2 "general_operand" "")))
8927 (clobber (reg:CC FLAGS_REG))]
8928 "TARGET_HIMODE_MATH"
8929 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8931 (define_insn "*andhi_1"
8932 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8933 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8934 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8935 (clobber (reg:CC FLAGS_REG))]
8936 "ix86_binary_operator_ok (AND, HImode, operands)"
8938 switch (get_attr_type (insn))
8941 gcc_assert (CONST_INT_P (operands[2]));
8942 gcc_assert (INTVAL (operands[2]) == 0xff);
8943 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8946 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8948 return "and{w}\t{%2, %0|%0, %2}";
8951 [(set_attr "type" "alu,alu,imovx")
8952 (set_attr "length_immediate" "*,*,0")
8953 (set_attr "mode" "HI,HI,SI")])
8955 (define_insn "*andhi_2"
8956 [(set (reg FLAGS_REG)
8957 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8958 (match_operand:HI 2 "general_operand" "g,ri"))
8960 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8961 (and:HI (match_dup 1) (match_dup 2)))]
8962 "ix86_match_ccmode (insn, CCNOmode)
8963 && ix86_binary_operator_ok (AND, HImode, operands)"
8964 "and{w}\t{%2, %0|%0, %2}"
8965 [(set_attr "type" "alu")
8966 (set_attr "mode" "HI")])
8968 (define_expand "andqi3"
8969 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8970 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8971 (match_operand:QI 2 "general_operand" "")))
8972 (clobber (reg:CC FLAGS_REG))]
8973 "TARGET_QIMODE_MATH"
8974 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8976 ;; %%% Potential partial reg stall on alternative 2. What to do?
8977 (define_insn "*andqi_1"
8978 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8979 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8980 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8981 (clobber (reg:CC FLAGS_REG))]
8982 "ix86_binary_operator_ok (AND, QImode, operands)"
8984 and{b}\t{%2, %0|%0, %2}
8985 and{b}\t{%2, %0|%0, %2}
8986 and{l}\t{%k2, %k0|%k0, %k2}"
8987 [(set_attr "type" "alu")
8988 (set_attr "mode" "QI,QI,SI")])
8990 (define_insn "*andqi_1_slp"
8991 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8992 (and:QI (match_dup 0)
8993 (match_operand:QI 1 "general_operand" "qi,qmi")))
8994 (clobber (reg:CC FLAGS_REG))]
8995 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8996 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8997 "and{b}\t{%1, %0|%0, %1}"
8998 [(set_attr "type" "alu1")
8999 (set_attr "mode" "QI")])
9001 (define_insn "*andqi_2_maybe_si"
9002 [(set (reg FLAGS_REG)
9004 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9005 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9007 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9008 (and:QI (match_dup 1) (match_dup 2)))]
9009 "ix86_binary_operator_ok (AND, QImode, operands)
9010 && ix86_match_ccmode (insn,
9011 CONST_INT_P (operands[2])
9012 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9014 if (which_alternative == 2)
9016 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9017 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9018 return "and{l}\t{%2, %k0|%k0, %2}";
9020 return "and{b}\t{%2, %0|%0, %2}";
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "QI,QI,SI")])
9025 (define_insn "*andqi_2"
9026 [(set (reg FLAGS_REG)
9028 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9029 (match_operand:QI 2 "general_operand" "qim,qi"))
9031 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9032 (and:QI (match_dup 1) (match_dup 2)))]
9033 "ix86_match_ccmode (insn, CCNOmode)
9034 && ix86_binary_operator_ok (AND, QImode, operands)"
9035 "and{b}\t{%2, %0|%0, %2}"
9036 [(set_attr "type" "alu")
9037 (set_attr "mode" "QI")])
9039 (define_insn "*andqi_2_slp"
9040 [(set (reg FLAGS_REG)
9042 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9043 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9045 (set (strict_low_part (match_dup 0))
9046 (and:QI (match_dup 0) (match_dup 1)))]
9047 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9048 && ix86_match_ccmode (insn, CCNOmode)
9049 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9050 "and{b}\t{%1, %0|%0, %1}"
9051 [(set_attr "type" "alu1")
9052 (set_attr "mode" "QI")])
9054 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9055 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9056 ;; for a QImode operand, which of course failed.
9058 (define_insn "andqi_ext_0"
9059 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9064 (match_operand 1 "ext_register_operand" "0")
9067 (match_operand 2 "const_int_operand" "n")))
9068 (clobber (reg:CC FLAGS_REG))]
9070 "and{b}\t{%2, %h0|%h0, %2}"
9071 [(set_attr "type" "alu")
9072 (set_attr "length_immediate" "1")
9073 (set_attr "mode" "QI")])
9075 ;; Generated by peephole translating test to and. This shows up
9076 ;; often in fp comparisons.
9078 (define_insn "*andqi_ext_0_cc"
9079 [(set (reg FLAGS_REG)
9083 (match_operand 1 "ext_register_operand" "0")
9086 (match_operand 2 "const_int_operand" "n"))
9088 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9097 "ix86_match_ccmode (insn, CCNOmode)"
9098 "and{b}\t{%2, %h0|%h0, %2}"
9099 [(set_attr "type" "alu")
9100 (set_attr "length_immediate" "1")
9101 (set_attr "mode" "QI")])
9103 (define_insn "*andqi_ext_1"
9104 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9109 (match_operand 1 "ext_register_operand" "0")
9113 (match_operand:QI 2 "general_operand" "Qm"))))
9114 (clobber (reg:CC FLAGS_REG))]
9116 "and{b}\t{%2, %h0|%h0, %2}"
9117 [(set_attr "type" "alu")
9118 (set_attr "length_immediate" "0")
9119 (set_attr "mode" "QI")])
9121 (define_insn "*andqi_ext_1_rex64"
9122 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127 (match_operand 1 "ext_register_operand" "0")
9131 (match_operand 2 "ext_register_operand" "Q"))))
9132 (clobber (reg:CC FLAGS_REG))]
9134 "and{b}\t{%2, %h0|%h0, %2}"
9135 [(set_attr "type" "alu")
9136 (set_attr "length_immediate" "0")
9137 (set_attr "mode" "QI")])
9139 (define_insn "*andqi_ext_2"
9140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (match_operand 1 "ext_register_operand" "%0")
9149 (match_operand 2 "ext_register_operand" "Q")
9152 (clobber (reg:CC FLAGS_REG))]
9154 "and{b}\t{%h2, %h0|%h0, %h2}"
9155 [(set_attr "type" "alu")
9156 (set_attr "length_immediate" "0")
9157 (set_attr "mode" "QI")])
9159 ;; Convert wide AND instructions with immediate operand to shorter QImode
9160 ;; equivalents when possible.
9161 ;; Don't do the splitting with memory operands, since it introduces risk
9162 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9163 ;; for size, but that can (should?) be handled by generic code instead.
9165 [(set (match_operand 0 "register_operand" "")
9166 (and (match_operand 1 "register_operand" "")
9167 (match_operand 2 "const_int_operand" "")))
9168 (clobber (reg:CC FLAGS_REG))]
9170 && QI_REG_P (operands[0])
9171 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9172 && !(~INTVAL (operands[2]) & ~(255 << 8))
9173 && GET_MODE (operands[0]) != QImode"
9174 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9175 (and:SI (zero_extract:SI (match_dup 1)
9176 (const_int 8) (const_int 8))
9178 (clobber (reg:CC FLAGS_REG))])]
9179 "operands[0] = gen_lowpart (SImode, operands[0]);
9180 operands[1] = gen_lowpart (SImode, operands[1]);
9181 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9183 ;; Since AND can be encoded with sign extended immediate, this is only
9184 ;; profitable when 7th bit is not set.
9186 [(set (match_operand 0 "register_operand" "")
9187 (and (match_operand 1 "general_operand" "")
9188 (match_operand 2 "const_int_operand" "")))
9189 (clobber (reg:CC FLAGS_REG))]
9191 && ANY_QI_REG_P (operands[0])
9192 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9193 && !(~INTVAL (operands[2]) & ~255)
9194 && !(INTVAL (operands[2]) & 128)
9195 && GET_MODE (operands[0]) != QImode"
9196 [(parallel [(set (strict_low_part (match_dup 0))
9197 (and:QI (match_dup 1)
9199 (clobber (reg:CC FLAGS_REG))])]
9200 "operands[0] = gen_lowpart (QImode, operands[0]);
9201 operands[1] = gen_lowpart (QImode, operands[1]);
9202 operands[2] = gen_lowpart (QImode, operands[2]);")
9204 ;; Logical inclusive OR instructions
9206 ;; %%% This used to optimize known byte-wide and operations to memory.
9207 ;; If this is considered useful, it should be done with splitters.
9209 (define_expand "iordi3"
9210 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9211 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9212 (match_operand:DI 2 "x86_64_general_operand" "")))
9213 (clobber (reg:CC FLAGS_REG))]
9215 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9217 (define_insn "*iordi_1_rex64"
9218 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9219 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9220 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9221 (clobber (reg:CC FLAGS_REG))]
9223 && ix86_binary_operator_ok (IOR, DImode, operands)"
9224 "or{q}\t{%2, %0|%0, %2}"
9225 [(set_attr "type" "alu")
9226 (set_attr "mode" "DI")])
9228 (define_insn "*iordi_2_rex64"
9229 [(set (reg FLAGS_REG)
9230 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9231 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9233 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9234 (ior:DI (match_dup 1) (match_dup 2)))]
9236 && ix86_match_ccmode (insn, CCNOmode)
9237 && ix86_binary_operator_ok (IOR, DImode, operands)"
9238 "or{q}\t{%2, %0|%0, %2}"
9239 [(set_attr "type" "alu")
9240 (set_attr "mode" "DI")])
9242 (define_insn "*iordi_3_rex64"
9243 [(set (reg FLAGS_REG)
9244 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9245 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9247 (clobber (match_scratch:DI 0 "=r"))]
9249 && ix86_match_ccmode (insn, CCNOmode)
9250 && ix86_binary_operator_ok (IOR, DImode, operands)"
9251 "or{q}\t{%2, %0|%0, %2}"
9252 [(set_attr "type" "alu")
9253 (set_attr "mode" "DI")])
9256 (define_expand "iorsi3"
9257 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9258 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9259 (match_operand:SI 2 "general_operand" "")))
9260 (clobber (reg:CC FLAGS_REG))]
9262 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9264 (define_insn "*iorsi_1"
9265 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9266 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9267 (match_operand:SI 2 "general_operand" "ri,g")))
9268 (clobber (reg:CC FLAGS_REG))]
9269 "ix86_binary_operator_ok (IOR, SImode, operands)"
9270 "or{l}\t{%2, %0|%0, %2}"
9271 [(set_attr "type" "alu")
9272 (set_attr "mode" "SI")])
9274 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9275 (define_insn "*iorsi_1_zext"
9276 [(set (match_operand:DI 0 "register_operand" "=r")
9278 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9279 (match_operand:SI 2 "general_operand" "g"))))
9280 (clobber (reg:CC FLAGS_REG))]
9281 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9282 "or{l}\t{%2, %k0|%k0, %2}"
9283 [(set_attr "type" "alu")
9284 (set_attr "mode" "SI")])
9286 (define_insn "*iorsi_1_zext_imm"
9287 [(set (match_operand:DI 0 "register_operand" "=r")
9288 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9289 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9290 (clobber (reg:CC FLAGS_REG))]
9292 "or{l}\t{%2, %k0|%k0, %2}"
9293 [(set_attr "type" "alu")
9294 (set_attr "mode" "SI")])
9296 (define_insn "*iorsi_2"
9297 [(set (reg FLAGS_REG)
9298 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9299 (match_operand:SI 2 "general_operand" "g,ri"))
9301 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9302 (ior:SI (match_dup 1) (match_dup 2)))]
9303 "ix86_match_ccmode (insn, CCNOmode)
9304 && ix86_binary_operator_ok (IOR, SImode, operands)"
9305 "or{l}\t{%2, %0|%0, %2}"
9306 [(set_attr "type" "alu")
9307 (set_attr "mode" "SI")])
9309 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9310 ;; ??? Special case for immediate operand is missing - it is tricky.
9311 (define_insn "*iorsi_2_zext"
9312 [(set (reg FLAGS_REG)
9313 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9314 (match_operand:SI 2 "general_operand" "g"))
9316 (set (match_operand:DI 0 "register_operand" "=r")
9317 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9318 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9319 && ix86_binary_operator_ok (IOR, SImode, operands)"
9320 "or{l}\t{%2, %k0|%k0, %2}"
9321 [(set_attr "type" "alu")
9322 (set_attr "mode" "SI")])
9324 (define_insn "*iorsi_2_zext_imm"
9325 [(set (reg FLAGS_REG)
9326 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9327 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9329 (set (match_operand:DI 0 "register_operand" "=r")
9330 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9331 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9332 && ix86_binary_operator_ok (IOR, SImode, operands)"
9333 "or{l}\t{%2, %k0|%k0, %2}"
9334 [(set_attr "type" "alu")
9335 (set_attr "mode" "SI")])
9337 (define_insn "*iorsi_3"
9338 [(set (reg FLAGS_REG)
9339 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9340 (match_operand:SI 2 "general_operand" "g"))
9342 (clobber (match_scratch:SI 0 "=r"))]
9343 "ix86_match_ccmode (insn, CCNOmode)
9344 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9345 "or{l}\t{%2, %0|%0, %2}"
9346 [(set_attr "type" "alu")
9347 (set_attr "mode" "SI")])
9349 (define_expand "iorhi3"
9350 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9351 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9352 (match_operand:HI 2 "general_operand" "")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "TARGET_HIMODE_MATH"
9355 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9357 (define_insn "*iorhi_1"
9358 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9359 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9360 (match_operand:HI 2 "general_operand" "g,ri")))
9361 (clobber (reg:CC FLAGS_REG))]
9362 "ix86_binary_operator_ok (IOR, HImode, operands)"
9363 "or{w}\t{%2, %0|%0, %2}"
9364 [(set_attr "type" "alu")
9365 (set_attr "mode" "HI")])
9367 (define_insn "*iorhi_2"
9368 [(set (reg FLAGS_REG)
9369 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9370 (match_operand:HI 2 "general_operand" "g,ri"))
9372 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9373 (ior:HI (match_dup 1) (match_dup 2)))]
9374 "ix86_match_ccmode (insn, CCNOmode)
9375 && ix86_binary_operator_ok (IOR, HImode, operands)"
9376 "or{w}\t{%2, %0|%0, %2}"
9377 [(set_attr "type" "alu")
9378 (set_attr "mode" "HI")])
9380 (define_insn "*iorhi_3"
9381 [(set (reg FLAGS_REG)
9382 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9383 (match_operand:HI 2 "general_operand" "g"))
9385 (clobber (match_scratch:HI 0 "=r"))]
9386 "ix86_match_ccmode (insn, CCNOmode)
9387 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9388 "or{w}\t{%2, %0|%0, %2}"
9389 [(set_attr "type" "alu")
9390 (set_attr "mode" "HI")])
9392 (define_expand "iorqi3"
9393 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9394 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9395 (match_operand:QI 2 "general_operand" "")))
9396 (clobber (reg:CC FLAGS_REG))]
9397 "TARGET_QIMODE_MATH"
9398 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9400 ;; %%% Potential partial reg stall on alternative 2. What to do?
9401 (define_insn "*iorqi_1"
9402 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9403 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9404 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9405 (clobber (reg:CC FLAGS_REG))]
9406 "ix86_binary_operator_ok (IOR, QImode, operands)"
9408 or{b}\t{%2, %0|%0, %2}
9409 or{b}\t{%2, %0|%0, %2}
9410 or{l}\t{%k2, %k0|%k0, %k2}"
9411 [(set_attr "type" "alu")
9412 (set_attr "mode" "QI,QI,SI")])
9414 (define_insn "*iorqi_1_slp"
9415 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9416 (ior:QI (match_dup 0)
9417 (match_operand:QI 1 "general_operand" "qmi,qi")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9421 "or{b}\t{%1, %0|%0, %1}"
9422 [(set_attr "type" "alu1")
9423 (set_attr "mode" "QI")])
9425 (define_insn "*iorqi_2"
9426 [(set (reg FLAGS_REG)
9427 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9428 (match_operand:QI 2 "general_operand" "qim,qi"))
9430 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9431 (ior:QI (match_dup 1) (match_dup 2)))]
9432 "ix86_match_ccmode (insn, CCNOmode)
9433 && ix86_binary_operator_ok (IOR, QImode, operands)"
9434 "or{b}\t{%2, %0|%0, %2}"
9435 [(set_attr "type" "alu")
9436 (set_attr "mode" "QI")])
9438 (define_insn "*iorqi_2_slp"
9439 [(set (reg FLAGS_REG)
9440 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9441 (match_operand:QI 1 "general_operand" "qim,qi"))
9443 (set (strict_low_part (match_dup 0))
9444 (ior:QI (match_dup 0) (match_dup 1)))]
9445 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9446 && ix86_match_ccmode (insn, CCNOmode)
9447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9448 "or{b}\t{%1, %0|%0, %1}"
9449 [(set_attr "type" "alu1")
9450 (set_attr "mode" "QI")])
9452 (define_insn "*iorqi_3"
9453 [(set (reg FLAGS_REG)
9454 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9455 (match_operand:QI 2 "general_operand" "qim"))
9457 (clobber (match_scratch:QI 0 "=q"))]
9458 "ix86_match_ccmode (insn, CCNOmode)
9459 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9460 "or{b}\t{%2, %0|%0, %2}"
9461 [(set_attr "type" "alu")
9462 (set_attr "mode" "QI")])
9464 (define_insn "iorqi_ext_0"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9470 (match_operand 1 "ext_register_operand" "0")
9473 (match_operand 2 "const_int_operand" "n")))
9474 (clobber (reg:CC FLAGS_REG))]
9475 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9476 "or{b}\t{%2, %h0|%h0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "length_immediate" "1")
9479 (set_attr "mode" "QI")])
9481 (define_insn "*iorqi_ext_1"
9482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9487 (match_operand 1 "ext_register_operand" "0")
9491 (match_operand:QI 2 "general_operand" "Qm"))))
9492 (clobber (reg:CC FLAGS_REG))]
9494 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9495 "or{b}\t{%2, %h0|%h0, %2}"
9496 [(set_attr "type" "alu")
9497 (set_attr "length_immediate" "0")
9498 (set_attr "mode" "QI")])
9500 (define_insn "*iorqi_ext_1_rex64"
9501 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9506 (match_operand 1 "ext_register_operand" "0")
9510 (match_operand 2 "ext_register_operand" "Q"))))
9511 (clobber (reg:CC FLAGS_REG))]
9513 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9514 "or{b}\t{%2, %h0|%h0, %2}"
9515 [(set_attr "type" "alu")
9516 (set_attr "length_immediate" "0")
9517 (set_attr "mode" "QI")])
9519 (define_insn "*iorqi_ext_2"
9520 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9524 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9527 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9530 (clobber (reg:CC FLAGS_REG))]
9531 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9532 "ior{b}\t{%h2, %h0|%h0, %h2}"
9533 [(set_attr "type" "alu")
9534 (set_attr "length_immediate" "0")
9535 (set_attr "mode" "QI")])
9538 [(set (match_operand 0 "register_operand" "")
9539 (ior (match_operand 1 "register_operand" "")
9540 (match_operand 2 "const_int_operand" "")))
9541 (clobber (reg:CC FLAGS_REG))]
9543 && QI_REG_P (operands[0])
9544 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9545 && !(INTVAL (operands[2]) & ~(255 << 8))
9546 && GET_MODE (operands[0]) != QImode"
9547 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9548 (ior:SI (zero_extract:SI (match_dup 1)
9549 (const_int 8) (const_int 8))
9551 (clobber (reg:CC FLAGS_REG))])]
9552 "operands[0] = gen_lowpart (SImode, operands[0]);
9553 operands[1] = gen_lowpart (SImode, operands[1]);
9554 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9556 ;; Since OR can be encoded with sign extended immediate, this is only
9557 ;; profitable when 7th bit is set.
9559 [(set (match_operand 0 "register_operand" "")
9560 (ior (match_operand 1 "general_operand" "")
9561 (match_operand 2 "const_int_operand" "")))
9562 (clobber (reg:CC FLAGS_REG))]
9564 && ANY_QI_REG_P (operands[0])
9565 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9566 && !(INTVAL (operands[2]) & ~255)
9567 && (INTVAL (operands[2]) & 128)
9568 && GET_MODE (operands[0]) != QImode"
9569 [(parallel [(set (strict_low_part (match_dup 0))
9570 (ior:QI (match_dup 1)
9572 (clobber (reg:CC FLAGS_REG))])]
9573 "operands[0] = gen_lowpart (QImode, operands[0]);
9574 operands[1] = gen_lowpart (QImode, operands[1]);
9575 operands[2] = gen_lowpart (QImode, operands[2]);")
9577 ;; Logical XOR instructions
9579 ;; %%% This used to optimize known byte-wide and operations to memory.
9580 ;; If this is considered useful, it should be done with splitters.
9582 (define_expand "xordi3"
9583 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9584 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9585 (match_operand:DI 2 "x86_64_general_operand" "")))
9586 (clobber (reg:CC FLAGS_REG))]
9588 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9590 (define_insn "*xordi_1_rex64"
9591 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9592 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9593 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9594 (clobber (reg:CC FLAGS_REG))]
9596 && ix86_binary_operator_ok (XOR, DImode, operands)"
9598 xor{q}\t{%2, %0|%0, %2}
9599 xor{q}\t{%2, %0|%0, %2}"
9600 [(set_attr "type" "alu")
9601 (set_attr "mode" "DI,DI")])
9603 (define_insn "*xordi_2_rex64"
9604 [(set (reg FLAGS_REG)
9605 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9606 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9608 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9609 (xor:DI (match_dup 1) (match_dup 2)))]
9611 && ix86_match_ccmode (insn, CCNOmode)
9612 && ix86_binary_operator_ok (XOR, DImode, operands)"
9614 xor{q}\t{%2, %0|%0, %2}
9615 xor{q}\t{%2, %0|%0, %2}"
9616 [(set_attr "type" "alu")
9617 (set_attr "mode" "DI,DI")])
9619 (define_insn "*xordi_3_rex64"
9620 [(set (reg FLAGS_REG)
9621 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9622 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9624 (clobber (match_scratch:DI 0 "=r"))]
9626 && ix86_match_ccmode (insn, CCNOmode)
9627 && ix86_binary_operator_ok (XOR, DImode, operands)"
9628 "xor{q}\t{%2, %0|%0, %2}"
9629 [(set_attr "type" "alu")
9630 (set_attr "mode" "DI")])
9632 (define_expand "xorsi3"
9633 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9634 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9635 (match_operand:SI 2 "general_operand" "")))
9636 (clobber (reg:CC FLAGS_REG))]
9638 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9640 (define_insn "*xorsi_1"
9641 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9642 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9643 (match_operand:SI 2 "general_operand" "ri,rm")))
9644 (clobber (reg:CC FLAGS_REG))]
9645 "ix86_binary_operator_ok (XOR, SImode, operands)"
9646 "xor{l}\t{%2, %0|%0, %2}"
9647 [(set_attr "type" "alu")
9648 (set_attr "mode" "SI")])
9650 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9651 ;; Add speccase for immediates
9652 (define_insn "*xorsi_1_zext"
9653 [(set (match_operand:DI 0 "register_operand" "=r")
9655 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9656 (match_operand:SI 2 "general_operand" "g"))))
9657 (clobber (reg:CC FLAGS_REG))]
9658 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9659 "xor{l}\t{%2, %k0|%k0, %2}"
9660 [(set_attr "type" "alu")
9661 (set_attr "mode" "SI")])
9663 (define_insn "*xorsi_1_zext_imm"
9664 [(set (match_operand:DI 0 "register_operand" "=r")
9665 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9666 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9667 (clobber (reg:CC FLAGS_REG))]
9668 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9669 "xor{l}\t{%2, %k0|%k0, %2}"
9670 [(set_attr "type" "alu")
9671 (set_attr "mode" "SI")])
9673 (define_insn "*xorsi_2"
9674 [(set (reg FLAGS_REG)
9675 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9676 (match_operand:SI 2 "general_operand" "g,ri"))
9678 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9679 (xor:SI (match_dup 1) (match_dup 2)))]
9680 "ix86_match_ccmode (insn, CCNOmode)
9681 && ix86_binary_operator_ok (XOR, SImode, operands)"
9682 "xor{l}\t{%2, %0|%0, %2}"
9683 [(set_attr "type" "alu")
9684 (set_attr "mode" "SI")])
9686 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9687 ;; ??? Special case for immediate operand is missing - it is tricky.
9688 (define_insn "*xorsi_2_zext"
9689 [(set (reg FLAGS_REG)
9690 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9691 (match_operand:SI 2 "general_operand" "g"))
9693 (set (match_operand:DI 0 "register_operand" "=r")
9694 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9695 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9696 && ix86_binary_operator_ok (XOR, SImode, operands)"
9697 "xor{l}\t{%2, %k0|%k0, %2}"
9698 [(set_attr "type" "alu")
9699 (set_attr "mode" "SI")])
9701 (define_insn "*xorsi_2_zext_imm"
9702 [(set (reg FLAGS_REG)
9703 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9704 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9706 (set (match_operand:DI 0 "register_operand" "=r")
9707 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9708 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9709 && ix86_binary_operator_ok (XOR, SImode, operands)"
9710 "xor{l}\t{%2, %k0|%k0, %2}"
9711 [(set_attr "type" "alu")
9712 (set_attr "mode" "SI")])
9714 (define_insn "*xorsi_3"
9715 [(set (reg FLAGS_REG)
9716 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9717 (match_operand:SI 2 "general_operand" "g"))
9719 (clobber (match_scratch:SI 0 "=r"))]
9720 "ix86_match_ccmode (insn, CCNOmode)
9721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9722 "xor{l}\t{%2, %0|%0, %2}"
9723 [(set_attr "type" "alu")
9724 (set_attr "mode" "SI")])
9726 (define_expand "xorhi3"
9727 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9728 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9729 (match_operand:HI 2 "general_operand" "")))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "TARGET_HIMODE_MATH"
9732 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9734 (define_insn "*xorhi_1"
9735 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9736 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9737 (match_operand:HI 2 "general_operand" "g,ri")))
9738 (clobber (reg:CC FLAGS_REG))]
9739 "ix86_binary_operator_ok (XOR, HImode, operands)"
9740 "xor{w}\t{%2, %0|%0, %2}"
9741 [(set_attr "type" "alu")
9742 (set_attr "mode" "HI")])
9744 (define_insn "*xorhi_2"
9745 [(set (reg FLAGS_REG)
9746 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9747 (match_operand:HI 2 "general_operand" "g,ri"))
9749 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9750 (xor:HI (match_dup 1) (match_dup 2)))]
9751 "ix86_match_ccmode (insn, CCNOmode)
9752 && ix86_binary_operator_ok (XOR, HImode, operands)"
9753 "xor{w}\t{%2, %0|%0, %2}"
9754 [(set_attr "type" "alu")
9755 (set_attr "mode" "HI")])
9757 (define_insn "*xorhi_3"
9758 [(set (reg FLAGS_REG)
9759 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9760 (match_operand:HI 2 "general_operand" "g"))
9762 (clobber (match_scratch:HI 0 "=r"))]
9763 "ix86_match_ccmode (insn, CCNOmode)
9764 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9765 "xor{w}\t{%2, %0|%0, %2}"
9766 [(set_attr "type" "alu")
9767 (set_attr "mode" "HI")])
9769 (define_expand "xorqi3"
9770 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9771 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9772 (match_operand:QI 2 "general_operand" "")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "TARGET_QIMODE_MATH"
9775 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9777 ;; %%% Potential partial reg stall on alternative 2. What to do?
9778 (define_insn "*xorqi_1"
9779 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9780 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9781 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9782 (clobber (reg:CC FLAGS_REG))]
9783 "ix86_binary_operator_ok (XOR, QImode, operands)"
9785 xor{b}\t{%2, %0|%0, %2}
9786 xor{b}\t{%2, %0|%0, %2}
9787 xor{l}\t{%k2, %k0|%k0, %k2}"
9788 [(set_attr "type" "alu")
9789 (set_attr "mode" "QI,QI,SI")])
9791 (define_insn "*xorqi_1_slp"
9792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9793 (xor:QI (match_dup 0)
9794 (match_operand:QI 1 "general_operand" "qi,qmi")))
9795 (clobber (reg:CC FLAGS_REG))]
9796 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9797 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9798 "xor{b}\t{%1, %0|%0, %1}"
9799 [(set_attr "type" "alu1")
9800 (set_attr "mode" "QI")])
9802 (define_insn "xorqi_ext_0"
9803 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9808 (match_operand 1 "ext_register_operand" "0")
9811 (match_operand 2 "const_int_operand" "n")))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9814 "xor{b}\t{%2, %h0|%h0, %2}"
9815 [(set_attr "type" "alu")
9816 (set_attr "length_immediate" "1")
9817 (set_attr "mode" "QI")])
9819 (define_insn "*xorqi_ext_1"
9820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9825 (match_operand 1 "ext_register_operand" "0")
9829 (match_operand:QI 2 "general_operand" "Qm"))))
9830 (clobber (reg:CC FLAGS_REG))]
9832 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9833 "xor{b}\t{%2, %h0|%h0, %2}"
9834 [(set_attr "type" "alu")
9835 (set_attr "length_immediate" "0")
9836 (set_attr "mode" "QI")])
9838 (define_insn "*xorqi_ext_1_rex64"
9839 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9844 (match_operand 1 "ext_register_operand" "0")
9848 (match_operand 2 "ext_register_operand" "Q"))))
9849 (clobber (reg:CC FLAGS_REG))]
9851 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9852 "xor{b}\t{%2, %h0|%h0, %2}"
9853 [(set_attr "type" "alu")
9854 (set_attr "length_immediate" "0")
9855 (set_attr "mode" "QI")])
9857 (define_insn "*xorqi_ext_2"
9858 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9862 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9865 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9868 (clobber (reg:CC FLAGS_REG))]
9869 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9870 "xor{b}\t{%h2, %h0|%h0, %h2}"
9871 [(set_attr "type" "alu")
9872 (set_attr "length_immediate" "0")
9873 (set_attr "mode" "QI")])
9875 (define_insn "*xorqi_cc_1"
9876 [(set (reg FLAGS_REG)
9878 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9879 (match_operand:QI 2 "general_operand" "qim,qi"))
9881 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9882 (xor:QI (match_dup 1) (match_dup 2)))]
9883 "ix86_match_ccmode (insn, CCNOmode)
9884 && ix86_binary_operator_ok (XOR, QImode, operands)"
9885 "xor{b}\t{%2, %0|%0, %2}"
9886 [(set_attr "type" "alu")
9887 (set_attr "mode" "QI")])
9889 (define_insn "*xorqi_2_slp"
9890 [(set (reg FLAGS_REG)
9891 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9892 (match_operand:QI 1 "general_operand" "qim,qi"))
9894 (set (strict_low_part (match_dup 0))
9895 (xor:QI (match_dup 0) (match_dup 1)))]
9896 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9897 && ix86_match_ccmode (insn, CCNOmode)
9898 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9899 "xor{b}\t{%1, %0|%0, %1}"
9900 [(set_attr "type" "alu1")
9901 (set_attr "mode" "QI")])
9903 (define_insn "*xorqi_cc_2"
9904 [(set (reg FLAGS_REG)
9906 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9907 (match_operand:QI 2 "general_operand" "qim"))
9909 (clobber (match_scratch:QI 0 "=q"))]
9910 "ix86_match_ccmode (insn, CCNOmode)
9911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9912 "xor{b}\t{%2, %0|%0, %2}"
9913 [(set_attr "type" "alu")
9914 (set_attr "mode" "QI")])
9916 (define_insn "*xorqi_cc_ext_1"
9917 [(set (reg FLAGS_REG)
9921 (match_operand 1 "ext_register_operand" "0")
9924 (match_operand:QI 2 "general_operand" "qmn"))
9926 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9930 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9932 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9933 "xor{b}\t{%2, %h0|%h0, %2}"
9934 [(set_attr "type" "alu")
9935 (set_attr "mode" "QI")])
9937 (define_insn "*xorqi_cc_ext_1_rex64"
9938 [(set (reg FLAGS_REG)
9942 (match_operand 1 "ext_register_operand" "0")
9945 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9947 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9951 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9953 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9954 "xor{b}\t{%2, %h0|%h0, %2}"
9955 [(set_attr "type" "alu")
9956 (set_attr "mode" "QI")])
9958 (define_expand "xorqi_cc_ext_1"
9960 (set (reg:CCNO FLAGS_REG)
9964 (match_operand 1 "ext_register_operand" "")
9967 (match_operand:QI 2 "general_operand" ""))
9969 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9973 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9979 [(set (match_operand 0 "register_operand" "")
9980 (xor (match_operand 1 "register_operand" "")
9981 (match_operand 2 "const_int_operand" "")))
9982 (clobber (reg:CC FLAGS_REG))]
9984 && QI_REG_P (operands[0])
9985 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9986 && !(INTVAL (operands[2]) & ~(255 << 8))
9987 && GET_MODE (operands[0]) != QImode"
9988 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9989 (xor:SI (zero_extract:SI (match_dup 1)
9990 (const_int 8) (const_int 8))
9992 (clobber (reg:CC FLAGS_REG))])]
9993 "operands[0] = gen_lowpart (SImode, operands[0]);
9994 operands[1] = gen_lowpart (SImode, operands[1]);
9995 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9997 ;; Since XOR can be encoded with sign extended immediate, this is only
9998 ;; profitable when 7th bit is set.
10000 [(set (match_operand 0 "register_operand" "")
10001 (xor (match_operand 1 "general_operand" "")
10002 (match_operand 2 "const_int_operand" "")))
10003 (clobber (reg:CC FLAGS_REG))]
10005 && ANY_QI_REG_P (operands[0])
10006 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10007 && !(INTVAL (operands[2]) & ~255)
10008 && (INTVAL (operands[2]) & 128)
10009 && GET_MODE (operands[0]) != QImode"
10010 [(parallel [(set (strict_low_part (match_dup 0))
10011 (xor:QI (match_dup 1)
10013 (clobber (reg:CC FLAGS_REG))])]
10014 "operands[0] = gen_lowpart (QImode, operands[0]);
10015 operands[1] = gen_lowpart (QImode, operands[1]);
10016 operands[2] = gen_lowpart (QImode, operands[2]);")
10018 ;; Negation instructions
10020 (define_expand "negti2"
10021 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10022 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10023 (clobber (reg:CC FLAGS_REG))])]
10025 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10027 (define_insn "*negti2_1"
10028 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10029 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10030 (clobber (reg:CC FLAGS_REG))]
10032 && ix86_unary_operator_ok (NEG, TImode, operands)"
10036 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10037 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10038 (clobber (reg:CC FLAGS_REG))]
10039 "TARGET_64BIT && reload_completed"
10041 [(set (reg:CCZ FLAGS_REG)
10042 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10043 (set (match_dup 0) (neg:DI (match_dup 2)))])
10045 [(set (match_dup 1)
10046 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10049 (clobber (reg:CC FLAGS_REG))])
10051 [(set (match_dup 1)
10052 (neg:DI (match_dup 1)))
10053 (clobber (reg:CC FLAGS_REG))])]
10054 "split_ti (operands+1, 1, operands+2, operands+3);
10055 split_ti (operands+0, 1, operands+0, operands+1);")
10057 (define_expand "negdi2"
10058 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10059 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10060 (clobber (reg:CC FLAGS_REG))])]
10062 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10064 (define_insn "*negdi2_1"
10065 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10066 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10067 (clobber (reg:CC FLAGS_REG))]
10069 && ix86_unary_operator_ok (NEG, DImode, operands)"
10073 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10074 (neg:DI (match_operand:DI 1 "general_operand" "")))
10075 (clobber (reg:CC FLAGS_REG))]
10076 "!TARGET_64BIT && reload_completed"
10078 [(set (reg:CCZ FLAGS_REG)
10079 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10080 (set (match_dup 0) (neg:SI (match_dup 2)))])
10082 [(set (match_dup 1)
10083 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10086 (clobber (reg:CC FLAGS_REG))])
10088 [(set (match_dup 1)
10089 (neg:SI (match_dup 1)))
10090 (clobber (reg:CC FLAGS_REG))])]
10091 "split_di (operands+1, 1, operands+2, operands+3);
10092 split_di (operands+0, 1, operands+0, operands+1);")
10094 (define_insn "*negdi2_1_rex64"
10095 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10096 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10097 (clobber (reg:CC FLAGS_REG))]
10098 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10100 [(set_attr "type" "negnot")
10101 (set_attr "mode" "DI")])
10103 ;; The problem with neg is that it does not perform (compare x 0),
10104 ;; it really performs (compare 0 x), which leaves us with the zero
10105 ;; flag being the only useful item.
10107 (define_insn "*negdi2_cmpz_rex64"
10108 [(set (reg:CCZ FLAGS_REG)
10109 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10111 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10112 (neg:DI (match_dup 1)))]
10113 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10115 [(set_attr "type" "negnot")
10116 (set_attr "mode" "DI")])
10119 (define_expand "negsi2"
10120 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10121 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10122 (clobber (reg:CC FLAGS_REG))])]
10124 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10126 (define_insn "*negsi2_1"
10127 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10128 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10129 (clobber (reg:CC FLAGS_REG))]
10130 "ix86_unary_operator_ok (NEG, SImode, operands)"
10132 [(set_attr "type" "negnot")
10133 (set_attr "mode" "SI")])
10135 ;; Combine is quite creative about this pattern.
10136 (define_insn "*negsi2_1_zext"
10137 [(set (match_operand:DI 0 "register_operand" "=r")
10138 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10141 (clobber (reg:CC FLAGS_REG))]
10142 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10144 [(set_attr "type" "negnot")
10145 (set_attr "mode" "SI")])
10147 ;; The problem with neg is that it does not perform (compare x 0),
10148 ;; it really performs (compare 0 x), which leaves us with the zero
10149 ;; flag being the only useful item.
10151 (define_insn "*negsi2_cmpz"
10152 [(set (reg:CCZ FLAGS_REG)
10153 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10155 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10156 (neg:SI (match_dup 1)))]
10157 "ix86_unary_operator_ok (NEG, SImode, operands)"
10159 [(set_attr "type" "negnot")
10160 (set_attr "mode" "SI")])
10162 (define_insn "*negsi2_cmpz_zext"
10163 [(set (reg:CCZ FLAGS_REG)
10164 (compare:CCZ (lshiftrt:DI
10166 (match_operand:DI 1 "register_operand" "0")
10170 (set (match_operand:DI 0 "register_operand" "=r")
10171 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10174 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10176 [(set_attr "type" "negnot")
10177 (set_attr "mode" "SI")])
10179 (define_expand "neghi2"
10180 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10181 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10182 (clobber (reg:CC FLAGS_REG))])]
10183 "TARGET_HIMODE_MATH"
10184 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10186 (define_insn "*neghi2_1"
10187 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10188 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10189 (clobber (reg:CC FLAGS_REG))]
10190 "ix86_unary_operator_ok (NEG, HImode, operands)"
10192 [(set_attr "type" "negnot")
10193 (set_attr "mode" "HI")])
10195 (define_insn "*neghi2_cmpz"
10196 [(set (reg:CCZ FLAGS_REG)
10197 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10199 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10200 (neg:HI (match_dup 1)))]
10201 "ix86_unary_operator_ok (NEG, HImode, operands)"
10203 [(set_attr "type" "negnot")
10204 (set_attr "mode" "HI")])
10206 (define_expand "negqi2"
10207 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10208 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10209 (clobber (reg:CC FLAGS_REG))])]
10210 "TARGET_QIMODE_MATH"
10211 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10213 (define_insn "*negqi2_1"
10214 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10215 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10216 (clobber (reg:CC FLAGS_REG))]
10217 "ix86_unary_operator_ok (NEG, QImode, operands)"
10219 [(set_attr "type" "negnot")
10220 (set_attr "mode" "QI")])
10222 (define_insn "*negqi2_cmpz"
10223 [(set (reg:CCZ FLAGS_REG)
10224 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10226 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10227 (neg:QI (match_dup 1)))]
10228 "ix86_unary_operator_ok (NEG, QImode, operands)"
10230 [(set_attr "type" "negnot")
10231 (set_attr "mode" "QI")])
10233 ;; Changing of sign for FP values is doable using integer unit too.
10235 (define_expand "neg<mode>2"
10236 [(set (match_operand:X87MODEF 0 "register_operand" "")
10237 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10238 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10239 "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10241 (define_expand "abs<mode>2"
10242 [(set (match_operand:X87MODEF 0 "register_operand" "")
10243 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10244 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10245 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10247 (define_insn "*absneg<mode>2_mixed"
10248 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10249 (match_operator:MODEF 3 "absneg_operator"
10250 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10251 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10256 (define_insn "*absneg<mode>2_sse"
10257 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10258 (match_operator:MODEF 3 "absneg_operator"
10259 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10260 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10265 (define_insn "*absneg<mode>2_i387"
10266 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10267 (match_operator:X87MODEF 3 "absneg_operator"
10268 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10269 (use (match_operand 2 "" ""))
10270 (clobber (reg:CC FLAGS_REG))]
10271 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10274 (define_expand "negtf2"
10275 [(set (match_operand:TF 0 "register_operand" "")
10276 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10278 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10280 (define_expand "abstf2"
10281 [(set (match_operand:TF 0 "register_operand" "")
10282 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10284 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10286 (define_insn "*absnegtf2_sse"
10287 [(set (match_operand:TF 0 "register_operand" "=x,x")
10288 (match_operator:TF 3 "absneg_operator"
10289 [(match_operand:TF 1 "register_operand" "0,x")]))
10290 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10291 (clobber (reg:CC FLAGS_REG))]
10295 ;; Splitters for fp abs and neg.
10298 [(set (match_operand 0 "fp_register_operand" "")
10299 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10300 (use (match_operand 2 "" ""))
10301 (clobber (reg:CC FLAGS_REG))]
10303 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10306 [(set (match_operand 0 "register_operand" "")
10307 (match_operator 3 "absneg_operator"
10308 [(match_operand 1 "register_operand" "")]))
10309 (use (match_operand 2 "nonimmediate_operand" ""))
10310 (clobber (reg:CC FLAGS_REG))]
10311 "reload_completed && SSE_REG_P (operands[0])"
10312 [(set (match_dup 0) (match_dup 3))]
10314 enum machine_mode mode = GET_MODE (operands[0]);
10315 enum machine_mode vmode = GET_MODE (operands[2]);
10318 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10319 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10320 if (operands_match_p (operands[0], operands[2]))
10323 operands[1] = operands[2];
10326 if (GET_CODE (operands[3]) == ABS)
10327 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10329 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10334 [(set (match_operand:SF 0 "register_operand" "")
10335 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10336 (use (match_operand:V4SF 2 "" ""))
10337 (clobber (reg:CC FLAGS_REG))]
10339 [(parallel [(set (match_dup 0) (match_dup 1))
10340 (clobber (reg:CC FLAGS_REG))])]
10343 operands[0] = gen_lowpart (SImode, operands[0]);
10344 if (GET_CODE (operands[1]) == ABS)
10346 tmp = gen_int_mode (0x7fffffff, SImode);
10347 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10351 tmp = gen_int_mode (0x80000000, SImode);
10352 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10358 [(set (match_operand:DF 0 "register_operand" "")
10359 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10360 (use (match_operand 2 "" ""))
10361 (clobber (reg:CC FLAGS_REG))]
10363 [(parallel [(set (match_dup 0) (match_dup 1))
10364 (clobber (reg:CC FLAGS_REG))])]
10369 tmp = gen_lowpart (DImode, operands[0]);
10370 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10373 if (GET_CODE (operands[1]) == ABS)
10376 tmp = gen_rtx_NOT (DImode, tmp);
10380 operands[0] = gen_highpart (SImode, operands[0]);
10381 if (GET_CODE (operands[1]) == ABS)
10383 tmp = gen_int_mode (0x7fffffff, SImode);
10384 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10388 tmp = gen_int_mode (0x80000000, SImode);
10389 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10396 [(set (match_operand:XF 0 "register_operand" "")
10397 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10398 (use (match_operand 2 "" ""))
10399 (clobber (reg:CC FLAGS_REG))]
10401 [(parallel [(set (match_dup 0) (match_dup 1))
10402 (clobber (reg:CC FLAGS_REG))])]
10405 operands[0] = gen_rtx_REG (SImode,
10406 true_regnum (operands[0])
10407 + (TARGET_64BIT ? 1 : 2));
10408 if (GET_CODE (operands[1]) == ABS)
10410 tmp = GEN_INT (0x7fff);
10411 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10415 tmp = GEN_INT (0x8000);
10416 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10421 ;; Conditionalize these after reload. If they match before reload, we
10422 ;; lose the clobber and ability to use integer instructions.
10424 (define_insn "*neg<mode>2_1"
10425 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10426 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10428 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10430 [(set_attr "type" "fsgn")
10431 (set_attr "mode" "<MODE>")])
10433 (define_insn "*abs<mode>2_1"
10434 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10435 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10437 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10439 [(set_attr "type" "fsgn")
10440 (set_attr "mode" "<MODE>")])
10442 (define_insn "*negextendsfdf2"
10443 [(set (match_operand:DF 0 "register_operand" "=f")
10444 (neg:DF (float_extend:DF
10445 (match_operand:SF 1 "register_operand" "0"))))]
10446 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10448 [(set_attr "type" "fsgn")
10449 (set_attr "mode" "DF")])
10451 (define_insn "*negextenddfxf2"
10452 [(set (match_operand:XF 0 "register_operand" "=f")
10453 (neg:XF (float_extend:XF
10454 (match_operand:DF 1 "register_operand" "0"))))]
10457 [(set_attr "type" "fsgn")
10458 (set_attr "mode" "XF")])
10460 (define_insn "*negextendsfxf2"
10461 [(set (match_operand:XF 0 "register_operand" "=f")
10462 (neg:XF (float_extend:XF
10463 (match_operand:SF 1 "register_operand" "0"))))]
10466 [(set_attr "type" "fsgn")
10467 (set_attr "mode" "XF")])
10469 (define_insn "*absextendsfdf2"
10470 [(set (match_operand:DF 0 "register_operand" "=f")
10471 (abs:DF (float_extend:DF
10472 (match_operand:SF 1 "register_operand" "0"))))]
10473 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10475 [(set_attr "type" "fsgn")
10476 (set_attr "mode" "DF")])
10478 (define_insn "*absextenddfxf2"
10479 [(set (match_operand:XF 0 "register_operand" "=f")
10480 (abs:XF (float_extend:XF
10481 (match_operand:DF 1 "register_operand" "0"))))]
10484 [(set_attr "type" "fsgn")
10485 (set_attr "mode" "XF")])
10487 (define_insn "*absextendsfxf2"
10488 [(set (match_operand:XF 0 "register_operand" "=f")
10489 (abs:XF (float_extend:XF
10490 (match_operand:SF 1 "register_operand" "0"))))]
10493 [(set_attr "type" "fsgn")
10494 (set_attr "mode" "XF")])
10496 ;; Copysign instructions
10498 (define_mode_iterator CSGNMODE [SF DF TF])
10499 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10501 (define_expand "copysign<mode>3"
10502 [(match_operand:CSGNMODE 0 "register_operand" "")
10503 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10504 (match_operand:CSGNMODE 2 "register_operand" "")]
10505 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10506 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10508 ix86_expand_copysign (operands);
10512 (define_insn_and_split "copysign<mode>3_const"
10513 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10515 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10516 (match_operand:CSGNMODE 2 "register_operand" "0")
10517 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10519 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10520 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10522 "&& reload_completed"
10525 ix86_split_copysign_const (operands);
10529 (define_insn "copysign<mode>3_var"
10530 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10532 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10533 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10534 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10535 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10537 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10538 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10539 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10543 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10545 [(match_operand:CSGNMODE 2 "register_operand" "")
10546 (match_operand:CSGNMODE 3 "register_operand" "")
10547 (match_operand:<CSGNVMODE> 4 "" "")
10548 (match_operand:<CSGNVMODE> 5 "" "")]
10550 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10551 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10552 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10553 && reload_completed"
10556 ix86_split_copysign_var (operands);
10560 ;; One complement instructions
10562 (define_expand "one_cmpldi2"
10563 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10564 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10566 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10568 (define_insn "*one_cmpldi2_1_rex64"
10569 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10570 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10571 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10573 [(set_attr "type" "negnot")
10574 (set_attr "mode" "DI")])
10576 (define_insn "*one_cmpldi2_2_rex64"
10577 [(set (reg FLAGS_REG)
10578 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10580 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10581 (not:DI (match_dup 1)))]
10582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10583 && ix86_unary_operator_ok (NOT, DImode, operands)"
10585 [(set_attr "type" "alu1")
10586 (set_attr "mode" "DI")])
10589 [(set (match_operand 0 "flags_reg_operand" "")
10590 (match_operator 2 "compare_operator"
10591 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10593 (set (match_operand:DI 1 "nonimmediate_operand" "")
10594 (not:DI (match_dup 3)))]
10595 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10596 [(parallel [(set (match_dup 0)
10598 [(xor:DI (match_dup 3) (const_int -1))
10601 (xor:DI (match_dup 3) (const_int -1)))])]
10604 (define_expand "one_cmplsi2"
10605 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10606 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10608 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10610 (define_insn "*one_cmplsi2_1"
10611 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10612 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10613 "ix86_unary_operator_ok (NOT, SImode, operands)"
10615 [(set_attr "type" "negnot")
10616 (set_attr "mode" "SI")])
10618 ;; ??? Currently never generated - xor is used instead.
10619 (define_insn "*one_cmplsi2_1_zext"
10620 [(set (match_operand:DI 0 "register_operand" "=r")
10621 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10622 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10624 [(set_attr "type" "negnot")
10625 (set_attr "mode" "SI")])
10627 (define_insn "*one_cmplsi2_2"
10628 [(set (reg FLAGS_REG)
10629 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10631 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10632 (not:SI (match_dup 1)))]
10633 "ix86_match_ccmode (insn, CCNOmode)
10634 && ix86_unary_operator_ok (NOT, SImode, operands)"
10636 [(set_attr "type" "alu1")
10637 (set_attr "mode" "SI")])
10640 [(set (match_operand 0 "flags_reg_operand" "")
10641 (match_operator 2 "compare_operator"
10642 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10644 (set (match_operand:SI 1 "nonimmediate_operand" "")
10645 (not:SI (match_dup 3)))]
10646 "ix86_match_ccmode (insn, CCNOmode)"
10647 [(parallel [(set (match_dup 0)
10648 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10651 (xor:SI (match_dup 3) (const_int -1)))])]
10654 ;; ??? Currently never generated - xor is used instead.
10655 (define_insn "*one_cmplsi2_2_zext"
10656 [(set (reg FLAGS_REG)
10657 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10659 (set (match_operand:DI 0 "register_operand" "=r")
10660 (zero_extend:DI (not:SI (match_dup 1))))]
10661 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10662 && ix86_unary_operator_ok (NOT, SImode, operands)"
10664 [(set_attr "type" "alu1")
10665 (set_attr "mode" "SI")])
10668 [(set (match_operand 0 "flags_reg_operand" "")
10669 (match_operator 2 "compare_operator"
10670 [(not:SI (match_operand:SI 3 "register_operand" ""))
10672 (set (match_operand:DI 1 "register_operand" "")
10673 (zero_extend:DI (not:SI (match_dup 3))))]
10674 "ix86_match_ccmode (insn, CCNOmode)"
10675 [(parallel [(set (match_dup 0)
10676 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10679 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10682 (define_expand "one_cmplhi2"
10683 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10684 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10685 "TARGET_HIMODE_MATH"
10686 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10688 (define_insn "*one_cmplhi2_1"
10689 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10690 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10691 "ix86_unary_operator_ok (NOT, HImode, operands)"
10693 [(set_attr "type" "negnot")
10694 (set_attr "mode" "HI")])
10696 (define_insn "*one_cmplhi2_2"
10697 [(set (reg FLAGS_REG)
10698 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10700 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10701 (not:HI (match_dup 1)))]
10702 "ix86_match_ccmode (insn, CCNOmode)
10703 && ix86_unary_operator_ok (NEG, HImode, operands)"
10705 [(set_attr "type" "alu1")
10706 (set_attr "mode" "HI")])
10709 [(set (match_operand 0 "flags_reg_operand" "")
10710 (match_operator 2 "compare_operator"
10711 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10713 (set (match_operand:HI 1 "nonimmediate_operand" "")
10714 (not:HI (match_dup 3)))]
10715 "ix86_match_ccmode (insn, CCNOmode)"
10716 [(parallel [(set (match_dup 0)
10717 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10720 (xor:HI (match_dup 3) (const_int -1)))])]
10723 ;; %%% Potential partial reg stall on alternative 1. What to do?
10724 (define_expand "one_cmplqi2"
10725 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10726 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10727 "TARGET_QIMODE_MATH"
10728 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10730 (define_insn "*one_cmplqi2_1"
10731 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10732 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10733 "ix86_unary_operator_ok (NOT, QImode, operands)"
10737 [(set_attr "type" "negnot")
10738 (set_attr "mode" "QI,SI")])
10740 (define_insn "*one_cmplqi2_2"
10741 [(set (reg FLAGS_REG)
10742 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10744 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10745 (not:QI (match_dup 1)))]
10746 "ix86_match_ccmode (insn, CCNOmode)
10747 && ix86_unary_operator_ok (NOT, QImode, operands)"
10749 [(set_attr "type" "alu1")
10750 (set_attr "mode" "QI")])
10753 [(set (match_operand 0 "flags_reg_operand" "")
10754 (match_operator 2 "compare_operator"
10755 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10757 (set (match_operand:QI 1 "nonimmediate_operand" "")
10758 (not:QI (match_dup 3)))]
10759 "ix86_match_ccmode (insn, CCNOmode)"
10760 [(parallel [(set (match_dup 0)
10761 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10764 (xor:QI (match_dup 3) (const_int -1)))])]
10767 ;; Arithmetic shift instructions
10769 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10770 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10771 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10772 ;; from the assembler input.
10774 ;; This instruction shifts the target reg/mem as usual, but instead of
10775 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10776 ;; is a left shift double, bits are taken from the high order bits of
10777 ;; reg, else if the insn is a shift right double, bits are taken from the
10778 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10779 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10781 ;; Since sh[lr]d does not change the `reg' operand, that is done
10782 ;; separately, making all shifts emit pairs of shift double and normal
10783 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10784 ;; support a 63 bit shift, each shift where the count is in a reg expands
10785 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10787 ;; If the shift count is a constant, we need never emit more than one
10788 ;; shift pair, instead using moves and sign extension for counts greater
10791 (define_expand "ashlti3"
10792 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10793 (ashift:TI (match_operand:TI 1 "register_operand" "")
10794 (match_operand:QI 2 "nonmemory_operand" "")))
10795 (clobber (reg:CC FLAGS_REG))])]
10798 if (! immediate_operand (operands[2], QImode))
10800 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10803 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10807 (define_insn "ashlti3_1"
10808 [(set (match_operand:TI 0 "register_operand" "=r")
10809 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10810 (match_operand:QI 2 "register_operand" "c")))
10811 (clobber (match_scratch:DI 3 "=&r"))
10812 (clobber (reg:CC FLAGS_REG))]
10815 [(set_attr "type" "multi")])
10817 ;; This pattern must be defined before *ashlti3_2 to prevent
10818 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10820 (define_insn "sse2_ashlti3"
10821 [(set (match_operand:TI 0 "register_operand" "=x")
10822 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10823 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10826 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10827 return "pslldq\t{%2, %0|%0, %2}";
10829 [(set_attr "type" "sseishft")
10830 (set_attr "prefix_data16" "1")
10831 (set_attr "mode" "TI")])
10833 (define_insn "*ashlti3_2"
10834 [(set (match_operand:TI 0 "register_operand" "=r")
10835 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10836 (match_operand:QI 2 "immediate_operand" "O")))
10837 (clobber (reg:CC FLAGS_REG))]
10840 [(set_attr "type" "multi")])
10843 [(set (match_operand:TI 0 "register_operand" "")
10844 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10845 (match_operand:QI 2 "register_operand" "")))
10846 (clobber (match_scratch:DI 3 ""))
10847 (clobber (reg:CC FLAGS_REG))]
10848 "TARGET_64BIT && reload_completed"
10850 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10853 [(set (match_operand:TI 0 "register_operand" "")
10854 (ashift:TI (match_operand:TI 1 "register_operand" "")
10855 (match_operand:QI 2 "immediate_operand" "")))
10856 (clobber (reg:CC FLAGS_REG))]
10857 "TARGET_64BIT && reload_completed"
10859 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10861 (define_insn "x86_64_shld"
10862 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10863 (ior:DI (ashift:DI (match_dup 0)
10864 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10865 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10866 (minus:QI (const_int 64) (match_dup 2)))))
10867 (clobber (reg:CC FLAGS_REG))]
10870 shld{q}\t{%2, %1, %0|%0, %1, %2}
10871 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10872 [(set_attr "type" "ishift")
10873 (set_attr "prefix_0f" "1")
10874 (set_attr "mode" "DI")
10875 (set_attr "athlon_decode" "vector")
10876 (set_attr "amdfam10_decode" "vector")])
10878 (define_expand "x86_64_shift_adj"
10879 [(set (reg:CCZ FLAGS_REG)
10880 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10883 (set (match_operand:DI 0 "register_operand" "")
10884 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10885 (match_operand:DI 1 "register_operand" "")
10888 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10889 (match_operand:DI 3 "register_operand" "r")
10894 (define_expand "ashldi3"
10895 [(set (match_operand:DI 0 "shiftdi_operand" "")
10896 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10897 (match_operand:QI 2 "nonmemory_operand" "")))]
10899 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10901 (define_insn "*ashldi3_1_rex64"
10902 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10903 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10904 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10905 (clobber (reg:CC FLAGS_REG))]
10906 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10908 switch (get_attr_type (insn))
10911 gcc_assert (operands[2] == const1_rtx);
10912 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10913 return "add{q}\t%0, %0";
10916 gcc_assert (CONST_INT_P (operands[2]));
10917 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10918 operands[1] = gen_rtx_MULT (DImode, operands[1],
10919 GEN_INT (1 << INTVAL (operands[2])));
10920 return "lea{q}\t{%a1, %0|%0, %a1}";
10923 if (REG_P (operands[2]))
10924 return "sal{q}\t{%b2, %0|%0, %b2}";
10925 else if (operands[2] == const1_rtx
10926 && (TARGET_SHIFT1 || optimize_size))
10927 return "sal{q}\t%0";
10929 return "sal{q}\t{%2, %0|%0, %2}";
10932 [(set (attr "type")
10933 (cond [(eq_attr "alternative" "1")
10934 (const_string "lea")
10935 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10937 (match_operand 0 "register_operand" ""))
10938 (match_operand 2 "const1_operand" ""))
10939 (const_string "alu")
10941 (const_string "ishift")))
10942 (set_attr "mode" "DI")])
10944 ;; Convert lea to the lea pattern to avoid flags dependency.
10946 [(set (match_operand:DI 0 "register_operand" "")
10947 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10948 (match_operand:QI 2 "immediate_operand" "")))
10949 (clobber (reg:CC FLAGS_REG))]
10950 "TARGET_64BIT && reload_completed
10951 && true_regnum (operands[0]) != true_regnum (operands[1])"
10952 [(set (match_dup 0)
10953 (mult:DI (match_dup 1)
10955 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10957 ;; This pattern can't accept a variable shift count, since shifts by
10958 ;; zero don't affect the flags. We assume that shifts by constant
10959 ;; zero are optimized away.
10960 (define_insn "*ashldi3_cmp_rex64"
10961 [(set (reg FLAGS_REG)
10963 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10964 (match_operand:QI 2 "immediate_operand" "e"))
10966 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10967 (ashift:DI (match_dup 1) (match_dup 2)))]
10970 || !TARGET_PARTIAL_FLAG_REG_STALL
10971 || (operands[2] == const1_rtx
10973 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10974 && ix86_match_ccmode (insn, CCGOCmode)
10975 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10977 switch (get_attr_type (insn))
10980 gcc_assert (operands[2] == const1_rtx);
10981 return "add{q}\t%0, %0";
10984 if (REG_P (operands[2]))
10985 return "sal{q}\t{%b2, %0|%0, %b2}";
10986 else if (operands[2] == const1_rtx
10987 && (TARGET_SHIFT1 || optimize_size))
10988 return "sal{q}\t%0";
10990 return "sal{q}\t{%2, %0|%0, %2}";
10993 [(set (attr "type")
10994 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10996 (match_operand 0 "register_operand" ""))
10997 (match_operand 2 "const1_operand" ""))
10998 (const_string "alu")
11000 (const_string "ishift")))
11001 (set_attr "mode" "DI")])
11003 (define_insn "*ashldi3_cconly_rex64"
11004 [(set (reg FLAGS_REG)
11006 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11007 (match_operand:QI 2 "immediate_operand" "e"))
11009 (clobber (match_scratch:DI 0 "=r"))]
11012 || !TARGET_PARTIAL_FLAG_REG_STALL
11013 || (operands[2] == const1_rtx
11015 || TARGET_DOUBLE_WITH_ADD)))
11016 && ix86_match_ccmode (insn, CCGOCmode)
11017 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11019 switch (get_attr_type (insn))
11022 gcc_assert (operands[2] == const1_rtx);
11023 return "add{q}\t%0, %0";
11026 if (REG_P (operands[2]))
11027 return "sal{q}\t{%b2, %0|%0, %b2}";
11028 else if (operands[2] == const1_rtx
11029 && (TARGET_SHIFT1 || optimize_size))
11030 return "sal{q}\t%0";
11032 return "sal{q}\t{%2, %0|%0, %2}";
11035 [(set (attr "type")
11036 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11038 (match_operand 0 "register_operand" ""))
11039 (match_operand 2 "const1_operand" ""))
11040 (const_string "alu")
11042 (const_string "ishift")))
11043 (set_attr "mode" "DI")])
11045 (define_insn "*ashldi3_1"
11046 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11047 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11048 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11049 (clobber (reg:CC FLAGS_REG))]
11052 [(set_attr "type" "multi")])
11054 ;; By default we don't ask for a scratch register, because when DImode
11055 ;; values are manipulated, registers are already at a premium. But if
11056 ;; we have one handy, we won't turn it away.
11058 [(match_scratch:SI 3 "r")
11059 (parallel [(set (match_operand:DI 0 "register_operand" "")
11060 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11061 (match_operand:QI 2 "nonmemory_operand" "")))
11062 (clobber (reg:CC FLAGS_REG))])
11064 "!TARGET_64BIT && TARGET_CMOVE"
11066 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11069 [(set (match_operand:DI 0 "register_operand" "")
11070 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11071 (match_operand:QI 2 "nonmemory_operand" "")))
11072 (clobber (reg:CC FLAGS_REG))]
11073 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11074 ? epilogue_completed : reload_completed)"
11076 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11078 (define_insn "x86_shld_1"
11079 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11080 (ior:SI (ashift:SI (match_dup 0)
11081 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11082 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11083 (minus:QI (const_int 32) (match_dup 2)))))
11084 (clobber (reg:CC FLAGS_REG))]
11087 shld{l}\t{%2, %1, %0|%0, %1, %2}
11088 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11089 [(set_attr "type" "ishift")
11090 (set_attr "prefix_0f" "1")
11091 (set_attr "mode" "SI")
11092 (set_attr "pent_pair" "np")
11093 (set_attr "athlon_decode" "vector")
11094 (set_attr "amdfam10_decode" "vector")])
11096 (define_expand "x86_shift_adj_1"
11097 [(set (reg:CCZ FLAGS_REG)
11098 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11101 (set (match_operand:SI 0 "register_operand" "")
11102 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11103 (match_operand:SI 1 "register_operand" "")
11106 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11107 (match_operand:SI 3 "register_operand" "r")
11112 (define_expand "x86_shift_adj_2"
11113 [(use (match_operand:SI 0 "register_operand" ""))
11114 (use (match_operand:SI 1 "register_operand" ""))
11115 (use (match_operand:QI 2 "register_operand" ""))]
11118 rtx label = gen_label_rtx ();
11121 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11123 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11124 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11125 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11126 gen_rtx_LABEL_REF (VOIDmode, label),
11128 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11129 JUMP_LABEL (tmp) = label;
11131 emit_move_insn (operands[0], operands[1]);
11132 ix86_expand_clear (operands[1]);
11134 emit_label (label);
11135 LABEL_NUSES (label) = 1;
11140 (define_expand "ashlsi3"
11141 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11142 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11143 (match_operand:QI 2 "nonmemory_operand" "")))
11144 (clobber (reg:CC FLAGS_REG))]
11146 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11148 (define_insn "*ashlsi3_1"
11149 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11150 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11151 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11152 (clobber (reg:CC FLAGS_REG))]
11153 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11155 switch (get_attr_type (insn))
11158 gcc_assert (operands[2] == const1_rtx);
11159 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11160 return "add{l}\t%0, %0";
11166 if (REG_P (operands[2]))
11167 return "sal{l}\t{%b2, %0|%0, %b2}";
11168 else if (operands[2] == const1_rtx
11169 && (TARGET_SHIFT1 || optimize_size))
11170 return "sal{l}\t%0";
11172 return "sal{l}\t{%2, %0|%0, %2}";
11175 [(set (attr "type")
11176 (cond [(eq_attr "alternative" "1")
11177 (const_string "lea")
11178 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11180 (match_operand 0 "register_operand" ""))
11181 (match_operand 2 "const1_operand" ""))
11182 (const_string "alu")
11184 (const_string "ishift")))
11185 (set_attr "mode" "SI")])
11187 ;; Convert lea to the lea pattern to avoid flags dependency.
11189 [(set (match_operand 0 "register_operand" "")
11190 (ashift (match_operand 1 "index_register_operand" "")
11191 (match_operand:QI 2 "const_int_operand" "")))
11192 (clobber (reg:CC FLAGS_REG))]
11194 && true_regnum (operands[0]) != true_regnum (operands[1])
11195 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11199 enum machine_mode mode = GET_MODE (operands[0]);
11201 if (GET_MODE_SIZE (mode) < 4)
11202 operands[0] = gen_lowpart (SImode, operands[0]);
11204 operands[1] = gen_lowpart (Pmode, operands[1]);
11205 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11207 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11208 if (Pmode != SImode)
11209 pat = gen_rtx_SUBREG (SImode, pat, 0);
11210 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11214 ;; Rare case of shifting RSP is handled by generating move and shift
11216 [(set (match_operand 0 "register_operand" "")
11217 (ashift (match_operand 1 "register_operand" "")
11218 (match_operand:QI 2 "const_int_operand" "")))
11219 (clobber (reg:CC FLAGS_REG))]
11221 && true_regnum (operands[0]) != true_regnum (operands[1])"
11225 emit_move_insn (operands[0], operands[1]);
11226 pat = gen_rtx_SET (VOIDmode, operands[0],
11227 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11228 operands[0], operands[2]));
11229 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11230 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11234 (define_insn "*ashlsi3_1_zext"
11235 [(set (match_operand:DI 0 "register_operand" "=r,r")
11236 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11237 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11241 switch (get_attr_type (insn))
11244 gcc_assert (operands[2] == const1_rtx);
11245 return "add{l}\t%k0, %k0";
11251 if (REG_P (operands[2]))
11252 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11253 else if (operands[2] == const1_rtx
11254 && (TARGET_SHIFT1 || optimize_size))
11255 return "sal{l}\t%k0";
11257 return "sal{l}\t{%2, %k0|%k0, %2}";
11260 [(set (attr "type")
11261 (cond [(eq_attr "alternative" "1")
11262 (const_string "lea")
11263 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11265 (match_operand 2 "const1_operand" ""))
11266 (const_string "alu")
11268 (const_string "ishift")))
11269 (set_attr "mode" "SI")])
11271 ;; Convert lea to the lea pattern to avoid flags dependency.
11273 [(set (match_operand:DI 0 "register_operand" "")
11274 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11275 (match_operand:QI 2 "const_int_operand" ""))))
11276 (clobber (reg:CC FLAGS_REG))]
11277 "TARGET_64BIT && reload_completed
11278 && true_regnum (operands[0]) != true_regnum (operands[1])"
11279 [(set (match_dup 0) (zero_extend:DI
11280 (subreg:SI (mult:SI (match_dup 1)
11281 (match_dup 2)) 0)))]
11283 operands[1] = gen_lowpart (Pmode, operands[1]);
11284 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11287 ;; This pattern can't accept a variable shift count, since shifts by
11288 ;; zero don't affect the flags. We assume that shifts by constant
11289 ;; zero are optimized away.
11290 (define_insn "*ashlsi3_cmp"
11291 [(set (reg FLAGS_REG)
11293 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11294 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11296 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11297 (ashift:SI (match_dup 1) (match_dup 2)))]
11299 || !TARGET_PARTIAL_FLAG_REG_STALL
11300 || (operands[2] == const1_rtx
11302 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11303 && ix86_match_ccmode (insn, CCGOCmode)
11304 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11306 switch (get_attr_type (insn))
11309 gcc_assert (operands[2] == const1_rtx);
11310 return "add{l}\t%0, %0";
11313 if (REG_P (operands[2]))
11314 return "sal{l}\t{%b2, %0|%0, %b2}";
11315 else if (operands[2] == const1_rtx
11316 && (TARGET_SHIFT1 || optimize_size))
11317 return "sal{l}\t%0";
11319 return "sal{l}\t{%2, %0|%0, %2}";
11322 [(set (attr "type")
11323 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11325 (match_operand 0 "register_operand" ""))
11326 (match_operand 2 "const1_operand" ""))
11327 (const_string "alu")
11329 (const_string "ishift")))
11330 (set_attr "mode" "SI")])
11332 (define_insn "*ashlsi3_cconly"
11333 [(set (reg FLAGS_REG)
11335 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11336 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11338 (clobber (match_scratch:SI 0 "=r"))]
11340 || !TARGET_PARTIAL_FLAG_REG_STALL
11341 || (operands[2] == const1_rtx
11343 || TARGET_DOUBLE_WITH_ADD)))
11344 && ix86_match_ccmode (insn, CCGOCmode)
11345 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11347 switch (get_attr_type (insn))
11350 gcc_assert (operands[2] == const1_rtx);
11351 return "add{l}\t%0, %0";
11354 if (REG_P (operands[2]))
11355 return "sal{l}\t{%b2, %0|%0, %b2}";
11356 else if (operands[2] == const1_rtx
11357 && (TARGET_SHIFT1 || optimize_size))
11358 return "sal{l}\t%0";
11360 return "sal{l}\t{%2, %0|%0, %2}";
11363 [(set (attr "type")
11364 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11366 (match_operand 0 "register_operand" ""))
11367 (match_operand 2 "const1_operand" ""))
11368 (const_string "alu")
11370 (const_string "ishift")))
11371 (set_attr "mode" "SI")])
11373 (define_insn "*ashlsi3_cmp_zext"
11374 [(set (reg FLAGS_REG)
11376 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11377 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11379 (set (match_operand:DI 0 "register_operand" "=r")
11380 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11383 || !TARGET_PARTIAL_FLAG_REG_STALL
11384 || (operands[2] == const1_rtx
11386 || TARGET_DOUBLE_WITH_ADD)))
11387 && ix86_match_ccmode (insn, CCGOCmode)
11388 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11390 switch (get_attr_type (insn))
11393 gcc_assert (operands[2] == const1_rtx);
11394 return "add{l}\t%k0, %k0";
11397 if (REG_P (operands[2]))
11398 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11399 else if (operands[2] == const1_rtx
11400 && (TARGET_SHIFT1 || optimize_size))
11401 return "sal{l}\t%k0";
11403 return "sal{l}\t{%2, %k0|%k0, %2}";
11406 [(set (attr "type")
11407 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11409 (match_operand 2 "const1_operand" ""))
11410 (const_string "alu")
11412 (const_string "ishift")))
11413 (set_attr "mode" "SI")])
11415 (define_expand "ashlhi3"
11416 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11417 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11418 (match_operand:QI 2 "nonmemory_operand" "")))
11419 (clobber (reg:CC FLAGS_REG))]
11420 "TARGET_HIMODE_MATH"
11421 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11423 (define_insn "*ashlhi3_1_lea"
11424 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11425 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11426 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11427 (clobber (reg:CC FLAGS_REG))]
11428 "!TARGET_PARTIAL_REG_STALL
11429 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11431 switch (get_attr_type (insn))
11436 gcc_assert (operands[2] == const1_rtx);
11437 return "add{w}\t%0, %0";
11440 if (REG_P (operands[2]))
11441 return "sal{w}\t{%b2, %0|%0, %b2}";
11442 else if (operands[2] == const1_rtx
11443 && (TARGET_SHIFT1 || optimize_size))
11444 return "sal{w}\t%0";
11446 return "sal{w}\t{%2, %0|%0, %2}";
11449 [(set (attr "type")
11450 (cond [(eq_attr "alternative" "1")
11451 (const_string "lea")
11452 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11454 (match_operand 0 "register_operand" ""))
11455 (match_operand 2 "const1_operand" ""))
11456 (const_string "alu")
11458 (const_string "ishift")))
11459 (set_attr "mode" "HI,SI")])
11461 (define_insn "*ashlhi3_1"
11462 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11463 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11464 (match_operand:QI 2 "nonmemory_operand" "cI")))
11465 (clobber (reg:CC FLAGS_REG))]
11466 "TARGET_PARTIAL_REG_STALL
11467 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11469 switch (get_attr_type (insn))
11472 gcc_assert (operands[2] == const1_rtx);
11473 return "add{w}\t%0, %0";
11476 if (REG_P (operands[2]))
11477 return "sal{w}\t{%b2, %0|%0, %b2}";
11478 else if (operands[2] == const1_rtx
11479 && (TARGET_SHIFT1 || optimize_size))
11480 return "sal{w}\t%0";
11482 return "sal{w}\t{%2, %0|%0, %2}";
11485 [(set (attr "type")
11486 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11488 (match_operand 0 "register_operand" ""))
11489 (match_operand 2 "const1_operand" ""))
11490 (const_string "alu")
11492 (const_string "ishift")))
11493 (set_attr "mode" "HI")])
11495 ;; This pattern can't accept a variable shift count, since shifts by
11496 ;; zero don't affect the flags. We assume that shifts by constant
11497 ;; zero are optimized away.
11498 (define_insn "*ashlhi3_cmp"
11499 [(set (reg FLAGS_REG)
11501 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11502 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11504 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11505 (ashift:HI (match_dup 1) (match_dup 2)))]
11507 || !TARGET_PARTIAL_FLAG_REG_STALL
11508 || (operands[2] == const1_rtx
11510 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11511 && ix86_match_ccmode (insn, CCGOCmode)
11512 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11514 switch (get_attr_type (insn))
11517 gcc_assert (operands[2] == const1_rtx);
11518 return "add{w}\t%0, %0";
11521 if (REG_P (operands[2]))
11522 return "sal{w}\t{%b2, %0|%0, %b2}";
11523 else if (operands[2] == const1_rtx
11524 && (TARGET_SHIFT1 || optimize_size))
11525 return "sal{w}\t%0";
11527 return "sal{w}\t{%2, %0|%0, %2}";
11530 [(set (attr "type")
11531 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11533 (match_operand 0 "register_operand" ""))
11534 (match_operand 2 "const1_operand" ""))
11535 (const_string "alu")
11537 (const_string "ishift")))
11538 (set_attr "mode" "HI")])
11540 (define_insn "*ashlhi3_cconly"
11541 [(set (reg FLAGS_REG)
11543 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11544 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11546 (clobber (match_scratch:HI 0 "=r"))]
11548 || !TARGET_PARTIAL_FLAG_REG_STALL
11549 || (operands[2] == const1_rtx
11551 || TARGET_DOUBLE_WITH_ADD)))
11552 && ix86_match_ccmode (insn, CCGOCmode)
11553 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11555 switch (get_attr_type (insn))
11558 gcc_assert (operands[2] == const1_rtx);
11559 return "add{w}\t%0, %0";
11562 if (REG_P (operands[2]))
11563 return "sal{w}\t{%b2, %0|%0, %b2}";
11564 else if (operands[2] == const1_rtx
11565 && (TARGET_SHIFT1 || optimize_size))
11566 return "sal{w}\t%0";
11568 return "sal{w}\t{%2, %0|%0, %2}";
11571 [(set (attr "type")
11572 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11574 (match_operand 0 "register_operand" ""))
11575 (match_operand 2 "const1_operand" ""))
11576 (const_string "alu")
11578 (const_string "ishift")))
11579 (set_attr "mode" "HI")])
11581 (define_expand "ashlqi3"
11582 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11583 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11584 (match_operand:QI 2 "nonmemory_operand" "")))
11585 (clobber (reg:CC FLAGS_REG))]
11586 "TARGET_QIMODE_MATH"
11587 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11589 ;; %%% Potential partial reg stall on alternative 2. What to do?
11591 (define_insn "*ashlqi3_1_lea"
11592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11593 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11594 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11595 (clobber (reg:CC FLAGS_REG))]
11596 "!TARGET_PARTIAL_REG_STALL
11597 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11599 switch (get_attr_type (insn))
11604 gcc_assert (operands[2] == const1_rtx);
11605 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11606 return "add{l}\t%k0, %k0";
11608 return "add{b}\t%0, %0";
11611 if (REG_P (operands[2]))
11613 if (get_attr_mode (insn) == MODE_SI)
11614 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11616 return "sal{b}\t{%b2, %0|%0, %b2}";
11618 else if (operands[2] == const1_rtx
11619 && (TARGET_SHIFT1 || optimize_size))
11621 if (get_attr_mode (insn) == MODE_SI)
11622 return "sal{l}\t%0";
11624 return "sal{b}\t%0";
11628 if (get_attr_mode (insn) == MODE_SI)
11629 return "sal{l}\t{%2, %k0|%k0, %2}";
11631 return "sal{b}\t{%2, %0|%0, %2}";
11635 [(set (attr "type")
11636 (cond [(eq_attr "alternative" "2")
11637 (const_string "lea")
11638 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11640 (match_operand 0 "register_operand" ""))
11641 (match_operand 2 "const1_operand" ""))
11642 (const_string "alu")
11644 (const_string "ishift")))
11645 (set_attr "mode" "QI,SI,SI")])
11647 (define_insn "*ashlqi3_1"
11648 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11649 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11650 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11651 (clobber (reg:CC FLAGS_REG))]
11652 "TARGET_PARTIAL_REG_STALL
11653 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11655 switch (get_attr_type (insn))
11658 gcc_assert (operands[2] == const1_rtx);
11659 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11660 return "add{l}\t%k0, %k0";
11662 return "add{b}\t%0, %0";
11665 if (REG_P (operands[2]))
11667 if (get_attr_mode (insn) == MODE_SI)
11668 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11670 return "sal{b}\t{%b2, %0|%0, %b2}";
11672 else if (operands[2] == const1_rtx
11673 && (TARGET_SHIFT1 || optimize_size))
11675 if (get_attr_mode (insn) == MODE_SI)
11676 return "sal{l}\t%0";
11678 return "sal{b}\t%0";
11682 if (get_attr_mode (insn) == MODE_SI)
11683 return "sal{l}\t{%2, %k0|%k0, %2}";
11685 return "sal{b}\t{%2, %0|%0, %2}";
11689 [(set (attr "type")
11690 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11692 (match_operand 0 "register_operand" ""))
11693 (match_operand 2 "const1_operand" ""))
11694 (const_string "alu")
11696 (const_string "ishift")))
11697 (set_attr "mode" "QI,SI")])
11699 ;; This pattern can't accept a variable shift count, since shifts by
11700 ;; zero don't affect the flags. We assume that shifts by constant
11701 ;; zero are optimized away.
11702 (define_insn "*ashlqi3_cmp"
11703 [(set (reg FLAGS_REG)
11705 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11706 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11708 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11709 (ashift:QI (match_dup 1) (match_dup 2)))]
11711 || !TARGET_PARTIAL_FLAG_REG_STALL
11712 || (operands[2] == const1_rtx
11714 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11715 && ix86_match_ccmode (insn, CCGOCmode)
11716 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11718 switch (get_attr_type (insn))
11721 gcc_assert (operands[2] == const1_rtx);
11722 return "add{b}\t%0, %0";
11725 if (REG_P (operands[2]))
11726 return "sal{b}\t{%b2, %0|%0, %b2}";
11727 else if (operands[2] == const1_rtx
11728 && (TARGET_SHIFT1 || optimize_size))
11729 return "sal{b}\t%0";
11731 return "sal{b}\t{%2, %0|%0, %2}";
11734 [(set (attr "type")
11735 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11737 (match_operand 0 "register_operand" ""))
11738 (match_operand 2 "const1_operand" ""))
11739 (const_string "alu")
11741 (const_string "ishift")))
11742 (set_attr "mode" "QI")])
11744 (define_insn "*ashlqi3_cconly"
11745 [(set (reg FLAGS_REG)
11747 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11748 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11750 (clobber (match_scratch:QI 0 "=q"))]
11752 || !TARGET_PARTIAL_FLAG_REG_STALL
11753 || (operands[2] == const1_rtx
11755 || TARGET_DOUBLE_WITH_ADD)))
11756 && ix86_match_ccmode (insn, CCGOCmode)
11757 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11759 switch (get_attr_type (insn))
11762 gcc_assert (operands[2] == const1_rtx);
11763 return "add{b}\t%0, %0";
11766 if (REG_P (operands[2]))
11767 return "sal{b}\t{%b2, %0|%0, %b2}";
11768 else if (operands[2] == const1_rtx
11769 && (TARGET_SHIFT1 || optimize_size))
11770 return "sal{b}\t%0";
11772 return "sal{b}\t{%2, %0|%0, %2}";
11775 [(set (attr "type")
11776 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778 (match_operand 0 "register_operand" ""))
11779 (match_operand 2 "const1_operand" ""))
11780 (const_string "alu")
11782 (const_string "ishift")))
11783 (set_attr "mode" "QI")])
11785 ;; See comment above `ashldi3' about how this works.
11787 (define_expand "ashrti3"
11788 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11789 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11790 (match_operand:QI 2 "nonmemory_operand" "")))
11791 (clobber (reg:CC FLAGS_REG))])]
11794 if (! immediate_operand (operands[2], QImode))
11796 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11799 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11803 (define_insn "ashrti3_1"
11804 [(set (match_operand:TI 0 "register_operand" "=r")
11805 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11806 (match_operand:QI 2 "register_operand" "c")))
11807 (clobber (match_scratch:DI 3 "=&r"))
11808 (clobber (reg:CC FLAGS_REG))]
11811 [(set_attr "type" "multi")])
11813 (define_insn "*ashrti3_2"
11814 [(set (match_operand:TI 0 "register_operand" "=r")
11815 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11816 (match_operand:QI 2 "immediate_operand" "O")))
11817 (clobber (reg:CC FLAGS_REG))]
11820 [(set_attr "type" "multi")])
11823 [(set (match_operand:TI 0 "register_operand" "")
11824 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11825 (match_operand:QI 2 "register_operand" "")))
11826 (clobber (match_scratch:DI 3 ""))
11827 (clobber (reg:CC FLAGS_REG))]
11828 "TARGET_64BIT && reload_completed"
11830 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11833 [(set (match_operand:TI 0 "register_operand" "")
11834 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11835 (match_operand:QI 2 "immediate_operand" "")))
11836 (clobber (reg:CC FLAGS_REG))]
11837 "TARGET_64BIT && reload_completed"
11839 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11841 (define_insn "x86_64_shrd"
11842 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11843 (ior:DI (ashiftrt:DI (match_dup 0)
11844 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11845 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11846 (minus:QI (const_int 64) (match_dup 2)))))
11847 (clobber (reg:CC FLAGS_REG))]
11850 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11851 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11852 [(set_attr "type" "ishift")
11853 (set_attr "prefix_0f" "1")
11854 (set_attr "mode" "DI")
11855 (set_attr "athlon_decode" "vector")
11856 (set_attr "amdfam10_decode" "vector")])
11858 (define_expand "ashrdi3"
11859 [(set (match_operand:DI 0 "shiftdi_operand" "")
11860 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11861 (match_operand:QI 2 "nonmemory_operand" "")))]
11863 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11865 (define_insn "*ashrdi3_63_rex64"
11866 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11867 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11868 (match_operand:DI 2 "const_int_operand" "i,i")))
11869 (clobber (reg:CC FLAGS_REG))]
11870 "TARGET_64BIT && INTVAL (operands[2]) == 63
11871 && (TARGET_USE_CLTD || optimize_size)
11872 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11875 sar{q}\t{%2, %0|%0, %2}"
11876 [(set_attr "type" "imovx,ishift")
11877 (set_attr "prefix_0f" "0,*")
11878 (set_attr "length_immediate" "0,*")
11879 (set_attr "modrm" "0,1")
11880 (set_attr "mode" "DI")])
11882 (define_insn "*ashrdi3_1_one_bit_rex64"
11883 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11884 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "const1_operand" "")))
11886 (clobber (reg:CC FLAGS_REG))]
11888 && (TARGET_SHIFT1 || optimize_size)
11889 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11891 [(set_attr "type" "ishift")
11892 (set (attr "length")
11893 (if_then_else (match_operand:DI 0 "register_operand" "")
11895 (const_string "*")))])
11897 (define_insn "*ashrdi3_1_rex64"
11898 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11899 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11900 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11901 (clobber (reg:CC FLAGS_REG))]
11902 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11904 sar{q}\t{%2, %0|%0, %2}
11905 sar{q}\t{%b2, %0|%0, %b2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "DI")])
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags. We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11913 [(set (reg FLAGS_REG)
11915 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11916 (match_operand:QI 2 "const1_operand" ""))
11918 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11919 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11921 && (TARGET_SHIFT1 || optimize_size)
11922 && ix86_match_ccmode (insn, CCGOCmode)
11923 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11925 [(set_attr "type" "ishift")
11926 (set (attr "length")
11927 (if_then_else (match_operand:DI 0 "register_operand" "")
11929 (const_string "*")))])
11931 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11932 [(set (reg FLAGS_REG)
11934 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const1_operand" ""))
11937 (clobber (match_scratch:DI 0 "=r"))]
11939 && (TARGET_SHIFT1 || optimize_size)
11940 && ix86_match_ccmode (insn, CCGOCmode)
11941 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11943 [(set_attr "type" "ishift")
11944 (set_attr "length" "2")])
11946 ;; This pattern can't accept a variable shift count, since shifts by
11947 ;; zero don't affect the flags. We assume that shifts by constant
11948 ;; zero are optimized away.
11949 (define_insn "*ashrdi3_cmp_rex64"
11950 [(set (reg FLAGS_REG)
11952 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11953 (match_operand:QI 2 "const_int_operand" "n"))
11955 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11956 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11958 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11959 && ix86_match_ccmode (insn, CCGOCmode)
11960 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11961 "sar{q}\t{%2, %0|%0, %2}"
11962 [(set_attr "type" "ishift")
11963 (set_attr "mode" "DI")])
11965 (define_insn "*ashrdi3_cconly_rex64"
11966 [(set (reg FLAGS_REG)
11968 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11969 (match_operand:QI 2 "const_int_operand" "n"))
11971 (clobber (match_scratch:DI 0 "=r"))]
11973 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11974 && ix86_match_ccmode (insn, CCGOCmode)
11975 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11976 "sar{q}\t{%2, %0|%0, %2}"
11977 [(set_attr "type" "ishift")
11978 (set_attr "mode" "DI")])
11980 (define_insn "*ashrdi3_1"
11981 [(set (match_operand:DI 0 "register_operand" "=r")
11982 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11983 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11984 (clobber (reg:CC FLAGS_REG))]
11987 [(set_attr "type" "multi")])
11989 ;; By default we don't ask for a scratch register, because when DImode
11990 ;; values are manipulated, registers are already at a premium. But if
11991 ;; we have one handy, we won't turn it away.
11993 [(match_scratch:SI 3 "r")
11994 (parallel [(set (match_operand:DI 0 "register_operand" "")
11995 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11996 (match_operand:QI 2 "nonmemory_operand" "")))
11997 (clobber (reg:CC FLAGS_REG))])
11999 "!TARGET_64BIT && TARGET_CMOVE"
12001 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12004 [(set (match_operand:DI 0 "register_operand" "")
12005 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12006 (match_operand:QI 2 "nonmemory_operand" "")))
12007 (clobber (reg:CC FLAGS_REG))]
12008 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12009 ? epilogue_completed : reload_completed)"
12011 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12013 (define_insn "x86_shrd_1"
12014 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12015 (ior:SI (ashiftrt:SI (match_dup 0)
12016 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12017 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12018 (minus:QI (const_int 32) (match_dup 2)))))
12019 (clobber (reg:CC FLAGS_REG))]
12022 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12023 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12024 [(set_attr "type" "ishift")
12025 (set_attr "prefix_0f" "1")
12026 (set_attr "pent_pair" "np")
12027 (set_attr "mode" "SI")])
12029 (define_expand "x86_shift_adj_3"
12030 [(use (match_operand:SI 0 "register_operand" ""))
12031 (use (match_operand:SI 1 "register_operand" ""))
12032 (use (match_operand:QI 2 "register_operand" ""))]
12035 rtx label = gen_label_rtx ();
12038 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12040 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12041 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12042 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12043 gen_rtx_LABEL_REF (VOIDmode, label),
12045 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12046 JUMP_LABEL (tmp) = label;
12048 emit_move_insn (operands[0], operands[1]);
12049 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12051 emit_label (label);
12052 LABEL_NUSES (label) = 1;
12057 (define_insn "ashrsi3_31"
12058 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12059 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12060 (match_operand:SI 2 "const_int_operand" "i,i")))
12061 (clobber (reg:CC FLAGS_REG))]
12062 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12063 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12066 sar{l}\t{%2, %0|%0, %2}"
12067 [(set_attr "type" "imovx,ishift")
12068 (set_attr "prefix_0f" "0,*")
12069 (set_attr "length_immediate" "0,*")
12070 (set_attr "modrm" "0,1")
12071 (set_attr "mode" "SI")])
12073 (define_insn "*ashrsi3_31_zext"
12074 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12075 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12076 (match_operand:SI 2 "const_int_operand" "i,i"))))
12077 (clobber (reg:CC FLAGS_REG))]
12078 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12079 && INTVAL (operands[2]) == 31
12080 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12083 sar{l}\t{%2, %k0|%k0, %2}"
12084 [(set_attr "type" "imovx,ishift")
12085 (set_attr "prefix_0f" "0,*")
12086 (set_attr "length_immediate" "0,*")
12087 (set_attr "modrm" "0,1")
12088 (set_attr "mode" "SI")])
12090 (define_expand "ashrsi3"
12091 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12092 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12093 (match_operand:QI 2 "nonmemory_operand" "")))
12094 (clobber (reg:CC FLAGS_REG))]
12096 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12098 (define_insn "*ashrsi3_1_one_bit"
12099 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12100 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12101 (match_operand:QI 2 "const1_operand" "")))
12102 (clobber (reg:CC FLAGS_REG))]
12103 "(TARGET_SHIFT1 || optimize_size)
12104 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12106 [(set_attr "type" "ishift")
12107 (set (attr "length")
12108 (if_then_else (match_operand:SI 0 "register_operand" "")
12110 (const_string "*")))])
12112 (define_insn "*ashrsi3_1_one_bit_zext"
12113 [(set (match_operand:DI 0 "register_operand" "=r")
12114 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12115 (match_operand:QI 2 "const1_operand" ""))))
12116 (clobber (reg:CC FLAGS_REG))]
12118 && (TARGET_SHIFT1 || optimize_size)
12119 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12121 [(set_attr "type" "ishift")
12122 (set_attr "length" "2")])
12124 (define_insn "*ashrsi3_1"
12125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12126 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12127 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12128 (clobber (reg:CC FLAGS_REG))]
12129 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12131 sar{l}\t{%2, %0|%0, %2}
12132 sar{l}\t{%b2, %0|%0, %b2}"
12133 [(set_attr "type" "ishift")
12134 (set_attr "mode" "SI")])
12136 (define_insn "*ashrsi3_1_zext"
12137 [(set (match_operand:DI 0 "register_operand" "=r,r")
12138 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12140 (clobber (reg:CC FLAGS_REG))]
12141 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12143 sar{l}\t{%2, %k0|%k0, %2}
12144 sar{l}\t{%b2, %k0|%k0, %b2}"
12145 [(set_attr "type" "ishift")
12146 (set_attr "mode" "SI")])
12148 ;; This pattern can't accept a variable shift count, since shifts by
12149 ;; zero don't affect the flags. We assume that shifts by constant
12150 ;; zero are optimized away.
12151 (define_insn "*ashrsi3_one_bit_cmp"
12152 [(set (reg FLAGS_REG)
12154 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12155 (match_operand:QI 2 "const1_operand" ""))
12157 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12158 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12159 "(TARGET_SHIFT1 || optimize_size)
12160 && ix86_match_ccmode (insn, CCGOCmode)
12161 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12163 [(set_attr "type" "ishift")
12164 (set (attr "length")
12165 (if_then_else (match_operand:SI 0 "register_operand" "")
12167 (const_string "*")))])
12169 (define_insn "*ashrsi3_one_bit_cconly"
12170 [(set (reg FLAGS_REG)
12172 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12173 (match_operand:QI 2 "const1_operand" ""))
12175 (clobber (match_scratch:SI 0 "=r"))]
12176 "(TARGET_SHIFT1 || optimize_size)
12177 && ix86_match_ccmode (insn, CCGOCmode)
12178 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12180 [(set_attr "type" "ishift")
12181 (set_attr "length" "2")])
12183 (define_insn "*ashrsi3_one_bit_cmp_zext"
12184 [(set (reg FLAGS_REG)
12186 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12187 (match_operand:QI 2 "const1_operand" ""))
12189 (set (match_operand:DI 0 "register_operand" "=r")
12190 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12192 && (TARGET_SHIFT1 || optimize_size)
12193 && ix86_match_ccmode (insn, CCmode)
12194 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12196 [(set_attr "type" "ishift")
12197 (set_attr "length" "2")])
12199 ;; This pattern can't accept a variable shift count, since shifts by
12200 ;; zero don't affect the flags. We assume that shifts by constant
12201 ;; zero are optimized away.
12202 (define_insn "*ashrsi3_cmp"
12203 [(set (reg FLAGS_REG)
12205 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12206 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12208 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12210 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12211 && ix86_match_ccmode (insn, CCGOCmode)
12212 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12213 "sar{l}\t{%2, %0|%0, %2}"
12214 [(set_attr "type" "ishift")
12215 (set_attr "mode" "SI")])
12217 (define_insn "*ashrsi3_cconly"
12218 [(set (reg FLAGS_REG)
12220 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12221 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12223 (clobber (match_scratch:SI 0 "=r"))]
12224 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12225 && ix86_match_ccmode (insn, CCGOCmode)
12226 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12227 "sar{l}\t{%2, %0|%0, %2}"
12228 [(set_attr "type" "ishift")
12229 (set_attr "mode" "SI")])
12231 (define_insn "*ashrsi3_cmp_zext"
12232 [(set (reg FLAGS_REG)
12234 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12235 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12237 (set (match_operand:DI 0 "register_operand" "=r")
12238 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12240 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12241 && ix86_match_ccmode (insn, CCGOCmode)
12242 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12243 "sar{l}\t{%2, %k0|%k0, %2}"
12244 [(set_attr "type" "ishift")
12245 (set_attr "mode" "SI")])
12247 (define_expand "ashrhi3"
12248 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12249 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12250 (match_operand:QI 2 "nonmemory_operand" "")))
12251 (clobber (reg:CC FLAGS_REG))]
12252 "TARGET_HIMODE_MATH"
12253 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12255 (define_insn "*ashrhi3_1_one_bit"
12256 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12257 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12258 (match_operand:QI 2 "const1_operand" "")))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "(TARGET_SHIFT1 || optimize_size)
12261 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12263 [(set_attr "type" "ishift")
12264 (set (attr "length")
12265 (if_then_else (match_operand 0 "register_operand" "")
12267 (const_string "*")))])
12269 (define_insn "*ashrhi3_1"
12270 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12271 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12272 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12273 (clobber (reg:CC FLAGS_REG))]
12274 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12276 sar{w}\t{%2, %0|%0, %2}
12277 sar{w}\t{%b2, %0|%0, %b2}"
12278 [(set_attr "type" "ishift")
12279 (set_attr "mode" "HI")])
12281 ;; This pattern can't accept a variable shift count, since shifts by
12282 ;; zero don't affect the flags. We assume that shifts by constant
12283 ;; zero are optimized away.
12284 (define_insn "*ashrhi3_one_bit_cmp"
12285 [(set (reg FLAGS_REG)
12287 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12288 (match_operand:QI 2 "const1_operand" ""))
12290 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12291 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12292 "(TARGET_SHIFT1 || optimize_size)
12293 && ix86_match_ccmode (insn, CCGOCmode)
12294 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12296 [(set_attr "type" "ishift")
12297 (set (attr "length")
12298 (if_then_else (match_operand 0 "register_operand" "")
12300 (const_string "*")))])
12302 (define_insn "*ashrhi3_one_bit_cconly"
12303 [(set (reg FLAGS_REG)
12305 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12306 (match_operand:QI 2 "const1_operand" ""))
12308 (clobber (match_scratch:HI 0 "=r"))]
12309 "(TARGET_SHIFT1 || optimize_size)
12310 && ix86_match_ccmode (insn, CCGOCmode)
12311 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12313 [(set_attr "type" "ishift")
12314 (set_attr "length" "2")])
12316 ;; This pattern can't accept a variable shift count, since shifts by
12317 ;; zero don't affect the flags. We assume that shifts by constant
12318 ;; zero are optimized away.
12319 (define_insn "*ashrhi3_cmp"
12320 [(set (reg FLAGS_REG)
12322 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12323 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12325 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12326 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12327 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12328 && ix86_match_ccmode (insn, CCGOCmode)
12329 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12330 "sar{w}\t{%2, %0|%0, %2}"
12331 [(set_attr "type" "ishift")
12332 (set_attr "mode" "HI")])
12334 (define_insn "*ashrhi3_cconly"
12335 [(set (reg FLAGS_REG)
12337 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12338 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12340 (clobber (match_scratch:HI 0 "=r"))]
12341 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12342 && ix86_match_ccmode (insn, CCGOCmode)
12343 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12344 "sar{w}\t{%2, %0|%0, %2}"
12345 [(set_attr "type" "ishift")
12346 (set_attr "mode" "HI")])
12348 (define_expand "ashrqi3"
12349 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12350 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12351 (match_operand:QI 2 "nonmemory_operand" "")))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "TARGET_QIMODE_MATH"
12354 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12356 (define_insn "*ashrqi3_1_one_bit"
12357 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12358 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12359 (match_operand:QI 2 "const1_operand" "")))
12360 (clobber (reg:CC FLAGS_REG))]
12361 "(TARGET_SHIFT1 || optimize_size)
12362 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12364 [(set_attr "type" "ishift")
12365 (set (attr "length")
12366 (if_then_else (match_operand 0 "register_operand" "")
12368 (const_string "*")))])
12370 (define_insn "*ashrqi3_1_one_bit_slp"
12371 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12372 (ashiftrt:QI (match_dup 0)
12373 (match_operand:QI 1 "const1_operand" "")))
12374 (clobber (reg:CC FLAGS_REG))]
12375 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12376 && (TARGET_SHIFT1 || optimize_size)
12377 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12379 [(set_attr "type" "ishift1")
12380 (set (attr "length")
12381 (if_then_else (match_operand 0 "register_operand" "")
12383 (const_string "*")))])
12385 (define_insn "*ashrqi3_1"
12386 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12387 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12388 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12389 (clobber (reg:CC FLAGS_REG))]
12390 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12392 sar{b}\t{%2, %0|%0, %2}
12393 sar{b}\t{%b2, %0|%0, %b2}"
12394 [(set_attr "type" "ishift")
12395 (set_attr "mode" "QI")])
12397 (define_insn "*ashrqi3_1_slp"
12398 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12399 (ashiftrt:QI (match_dup 0)
12400 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12403 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12405 sar{b}\t{%1, %0|%0, %1}
12406 sar{b}\t{%b1, %0|%0, %b1}"
12407 [(set_attr "type" "ishift1")
12408 (set_attr "mode" "QI")])
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 "*ashrqi3_one_bit_cmp"
12414 [(set (reg FLAGS_REG)
12416 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12417 (match_operand:QI 2 "const1_operand" "I"))
12419 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12420 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12421 "(TARGET_SHIFT1 || optimize_size)
12422 && ix86_match_ccmode (insn, CCGOCmode)
12423 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12425 [(set_attr "type" "ishift")
12426 (set (attr "length")
12427 (if_then_else (match_operand 0 "register_operand" "")
12429 (const_string "*")))])
12431 (define_insn "*ashrqi3_one_bit_cconly"
12432 [(set (reg FLAGS_REG)
12434 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12435 (match_operand:QI 2 "const1_operand" "I"))
12437 (clobber (match_scratch:QI 0 "=q"))]
12438 "(TARGET_SHIFT1 || optimize_size)
12439 && ix86_match_ccmode (insn, CCGOCmode)
12440 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12442 [(set_attr "type" "ishift")
12443 (set_attr "length" "2")])
12445 ;; This pattern can't accept a variable shift count, since shifts by
12446 ;; zero don't affect the flags. We assume that shifts by constant
12447 ;; zero are optimized away.
12448 (define_insn "*ashrqi3_cmp"
12449 [(set (reg FLAGS_REG)
12451 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12452 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12454 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12455 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12456 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12457 && ix86_match_ccmode (insn, CCGOCmode)
12458 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12459 "sar{b}\t{%2, %0|%0, %2}"
12460 [(set_attr "type" "ishift")
12461 (set_attr "mode" "QI")])
12463 (define_insn "*ashrqi3_cconly"
12464 [(set (reg FLAGS_REG)
12466 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12467 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12469 (clobber (match_scratch:QI 0 "=q"))]
12470 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12471 && ix86_match_ccmode (insn, CCGOCmode)
12472 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12473 "sar{b}\t{%2, %0|%0, %2}"
12474 [(set_attr "type" "ishift")
12475 (set_attr "mode" "QI")])
12478 ;; Logical shift instructions
12480 ;; See comment above `ashldi3' about how this works.
12482 (define_expand "lshrti3"
12483 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12484 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12485 (match_operand:QI 2 "nonmemory_operand" "")))
12486 (clobber (reg:CC FLAGS_REG))])]
12489 if (! immediate_operand (operands[2], QImode))
12491 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12494 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12498 (define_insn "lshrti3_1"
12499 [(set (match_operand:TI 0 "register_operand" "=r")
12500 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12501 (match_operand:QI 2 "register_operand" "c")))
12502 (clobber (match_scratch:DI 3 "=&r"))
12503 (clobber (reg:CC FLAGS_REG))]
12506 [(set_attr "type" "multi")])
12508 ;; This pattern must be defined before *lshrti3_2 to prevent
12509 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12511 (define_insn "sse2_lshrti3"
12512 [(set (match_operand:TI 0 "register_operand" "=x")
12513 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12514 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12517 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12518 return "psrldq\t{%2, %0|%0, %2}";
12520 [(set_attr "type" "sseishft")
12521 (set_attr "prefix_data16" "1")
12522 (set_attr "mode" "TI")])
12524 (define_insn "*lshrti3_2"
12525 [(set (match_operand:TI 0 "register_operand" "=r")
12526 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12527 (match_operand:QI 2 "immediate_operand" "O")))
12528 (clobber (reg:CC FLAGS_REG))]
12531 [(set_attr "type" "multi")])
12534 [(set (match_operand:TI 0 "register_operand" "")
12535 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12536 (match_operand:QI 2 "register_operand" "")))
12537 (clobber (match_scratch:DI 3 ""))
12538 (clobber (reg:CC FLAGS_REG))]
12539 "TARGET_64BIT && reload_completed"
12541 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12544 [(set (match_operand:TI 0 "register_operand" "")
12545 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12546 (match_operand:QI 2 "immediate_operand" "")))
12547 (clobber (reg:CC FLAGS_REG))]
12548 "TARGET_64BIT && reload_completed"
12550 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12552 (define_expand "lshrdi3"
12553 [(set (match_operand:DI 0 "shiftdi_operand" "")
12554 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12555 (match_operand:QI 2 "nonmemory_operand" "")))]
12557 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12559 (define_insn "*lshrdi3_1_one_bit_rex64"
12560 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12561 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12562 (match_operand:QI 2 "const1_operand" "")))
12563 (clobber (reg:CC FLAGS_REG))]
12565 && (TARGET_SHIFT1 || optimize_size)
12566 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12568 [(set_attr "type" "ishift")
12569 (set (attr "length")
12570 (if_then_else (match_operand:DI 0 "register_operand" "")
12572 (const_string "*")))])
12574 (define_insn "*lshrdi3_1_rex64"
12575 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12576 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12577 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12578 (clobber (reg:CC FLAGS_REG))]
12579 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12581 shr{q}\t{%2, %0|%0, %2}
12582 shr{q}\t{%b2, %0|%0, %b2}"
12583 [(set_attr "type" "ishift")
12584 (set_attr "mode" "DI")])
12586 ;; This pattern can't accept a variable shift count, since shifts by
12587 ;; zero don't affect the flags. We assume that shifts by constant
12588 ;; zero are optimized away.
12589 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12590 [(set (reg FLAGS_REG)
12592 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12593 (match_operand:QI 2 "const1_operand" ""))
12595 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12596 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12598 && (TARGET_SHIFT1 || optimize_size)
12599 && ix86_match_ccmode (insn, CCGOCmode)
12600 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12602 [(set_attr "type" "ishift")
12603 (set (attr "length")
12604 (if_then_else (match_operand:DI 0 "register_operand" "")
12606 (const_string "*")))])
12608 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12609 [(set (reg FLAGS_REG)
12611 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12612 (match_operand:QI 2 "const1_operand" ""))
12614 (clobber (match_scratch:DI 0 "=r"))]
12616 && (TARGET_SHIFT1 || optimize_size)
12617 && ix86_match_ccmode (insn, CCGOCmode)
12618 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12620 [(set_attr "type" "ishift")
12621 (set_attr "length" "2")])
12623 ;; This pattern can't accept a variable shift count, since shifts by
12624 ;; zero don't affect the flags. We assume that shifts by constant
12625 ;; zero are optimized away.
12626 (define_insn "*lshrdi3_cmp_rex64"
12627 [(set (reg FLAGS_REG)
12629 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12630 (match_operand:QI 2 "const_int_operand" "e"))
12632 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12633 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12635 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12636 && ix86_match_ccmode (insn, CCGOCmode)
12637 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12638 "shr{q}\t{%2, %0|%0, %2}"
12639 [(set_attr "type" "ishift")
12640 (set_attr "mode" "DI")])
12642 (define_insn "*lshrdi3_cconly_rex64"
12643 [(set (reg FLAGS_REG)
12645 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12646 (match_operand:QI 2 "const_int_operand" "e"))
12648 (clobber (match_scratch:DI 0 "=r"))]
12650 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12651 && ix86_match_ccmode (insn, CCGOCmode)
12652 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12653 "shr{q}\t{%2, %0|%0, %2}"
12654 [(set_attr "type" "ishift")
12655 (set_attr "mode" "DI")])
12657 (define_insn "*lshrdi3_1"
12658 [(set (match_operand:DI 0 "register_operand" "=r")
12659 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12660 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12661 (clobber (reg:CC FLAGS_REG))]
12664 [(set_attr "type" "multi")])
12666 ;; By default we don't ask for a scratch register, because when DImode
12667 ;; values are manipulated, registers are already at a premium. But if
12668 ;; we have one handy, we won't turn it away.
12670 [(match_scratch:SI 3 "r")
12671 (parallel [(set (match_operand:DI 0 "register_operand" "")
12672 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12673 (match_operand:QI 2 "nonmemory_operand" "")))
12674 (clobber (reg:CC FLAGS_REG))])
12676 "!TARGET_64BIT && TARGET_CMOVE"
12678 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12681 [(set (match_operand:DI 0 "register_operand" "")
12682 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12683 (match_operand:QI 2 "nonmemory_operand" "")))
12684 (clobber (reg:CC FLAGS_REG))]
12685 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12686 ? epilogue_completed : reload_completed)"
12688 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12690 (define_expand "lshrsi3"
12691 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12692 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12693 (match_operand:QI 2 "nonmemory_operand" "")))
12694 (clobber (reg:CC FLAGS_REG))]
12696 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12698 (define_insn "*lshrsi3_1_one_bit"
12699 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12700 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12701 (match_operand:QI 2 "const1_operand" "")))
12702 (clobber (reg:CC FLAGS_REG))]
12703 "(TARGET_SHIFT1 || optimize_size)
12704 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12706 [(set_attr "type" "ishift")
12707 (set (attr "length")
12708 (if_then_else (match_operand:SI 0 "register_operand" "")
12710 (const_string "*")))])
12712 (define_insn "*lshrsi3_1_one_bit_zext"
12713 [(set (match_operand:DI 0 "register_operand" "=r")
12714 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12715 (match_operand:QI 2 "const1_operand" "")))
12716 (clobber (reg:CC FLAGS_REG))]
12718 && (TARGET_SHIFT1 || optimize_size)
12719 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12721 [(set_attr "type" "ishift")
12722 (set_attr "length" "2")])
12724 (define_insn "*lshrsi3_1"
12725 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12726 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12727 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12728 (clobber (reg:CC FLAGS_REG))]
12729 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12731 shr{l}\t{%2, %0|%0, %2}
12732 shr{l}\t{%b2, %0|%0, %b2}"
12733 [(set_attr "type" "ishift")
12734 (set_attr "mode" "SI")])
12736 (define_insn "*lshrsi3_1_zext"
12737 [(set (match_operand:DI 0 "register_operand" "=r,r")
12739 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12740 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12741 (clobber (reg:CC FLAGS_REG))]
12742 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12744 shr{l}\t{%2, %k0|%k0, %2}
12745 shr{l}\t{%b2, %k0|%k0, %b2}"
12746 [(set_attr "type" "ishift")
12747 (set_attr "mode" "SI")])
12749 ;; This pattern can't accept a variable shift count, since shifts by
12750 ;; zero don't affect the flags. We assume that shifts by constant
12751 ;; zero are optimized away.
12752 (define_insn "*lshrsi3_one_bit_cmp"
12753 [(set (reg FLAGS_REG)
12755 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12756 (match_operand:QI 2 "const1_operand" ""))
12758 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12759 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12760 "(TARGET_SHIFT1 || optimize_size)
12761 && ix86_match_ccmode (insn, CCGOCmode)
12762 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12764 [(set_attr "type" "ishift")
12765 (set (attr "length")
12766 (if_then_else (match_operand:SI 0 "register_operand" "")
12768 (const_string "*")))])
12770 (define_insn "*lshrsi3_one_bit_cconly"
12771 [(set (reg FLAGS_REG)
12773 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12774 (match_operand:QI 2 "const1_operand" ""))
12776 (clobber (match_scratch:SI 0 "=r"))]
12777 "(TARGET_SHIFT1 || optimize_size)
12778 && ix86_match_ccmode (insn, CCGOCmode)
12779 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781 [(set_attr "type" "ishift")
12782 (set_attr "length" "2")])
12784 (define_insn "*lshrsi3_cmp_one_bit_zext"
12785 [(set (reg FLAGS_REG)
12787 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12788 (match_operand:QI 2 "const1_operand" ""))
12790 (set (match_operand:DI 0 "register_operand" "=r")
12791 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12793 && (TARGET_SHIFT1 || optimize_size)
12794 && ix86_match_ccmode (insn, CCGOCmode)
12795 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12797 [(set_attr "type" "ishift")
12798 (set_attr "length" "2")])
12800 ;; This pattern can't accept a variable shift count, since shifts by
12801 ;; zero don't affect the flags. We assume that shifts by constant
12802 ;; zero are optimized away.
12803 (define_insn "*lshrsi3_cmp"
12804 [(set (reg FLAGS_REG)
12806 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12807 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12809 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12810 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12811 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12812 && ix86_match_ccmode (insn, CCGOCmode)
12813 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12814 "shr{l}\t{%2, %0|%0, %2}"
12815 [(set_attr "type" "ishift")
12816 (set_attr "mode" "SI")])
12818 (define_insn "*lshrsi3_cconly"
12819 [(set (reg FLAGS_REG)
12821 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12822 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12824 (clobber (match_scratch:SI 0 "=r"))]
12825 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12826 && ix86_match_ccmode (insn, CCGOCmode)
12827 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12828 "shr{l}\t{%2, %0|%0, %2}"
12829 [(set_attr "type" "ishift")
12830 (set_attr "mode" "SI")])
12832 (define_insn "*lshrsi3_cmp_zext"
12833 [(set (reg FLAGS_REG)
12835 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12836 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12838 (set (match_operand:DI 0 "register_operand" "=r")
12839 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12841 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12842 && ix86_match_ccmode (insn, CCGOCmode)
12843 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12844 "shr{l}\t{%2, %k0|%k0, %2}"
12845 [(set_attr "type" "ishift")
12846 (set_attr "mode" "SI")])
12848 (define_expand "lshrhi3"
12849 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12850 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12851 (match_operand:QI 2 "nonmemory_operand" "")))
12852 (clobber (reg:CC FLAGS_REG))]
12853 "TARGET_HIMODE_MATH"
12854 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12856 (define_insn "*lshrhi3_1_one_bit"
12857 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12858 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12859 (match_operand:QI 2 "const1_operand" "")))
12860 (clobber (reg:CC FLAGS_REG))]
12861 "(TARGET_SHIFT1 || optimize_size)
12862 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12864 [(set_attr "type" "ishift")
12865 (set (attr "length")
12866 (if_then_else (match_operand 0 "register_operand" "")
12868 (const_string "*")))])
12870 (define_insn "*lshrhi3_1"
12871 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12872 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12873 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12874 (clobber (reg:CC FLAGS_REG))]
12875 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12877 shr{w}\t{%2, %0|%0, %2}
12878 shr{w}\t{%b2, %0|%0, %b2}"
12879 [(set_attr "type" "ishift")
12880 (set_attr "mode" "HI")])
12882 ;; This pattern can't accept a variable shift count, since shifts by
12883 ;; zero don't affect the flags. We assume that shifts by constant
12884 ;; zero are optimized away.
12885 (define_insn "*lshrhi3_one_bit_cmp"
12886 [(set (reg FLAGS_REG)
12888 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12889 (match_operand:QI 2 "const1_operand" ""))
12891 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12892 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12893 "(TARGET_SHIFT1 || optimize_size)
12894 && ix86_match_ccmode (insn, CCGOCmode)
12895 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897 [(set_attr "type" "ishift")
12898 (set (attr "length")
12899 (if_then_else (match_operand:SI 0 "register_operand" "")
12901 (const_string "*")))])
12903 (define_insn "*lshrhi3_one_bit_cconly"
12904 [(set (reg FLAGS_REG)
12906 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12907 (match_operand:QI 2 "const1_operand" ""))
12909 (clobber (match_scratch:HI 0 "=r"))]
12910 "(TARGET_SHIFT1 || optimize_size)
12911 && ix86_match_ccmode (insn, CCGOCmode)
12912 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12914 [(set_attr "type" "ishift")
12915 (set_attr "length" "2")])
12917 ;; This pattern can't accept a variable shift count, since shifts by
12918 ;; zero don't affect the flags. We assume that shifts by constant
12919 ;; zero are optimized away.
12920 (define_insn "*lshrhi3_cmp"
12921 [(set (reg FLAGS_REG)
12923 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12924 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12926 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12927 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12928 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12929 && ix86_match_ccmode (insn, CCGOCmode)
12930 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12931 "shr{w}\t{%2, %0|%0, %2}"
12932 [(set_attr "type" "ishift")
12933 (set_attr "mode" "HI")])
12935 (define_insn "*lshrhi3_cconly"
12936 [(set (reg FLAGS_REG)
12938 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12939 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12941 (clobber (match_scratch:HI 0 "=r"))]
12942 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12943 && ix86_match_ccmode (insn, CCGOCmode)
12944 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12945 "shr{w}\t{%2, %0|%0, %2}"
12946 [(set_attr "type" "ishift")
12947 (set_attr "mode" "HI")])
12949 (define_expand "lshrqi3"
12950 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12951 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12952 (match_operand:QI 2 "nonmemory_operand" "")))
12953 (clobber (reg:CC FLAGS_REG))]
12954 "TARGET_QIMODE_MATH"
12955 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12957 (define_insn "*lshrqi3_1_one_bit"
12958 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12959 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12960 (match_operand:QI 2 "const1_operand" "")))
12961 (clobber (reg:CC FLAGS_REG))]
12962 "(TARGET_SHIFT1 || optimize_size)
12963 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12965 [(set_attr "type" "ishift")
12966 (set (attr "length")
12967 (if_then_else (match_operand 0 "register_operand" "")
12969 (const_string "*")))])
12971 (define_insn "*lshrqi3_1_one_bit_slp"
12972 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12973 (lshiftrt:QI (match_dup 0)
12974 (match_operand:QI 1 "const1_operand" "")))
12975 (clobber (reg:CC FLAGS_REG))]
12976 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12977 && (TARGET_SHIFT1 || optimize_size)"
12979 [(set_attr "type" "ishift1")
12980 (set (attr "length")
12981 (if_then_else (match_operand 0 "register_operand" "")
12983 (const_string "*")))])
12985 (define_insn "*lshrqi3_1"
12986 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12987 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12988 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12989 (clobber (reg:CC FLAGS_REG))]
12990 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12992 shr{b}\t{%2, %0|%0, %2}
12993 shr{b}\t{%b2, %0|%0, %b2}"
12994 [(set_attr "type" "ishift")
12995 (set_attr "mode" "QI")])
12997 (define_insn "*lshrqi3_1_slp"
12998 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12999 (lshiftrt:QI (match_dup 0)
13000 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13001 (clobber (reg:CC FLAGS_REG))]
13002 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13003 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13005 shr{b}\t{%1, %0|%0, %1}
13006 shr{b}\t{%b1, %0|%0, %b1}"
13007 [(set_attr "type" "ishift1")
13008 (set_attr "mode" "QI")])
13010 ;; This pattern can't accept a variable shift count, since shifts by
13011 ;; zero don't affect the flags. We assume that shifts by constant
13012 ;; zero are optimized away.
13013 (define_insn "*lshrqi2_one_bit_cmp"
13014 [(set (reg FLAGS_REG)
13016 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13017 (match_operand:QI 2 "const1_operand" ""))
13019 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13020 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13021 "(TARGET_SHIFT1 || optimize_size)
13022 && ix86_match_ccmode (insn, CCGOCmode)
13023 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13025 [(set_attr "type" "ishift")
13026 (set (attr "length")
13027 (if_then_else (match_operand:SI 0 "register_operand" "")
13029 (const_string "*")))])
13031 (define_insn "*lshrqi2_one_bit_cconly"
13032 [(set (reg FLAGS_REG)
13034 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13035 (match_operand:QI 2 "const1_operand" ""))
13037 (clobber (match_scratch:QI 0 "=q"))]
13038 "(TARGET_SHIFT1 || optimize_size)
13039 && ix86_match_ccmode (insn, CCGOCmode)
13040 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13042 [(set_attr "type" "ishift")
13043 (set_attr "length" "2")])
13045 ;; This pattern can't accept a variable shift count, since shifts by
13046 ;; zero don't affect the flags. We assume that shifts by constant
13047 ;; zero are optimized away.
13048 (define_insn "*lshrqi2_cmp"
13049 [(set (reg FLAGS_REG)
13051 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13052 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13054 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13055 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13056 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13057 && ix86_match_ccmode (insn, CCGOCmode)
13058 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13059 "shr{b}\t{%2, %0|%0, %2}"
13060 [(set_attr "type" "ishift")
13061 (set_attr "mode" "QI")])
13063 (define_insn "*lshrqi2_cconly"
13064 [(set (reg FLAGS_REG)
13066 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13067 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13069 (clobber (match_scratch:QI 0 "=q"))]
13070 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13071 && ix86_match_ccmode (insn, CCGOCmode)
13072 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13073 "shr{b}\t{%2, %0|%0, %2}"
13074 [(set_attr "type" "ishift")
13075 (set_attr "mode" "QI")])
13077 ;; Rotate instructions
13079 (define_expand "rotldi3"
13080 [(set (match_operand:DI 0 "shiftdi_operand" "")
13081 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13082 (match_operand:QI 2 "nonmemory_operand" "")))
13083 (clobber (reg:CC FLAGS_REG))]
13088 ix86_expand_binary_operator (ROTATE, DImode, operands);
13091 if (!const_1_to_31_operand (operands[2], VOIDmode))
13093 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13097 ;; Implement rotation using two double-precision shift instructions
13098 ;; and a scratch register.
13099 (define_insn_and_split "ix86_rotldi3"
13100 [(set (match_operand:DI 0 "register_operand" "=r")
13101 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13102 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13103 (clobber (reg:CC FLAGS_REG))
13104 (clobber (match_scratch:SI 3 "=&r"))]
13107 "&& reload_completed"
13108 [(set (match_dup 3) (match_dup 4))
13110 [(set (match_dup 4)
13111 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13112 (lshiftrt:SI (match_dup 5)
13113 (minus:QI (const_int 32) (match_dup 2)))))
13114 (clobber (reg:CC FLAGS_REG))])
13116 [(set (match_dup 5)
13117 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13118 (lshiftrt:SI (match_dup 3)
13119 (minus:QI (const_int 32) (match_dup 2)))))
13120 (clobber (reg:CC FLAGS_REG))])]
13121 "split_di (operands, 1, operands + 4, operands + 5);")
13123 (define_insn "*rotlsi3_1_one_bit_rex64"
13124 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13125 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13126 (match_operand:QI 2 "const1_operand" "")))
13127 (clobber (reg:CC FLAGS_REG))]
13129 && (TARGET_SHIFT1 || optimize_size)
13130 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13132 [(set_attr "type" "rotate")
13133 (set (attr "length")
13134 (if_then_else (match_operand:DI 0 "register_operand" "")
13136 (const_string "*")))])
13138 (define_insn "*rotldi3_1_rex64"
13139 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13140 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13141 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13142 (clobber (reg:CC FLAGS_REG))]
13143 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13145 rol{q}\t{%2, %0|%0, %2}
13146 rol{q}\t{%b2, %0|%0, %b2}"
13147 [(set_attr "type" "rotate")
13148 (set_attr "mode" "DI")])
13150 (define_expand "rotlsi3"
13151 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13152 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13153 (match_operand:QI 2 "nonmemory_operand" "")))
13154 (clobber (reg:CC FLAGS_REG))]
13156 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13158 (define_insn "*rotlsi3_1_one_bit"
13159 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13160 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13161 (match_operand:QI 2 "const1_operand" "")))
13162 (clobber (reg:CC FLAGS_REG))]
13163 "(TARGET_SHIFT1 || optimize_size)
13164 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13166 [(set_attr "type" "rotate")
13167 (set (attr "length")
13168 (if_then_else (match_operand:SI 0 "register_operand" "")
13170 (const_string "*")))])
13172 (define_insn "*rotlsi3_1_one_bit_zext"
13173 [(set (match_operand:DI 0 "register_operand" "=r")
13175 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13176 (match_operand:QI 2 "const1_operand" ""))))
13177 (clobber (reg:CC FLAGS_REG))]
13179 && (TARGET_SHIFT1 || optimize_size)
13180 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13182 [(set_attr "type" "rotate")
13183 (set_attr "length" "2")])
13185 (define_insn "*rotlsi3_1"
13186 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13187 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13188 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13189 (clobber (reg:CC FLAGS_REG))]
13190 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13192 rol{l}\t{%2, %0|%0, %2}
13193 rol{l}\t{%b2, %0|%0, %b2}"
13194 [(set_attr "type" "rotate")
13195 (set_attr "mode" "SI")])
13197 (define_insn "*rotlsi3_1_zext"
13198 [(set (match_operand:DI 0 "register_operand" "=r,r")
13200 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13201 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13202 (clobber (reg:CC FLAGS_REG))]
13203 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13205 rol{l}\t{%2, %k0|%k0, %2}
13206 rol{l}\t{%b2, %k0|%k0, %b2}"
13207 [(set_attr "type" "rotate")
13208 (set_attr "mode" "SI")])
13210 (define_expand "rotlhi3"
13211 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13212 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13213 (match_operand:QI 2 "nonmemory_operand" "")))
13214 (clobber (reg:CC FLAGS_REG))]
13215 "TARGET_HIMODE_MATH"
13216 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13218 (define_insn "*rotlhi3_1_one_bit"
13219 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13220 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13221 (match_operand:QI 2 "const1_operand" "")))
13222 (clobber (reg:CC FLAGS_REG))]
13223 "(TARGET_SHIFT1 || optimize_size)
13224 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13226 [(set_attr "type" "rotate")
13227 (set (attr "length")
13228 (if_then_else (match_operand 0 "register_operand" "")
13230 (const_string "*")))])
13232 (define_insn "*rotlhi3_1"
13233 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13234 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13235 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13236 (clobber (reg:CC FLAGS_REG))]
13237 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13239 rol{w}\t{%2, %0|%0, %2}
13240 rol{w}\t{%b2, %0|%0, %b2}"
13241 [(set_attr "type" "rotate")
13242 (set_attr "mode" "HI")])
13245 [(set (match_operand:HI 0 "register_operand" "")
13246 (rotate:HI (match_dup 0) (const_int 8)))
13247 (clobber (reg:CC FLAGS_REG))]
13249 [(parallel [(set (strict_low_part (match_dup 0))
13250 (bswap:HI (match_dup 0)))
13251 (clobber (reg:CC FLAGS_REG))])]
13254 (define_expand "rotlqi3"
13255 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13256 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13257 (match_operand:QI 2 "nonmemory_operand" "")))
13258 (clobber (reg:CC FLAGS_REG))]
13259 "TARGET_QIMODE_MATH"
13260 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13262 (define_insn "*rotlqi3_1_one_bit_slp"
13263 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13264 (rotate:QI (match_dup 0)
13265 (match_operand:QI 1 "const1_operand" "")))
13266 (clobber (reg:CC FLAGS_REG))]
13267 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13268 && (TARGET_SHIFT1 || optimize_size)"
13270 [(set_attr "type" "rotate1")
13271 (set (attr "length")
13272 (if_then_else (match_operand 0 "register_operand" "")
13274 (const_string "*")))])
13276 (define_insn "*rotlqi3_1_one_bit"
13277 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13278 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13279 (match_operand:QI 2 "const1_operand" "")))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "(TARGET_SHIFT1 || optimize_size)
13282 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13284 [(set_attr "type" "rotate")
13285 (set (attr "length")
13286 (if_then_else (match_operand 0 "register_operand" "")
13288 (const_string "*")))])
13290 (define_insn "*rotlqi3_1_slp"
13291 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13292 (rotate:QI (match_dup 0)
13293 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13294 (clobber (reg:CC FLAGS_REG))]
13295 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13296 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13298 rol{b}\t{%1, %0|%0, %1}
13299 rol{b}\t{%b1, %0|%0, %b1}"
13300 [(set_attr "type" "rotate1")
13301 (set_attr "mode" "QI")])
13303 (define_insn "*rotlqi3_1"
13304 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13305 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13306 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13307 (clobber (reg:CC FLAGS_REG))]
13308 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13310 rol{b}\t{%2, %0|%0, %2}
13311 rol{b}\t{%b2, %0|%0, %b2}"
13312 [(set_attr "type" "rotate")
13313 (set_attr "mode" "QI")])
13315 (define_expand "rotrdi3"
13316 [(set (match_operand:DI 0 "shiftdi_operand" "")
13317 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13318 (match_operand:QI 2 "nonmemory_operand" "")))
13319 (clobber (reg:CC FLAGS_REG))]
13324 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13327 if (!const_1_to_31_operand (operands[2], VOIDmode))
13329 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13333 ;; Implement rotation using two double-precision shift instructions
13334 ;; and a scratch register.
13335 (define_insn_and_split "ix86_rotrdi3"
13336 [(set (match_operand:DI 0 "register_operand" "=r")
13337 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13338 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13339 (clobber (reg:CC FLAGS_REG))
13340 (clobber (match_scratch:SI 3 "=&r"))]
13343 "&& reload_completed"
13344 [(set (match_dup 3) (match_dup 4))
13346 [(set (match_dup 4)
13347 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13348 (ashift:SI (match_dup 5)
13349 (minus:QI (const_int 32) (match_dup 2)))))
13350 (clobber (reg:CC FLAGS_REG))])
13352 [(set (match_dup 5)
13353 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13354 (ashift:SI (match_dup 3)
13355 (minus:QI (const_int 32) (match_dup 2)))))
13356 (clobber (reg:CC FLAGS_REG))])]
13357 "split_di (operands, 1, operands + 4, operands + 5);")
13359 (define_insn "*rotrdi3_1_one_bit_rex64"
13360 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13361 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13362 (match_operand:QI 2 "const1_operand" "")))
13363 (clobber (reg:CC FLAGS_REG))]
13365 && (TARGET_SHIFT1 || optimize_size)
13366 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13368 [(set_attr "type" "rotate")
13369 (set (attr "length")
13370 (if_then_else (match_operand:DI 0 "register_operand" "")
13372 (const_string "*")))])
13374 (define_insn "*rotrdi3_1_rex64"
13375 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13376 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13377 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13378 (clobber (reg:CC FLAGS_REG))]
13379 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13381 ror{q}\t{%2, %0|%0, %2}
13382 ror{q}\t{%b2, %0|%0, %b2}"
13383 [(set_attr "type" "rotate")
13384 (set_attr "mode" "DI")])
13386 (define_expand "rotrsi3"
13387 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13388 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13389 (match_operand:QI 2 "nonmemory_operand" "")))
13390 (clobber (reg:CC FLAGS_REG))]
13392 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13394 (define_insn "*rotrsi3_1_one_bit"
13395 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13396 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13397 (match_operand:QI 2 "const1_operand" "")))
13398 (clobber (reg:CC FLAGS_REG))]
13399 "(TARGET_SHIFT1 || optimize_size)
13400 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13402 [(set_attr "type" "rotate")
13403 (set (attr "length")
13404 (if_then_else (match_operand:SI 0 "register_operand" "")
13406 (const_string "*")))])
13408 (define_insn "*rotrsi3_1_one_bit_zext"
13409 [(set (match_operand:DI 0 "register_operand" "=r")
13411 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13412 (match_operand:QI 2 "const1_operand" ""))))
13413 (clobber (reg:CC FLAGS_REG))]
13415 && (TARGET_SHIFT1 || optimize_size)
13416 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13418 [(set_attr "type" "rotate")
13419 (set (attr "length")
13420 (if_then_else (match_operand:SI 0 "register_operand" "")
13422 (const_string "*")))])
13424 (define_insn "*rotrsi3_1"
13425 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13426 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13427 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13428 (clobber (reg:CC FLAGS_REG))]
13429 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13431 ror{l}\t{%2, %0|%0, %2}
13432 ror{l}\t{%b2, %0|%0, %b2}"
13433 [(set_attr "type" "rotate")
13434 (set_attr "mode" "SI")])
13436 (define_insn "*rotrsi3_1_zext"
13437 [(set (match_operand:DI 0 "register_operand" "=r,r")
13439 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13440 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13441 (clobber (reg:CC FLAGS_REG))]
13442 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13444 ror{l}\t{%2, %k0|%k0, %2}
13445 ror{l}\t{%b2, %k0|%k0, %b2}"
13446 [(set_attr "type" "rotate")
13447 (set_attr "mode" "SI")])
13449 (define_expand "rotrhi3"
13450 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13451 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13452 (match_operand:QI 2 "nonmemory_operand" "")))
13453 (clobber (reg:CC FLAGS_REG))]
13454 "TARGET_HIMODE_MATH"
13455 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13457 (define_insn "*rotrhi3_one_bit"
13458 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13459 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13460 (match_operand:QI 2 "const1_operand" "")))
13461 (clobber (reg:CC FLAGS_REG))]
13462 "(TARGET_SHIFT1 || optimize_size)
13463 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13465 [(set_attr "type" "rotate")
13466 (set (attr "length")
13467 (if_then_else (match_operand 0 "register_operand" "")
13469 (const_string "*")))])
13471 (define_insn "*rotrhi3_1"
13472 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13473 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13474 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13475 (clobber (reg:CC FLAGS_REG))]
13476 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13478 ror{w}\t{%2, %0|%0, %2}
13479 ror{w}\t{%b2, %0|%0, %b2}"
13480 [(set_attr "type" "rotate")
13481 (set_attr "mode" "HI")])
13484 [(set (match_operand:HI 0 "register_operand" "")
13485 (rotatert:HI (match_dup 0) (const_int 8)))
13486 (clobber (reg:CC FLAGS_REG))]
13488 [(parallel [(set (strict_low_part (match_dup 0))
13489 (bswap:HI (match_dup 0)))
13490 (clobber (reg:CC FLAGS_REG))])]
13493 (define_expand "rotrqi3"
13494 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13495 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13496 (match_operand:QI 2 "nonmemory_operand" "")))
13497 (clobber (reg:CC FLAGS_REG))]
13498 "TARGET_QIMODE_MATH"
13499 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13501 (define_insn "*rotrqi3_1_one_bit"
13502 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13503 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13504 (match_operand:QI 2 "const1_operand" "")))
13505 (clobber (reg:CC FLAGS_REG))]
13506 "(TARGET_SHIFT1 || optimize_size)
13507 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13509 [(set_attr "type" "rotate")
13510 (set (attr "length")
13511 (if_then_else (match_operand 0 "register_operand" "")
13513 (const_string "*")))])
13515 (define_insn "*rotrqi3_1_one_bit_slp"
13516 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13517 (rotatert:QI (match_dup 0)
13518 (match_operand:QI 1 "const1_operand" "")))
13519 (clobber (reg:CC FLAGS_REG))]
13520 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13521 && (TARGET_SHIFT1 || optimize_size)"
13523 [(set_attr "type" "rotate1")
13524 (set (attr "length")
13525 (if_then_else (match_operand 0 "register_operand" "")
13527 (const_string "*")))])
13529 (define_insn "*rotrqi3_1"
13530 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13531 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13532 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13533 (clobber (reg:CC FLAGS_REG))]
13534 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13536 ror{b}\t{%2, %0|%0, %2}
13537 ror{b}\t{%b2, %0|%0, %b2}"
13538 [(set_attr "type" "rotate")
13539 (set_attr "mode" "QI")])
13541 (define_insn "*rotrqi3_1_slp"
13542 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13543 (rotatert:QI (match_dup 0)
13544 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13545 (clobber (reg:CC FLAGS_REG))]
13546 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13547 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13549 ror{b}\t{%1, %0|%0, %1}
13550 ror{b}\t{%b1, %0|%0, %b1}"
13551 [(set_attr "type" "rotate1")
13552 (set_attr "mode" "QI")])
13554 ;; Bit set / bit test instructions
13556 (define_expand "extv"
13557 [(set (match_operand:SI 0 "register_operand" "")
13558 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13559 (match_operand:SI 2 "const8_operand" "")
13560 (match_operand:SI 3 "const8_operand" "")))]
13563 /* Handle extractions from %ah et al. */
13564 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13567 /* From mips.md: extract_bit_field doesn't verify that our source
13568 matches the predicate, so check it again here. */
13569 if (! ext_register_operand (operands[1], VOIDmode))
13573 (define_expand "extzv"
13574 [(set (match_operand:SI 0 "register_operand" "")
13575 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13576 (match_operand:SI 2 "const8_operand" "")
13577 (match_operand:SI 3 "const8_operand" "")))]
13580 /* Handle extractions from %ah et al. */
13581 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13584 /* From mips.md: extract_bit_field doesn't verify that our source
13585 matches the predicate, so check it again here. */
13586 if (! ext_register_operand (operands[1], VOIDmode))
13590 (define_expand "insv"
13591 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13592 (match_operand 1 "const8_operand" "")
13593 (match_operand 2 "const8_operand" ""))
13594 (match_operand 3 "register_operand" ""))]
13597 /* Handle insertions to %ah et al. */
13598 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13601 /* From mips.md: insert_bit_field doesn't verify that our source
13602 matches the predicate, so check it again here. */
13603 if (! ext_register_operand (operands[0], VOIDmode))
13607 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13609 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13614 ;; %%% bts, btr, btc, bt.
13615 ;; In general these instructions are *slow* when applied to memory,
13616 ;; since they enforce atomic operation. When applied to registers,
13617 ;; it depends on the cpu implementation. They're never faster than
13618 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13619 ;; no point. But in 64-bit, we can't hold the relevant immediates
13620 ;; within the instruction itself, so operating on bits in the high
13621 ;; 32-bits of a register becomes easier.
13623 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13624 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13625 ;; negdf respectively, so they can never be disabled entirely.
13627 (define_insn "*btsq"
13628 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13630 (match_operand:DI 1 "const_0_to_63_operand" ""))
13632 (clobber (reg:CC FLAGS_REG))]
13633 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13635 [(set_attr "type" "alu1")])
13637 (define_insn "*btrq"
13638 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13640 (match_operand:DI 1 "const_0_to_63_operand" ""))
13642 (clobber (reg:CC FLAGS_REG))]
13643 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13645 [(set_attr "type" "alu1")])
13647 (define_insn "*btcq"
13648 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13650 (match_operand:DI 1 "const_0_to_63_operand" ""))
13651 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13652 (clobber (reg:CC FLAGS_REG))]
13653 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13655 [(set_attr "type" "alu1")])
13657 ;; Allow Nocona to avoid these instructions if a register is available.
13660 [(match_scratch:DI 2 "r")
13661 (parallel [(set (zero_extract:DI
13662 (match_operand:DI 0 "register_operand" "")
13664 (match_operand:DI 1 "const_0_to_63_operand" ""))
13666 (clobber (reg:CC FLAGS_REG))])]
13667 "TARGET_64BIT && !TARGET_USE_BT"
13670 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13673 if (HOST_BITS_PER_WIDE_INT >= 64)
13674 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13675 else if (i < HOST_BITS_PER_WIDE_INT)
13676 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13678 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13680 op1 = immed_double_const (lo, hi, DImode);
13683 emit_move_insn (operands[2], op1);
13687 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13692 [(match_scratch:DI 2 "r")
13693 (parallel [(set (zero_extract:DI
13694 (match_operand:DI 0 "register_operand" "")
13696 (match_operand:DI 1 "const_0_to_63_operand" ""))
13698 (clobber (reg:CC FLAGS_REG))])]
13699 "TARGET_64BIT && !TARGET_USE_BT"
13702 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13705 if (HOST_BITS_PER_WIDE_INT >= 64)
13706 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13707 else if (i < HOST_BITS_PER_WIDE_INT)
13708 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13710 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13712 op1 = immed_double_const (~lo, ~hi, DImode);
13715 emit_move_insn (operands[2], op1);
13719 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13724 [(match_scratch:DI 2 "r")
13725 (parallel [(set (zero_extract:DI
13726 (match_operand:DI 0 "register_operand" "")
13728 (match_operand:DI 1 "const_0_to_63_operand" ""))
13729 (not:DI (zero_extract:DI
13730 (match_dup 0) (const_int 1) (match_dup 1))))
13731 (clobber (reg:CC FLAGS_REG))])]
13732 "TARGET_64BIT && !TARGET_USE_BT"
13735 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13738 if (HOST_BITS_PER_WIDE_INT >= 64)
13739 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13740 else if (i < HOST_BITS_PER_WIDE_INT)
13741 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13743 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13745 op1 = immed_double_const (lo, hi, DImode);
13748 emit_move_insn (operands[2], op1);
13752 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13756 ;; Store-flag instructions.
13758 ;; For all sCOND expanders, also expand the compare or test insn that
13759 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13761 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13762 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13763 ;; way, which can later delete the movzx if only QImode is needed.
13765 (define_expand "seq"
13766 [(set (match_operand:QI 0 "register_operand" "")
13767 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13769 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13771 (define_expand "sne"
13772 [(set (match_operand:QI 0 "register_operand" "")
13773 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13775 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13777 (define_expand "sgt"
13778 [(set (match_operand:QI 0 "register_operand" "")
13779 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13781 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13783 (define_expand "sgtu"
13784 [(set (match_operand:QI 0 "register_operand" "")
13785 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13787 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13789 (define_expand "slt"
13790 [(set (match_operand:QI 0 "register_operand" "")
13791 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13793 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13795 (define_expand "sltu"
13796 [(set (match_operand:QI 0 "register_operand" "")
13797 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13799 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13801 (define_expand "sge"
13802 [(set (match_operand:QI 0 "register_operand" "")
13803 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13805 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13807 (define_expand "sgeu"
13808 [(set (match_operand:QI 0 "register_operand" "")
13809 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13811 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13813 (define_expand "sle"
13814 [(set (match_operand:QI 0 "register_operand" "")
13815 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13817 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13819 (define_expand "sleu"
13820 [(set (match_operand:QI 0 "register_operand" "")
13821 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13823 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13825 (define_expand "sunordered"
13826 [(set (match_operand:QI 0 "register_operand" "")
13827 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13828 "TARGET_80387 || TARGET_SSE"
13829 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13831 (define_expand "sordered"
13832 [(set (match_operand:QI 0 "register_operand" "")
13833 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13835 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13837 (define_expand "suneq"
13838 [(set (match_operand:QI 0 "register_operand" "")
13839 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13840 "TARGET_80387 || TARGET_SSE"
13841 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13843 (define_expand "sunge"
13844 [(set (match_operand:QI 0 "register_operand" "")
13845 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13846 "TARGET_80387 || TARGET_SSE"
13847 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13849 (define_expand "sungt"
13850 [(set (match_operand:QI 0 "register_operand" "")
13851 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13852 "TARGET_80387 || TARGET_SSE"
13853 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13855 (define_expand "sunle"
13856 [(set (match_operand:QI 0 "register_operand" "")
13857 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858 "TARGET_80387 || TARGET_SSE"
13859 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13861 (define_expand "sunlt"
13862 [(set (match_operand:QI 0 "register_operand" "")
13863 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13864 "TARGET_80387 || TARGET_SSE"
13865 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13867 (define_expand "sltgt"
13868 [(set (match_operand:QI 0 "register_operand" "")
13869 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13870 "TARGET_80387 || TARGET_SSE"
13871 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13873 (define_insn "*setcc_1"
13874 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13875 (match_operator:QI 1 "ix86_comparison_operator"
13876 [(reg FLAGS_REG) (const_int 0)]))]
13879 [(set_attr "type" "setcc")
13880 (set_attr "mode" "QI")])
13882 (define_insn "*setcc_2"
13883 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13884 (match_operator:QI 1 "ix86_comparison_operator"
13885 [(reg FLAGS_REG) (const_int 0)]))]
13888 [(set_attr "type" "setcc")
13889 (set_attr "mode" "QI")])
13891 ;; In general it is not safe to assume too much about CCmode registers,
13892 ;; so simplify-rtx stops when it sees a second one. Under certain
13893 ;; conditions this is safe on x86, so help combine not create
13900 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13901 (ne:QI (match_operator 1 "ix86_comparison_operator"
13902 [(reg FLAGS_REG) (const_int 0)])
13905 [(set (match_dup 0) (match_dup 1))]
13907 PUT_MODE (operands[1], QImode);
13911 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13912 (ne:QI (match_operator 1 "ix86_comparison_operator"
13913 [(reg FLAGS_REG) (const_int 0)])
13916 [(set (match_dup 0) (match_dup 1))]
13918 PUT_MODE (operands[1], QImode);
13922 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13923 (eq:QI (match_operator 1 "ix86_comparison_operator"
13924 [(reg FLAGS_REG) (const_int 0)])
13927 [(set (match_dup 0) (match_dup 1))]
13929 rtx new_op1 = copy_rtx (operands[1]);
13930 operands[1] = new_op1;
13931 PUT_MODE (new_op1, QImode);
13932 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13933 GET_MODE (XEXP (new_op1, 0))));
13935 /* Make sure that (a) the CCmode we have for the flags is strong
13936 enough for the reversed compare or (b) we have a valid FP compare. */
13937 if (! ix86_comparison_operator (new_op1, VOIDmode))
13942 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13943 (eq:QI (match_operator 1 "ix86_comparison_operator"
13944 [(reg FLAGS_REG) (const_int 0)])
13947 [(set (match_dup 0) (match_dup 1))]
13949 rtx new_op1 = copy_rtx (operands[1]);
13950 operands[1] = new_op1;
13951 PUT_MODE (new_op1, QImode);
13952 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13953 GET_MODE (XEXP (new_op1, 0))));
13955 /* Make sure that (a) the CCmode we have for the flags is strong
13956 enough for the reversed compare or (b) we have a valid FP compare. */
13957 if (! ix86_comparison_operator (new_op1, VOIDmode))
13961 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13962 ;; subsequent logical operations are used to imitate conditional moves.
13963 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13966 (define_insn "*sse_setcc<mode>"
13967 [(set (match_operand:MODEF 0 "register_operand" "=x")
13968 (match_operator:MODEF 1 "sse_comparison_operator"
13969 [(match_operand:MODEF 2 "register_operand" "0")
13970 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13971 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13972 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13973 [(set_attr "type" "ssecmp")
13974 (set_attr "mode" "<MODE>")])
13976 (define_insn "*sse5_setcc<mode>"
13977 [(set (match_operand:MODEF 0 "register_operand" "=x")
13978 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13979 [(match_operand:MODEF 2 "register_operand" "x")
13980 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13982 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13983 [(set_attr "type" "sse4arg")
13984 (set_attr "mode" "<MODE>")])
13987 ;; Basic conditional jump instructions.
13988 ;; We ignore the overflow flag for signed branch instructions.
13990 ;; For all bCOND expanders, also expand the compare or test insn that
13991 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13993 (define_expand "beq"
13995 (if_then_else (match_dup 1)
13996 (label_ref (match_operand 0 "" ""))
13999 "ix86_expand_branch (EQ, operands[0]); DONE;")
14001 (define_expand "bne"
14003 (if_then_else (match_dup 1)
14004 (label_ref (match_operand 0 "" ""))
14007 "ix86_expand_branch (NE, operands[0]); DONE;")
14009 (define_expand "bgt"
14011 (if_then_else (match_dup 1)
14012 (label_ref (match_operand 0 "" ""))
14015 "ix86_expand_branch (GT, operands[0]); DONE;")
14017 (define_expand "bgtu"
14019 (if_then_else (match_dup 1)
14020 (label_ref (match_operand 0 "" ""))
14023 "ix86_expand_branch (GTU, operands[0]); DONE;")
14025 (define_expand "blt"
14027 (if_then_else (match_dup 1)
14028 (label_ref (match_operand 0 "" ""))
14031 "ix86_expand_branch (LT, operands[0]); DONE;")
14033 (define_expand "bltu"
14035 (if_then_else (match_dup 1)
14036 (label_ref (match_operand 0 "" ""))
14039 "ix86_expand_branch (LTU, operands[0]); DONE;")
14041 (define_expand "bge"
14043 (if_then_else (match_dup 1)
14044 (label_ref (match_operand 0 "" ""))
14047 "ix86_expand_branch (GE, operands[0]); DONE;")
14049 (define_expand "bgeu"
14051 (if_then_else (match_dup 1)
14052 (label_ref (match_operand 0 "" ""))
14055 "ix86_expand_branch (GEU, operands[0]); DONE;")
14057 (define_expand "ble"
14059 (if_then_else (match_dup 1)
14060 (label_ref (match_operand 0 "" ""))
14063 "ix86_expand_branch (LE, operands[0]); DONE;")
14065 (define_expand "bleu"
14067 (if_then_else (match_dup 1)
14068 (label_ref (match_operand 0 "" ""))
14071 "ix86_expand_branch (LEU, operands[0]); DONE;")
14073 (define_expand "bunordered"
14075 (if_then_else (match_dup 1)
14076 (label_ref (match_operand 0 "" ""))
14078 "TARGET_80387 || TARGET_SSE_MATH"
14079 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14081 (define_expand "bordered"
14083 (if_then_else (match_dup 1)
14084 (label_ref (match_operand 0 "" ""))
14086 "TARGET_80387 || TARGET_SSE_MATH"
14087 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14089 (define_expand "buneq"
14091 (if_then_else (match_dup 1)
14092 (label_ref (match_operand 0 "" ""))
14094 "TARGET_80387 || TARGET_SSE_MATH"
14095 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14097 (define_expand "bunge"
14099 (if_then_else (match_dup 1)
14100 (label_ref (match_operand 0 "" ""))
14102 "TARGET_80387 || TARGET_SSE_MATH"
14103 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14105 (define_expand "bungt"
14107 (if_then_else (match_dup 1)
14108 (label_ref (match_operand 0 "" ""))
14110 "TARGET_80387 || TARGET_SSE_MATH"
14111 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14113 (define_expand "bunle"
14115 (if_then_else (match_dup 1)
14116 (label_ref (match_operand 0 "" ""))
14118 "TARGET_80387 || TARGET_SSE_MATH"
14119 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14121 (define_expand "bunlt"
14123 (if_then_else (match_dup 1)
14124 (label_ref (match_operand 0 "" ""))
14126 "TARGET_80387 || TARGET_SSE_MATH"
14127 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14129 (define_expand "bltgt"
14131 (if_then_else (match_dup 1)
14132 (label_ref (match_operand 0 "" ""))
14134 "TARGET_80387 || TARGET_SSE_MATH"
14135 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14137 (define_insn "*jcc_1"
14139 (if_then_else (match_operator 1 "ix86_comparison_operator"
14140 [(reg FLAGS_REG) (const_int 0)])
14141 (label_ref (match_operand 0 "" ""))
14145 [(set_attr "type" "ibr")
14146 (set_attr "modrm" "0")
14147 (set (attr "length")
14148 (if_then_else (and (ge (minus (match_dup 0) (pc))
14150 (lt (minus (match_dup 0) (pc))
14155 (define_insn "*jcc_2"
14157 (if_then_else (match_operator 1 "ix86_comparison_operator"
14158 [(reg FLAGS_REG) (const_int 0)])
14160 (label_ref (match_operand 0 "" ""))))]
14163 [(set_attr "type" "ibr")
14164 (set_attr "modrm" "0")
14165 (set (attr "length")
14166 (if_then_else (and (ge (minus (match_dup 0) (pc))
14168 (lt (minus (match_dup 0) (pc))
14173 ;; In general it is not safe to assume too much about CCmode registers,
14174 ;; so simplify-rtx stops when it sees a second one. Under certain
14175 ;; conditions this is safe on x86, so help combine not create
14183 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14184 [(reg FLAGS_REG) (const_int 0)])
14186 (label_ref (match_operand 1 "" ""))
14190 (if_then_else (match_dup 0)
14191 (label_ref (match_dup 1))
14194 PUT_MODE (operands[0], VOIDmode);
14199 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14200 [(reg FLAGS_REG) (const_int 0)])
14202 (label_ref (match_operand 1 "" ""))
14206 (if_then_else (match_dup 0)
14207 (label_ref (match_dup 1))
14210 rtx new_op0 = copy_rtx (operands[0]);
14211 operands[0] = new_op0;
14212 PUT_MODE (new_op0, VOIDmode);
14213 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14214 GET_MODE (XEXP (new_op0, 0))));
14216 /* Make sure that (a) the CCmode we have for the flags is strong
14217 enough for the reversed compare or (b) we have a valid FP compare. */
14218 if (! ix86_comparison_operator (new_op0, VOIDmode))
14222 ;; Define combination compare-and-branch fp compare instructions to use
14223 ;; during early optimization. Splitting the operation apart early makes
14224 ;; for bad code when we want to reverse the operation.
14226 (define_insn "*fp_jcc_1_mixed"
14228 (if_then_else (match_operator 0 "comparison_operator"
14229 [(match_operand 1 "register_operand" "f,x")
14230 (match_operand 2 "nonimmediate_operand" "f,xm")])
14231 (label_ref (match_operand 3 "" ""))
14233 (clobber (reg:CCFP FPSR_REG))
14234 (clobber (reg:CCFP FLAGS_REG))]
14235 "TARGET_MIX_SSE_I387
14236 && SSE_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_1_sse"
14243 (if_then_else (match_operator 0 "comparison_operator"
14244 [(match_operand 1 "register_operand" "x")
14245 (match_operand 2 "nonimmediate_operand" "xm")])
14246 (label_ref (match_operand 3 "" ""))
14248 (clobber (reg:CCFP FPSR_REG))
14249 (clobber (reg:CCFP FLAGS_REG))]
14251 && SSE_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_1_387"
14258 (if_then_else (match_operator 0 "comparison_operator"
14259 [(match_operand 1 "register_operand" "f")
14260 (match_operand 2 "register_operand" "f")])
14261 (label_ref (match_operand 3 "" ""))
14263 (clobber (reg:CCFP FPSR_REG))
14264 (clobber (reg:CCFP FLAGS_REG))]
14265 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14267 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14268 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14271 (define_insn "*fp_jcc_2_mixed"
14273 (if_then_else (match_operator 0 "comparison_operator"
14274 [(match_operand 1 "register_operand" "f,x")
14275 (match_operand 2 "nonimmediate_operand" "f,xm")])
14277 (label_ref (match_operand 3 "" ""))))
14278 (clobber (reg:CCFP FPSR_REG))
14279 (clobber (reg:CCFP FLAGS_REG))]
14280 "TARGET_MIX_SSE_I387
14281 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14282 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14283 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14286 (define_insn "*fp_jcc_2_sse"
14288 (if_then_else (match_operator 0 "comparison_operator"
14289 [(match_operand 1 "register_operand" "x")
14290 (match_operand 2 "nonimmediate_operand" "xm")])
14292 (label_ref (match_operand 3 "" ""))))
14293 (clobber (reg:CCFP FPSR_REG))
14294 (clobber (reg:CCFP FLAGS_REG))]
14296 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14297 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14298 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14301 (define_insn "*fp_jcc_2_387"
14303 (if_then_else (match_operator 0 "comparison_operator"
14304 [(match_operand 1 "register_operand" "f")
14305 (match_operand 2 "register_operand" "f")])
14307 (label_ref (match_operand 3 "" ""))))
14308 (clobber (reg:CCFP FPSR_REG))
14309 (clobber (reg:CCFP FLAGS_REG))]
14310 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14312 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14313 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14316 (define_insn "*fp_jcc_3_387"
14318 (if_then_else (match_operator 0 "comparison_operator"
14319 [(match_operand 1 "register_operand" "f")
14320 (match_operand 2 "nonimmediate_operand" "fm")])
14321 (label_ref (match_operand 3 "" ""))
14323 (clobber (reg:CCFP FPSR_REG))
14324 (clobber (reg:CCFP FLAGS_REG))
14325 (clobber (match_scratch:HI 4 "=a"))]
14327 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14328 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14329 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14330 && SELECT_CC_MODE (GET_CODE (operands[0]),
14331 operands[1], operands[2]) == CCFPmode
14332 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14335 (define_insn "*fp_jcc_4_387"
14337 (if_then_else (match_operator 0 "comparison_operator"
14338 [(match_operand 1 "register_operand" "f")
14339 (match_operand 2 "nonimmediate_operand" "fm")])
14341 (label_ref (match_operand 3 "" ""))))
14342 (clobber (reg:CCFP FPSR_REG))
14343 (clobber (reg:CCFP FLAGS_REG))
14344 (clobber (match_scratch:HI 4 "=a"))]
14346 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14347 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14348 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14349 && SELECT_CC_MODE (GET_CODE (operands[0]),
14350 operands[1], operands[2]) == CCFPmode
14351 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14354 (define_insn "*fp_jcc_5_387"
14356 (if_then_else (match_operator 0 "comparison_operator"
14357 [(match_operand 1 "register_operand" "f")
14358 (match_operand 2 "register_operand" "f")])
14359 (label_ref (match_operand 3 "" ""))
14361 (clobber (reg:CCFP FPSR_REG))
14362 (clobber (reg:CCFP FLAGS_REG))
14363 (clobber (match_scratch:HI 4 "=a"))]
14364 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14365 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14366 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14369 (define_insn "*fp_jcc_6_387"
14371 (if_then_else (match_operator 0 "comparison_operator"
14372 [(match_operand 1 "register_operand" "f")
14373 (match_operand 2 "register_operand" "f")])
14375 (label_ref (match_operand 3 "" ""))))
14376 (clobber (reg:CCFP FPSR_REG))
14377 (clobber (reg:CCFP FLAGS_REG))
14378 (clobber (match_scratch:HI 4 "=a"))]
14379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14380 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14381 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14384 (define_insn "*fp_jcc_7_387"
14386 (if_then_else (match_operator 0 "comparison_operator"
14387 [(match_operand 1 "register_operand" "f")
14388 (match_operand 2 "const0_operand" "X")])
14389 (label_ref (match_operand 3 "" ""))
14391 (clobber (reg:CCFP FPSR_REG))
14392 (clobber (reg:CCFP FLAGS_REG))
14393 (clobber (match_scratch:HI 4 "=a"))]
14394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14395 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14396 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14397 && SELECT_CC_MODE (GET_CODE (operands[0]),
14398 operands[1], operands[2]) == CCFPmode
14399 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14402 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14403 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14404 ;; with a precedence over other operators and is always put in the first
14405 ;; place. Swap condition and operands to match ficom instruction.
14407 (define_insn "*fp_jcc_8<mode>_387"
14409 (if_then_else (match_operator 0 "comparison_operator"
14410 [(match_operator 1 "float_operator"
14411 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14412 (match_operand 3 "register_operand" "f,f")])
14413 (label_ref (match_operand 4 "" ""))
14415 (clobber (reg:CCFP FPSR_REG))
14416 (clobber (reg:CCFP FLAGS_REG))
14417 (clobber (match_scratch:HI 5 "=a,a"))]
14418 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14419 && TARGET_USE_<MODE>MODE_FIOP
14420 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14421 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14422 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14423 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14428 (if_then_else (match_operator 0 "comparison_operator"
14429 [(match_operand 1 "register_operand" "")
14430 (match_operand 2 "nonimmediate_operand" "")])
14431 (match_operand 3 "" "")
14432 (match_operand 4 "" "")))
14433 (clobber (reg:CCFP FPSR_REG))
14434 (clobber (reg:CCFP FLAGS_REG))]
14438 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14439 operands[3], operands[4], NULL_RTX, NULL_RTX);
14445 (if_then_else (match_operator 0 "comparison_operator"
14446 [(match_operand 1 "register_operand" "")
14447 (match_operand 2 "general_operand" "")])
14448 (match_operand 3 "" "")
14449 (match_operand 4 "" "")))
14450 (clobber (reg:CCFP FPSR_REG))
14451 (clobber (reg:CCFP FLAGS_REG))
14452 (clobber (match_scratch:HI 5 "=a"))]
14456 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14457 operands[3], operands[4], operands[5], NULL_RTX);
14463 (if_then_else (match_operator 0 "comparison_operator"
14464 [(match_operator 1 "float_operator"
14465 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14466 (match_operand 3 "register_operand" "")])
14467 (match_operand 4 "" "")
14468 (match_operand 5 "" "")))
14469 (clobber (reg:CCFP FPSR_REG))
14470 (clobber (reg:CCFP FLAGS_REG))
14471 (clobber (match_scratch:HI 6 "=a"))]
14475 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14476 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14477 operands[3], operands[7],
14478 operands[4], operands[5], operands[6], NULL_RTX);
14482 ;; %%% Kill this when reload knows how to do it.
14485 (if_then_else (match_operator 0 "comparison_operator"
14486 [(match_operator 1 "float_operator"
14487 [(match_operand:X87MODEI12 2 "register_operand" "")])
14488 (match_operand 3 "register_operand" "")])
14489 (match_operand 4 "" "")
14490 (match_operand 5 "" "")))
14491 (clobber (reg:CCFP FPSR_REG))
14492 (clobber (reg:CCFP FLAGS_REG))
14493 (clobber (match_scratch:HI 6 "=a"))]
14497 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14498 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14499 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14500 operands[3], operands[7],
14501 operands[4], operands[5], operands[6], operands[2]);
14505 ;; Unconditional and other jump instructions
14507 (define_insn "jump"
14509 (label_ref (match_operand 0 "" "")))]
14512 [(set_attr "type" "ibr")
14513 (set (attr "length")
14514 (if_then_else (and (ge (minus (match_dup 0) (pc))
14516 (lt (minus (match_dup 0) (pc))
14520 (set_attr "modrm" "0")])
14522 (define_expand "indirect_jump"
14523 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14527 (define_insn "*indirect_jump"
14528 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14531 [(set_attr "type" "ibr")
14532 (set_attr "length_immediate" "0")])
14534 (define_insn "*indirect_jump_rtx64"
14535 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14538 [(set_attr "type" "ibr")
14539 (set_attr "length_immediate" "0")])
14541 (define_expand "tablejump"
14542 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14543 (use (label_ref (match_operand 1 "" "")))])]
14546 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14547 relative. Convert the relative address to an absolute address. */
14551 enum rtx_code code;
14553 /* We can't use @GOTOFF for text labels on VxWorks;
14554 see gotoff_operand. */
14555 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14559 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14561 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14565 op1 = pic_offset_table_rtx;
14570 op0 = pic_offset_table_rtx;
14574 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14579 (define_insn "*tablejump_1"
14580 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14581 (use (label_ref (match_operand 1 "" "")))]
14584 [(set_attr "type" "ibr")
14585 (set_attr "length_immediate" "0")])
14587 (define_insn "*tablejump_1_rtx64"
14588 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14589 (use (label_ref (match_operand 1 "" "")))]
14592 [(set_attr "type" "ibr")
14593 (set_attr "length_immediate" "0")])
14595 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14598 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14599 (set (match_operand:QI 1 "register_operand" "")
14600 (match_operator:QI 2 "ix86_comparison_operator"
14601 [(reg FLAGS_REG) (const_int 0)]))
14602 (set (match_operand 3 "q_regs_operand" "")
14603 (zero_extend (match_dup 1)))]
14604 "(peep2_reg_dead_p (3, operands[1])
14605 || operands_match_p (operands[1], operands[3]))
14606 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14607 [(set (match_dup 4) (match_dup 0))
14608 (set (strict_low_part (match_dup 5))
14611 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14612 operands[5] = gen_lowpart (QImode, operands[3]);
14613 ix86_expand_clear (operands[3]);
14616 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14619 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14620 (set (match_operand:QI 1 "register_operand" "")
14621 (match_operator:QI 2 "ix86_comparison_operator"
14622 [(reg FLAGS_REG) (const_int 0)]))
14623 (parallel [(set (match_operand 3 "q_regs_operand" "")
14624 (zero_extend (match_dup 1)))
14625 (clobber (reg:CC FLAGS_REG))])]
14626 "(peep2_reg_dead_p (3, operands[1])
14627 || operands_match_p (operands[1], operands[3]))
14628 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14629 [(set (match_dup 4) (match_dup 0))
14630 (set (strict_low_part (match_dup 5))
14633 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14634 operands[5] = gen_lowpart (QImode, operands[3]);
14635 ix86_expand_clear (operands[3]);
14638 ;; Call instructions.
14640 ;; The predicates normally associated with named expanders are not properly
14641 ;; checked for calls. This is a bug in the generic code, but it isn't that
14642 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14644 ;; Call subroutine returning no value.
14646 (define_expand "call_pop"
14647 [(parallel [(call (match_operand:QI 0 "" "")
14648 (match_operand:SI 1 "" ""))
14649 (set (reg:SI SP_REG)
14650 (plus:SI (reg:SI SP_REG)
14651 (match_operand:SI 3 "" "")))])]
14654 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14658 (define_insn "*call_pop_0"
14659 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14660 (match_operand:SI 1 "" ""))
14661 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14662 (match_operand:SI 2 "immediate_operand" "")))]
14665 if (SIBLING_CALL_P (insn))
14668 return "call\t%P0";
14670 [(set_attr "type" "call")])
14672 (define_insn "*call_pop_1"
14673 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14674 (match_operand:SI 1 "" ""))
14675 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14676 (match_operand:SI 2 "immediate_operand" "i")))]
14679 if (constant_call_address_operand (operands[0], Pmode))
14681 if (SIBLING_CALL_P (insn))
14684 return "call\t%P0";
14686 if (SIBLING_CALL_P (insn))
14689 return "call\t%A0";
14691 [(set_attr "type" "call")])
14693 (define_expand "call"
14694 [(call (match_operand:QI 0 "" "")
14695 (match_operand 1 "" ""))
14696 (use (match_operand 2 "" ""))]
14699 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14703 (define_expand "sibcall"
14704 [(call (match_operand:QI 0 "" "")
14705 (match_operand 1 "" ""))
14706 (use (match_operand 2 "" ""))]
14709 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14713 (define_insn "*call_0"
14714 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14715 (match_operand 1 "" ""))]
14718 if (SIBLING_CALL_P (insn))
14721 return "call\t%P0";
14723 [(set_attr "type" "call")])
14725 (define_insn "*call_1"
14726 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14727 (match_operand 1 "" ""))]
14728 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14730 if (constant_call_address_operand (operands[0], Pmode))
14731 return "call\t%P0";
14732 return "call\t%A0";
14734 [(set_attr "type" "call")])
14736 (define_insn "*sibcall_1"
14737 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14738 (match_operand 1 "" ""))]
14739 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14741 if (constant_call_address_operand (operands[0], Pmode))
14745 [(set_attr "type" "call")])
14747 (define_insn "*call_1_rex64"
14748 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14749 (match_operand 1 "" ""))]
14750 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14751 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14753 if (constant_call_address_operand (operands[0], Pmode))
14754 return "call\t%P0";
14755 return "call\t%A0";
14757 [(set_attr "type" "call")])
14759 (define_insn "*call_1_rex64_large"
14760 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14761 (match_operand 1 "" ""))]
14762 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14764 [(set_attr "type" "call")])
14766 (define_insn "*sibcall_1_rex64"
14767 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14768 (match_operand 1 "" ""))]
14769 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14771 [(set_attr "type" "call")])
14773 (define_insn "*sibcall_1_rex64_v"
14774 [(call (mem:QI (reg:DI R11_REG))
14775 (match_operand 0 "" ""))]
14776 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14778 [(set_attr "type" "call")])
14781 ;; Call subroutine, returning value in operand 0
14783 (define_expand "call_value_pop"
14784 [(parallel [(set (match_operand 0 "" "")
14785 (call (match_operand:QI 1 "" "")
14786 (match_operand:SI 2 "" "")))
14787 (set (reg:SI SP_REG)
14788 (plus:SI (reg:SI SP_REG)
14789 (match_operand:SI 4 "" "")))])]
14792 ix86_expand_call (operands[0], operands[1], operands[2],
14793 operands[3], operands[4], 0);
14797 (define_expand "call_value"
14798 [(set (match_operand 0 "" "")
14799 (call (match_operand:QI 1 "" "")
14800 (match_operand:SI 2 "" "")))
14801 (use (match_operand:SI 3 "" ""))]
14802 ;; Operand 2 not used on the i386.
14805 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14809 (define_expand "sibcall_value"
14810 [(set (match_operand 0 "" "")
14811 (call (match_operand:QI 1 "" "")
14812 (match_operand:SI 2 "" "")))
14813 (use (match_operand:SI 3 "" ""))]
14814 ;; Operand 2 not used on the i386.
14817 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14821 ;; Call subroutine returning any type.
14823 (define_expand "untyped_call"
14824 [(parallel [(call (match_operand 0 "" "")
14826 (match_operand 1 "" "")
14827 (match_operand 2 "" "")])]
14832 /* In order to give reg-stack an easier job in validating two
14833 coprocessor registers as containing a possible return value,
14834 simply pretend the untyped call returns a complex long double
14837 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14838 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14839 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14842 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14844 rtx set = XVECEXP (operands[2], 0, i);
14845 emit_move_insn (SET_DEST (set), SET_SRC (set));
14848 /* The optimizer does not know that the call sets the function value
14849 registers we stored in the result block. We avoid problems by
14850 claiming that all hard registers are used and clobbered at this
14852 emit_insn (gen_blockage ());
14857 ;; Prologue and epilogue instructions
14859 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14860 ;; all of memory. This blocks insns from being moved across this point.
14862 (define_insn "blockage"
14863 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14866 [(set_attr "length" "0")])
14868 ;; As USE insns aren't meaningful after reload, this is used instead
14869 ;; to prevent deleting instructions setting registers for PIC code
14870 (define_insn "prologue_use"
14871 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14874 [(set_attr "length" "0")])
14876 ;; Insn emitted into the body of a function to return from a function.
14877 ;; This is only done if the function's epilogue is known to be simple.
14878 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14880 (define_expand "return"
14882 "ix86_can_use_return_insn_p ()"
14884 if (current_function_pops_args)
14886 rtx popc = GEN_INT (current_function_pops_args);
14887 emit_jump_insn (gen_return_pop_internal (popc));
14892 (define_insn "return_internal"
14896 [(set_attr "length" "1")
14897 (set_attr "length_immediate" "0")
14898 (set_attr "modrm" "0")])
14900 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14901 ;; instruction Athlon and K8 have.
14903 (define_insn "return_internal_long"
14905 (unspec [(const_int 0)] UNSPEC_REP)]
14908 [(set_attr "length" "1")
14909 (set_attr "length_immediate" "0")
14910 (set_attr "prefix_rep" "1")
14911 (set_attr "modrm" "0")])
14913 (define_insn "return_pop_internal"
14915 (use (match_operand:SI 0 "const_int_operand" ""))]
14918 [(set_attr "length" "3")
14919 (set_attr "length_immediate" "2")
14920 (set_attr "modrm" "0")])
14922 (define_insn "return_indirect_internal"
14924 (use (match_operand:SI 0 "register_operand" "r"))]
14927 [(set_attr "type" "ibr")
14928 (set_attr "length_immediate" "0")])
14934 [(set_attr "length" "1")
14935 (set_attr "length_immediate" "0")
14936 (set_attr "modrm" "0")])
14938 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14939 ;; branch prediction penalty for the third jump in a 16-byte
14942 (define_insn "align"
14943 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14946 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14947 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14949 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14950 The align insn is used to avoid 3 jump instructions in the row to improve
14951 branch prediction and the benefits hardly outweigh the cost of extra 8
14952 nops on the average inserted by full alignment pseudo operation. */
14956 [(set_attr "length" "16")])
14958 (define_expand "prologue"
14961 "ix86_expand_prologue (); DONE;")
14963 (define_insn "set_got"
14964 [(set (match_operand:SI 0 "register_operand" "=r")
14965 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14966 (clobber (reg:CC FLAGS_REG))]
14968 { return output_set_got (operands[0], NULL_RTX); }
14969 [(set_attr "type" "multi")
14970 (set_attr "length" "12")])
14972 (define_insn "set_got_labelled"
14973 [(set (match_operand:SI 0 "register_operand" "=r")
14974 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14976 (clobber (reg:CC FLAGS_REG))]
14978 { return output_set_got (operands[0], operands[1]); }
14979 [(set_attr "type" "multi")
14980 (set_attr "length" "12")])
14982 (define_insn "set_got_rex64"
14983 [(set (match_operand:DI 0 "register_operand" "=r")
14984 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14986 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14987 [(set_attr "type" "lea")
14988 (set_attr "length" "6")])
14990 (define_insn "set_rip_rex64"
14991 [(set (match_operand:DI 0 "register_operand" "=r")
14992 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14994 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14995 [(set_attr "type" "lea")
14996 (set_attr "length" "6")])
14998 (define_insn "set_got_offset_rex64"
14999 [(set (match_operand:DI 0 "register_operand" "=r")
15000 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15002 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15003 [(set_attr "type" "imov")
15004 (set_attr "length" "11")])
15006 (define_expand "epilogue"
15009 "ix86_expand_epilogue (1); DONE;")
15011 (define_expand "sibcall_epilogue"
15014 "ix86_expand_epilogue (0); DONE;")
15016 (define_expand "eh_return"
15017 [(use (match_operand 0 "register_operand" ""))]
15020 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15022 /* Tricky bit: we write the address of the handler to which we will
15023 be returning into someone else's stack frame, one word below the
15024 stack address we wish to restore. */
15025 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15026 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15027 tmp = gen_rtx_MEM (Pmode, tmp);
15028 emit_move_insn (tmp, ra);
15030 if (Pmode == SImode)
15031 emit_jump_insn (gen_eh_return_si (sa));
15033 emit_jump_insn (gen_eh_return_di (sa));
15038 (define_insn_and_split "eh_return_si"
15040 (unspec [(match_operand:SI 0 "register_operand" "c")]
15041 UNSPEC_EH_RETURN))]
15046 "ix86_expand_epilogue (2); DONE;")
15048 (define_insn_and_split "eh_return_di"
15050 (unspec [(match_operand:DI 0 "register_operand" "c")]
15051 UNSPEC_EH_RETURN))]
15056 "ix86_expand_epilogue (2); DONE;")
15058 (define_insn "leave"
15059 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15060 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15061 (clobber (mem:BLK (scratch)))]
15064 [(set_attr "type" "leave")])
15066 (define_insn "leave_rex64"
15067 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15068 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15069 (clobber (mem:BLK (scratch)))]
15072 [(set_attr "type" "leave")])
15074 (define_expand "ffssi2"
15076 [(set (match_operand:SI 0 "register_operand" "")
15077 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15078 (clobber (match_scratch:SI 2 ""))
15079 (clobber (reg:CC FLAGS_REG))])]
15084 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15089 (define_expand "ffs_cmove"
15090 [(set (match_dup 2) (const_int -1))
15091 (parallel [(set (reg:CCZ FLAGS_REG)
15092 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15094 (set (match_operand:SI 0 "nonimmediate_operand" "")
15095 (ctz:SI (match_dup 1)))])
15096 (set (match_dup 0) (if_then_else:SI
15097 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15100 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15101 (clobber (reg:CC FLAGS_REG))])]
15103 "operands[2] = gen_reg_rtx (SImode);")
15105 (define_insn_and_split "*ffs_no_cmove"
15106 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15107 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15108 (clobber (match_scratch:SI 2 "=&q"))
15109 (clobber (reg:CC FLAGS_REG))]
15112 "&& reload_completed"
15113 [(parallel [(set (reg:CCZ FLAGS_REG)
15114 (compare:CCZ (match_dup 1) (const_int 0)))
15115 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15116 (set (strict_low_part (match_dup 3))
15117 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15118 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15119 (clobber (reg:CC FLAGS_REG))])
15120 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15121 (clobber (reg:CC FLAGS_REG))])
15122 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15123 (clobber (reg:CC FLAGS_REG))])]
15125 operands[3] = gen_lowpart (QImode, operands[2]);
15126 ix86_expand_clear (operands[2]);
15129 (define_insn "*ffssi_1"
15130 [(set (reg:CCZ FLAGS_REG)
15131 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15133 (set (match_operand:SI 0 "register_operand" "=r")
15134 (ctz:SI (match_dup 1)))]
15136 "bsf{l}\t{%1, %0|%0, %1}"
15137 [(set_attr "prefix_0f" "1")])
15139 (define_expand "ffsdi2"
15140 [(set (match_dup 2) (const_int -1))
15141 (parallel [(set (reg:CCZ FLAGS_REG)
15142 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15144 (set (match_operand:DI 0 "nonimmediate_operand" "")
15145 (ctz:DI (match_dup 1)))])
15146 (set (match_dup 0) (if_then_else:DI
15147 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15150 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15151 (clobber (reg:CC FLAGS_REG))])]
15153 "operands[2] = gen_reg_rtx (DImode);")
15155 (define_insn "*ffsdi_1"
15156 [(set (reg:CCZ FLAGS_REG)
15157 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15159 (set (match_operand:DI 0 "register_operand" "=r")
15160 (ctz:DI (match_dup 1)))]
15162 "bsf{q}\t{%1, %0|%0, %1}"
15163 [(set_attr "prefix_0f" "1")])
15165 (define_insn "ctzsi2"
15166 [(set (match_operand:SI 0 "register_operand" "=r")
15167 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15168 (clobber (reg:CC FLAGS_REG))]
15170 "bsf{l}\t{%1, %0|%0, %1}"
15171 [(set_attr "prefix_0f" "1")])
15173 (define_insn "ctzdi2"
15174 [(set (match_operand:DI 0 "register_operand" "=r")
15175 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15176 (clobber (reg:CC FLAGS_REG))]
15178 "bsf{q}\t{%1, %0|%0, %1}"
15179 [(set_attr "prefix_0f" "1")])
15181 (define_expand "clzsi2"
15183 [(set (match_operand:SI 0 "register_operand" "")
15184 (minus:SI (const_int 31)
15185 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15186 (clobber (reg:CC FLAGS_REG))])
15188 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15189 (clobber (reg:CC FLAGS_REG))])]
15194 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15199 (define_insn "clzsi2_abm"
15200 [(set (match_operand:SI 0 "register_operand" "=r")
15201 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15202 (clobber (reg:CC FLAGS_REG))]
15204 "lzcnt{l}\t{%1, %0|%0, %1}"
15205 [(set_attr "prefix_rep" "1")
15206 (set_attr "type" "bitmanip")
15207 (set_attr "mode" "SI")])
15209 (define_insn "*bsr"
15210 [(set (match_operand:SI 0 "register_operand" "=r")
15211 (minus:SI (const_int 31)
15212 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15213 (clobber (reg:CC FLAGS_REG))]
15215 "bsr{l}\t{%1, %0|%0, %1}"
15216 [(set_attr "prefix_0f" "1")
15217 (set_attr "mode" "SI")])
15219 (define_insn "popcountsi2"
15220 [(set (match_operand:SI 0 "register_operand" "=r")
15221 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15222 (clobber (reg:CC FLAGS_REG))]
15224 "popcnt{l}\t{%1, %0|%0, %1}"
15225 [(set_attr "prefix_rep" "1")
15226 (set_attr "type" "bitmanip")
15227 (set_attr "mode" "SI")])
15229 (define_insn "*popcountsi2_cmp"
15230 [(set (reg FLAGS_REG)
15232 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15234 (set (match_operand:SI 0 "register_operand" "=r")
15235 (popcount:SI (match_dup 1)))]
15236 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15237 "popcnt{l}\t{%1, %0|%0, %1}"
15238 [(set_attr "prefix_rep" "1")
15239 (set_attr "type" "bitmanip")
15240 (set_attr "mode" "SI")])
15242 (define_insn "*popcountsi2_cmp_zext"
15243 [(set (reg FLAGS_REG)
15245 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15247 (set (match_operand:DI 0 "register_operand" "=r")
15248 (zero_extend:DI(popcount:SI (match_dup 1))))]
15249 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15250 "popcnt{l}\t{%1, %0|%0, %1}"
15251 [(set_attr "prefix_rep" "1")
15252 (set_attr "type" "bitmanip")
15253 (set_attr "mode" "SI")])
15255 (define_expand "bswapsi2"
15256 [(set (match_operand:SI 0 "register_operand" "")
15257 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15262 rtx x = operands[0];
15264 emit_move_insn (x, operands[1]);
15265 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15266 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15267 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15272 (define_insn "*bswapsi_1"
15273 [(set (match_operand:SI 0 "register_operand" "=r")
15274 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15277 [(set_attr "prefix_0f" "1")
15278 (set_attr "length" "2")])
15280 (define_insn "*bswaphi_lowpart_1"
15281 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15282 (bswap:HI (match_dup 0)))
15283 (clobber (reg:CC FLAGS_REG))]
15284 "TARGET_USE_XCHGB || optimize_size"
15286 xchg{b}\t{%h0, %b0|%b0, %h0}
15287 rol{w}\t{$8, %0|%0, 8}"
15288 [(set_attr "length" "2,4")
15289 (set_attr "mode" "QI,HI")])
15291 (define_insn "bswaphi_lowpart"
15292 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15293 (bswap:HI (match_dup 0)))
15294 (clobber (reg:CC FLAGS_REG))]
15296 "rol{w}\t{$8, %0|%0, 8}"
15297 [(set_attr "length" "4")
15298 (set_attr "mode" "HI")])
15300 (define_insn "bswapdi2"
15301 [(set (match_operand:DI 0 "register_operand" "=r")
15302 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15305 [(set_attr "prefix_0f" "1")
15306 (set_attr "length" "3")])
15308 (define_expand "clzdi2"
15310 [(set (match_operand:DI 0 "register_operand" "")
15311 (minus:DI (const_int 63)
15312 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15313 (clobber (reg:CC FLAGS_REG))])
15315 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15316 (clobber (reg:CC FLAGS_REG))])]
15321 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15326 (define_insn "clzdi2_abm"
15327 [(set (match_operand:DI 0 "register_operand" "=r")
15328 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15329 (clobber (reg:CC FLAGS_REG))]
15330 "TARGET_64BIT && TARGET_ABM"
15331 "lzcnt{q}\t{%1, %0|%0, %1}"
15332 [(set_attr "prefix_rep" "1")
15333 (set_attr "type" "bitmanip")
15334 (set_attr "mode" "DI")])
15336 (define_insn "*bsr_rex64"
15337 [(set (match_operand:DI 0 "register_operand" "=r")
15338 (minus:DI (const_int 63)
15339 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15340 (clobber (reg:CC FLAGS_REG))]
15342 "bsr{q}\t{%1, %0|%0, %1}"
15343 [(set_attr "prefix_0f" "1")
15344 (set_attr "mode" "DI")])
15346 (define_insn "popcountdi2"
15347 [(set (match_operand:DI 0 "register_operand" "=r")
15348 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15349 (clobber (reg:CC FLAGS_REG))]
15350 "TARGET_64BIT && TARGET_POPCNT"
15351 "popcnt{q}\t{%1, %0|%0, %1}"
15352 [(set_attr "prefix_rep" "1")
15353 (set_attr "type" "bitmanip")
15354 (set_attr "mode" "DI")])
15356 (define_insn "*popcountdi2_cmp"
15357 [(set (reg FLAGS_REG)
15359 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15361 (set (match_operand:DI 0 "register_operand" "=r")
15362 (popcount:DI (match_dup 1)))]
15363 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15364 "popcnt{q}\t{%1, %0|%0, %1}"
15365 [(set_attr "prefix_rep" "1")
15366 (set_attr "type" "bitmanip")
15367 (set_attr "mode" "DI")])
15369 (define_expand "clzhi2"
15371 [(set (match_operand:HI 0 "register_operand" "")
15372 (minus:HI (const_int 15)
15373 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15374 (clobber (reg:CC FLAGS_REG))])
15376 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15377 (clobber (reg:CC FLAGS_REG))])]
15382 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15387 (define_insn "clzhi2_abm"
15388 [(set (match_operand:HI 0 "register_operand" "=r")
15389 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15390 (clobber (reg:CC FLAGS_REG))]
15392 "lzcnt{w}\t{%1, %0|%0, %1}"
15393 [(set_attr "prefix_rep" "1")
15394 (set_attr "type" "bitmanip")
15395 (set_attr "mode" "HI")])
15397 (define_insn "*bsrhi"
15398 [(set (match_operand:HI 0 "register_operand" "=r")
15399 (minus:HI (const_int 15)
15400 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15401 (clobber (reg:CC FLAGS_REG))]
15403 "bsr{w}\t{%1, %0|%0, %1}"
15404 [(set_attr "prefix_0f" "1")
15405 (set_attr "mode" "HI")])
15407 (define_insn "popcounthi2"
15408 [(set (match_operand:HI 0 "register_operand" "=r")
15409 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15410 (clobber (reg:CC FLAGS_REG))]
15412 "popcnt{w}\t{%1, %0|%0, %1}"
15413 [(set_attr "prefix_rep" "1")
15414 (set_attr "type" "bitmanip")
15415 (set_attr "mode" "HI")])
15417 (define_insn "*popcounthi2_cmp"
15418 [(set (reg FLAGS_REG)
15420 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15422 (set (match_operand:HI 0 "register_operand" "=r")
15423 (popcount:HI (match_dup 1)))]
15424 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15425 "popcnt{w}\t{%1, %0|%0, %1}"
15426 [(set_attr "prefix_rep" "1")
15427 (set_attr "type" "bitmanip")
15428 (set_attr "mode" "HI")])
15430 (define_expand "paritydi2"
15431 [(set (match_operand:DI 0 "register_operand" "")
15432 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15435 rtx scratch = gen_reg_rtx (QImode);
15438 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15439 NULL_RTX, operands[1]));
15441 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15442 gen_rtx_REG (CCmode, FLAGS_REG),
15444 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15447 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15450 rtx tmp = gen_reg_rtx (SImode);
15452 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15453 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15458 (define_insn_and_split "paritydi2_cmp"
15459 [(set (reg:CC FLAGS_REG)
15460 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15461 (clobber (match_scratch:DI 0 "=r,X"))
15462 (clobber (match_scratch:SI 1 "=r,r"))
15463 (clobber (match_scratch:HI 2 "=Q,Q"))]
15466 "&& reload_completed"
15468 [(set (match_dup 1)
15469 (xor:SI (match_dup 1) (match_dup 4)))
15470 (clobber (reg:CC FLAGS_REG))])
15472 [(set (reg:CC FLAGS_REG)
15473 (parity:CC (match_dup 1)))
15474 (clobber (match_dup 1))
15475 (clobber (match_dup 2))])]
15477 operands[4] = gen_lowpart (SImode, operands[3]);
15479 if (MEM_P (operands[3]))
15480 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15481 else if (! TARGET_64BIT)
15482 operands[1] = gen_highpart (SImode, operands[3]);
15485 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15486 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15490 (define_expand "paritysi2"
15491 [(set (match_operand:SI 0 "register_operand" "")
15492 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15495 rtx scratch = gen_reg_rtx (QImode);
15498 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15500 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15501 gen_rtx_REG (CCmode, FLAGS_REG),
15503 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15505 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15509 (define_insn_and_split "paritysi2_cmp"
15510 [(set (reg:CC FLAGS_REG)
15511 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15512 (clobber (match_scratch:SI 0 "=r,X"))
15513 (clobber (match_scratch:HI 1 "=Q,Q"))]
15516 "&& reload_completed"
15518 [(set (match_dup 1)
15519 (xor:HI (match_dup 1) (match_dup 3)))
15520 (clobber (reg:CC FLAGS_REG))])
15522 [(set (reg:CC FLAGS_REG)
15523 (parity:CC (match_dup 1)))
15524 (clobber (match_dup 1))])]
15526 operands[3] = gen_lowpart (HImode, operands[2]);
15528 if (MEM_P (operands[2]))
15529 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15532 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15533 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15537 (define_insn "*parityhi2_cmp"
15538 [(set (reg:CC FLAGS_REG)
15539 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15540 (clobber (match_scratch:HI 0 "=Q"))]
15542 "xor{b}\t{%h0, %b0|%b0, %h0}"
15543 [(set_attr "length" "2")
15544 (set_attr "mode" "HI")])
15546 (define_insn "*parityqi2_cmp"
15547 [(set (reg:CC FLAGS_REG)
15548 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15551 [(set_attr "length" "2")
15552 (set_attr "mode" "QI")])
15554 ;; Thread-local storage patterns for ELF.
15556 ;; Note that these code sequences must appear exactly as shown
15557 ;; in order to allow linker relaxation.
15559 (define_insn "*tls_global_dynamic_32_gnu"
15560 [(set (match_operand:SI 0 "register_operand" "=a")
15561 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15562 (match_operand:SI 2 "tls_symbolic_operand" "")
15563 (match_operand:SI 3 "call_insn_operand" "")]
15565 (clobber (match_scratch:SI 4 "=d"))
15566 (clobber (match_scratch:SI 5 "=c"))
15567 (clobber (reg:CC FLAGS_REG))]
15568 "!TARGET_64BIT && TARGET_GNU_TLS"
15569 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15570 [(set_attr "type" "multi")
15571 (set_attr "length" "12")])
15573 (define_insn "*tls_global_dynamic_32_sun"
15574 [(set (match_operand:SI 0 "register_operand" "=a")
15575 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15576 (match_operand:SI 2 "tls_symbolic_operand" "")
15577 (match_operand:SI 3 "call_insn_operand" "")]
15579 (clobber (match_scratch:SI 4 "=d"))
15580 (clobber (match_scratch:SI 5 "=c"))
15581 (clobber (reg:CC FLAGS_REG))]
15582 "!TARGET_64BIT && TARGET_SUN_TLS"
15583 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15584 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15585 [(set_attr "type" "multi")
15586 (set_attr "length" "14")])
15588 (define_expand "tls_global_dynamic_32"
15589 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15592 (match_operand:SI 1 "tls_symbolic_operand" "")
15595 (clobber (match_scratch:SI 4 ""))
15596 (clobber (match_scratch:SI 5 ""))
15597 (clobber (reg:CC FLAGS_REG))])]
15601 operands[2] = pic_offset_table_rtx;
15604 operands[2] = gen_reg_rtx (Pmode);
15605 emit_insn (gen_set_got (operands[2]));
15607 if (TARGET_GNU2_TLS)
15609 emit_insn (gen_tls_dynamic_gnu2_32
15610 (operands[0], operands[1], operands[2]));
15613 operands[3] = ix86_tls_get_addr ();
15616 (define_insn "*tls_global_dynamic_64"
15617 [(set (match_operand:DI 0 "register_operand" "=a")
15618 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15619 (match_operand:DI 3 "" "")))
15620 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15623 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15624 [(set_attr "type" "multi")
15625 (set_attr "length" "16")])
15627 (define_expand "tls_global_dynamic_64"
15628 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15629 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15630 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15634 if (TARGET_GNU2_TLS)
15636 emit_insn (gen_tls_dynamic_gnu2_64
15637 (operands[0], operands[1]));
15640 operands[2] = ix86_tls_get_addr ();
15643 (define_insn "*tls_local_dynamic_base_32_gnu"
15644 [(set (match_operand:SI 0 "register_operand" "=a")
15645 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15646 (match_operand:SI 2 "call_insn_operand" "")]
15647 UNSPEC_TLS_LD_BASE))
15648 (clobber (match_scratch:SI 3 "=d"))
15649 (clobber (match_scratch:SI 4 "=c"))
15650 (clobber (reg:CC FLAGS_REG))]
15651 "!TARGET_64BIT && TARGET_GNU_TLS"
15652 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15653 [(set_attr "type" "multi")
15654 (set_attr "length" "11")])
15656 (define_insn "*tls_local_dynamic_base_32_sun"
15657 [(set (match_operand:SI 0 "register_operand" "=a")
15658 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15659 (match_operand:SI 2 "call_insn_operand" "")]
15660 UNSPEC_TLS_LD_BASE))
15661 (clobber (match_scratch:SI 3 "=d"))
15662 (clobber (match_scratch:SI 4 "=c"))
15663 (clobber (reg:CC FLAGS_REG))]
15664 "!TARGET_64BIT && TARGET_SUN_TLS"
15665 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15666 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15667 [(set_attr "type" "multi")
15668 (set_attr "length" "13")])
15670 (define_expand "tls_local_dynamic_base_32"
15671 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15672 (unspec:SI [(match_dup 1) (match_dup 2)]
15673 UNSPEC_TLS_LD_BASE))
15674 (clobber (match_scratch:SI 3 ""))
15675 (clobber (match_scratch:SI 4 ""))
15676 (clobber (reg:CC FLAGS_REG))])]
15680 operands[1] = pic_offset_table_rtx;
15683 operands[1] = gen_reg_rtx (Pmode);
15684 emit_insn (gen_set_got (operands[1]));
15686 if (TARGET_GNU2_TLS)
15688 emit_insn (gen_tls_dynamic_gnu2_32
15689 (operands[0], ix86_tls_module_base (), operands[1]));
15692 operands[2] = ix86_tls_get_addr ();
15695 (define_insn "*tls_local_dynamic_base_64"
15696 [(set (match_operand:DI 0 "register_operand" "=a")
15697 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15698 (match_operand:DI 2 "" "")))
15699 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15701 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15702 [(set_attr "type" "multi")
15703 (set_attr "length" "12")])
15705 (define_expand "tls_local_dynamic_base_64"
15706 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15707 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15708 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15711 if (TARGET_GNU2_TLS)
15713 emit_insn (gen_tls_dynamic_gnu2_64
15714 (operands[0], ix86_tls_module_base ()));
15717 operands[1] = ix86_tls_get_addr ();
15720 ;; Local dynamic of a single variable is a lose. Show combine how
15721 ;; to convert that back to global dynamic.
15723 (define_insn_and_split "*tls_local_dynamic_32_once"
15724 [(set (match_operand:SI 0 "register_operand" "=a")
15725 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15726 (match_operand:SI 2 "call_insn_operand" "")]
15727 UNSPEC_TLS_LD_BASE)
15728 (const:SI (unspec:SI
15729 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15731 (clobber (match_scratch:SI 4 "=d"))
15732 (clobber (match_scratch:SI 5 "=c"))
15733 (clobber (reg:CC FLAGS_REG))]
15737 [(parallel [(set (match_dup 0)
15738 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15740 (clobber (match_dup 4))
15741 (clobber (match_dup 5))
15742 (clobber (reg:CC FLAGS_REG))])]
15745 ;; Load and add the thread base pointer from %gs:0.
15747 (define_insn "*load_tp_si"
15748 [(set (match_operand:SI 0 "register_operand" "=r")
15749 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15751 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15752 [(set_attr "type" "imov")
15753 (set_attr "modrm" "0")
15754 (set_attr "length" "7")
15755 (set_attr "memory" "load")
15756 (set_attr "imm_disp" "false")])
15758 (define_insn "*add_tp_si"
15759 [(set (match_operand:SI 0 "register_operand" "=r")
15760 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15761 (match_operand:SI 1 "register_operand" "0")))
15762 (clobber (reg:CC FLAGS_REG))]
15764 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15765 [(set_attr "type" "alu")
15766 (set_attr "modrm" "0")
15767 (set_attr "length" "7")
15768 (set_attr "memory" "load")
15769 (set_attr "imm_disp" "false")])
15771 (define_insn "*load_tp_di"
15772 [(set (match_operand:DI 0 "register_operand" "=r")
15773 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15775 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15776 [(set_attr "type" "imov")
15777 (set_attr "modrm" "0")
15778 (set_attr "length" "7")
15779 (set_attr "memory" "load")
15780 (set_attr "imm_disp" "false")])
15782 (define_insn "*add_tp_di"
15783 [(set (match_operand:DI 0 "register_operand" "=r")
15784 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15785 (match_operand:DI 1 "register_operand" "0")))
15786 (clobber (reg:CC FLAGS_REG))]
15788 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15789 [(set_attr "type" "alu")
15790 (set_attr "modrm" "0")
15791 (set_attr "length" "7")
15792 (set_attr "memory" "load")
15793 (set_attr "imm_disp" "false")])
15795 ;; GNU2 TLS patterns can be split.
15797 (define_expand "tls_dynamic_gnu2_32"
15798 [(set (match_dup 3)
15799 (plus:SI (match_operand:SI 2 "register_operand" "")
15801 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15804 [(set (match_operand:SI 0 "register_operand" "")
15805 (unspec:SI [(match_dup 1) (match_dup 3)
15806 (match_dup 2) (reg:SI SP_REG)]
15808 (clobber (reg:CC FLAGS_REG))])]
15809 "!TARGET_64BIT && TARGET_GNU2_TLS"
15811 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15812 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15815 (define_insn "*tls_dynamic_lea_32"
15816 [(set (match_operand:SI 0 "register_operand" "=r")
15817 (plus:SI (match_operand:SI 1 "register_operand" "b")
15819 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15820 UNSPEC_TLSDESC))))]
15821 "!TARGET_64BIT && TARGET_GNU2_TLS"
15822 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15823 [(set_attr "type" "lea")
15824 (set_attr "mode" "SI")
15825 (set_attr "length" "6")
15826 (set_attr "length_address" "4")])
15828 (define_insn "*tls_dynamic_call_32"
15829 [(set (match_operand:SI 0 "register_operand" "=a")
15830 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15831 (match_operand:SI 2 "register_operand" "0")
15832 ;; we have to make sure %ebx still points to the GOT
15833 (match_operand:SI 3 "register_operand" "b")
15836 (clobber (reg:CC FLAGS_REG))]
15837 "!TARGET_64BIT && TARGET_GNU2_TLS"
15838 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15839 [(set_attr "type" "call")
15840 (set_attr "length" "2")
15841 (set_attr "length_address" "0")])
15843 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15844 [(set (match_operand:SI 0 "register_operand" "=&a")
15846 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15847 (match_operand:SI 4 "" "")
15848 (match_operand:SI 2 "register_operand" "b")
15851 (const:SI (unspec:SI
15852 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15854 (clobber (reg:CC FLAGS_REG))]
15855 "!TARGET_64BIT && TARGET_GNU2_TLS"
15858 [(set (match_dup 0) (match_dup 5))]
15860 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15861 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15864 (define_expand "tls_dynamic_gnu2_64"
15865 [(set (match_dup 2)
15866 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15869 [(set (match_operand:DI 0 "register_operand" "")
15870 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15872 (clobber (reg:CC FLAGS_REG))])]
15873 "TARGET_64BIT && TARGET_GNU2_TLS"
15875 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15876 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15879 (define_insn "*tls_dynamic_lea_64"
15880 [(set (match_operand:DI 0 "register_operand" "=r")
15881 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15883 "TARGET_64BIT && TARGET_GNU2_TLS"
15884 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15885 [(set_attr "type" "lea")
15886 (set_attr "mode" "DI")
15887 (set_attr "length" "7")
15888 (set_attr "length_address" "4")])
15890 (define_insn "*tls_dynamic_call_64"
15891 [(set (match_operand:DI 0 "register_operand" "=a")
15892 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15893 (match_operand:DI 2 "register_operand" "0")
15896 (clobber (reg:CC FLAGS_REG))]
15897 "TARGET_64BIT && TARGET_GNU2_TLS"
15898 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15899 [(set_attr "type" "call")
15900 (set_attr "length" "2")
15901 (set_attr "length_address" "0")])
15903 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15904 [(set (match_operand:DI 0 "register_operand" "=&a")
15906 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15907 (match_operand:DI 3 "" "")
15910 (const:DI (unspec:DI
15911 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15913 (clobber (reg:CC FLAGS_REG))]
15914 "TARGET_64BIT && TARGET_GNU2_TLS"
15917 [(set (match_dup 0) (match_dup 4))]
15919 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15920 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15925 ;; These patterns match the binary 387 instructions for addM3, subM3,
15926 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15927 ;; SFmode. The first is the normal insn, the second the same insn but
15928 ;; with one operand a conversion, and the third the same insn but with
15929 ;; the other operand a conversion. The conversion may be SFmode or
15930 ;; SImode if the target mode DFmode, but only SImode if the target mode
15933 ;; Gcc is slightly more smart about handling normal two address instructions
15934 ;; so use special patterns for add and mull.
15936 (define_insn "*fop_sf_comm_mixed"
15937 [(set (match_operand:SF 0 "register_operand" "=f,x")
15938 (match_operator:SF 3 "binary_fp_operator"
15939 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15940 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15941 "TARGET_MIX_SSE_I387
15942 && COMMUTATIVE_ARITH_P (operands[3])
15943 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15944 "* return output_387_binary_op (insn, operands);"
15945 [(set (attr "type")
15946 (if_then_else (eq_attr "alternative" "1")
15947 (if_then_else (match_operand:SF 3 "mult_operator" "")
15948 (const_string "ssemul")
15949 (const_string "sseadd"))
15950 (if_then_else (match_operand:SF 3 "mult_operator" "")
15951 (const_string "fmul")
15952 (const_string "fop"))))
15953 (set_attr "mode" "SF")])
15955 (define_insn "*fop_sf_comm_sse"
15956 [(set (match_operand:SF 0 "register_operand" "=x")
15957 (match_operator:SF 3 "binary_fp_operator"
15958 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15959 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15961 && COMMUTATIVE_ARITH_P (operands[3])
15962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15963 "* return output_387_binary_op (insn, operands);"
15964 [(set (attr "type")
15965 (if_then_else (match_operand:SF 3 "mult_operator" "")
15966 (const_string "ssemul")
15967 (const_string "sseadd")))
15968 (set_attr "mode" "SF")])
15970 (define_insn "*fop_sf_comm_i387"
15971 [(set (match_operand:SF 0 "register_operand" "=f")
15972 (match_operator:SF 3 "binary_fp_operator"
15973 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15974 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15976 && COMMUTATIVE_ARITH_P (operands[3])
15977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15978 "* return output_387_binary_op (insn, operands);"
15979 [(set (attr "type")
15980 (if_then_else (match_operand:SF 3 "mult_operator" "")
15981 (const_string "fmul")
15982 (const_string "fop")))
15983 (set_attr "mode" "SF")])
15985 (define_insn "*fop_sf_1_mixed"
15986 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15987 (match_operator:SF 3 "binary_fp_operator"
15988 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15989 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15990 "TARGET_MIX_SSE_I387
15991 && !COMMUTATIVE_ARITH_P (operands[3])
15992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15993 "* return output_387_binary_op (insn, operands);"
15994 [(set (attr "type")
15995 (cond [(and (eq_attr "alternative" "2")
15996 (match_operand:SF 3 "mult_operator" ""))
15997 (const_string "ssemul")
15998 (and (eq_attr "alternative" "2")
15999 (match_operand:SF 3 "div_operator" ""))
16000 (const_string "ssediv")
16001 (eq_attr "alternative" "2")
16002 (const_string "sseadd")
16003 (match_operand:SF 3 "mult_operator" "")
16004 (const_string "fmul")
16005 (match_operand:SF 3 "div_operator" "")
16006 (const_string "fdiv")
16008 (const_string "fop")))
16009 (set_attr "mode" "SF")])
16011 (define_insn "*rcpsf2_sse"
16012 [(set (match_operand:SF 0 "register_operand" "=x")
16013 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16016 "rcpss\t{%1, %0|%0, %1}"
16017 [(set_attr "type" "sse")
16018 (set_attr "mode" "SF")])
16020 (define_insn "*fop_sf_1_sse"
16021 [(set (match_operand:SF 0 "register_operand" "=x")
16022 (match_operator:SF 3 "binary_fp_operator"
16023 [(match_operand:SF 1 "register_operand" "0")
16024 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16026 && !COMMUTATIVE_ARITH_P (operands[3])"
16027 "* return output_387_binary_op (insn, operands);"
16028 [(set (attr "type")
16029 (cond [(match_operand:SF 3 "mult_operator" "")
16030 (const_string "ssemul")
16031 (match_operand:SF 3 "div_operator" "")
16032 (const_string "ssediv")
16034 (const_string "sseadd")))
16035 (set_attr "mode" "SF")])
16037 ;; This pattern is not fully shadowed by the pattern above.
16038 (define_insn "*fop_sf_1_i387"
16039 [(set (match_operand:SF 0 "register_operand" "=f,f")
16040 (match_operator:SF 3 "binary_fp_operator"
16041 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16042 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16043 "TARGET_80387 && !TARGET_SSE_MATH
16044 && !COMMUTATIVE_ARITH_P (operands[3])
16045 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16046 "* return output_387_binary_op (insn, operands);"
16047 [(set (attr "type")
16048 (cond [(match_operand:SF 3 "mult_operator" "")
16049 (const_string "fmul")
16050 (match_operand:SF 3 "div_operator" "")
16051 (const_string "fdiv")
16053 (const_string "fop")))
16054 (set_attr "mode" "SF")])
16056 ;; ??? Add SSE splitters for these!
16057 (define_insn "*fop_sf_2<mode>_i387"
16058 [(set (match_operand:SF 0 "register_operand" "=f,f")
16059 (match_operator:SF 3 "binary_fp_operator"
16060 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16061 (match_operand:SF 2 "register_operand" "0,0")]))]
16062 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16063 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16064 [(set (attr "type")
16065 (cond [(match_operand:SF 3 "mult_operator" "")
16066 (const_string "fmul")
16067 (match_operand:SF 3 "div_operator" "")
16068 (const_string "fdiv")
16070 (const_string "fop")))
16071 (set_attr "fp_int_src" "true")
16072 (set_attr "mode" "<MODE>")])
16074 (define_insn "*fop_sf_3<mode>_i387"
16075 [(set (match_operand:SF 0 "register_operand" "=f,f")
16076 (match_operator:SF 3 "binary_fp_operator"
16077 [(match_operand:SF 1 "register_operand" "0,0")
16078 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16079 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16080 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16081 [(set (attr "type")
16082 (cond [(match_operand:SF 3 "mult_operator" "")
16083 (const_string "fmul")
16084 (match_operand:SF 3 "div_operator" "")
16085 (const_string "fdiv")
16087 (const_string "fop")))
16088 (set_attr "fp_int_src" "true")
16089 (set_attr "mode" "<MODE>")])
16091 (define_insn "*fop_df_comm_mixed"
16092 [(set (match_operand:DF 0 "register_operand" "=f,x")
16093 (match_operator:DF 3 "binary_fp_operator"
16094 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16095 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16096 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16097 && COMMUTATIVE_ARITH_P (operands[3])
16098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16099 "* return output_387_binary_op (insn, operands);"
16100 [(set (attr "type")
16101 (if_then_else (eq_attr "alternative" "1")
16102 (if_then_else (match_operand:DF 3 "mult_operator" "")
16103 (const_string "ssemul")
16104 (const_string "sseadd"))
16105 (if_then_else (match_operand:DF 3 "mult_operator" "")
16106 (const_string "fmul")
16107 (const_string "fop"))))
16108 (set_attr "mode" "DF")])
16110 (define_insn "*fop_df_comm_sse"
16111 [(set (match_operand:DF 0 "register_operand" "=x")
16112 (match_operator:DF 3 "binary_fp_operator"
16113 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16114 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16115 "TARGET_SSE2 && TARGET_SSE_MATH
16116 && COMMUTATIVE_ARITH_P (operands[3])
16117 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16118 "* return output_387_binary_op (insn, operands);"
16119 [(set (attr "type")
16120 (if_then_else (match_operand:DF 3 "mult_operator" "")
16121 (const_string "ssemul")
16122 (const_string "sseadd")))
16123 (set_attr "mode" "DF")])
16125 (define_insn "*fop_df_comm_i387"
16126 [(set (match_operand:DF 0 "register_operand" "=f")
16127 (match_operator:DF 3 "binary_fp_operator"
16128 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16129 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16131 && COMMUTATIVE_ARITH_P (operands[3])
16132 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16133 "* return output_387_binary_op (insn, operands);"
16134 [(set (attr "type")
16135 (if_then_else (match_operand:DF 3 "mult_operator" "")
16136 (const_string "fmul")
16137 (const_string "fop")))
16138 (set_attr "mode" "DF")])
16140 (define_insn "*fop_df_1_mixed"
16141 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16142 (match_operator:DF 3 "binary_fp_operator"
16143 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16144 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16145 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16146 && !COMMUTATIVE_ARITH_P (operands[3])
16147 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16148 "* return output_387_binary_op (insn, operands);"
16149 [(set (attr "type")
16150 (cond [(and (eq_attr "alternative" "2")
16151 (match_operand:DF 3 "mult_operator" ""))
16152 (const_string "ssemul")
16153 (and (eq_attr "alternative" "2")
16154 (match_operand:DF 3 "div_operator" ""))
16155 (const_string "ssediv")
16156 (eq_attr "alternative" "2")
16157 (const_string "sseadd")
16158 (match_operand:DF 3 "mult_operator" "")
16159 (const_string "fmul")
16160 (match_operand:DF 3 "div_operator" "")
16161 (const_string "fdiv")
16163 (const_string "fop")))
16164 (set_attr "mode" "DF")])
16166 (define_insn "*fop_df_1_sse"
16167 [(set (match_operand:DF 0 "register_operand" "=x")
16168 (match_operator:DF 3 "binary_fp_operator"
16169 [(match_operand:DF 1 "register_operand" "0")
16170 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16171 "TARGET_SSE2 && TARGET_SSE_MATH
16172 && !COMMUTATIVE_ARITH_P (operands[3])"
16173 "* return output_387_binary_op (insn, operands);"
16174 [(set_attr "mode" "DF")
16176 (cond [(match_operand:DF 3 "mult_operator" "")
16177 (const_string "ssemul")
16178 (match_operand:DF 3 "div_operator" "")
16179 (const_string "ssediv")
16181 (const_string "sseadd")))])
16183 ;; This pattern is not fully shadowed by the pattern above.
16184 (define_insn "*fop_df_1_i387"
16185 [(set (match_operand:DF 0 "register_operand" "=f,f")
16186 (match_operator:DF 3 "binary_fp_operator"
16187 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16188 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16189 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16190 && !COMMUTATIVE_ARITH_P (operands[3])
16191 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16192 "* return output_387_binary_op (insn, operands);"
16193 [(set (attr "type")
16194 (cond [(match_operand:DF 3 "mult_operator" "")
16195 (const_string "fmul")
16196 (match_operand:DF 3 "div_operator" "")
16197 (const_string "fdiv")
16199 (const_string "fop")))
16200 (set_attr "mode" "DF")])
16202 ;; ??? Add SSE splitters for these!
16203 (define_insn "*fop_df_2<mode>_i387"
16204 [(set (match_operand:DF 0 "register_operand" "=f,f")
16205 (match_operator:DF 3 "binary_fp_operator"
16206 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16207 (match_operand:DF 2 "register_operand" "0,0")]))]
16208 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16209 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16210 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16211 [(set (attr "type")
16212 (cond [(match_operand:DF 3 "mult_operator" "")
16213 (const_string "fmul")
16214 (match_operand:DF 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_df_3<mode>_i387"
16222 [(set (match_operand:DF 0 "register_operand" "=f,f")
16223 (match_operator:DF 3 "binary_fp_operator"
16224 [(match_operand:DF 1 "register_operand" "0,0")
16225 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16226 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16227 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16228 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16229 [(set (attr "type")
16230 (cond [(match_operand:DF 3 "mult_operator" "")
16231 (const_string "fmul")
16232 (match_operand:DF 3 "div_operator" "")
16233 (const_string "fdiv")
16235 (const_string "fop")))
16236 (set_attr "fp_int_src" "true")
16237 (set_attr "mode" "<MODE>")])
16239 (define_insn "*fop_df_4_i387"
16240 [(set (match_operand:DF 0 "register_operand" "=f,f")
16241 (match_operator:DF 3 "binary_fp_operator"
16242 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16243 (match_operand:DF 2 "register_operand" "0,f")]))]
16244 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16245 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16246 "* return output_387_binary_op (insn, operands);"
16247 [(set (attr "type")
16248 (cond [(match_operand:DF 3 "mult_operator" "")
16249 (const_string "fmul")
16250 (match_operand:DF 3 "div_operator" "")
16251 (const_string "fdiv")
16253 (const_string "fop")))
16254 (set_attr "mode" "SF")])
16256 (define_insn "*fop_df_5_i387"
16257 [(set (match_operand:DF 0 "register_operand" "=f,f")
16258 (match_operator:DF 3 "binary_fp_operator"
16259 [(match_operand:DF 1 "register_operand" "0,f")
16261 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16262 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16263 "* return output_387_binary_op (insn, operands);"
16264 [(set (attr "type")
16265 (cond [(match_operand:DF 3 "mult_operator" "")
16266 (const_string "fmul")
16267 (match_operand:DF 3 "div_operator" "")
16268 (const_string "fdiv")
16270 (const_string "fop")))
16271 (set_attr "mode" "SF")])
16273 (define_insn "*fop_df_6_i387"
16274 [(set (match_operand:DF 0 "register_operand" "=f,f")
16275 (match_operator:DF 3 "binary_fp_operator"
16277 (match_operand:SF 1 "register_operand" "0,f"))
16279 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16280 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16281 "* return output_387_binary_op (insn, operands);"
16282 [(set (attr "type")
16283 (cond [(match_operand:DF 3 "mult_operator" "")
16284 (const_string "fmul")
16285 (match_operand:DF 3 "div_operator" "")
16286 (const_string "fdiv")
16288 (const_string "fop")))
16289 (set_attr "mode" "SF")])
16291 (define_insn "*fop_xf_comm_i387"
16292 [(set (match_operand:XF 0 "register_operand" "=f")
16293 (match_operator:XF 3 "binary_fp_operator"
16294 [(match_operand:XF 1 "register_operand" "%0")
16295 (match_operand:XF 2 "register_operand" "f")]))]
16297 && COMMUTATIVE_ARITH_P (operands[3])"
16298 "* return output_387_binary_op (insn, operands);"
16299 [(set (attr "type")
16300 (if_then_else (match_operand:XF 3 "mult_operator" "")
16301 (const_string "fmul")
16302 (const_string "fop")))
16303 (set_attr "mode" "XF")])
16305 (define_insn "*fop_xf_1_i387"
16306 [(set (match_operand:XF 0 "register_operand" "=f,f")
16307 (match_operator:XF 3 "binary_fp_operator"
16308 [(match_operand:XF 1 "register_operand" "0,f")
16309 (match_operand:XF 2 "register_operand" "f,0")]))]
16311 && !COMMUTATIVE_ARITH_P (operands[3])"
16312 "* return output_387_binary_op (insn, operands);"
16313 [(set (attr "type")
16314 (cond [(match_operand:XF 3 "mult_operator" "")
16315 (const_string "fmul")
16316 (match_operand:XF 3 "div_operator" "")
16317 (const_string "fdiv")
16319 (const_string "fop")))
16320 (set_attr "mode" "XF")])
16322 (define_insn "*fop_xf_2<mode>_i387"
16323 [(set (match_operand:XF 0 "register_operand" "=f,f")
16324 (match_operator:XF 3 "binary_fp_operator"
16325 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16326 (match_operand:XF 2 "register_operand" "0,0")]))]
16327 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16328 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16329 [(set (attr "type")
16330 (cond [(match_operand:XF 3 "mult_operator" "")
16331 (const_string "fmul")
16332 (match_operand:XF 3 "div_operator" "")
16333 (const_string "fdiv")
16335 (const_string "fop")))
16336 (set_attr "fp_int_src" "true")
16337 (set_attr "mode" "<MODE>")])
16339 (define_insn "*fop_xf_3<mode>_i387"
16340 [(set (match_operand:XF 0 "register_operand" "=f,f")
16341 (match_operator:XF 3 "binary_fp_operator"
16342 [(match_operand:XF 1 "register_operand" "0,0")
16343 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16344 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16345 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16346 [(set (attr "type")
16347 (cond [(match_operand:XF 3 "mult_operator" "")
16348 (const_string "fmul")
16349 (match_operand:XF 3 "div_operator" "")
16350 (const_string "fdiv")
16352 (const_string "fop")))
16353 (set_attr "fp_int_src" "true")
16354 (set_attr "mode" "<MODE>")])
16356 (define_insn "*fop_xf_4_i387"
16357 [(set (match_operand:XF 0 "register_operand" "=f,f")
16358 (match_operator:XF 3 "binary_fp_operator"
16360 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16361 (match_operand:XF 2 "register_operand" "0,f")]))]
16363 "* return output_387_binary_op (insn, operands);"
16364 [(set (attr "type")
16365 (cond [(match_operand:XF 3 "mult_operator" "")
16366 (const_string "fmul")
16367 (match_operand:XF 3 "div_operator" "")
16368 (const_string "fdiv")
16370 (const_string "fop")))
16371 (set_attr "mode" "SF")])
16373 (define_insn "*fop_xf_5_i387"
16374 [(set (match_operand:XF 0 "register_operand" "=f,f")
16375 (match_operator:XF 3 "binary_fp_operator"
16376 [(match_operand:XF 1 "register_operand" "0,f")
16378 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16380 "* return output_387_binary_op (insn, operands);"
16381 [(set (attr "type")
16382 (cond [(match_operand:XF 3 "mult_operator" "")
16383 (const_string "fmul")
16384 (match_operand:XF 3 "div_operator" "")
16385 (const_string "fdiv")
16387 (const_string "fop")))
16388 (set_attr "mode" "SF")])
16390 (define_insn "*fop_xf_6_i387"
16391 [(set (match_operand:XF 0 "register_operand" "=f,f")
16392 (match_operator:XF 3 "binary_fp_operator"
16394 (match_operand:MODEF 1 "register_operand" "0,f"))
16396 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16398 "* return output_387_binary_op (insn, operands);"
16399 [(set (attr "type")
16400 (cond [(match_operand:XF 3 "mult_operator" "")
16401 (const_string "fmul")
16402 (match_operand:XF 3 "div_operator" "")
16403 (const_string "fdiv")
16405 (const_string "fop")))
16406 (set_attr "mode" "SF")])
16409 [(set (match_operand 0 "register_operand" "")
16410 (match_operator 3 "binary_fp_operator"
16411 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16412 (match_operand 2 "register_operand" "")]))]
16414 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16417 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16418 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16419 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16420 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16421 GET_MODE (operands[3]),
16424 ix86_free_from_memory (GET_MODE (operands[1]));
16429 [(set (match_operand 0 "register_operand" "")
16430 (match_operator 3 "binary_fp_operator"
16431 [(match_operand 1 "register_operand" "")
16432 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16434 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16437 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16438 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16439 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16440 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16441 GET_MODE (operands[3]),
16444 ix86_free_from_memory (GET_MODE (operands[2]));
16448 ;; FPU special functions.
16450 ;; This pattern implements a no-op XFmode truncation for
16451 ;; all fancy i386 XFmode math functions.
16453 (define_insn "truncxf<mode>2_i387_noop_unspec"
16454 [(set (match_operand:MODEF 0 "register_operand" "=f")
16455 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16456 UNSPEC_TRUNC_NOOP))]
16457 "TARGET_USE_FANCY_MATH_387"
16458 "* return output_387_reg_move (insn, operands);"
16459 [(set_attr "type" "fmov")
16460 (set_attr "mode" "<MODE>")])
16462 (define_insn "sqrtxf2"
16463 [(set (match_operand:XF 0 "register_operand" "=f")
16464 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16465 "TARGET_USE_FANCY_MATH_387"
16467 [(set_attr "type" "fpspc")
16468 (set_attr "mode" "XF")
16469 (set_attr "athlon_decode" "direct")
16470 (set_attr "amdfam10_decode" "direct")])
16472 (define_insn "sqrt_extend<mode>xf2_i387"
16473 [(set (match_operand:XF 0 "register_operand" "=f")
16476 (match_operand:MODEF 1 "register_operand" "0"))))]
16477 "TARGET_USE_FANCY_MATH_387"
16479 [(set_attr "type" "fpspc")
16480 (set_attr "mode" "XF")
16481 (set_attr "athlon_decode" "direct")
16482 (set_attr "amdfam10_decode" "direct")])
16484 (define_insn "*rsqrtsf2_sse"
16485 [(set (match_operand:SF 0 "register_operand" "=x")
16486 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16489 "rsqrtss\t{%1, %0|%0, %1}"
16490 [(set_attr "type" "sse")
16491 (set_attr "mode" "SF")])
16493 (define_expand "rsqrtsf2"
16494 [(set (match_operand:SF 0 "register_operand" "")
16495 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16499 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16503 (define_insn "*sqrt<mode>2_sse"
16504 [(set (match_operand:MODEF 0 "register_operand" "=x")
16506 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16507 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16508 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16509 [(set_attr "type" "sse")
16510 (set_attr "mode" "<MODE>")
16511 (set_attr "athlon_decode" "*")
16512 (set_attr "amdfam10_decode" "*")])
16514 (define_expand "sqrt<mode>2"
16515 [(set (match_operand:MODEF 0 "register_operand" "")
16517 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16518 "TARGET_USE_FANCY_MATH_387
16519 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16521 if (<MODE>mode == SFmode
16522 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16523 && flag_finite_math_only && !flag_trapping_math
16524 && flag_unsafe_math_optimizations)
16526 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16530 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16532 rtx op0 = gen_reg_rtx (XFmode);
16533 rtx op1 = force_reg (<MODE>mode, operands[1]);
16535 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16536 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16541 (define_insn "fpremxf4_i387"
16542 [(set (match_operand:XF 0 "register_operand" "=f")
16543 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16544 (match_operand:XF 3 "register_operand" "1")]
16546 (set (match_operand:XF 1 "register_operand" "=u")
16547 (unspec:XF [(match_dup 2) (match_dup 3)]
16549 (set (reg:CCFP FPSR_REG)
16550 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16552 "TARGET_USE_FANCY_MATH_387"
16554 [(set_attr "type" "fpspc")
16555 (set_attr "mode" "XF")])
16557 (define_expand "fmodxf3"
16558 [(use (match_operand:XF 0 "register_operand" ""))
16559 (use (match_operand:XF 1 "register_operand" ""))
16560 (use (match_operand:XF 2 "register_operand" ""))]
16561 "TARGET_USE_FANCY_MATH_387"
16563 rtx label = gen_label_rtx ();
16567 if (rtx_equal_p (operands[1], operands[2]))
16569 op2 = gen_reg_rtx (XFmode);
16570 emit_move_insn (op2, operands[2]);
16575 emit_label (label);
16576 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16577 ix86_emit_fp_unordered_jump (label);
16578 LABEL_NUSES (label) = 1;
16580 emit_move_insn (operands[0], operands[1]);
16584 (define_expand "fmod<mode>3"
16585 [(use (match_operand:MODEF 0 "register_operand" ""))
16586 (use (match_operand:MODEF 1 "general_operand" ""))
16587 (use (match_operand:MODEF 2 "general_operand" ""))]
16588 "TARGET_USE_FANCY_MATH_387"
16590 rtx label = gen_label_rtx ();
16592 rtx op1 = gen_reg_rtx (XFmode);
16593 rtx op2 = gen_reg_rtx (XFmode);
16595 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16596 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16598 emit_label (label);
16599 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16600 ix86_emit_fp_unordered_jump (label);
16601 LABEL_NUSES (label) = 1;
16603 /* Truncate the result properly for strict SSE math. */
16604 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16605 && !TARGET_MIX_SSE_I387)
16606 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16608 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16613 (define_insn "fprem1xf4_i387"
16614 [(set (match_operand:XF 0 "register_operand" "=f")
16615 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16616 (match_operand:XF 3 "register_operand" "1")]
16618 (set (match_operand:XF 1 "register_operand" "=u")
16619 (unspec:XF [(match_dup 2) (match_dup 3)]
16621 (set (reg:CCFP FPSR_REG)
16622 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16624 "TARGET_USE_FANCY_MATH_387"
16626 [(set_attr "type" "fpspc")
16627 (set_attr "mode" "XF")])
16629 (define_expand "remainderxf3"
16630 [(use (match_operand:XF 0 "register_operand" ""))
16631 (use (match_operand:XF 1 "register_operand" ""))
16632 (use (match_operand:XF 2 "register_operand" ""))]
16633 "TARGET_USE_FANCY_MATH_387"
16635 rtx label = gen_label_rtx ();
16639 if (rtx_equal_p (operands[1], operands[2]))
16641 op2 = gen_reg_rtx (XFmode);
16642 emit_move_insn (op2, operands[2]);
16647 emit_label (label);
16648 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16649 ix86_emit_fp_unordered_jump (label);
16650 LABEL_NUSES (label) = 1;
16652 emit_move_insn (operands[0], operands[1]);
16656 (define_expand "remainder<mode>3"
16657 [(use (match_operand:MODEF 0 "register_operand" ""))
16658 (use (match_operand:MODEF 1 "general_operand" ""))
16659 (use (match_operand:MODEF 2 "general_operand" ""))]
16660 "TARGET_USE_FANCY_MATH_387"
16662 rtx label = gen_label_rtx ();
16664 rtx op1 = gen_reg_rtx (XFmode);
16665 rtx op2 = gen_reg_rtx (XFmode);
16667 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16668 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16670 emit_label (label);
16672 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16673 ix86_emit_fp_unordered_jump (label);
16674 LABEL_NUSES (label) = 1;
16676 /* Truncate the result properly for strict SSE math. */
16677 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16678 && !TARGET_MIX_SSE_I387)
16679 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16681 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16686 (define_insn "*sinxf2_i387"
16687 [(set (match_operand:XF 0 "register_operand" "=f")
16688 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16689 "TARGET_USE_FANCY_MATH_387
16690 && flag_unsafe_math_optimizations"
16692 [(set_attr "type" "fpspc")
16693 (set_attr "mode" "XF")])
16695 (define_insn "*sin_extend<mode>xf2_i387"
16696 [(set (match_operand:XF 0 "register_operand" "=f")
16697 (unspec:XF [(float_extend:XF
16698 (match_operand:MODEF 1 "register_operand" "0"))]
16700 "TARGET_USE_FANCY_MATH_387
16701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16702 || TARGET_MIX_SSE_I387)
16703 && flag_unsafe_math_optimizations"
16705 [(set_attr "type" "fpspc")
16706 (set_attr "mode" "XF")])
16708 (define_insn "*cosxf2_i387"
16709 [(set (match_operand:XF 0 "register_operand" "=f")
16710 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16711 "TARGET_USE_FANCY_MATH_387
16712 && flag_unsafe_math_optimizations"
16714 [(set_attr "type" "fpspc")
16715 (set_attr "mode" "XF")])
16717 (define_insn "*cos_extend<mode>xf2_i387"
16718 [(set (match_operand:XF 0 "register_operand" "=f")
16719 (unspec:XF [(float_extend:XF
16720 (match_operand:MODEF 1 "register_operand" "0"))]
16722 "TARGET_USE_FANCY_MATH_387
16723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16724 || TARGET_MIX_SSE_I387)
16725 && flag_unsafe_math_optimizations"
16727 [(set_attr "type" "fpspc")
16728 (set_attr "mode" "XF")])
16730 ;; When sincos pattern is defined, sin and cos builtin functions will be
16731 ;; expanded to sincos pattern with one of its outputs left unused.
16732 ;; CSE pass will figure out if two sincos patterns can be combined,
16733 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16734 ;; depending on the unused output.
16736 (define_insn "sincosxf3"
16737 [(set (match_operand:XF 0 "register_operand" "=f")
16738 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16739 UNSPEC_SINCOS_COS))
16740 (set (match_operand:XF 1 "register_operand" "=u")
16741 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16742 "TARGET_USE_FANCY_MATH_387
16743 && flag_unsafe_math_optimizations"
16745 [(set_attr "type" "fpspc")
16746 (set_attr "mode" "XF")])
16749 [(set (match_operand:XF 0 "register_operand" "")
16750 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16751 UNSPEC_SINCOS_COS))
16752 (set (match_operand:XF 1 "register_operand" "")
16753 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16754 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16755 && !(reload_completed || reload_in_progress)"
16756 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16760 [(set (match_operand:XF 0 "register_operand" "")
16761 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16762 UNSPEC_SINCOS_COS))
16763 (set (match_operand:XF 1 "register_operand" "")
16764 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16765 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16766 && !(reload_completed || reload_in_progress)"
16767 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16770 (define_insn "sincos_extend<mode>xf3_i387"
16771 [(set (match_operand:XF 0 "register_operand" "=f")
16772 (unspec:XF [(float_extend:XF
16773 (match_operand:MODEF 2 "register_operand" "0"))]
16774 UNSPEC_SINCOS_COS))
16775 (set (match_operand:XF 1 "register_operand" "=u")
16776 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16777 "TARGET_USE_FANCY_MATH_387
16778 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16779 || TARGET_MIX_SSE_I387)
16780 && flag_unsafe_math_optimizations"
16782 [(set_attr "type" "fpspc")
16783 (set_attr "mode" "XF")])
16786 [(set (match_operand:XF 0 "register_operand" "")
16787 (unspec:XF [(float_extend:XF
16788 (match_operand:MODEF 2 "register_operand" ""))]
16789 UNSPEC_SINCOS_COS))
16790 (set (match_operand:XF 1 "register_operand" "")
16791 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16792 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16793 && !(reload_completed || reload_in_progress)"
16794 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16798 [(set (match_operand:XF 0 "register_operand" "")
16799 (unspec:XF [(float_extend:XF
16800 (match_operand:MODEF 2 "register_operand" ""))]
16801 UNSPEC_SINCOS_COS))
16802 (set (match_operand:XF 1 "register_operand" "")
16803 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16804 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16805 && !(reload_completed || reload_in_progress)"
16806 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16809 (define_expand "sincos<mode>3"
16810 [(use (match_operand:MODEF 0 "register_operand" ""))
16811 (use (match_operand:MODEF 1 "register_operand" ""))
16812 (use (match_operand:MODEF 2 "register_operand" ""))]
16813 "TARGET_USE_FANCY_MATH_387
16814 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16815 || TARGET_MIX_SSE_I387)
16816 && flag_unsafe_math_optimizations"
16818 rtx op0 = gen_reg_rtx (XFmode);
16819 rtx op1 = gen_reg_rtx (XFmode);
16821 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16822 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16823 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16827 (define_insn "fptanxf4_i387"
16828 [(set (match_operand:XF 0 "register_operand" "=f")
16829 (match_operand:XF 3 "const_double_operand" "F"))
16830 (set (match_operand:XF 1 "register_operand" "=u")
16831 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16833 "TARGET_USE_FANCY_MATH_387
16834 && flag_unsafe_math_optimizations
16835 && standard_80387_constant_p (operands[3]) == 2"
16837 [(set_attr "type" "fpspc")
16838 (set_attr "mode" "XF")])
16840 (define_insn "fptan_extend<mode>xf4_i387"
16841 [(set (match_operand:MODEF 0 "register_operand" "=f")
16842 (match_operand:MODEF 3 "const_double_operand" "F"))
16843 (set (match_operand:XF 1 "register_operand" "=u")
16844 (unspec:XF [(float_extend:XF
16845 (match_operand:MODEF 2 "register_operand" "0"))]
16847 "TARGET_USE_FANCY_MATH_387
16848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16849 || TARGET_MIX_SSE_I387)
16850 && flag_unsafe_math_optimizations
16851 && standard_80387_constant_p (operands[3]) == 2"
16853 [(set_attr "type" "fpspc")
16854 (set_attr "mode" "XF")])
16856 (define_expand "tanxf2"
16857 [(use (match_operand:XF 0 "register_operand" ""))
16858 (use (match_operand:XF 1 "register_operand" ""))]
16859 "TARGET_USE_FANCY_MATH_387
16860 && flag_unsafe_math_optimizations"
16862 rtx one = gen_reg_rtx (XFmode);
16863 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16865 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16869 (define_expand "tan<mode>2"
16870 [(use (match_operand:MODEF 0 "register_operand" ""))
16871 (use (match_operand:MODEF 1 "register_operand" ""))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16874 || TARGET_MIX_SSE_I387)
16875 && flag_unsafe_math_optimizations"
16877 rtx op0 = gen_reg_rtx (XFmode);
16879 rtx one = gen_reg_rtx (<MODE>mode);
16880 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16882 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16883 operands[1], op2));
16884 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16888 (define_insn "*fpatanxf3_i387"
16889 [(set (match_operand:XF 0 "register_operand" "=f")
16890 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16891 (match_operand:XF 2 "register_operand" "u")]
16893 (clobber (match_scratch:XF 3 "=2"))]
16894 "TARGET_USE_FANCY_MATH_387
16895 && flag_unsafe_math_optimizations"
16897 [(set_attr "type" "fpspc")
16898 (set_attr "mode" "XF")])
16900 (define_insn "fpatan_extend<mode>xf3_i387"
16901 [(set (match_operand:XF 0 "register_operand" "=f")
16902 (unspec:XF [(float_extend:XF
16903 (match_operand:MODEF 1 "register_operand" "0"))
16905 (match_operand:MODEF 2 "register_operand" "u"))]
16907 (clobber (match_scratch:XF 3 "=2"))]
16908 "TARGET_USE_FANCY_MATH_387
16909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16910 || TARGET_MIX_SSE_I387)
16911 && flag_unsafe_math_optimizations"
16913 [(set_attr "type" "fpspc")
16914 (set_attr "mode" "XF")])
16916 (define_expand "atan2xf3"
16917 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16918 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16919 (match_operand:XF 1 "register_operand" "")]
16921 (clobber (match_scratch:XF 3 ""))])]
16922 "TARGET_USE_FANCY_MATH_387
16923 && flag_unsafe_math_optimizations"
16926 (define_expand "atan2<mode>3"
16927 [(use (match_operand:MODEF 0 "register_operand" ""))
16928 (use (match_operand:MODEF 1 "register_operand" ""))
16929 (use (match_operand:MODEF 2 "register_operand" ""))]
16930 "TARGET_USE_FANCY_MATH_387
16931 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16932 || TARGET_MIX_SSE_I387)
16933 && flag_unsafe_math_optimizations"
16935 rtx op0 = gen_reg_rtx (XFmode);
16937 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16938 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16942 (define_expand "atanxf2"
16943 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16944 (unspec:XF [(match_dup 2)
16945 (match_operand:XF 1 "register_operand" "")]
16947 (clobber (match_scratch:XF 3 ""))])]
16948 "TARGET_USE_FANCY_MATH_387
16949 && flag_unsafe_math_optimizations"
16951 operands[2] = gen_reg_rtx (XFmode);
16952 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16955 (define_expand "atan<mode>2"
16956 [(use (match_operand:MODEF 0 "register_operand" ""))
16957 (use (match_operand:MODEF 1 "register_operand" ""))]
16958 "TARGET_USE_FANCY_MATH_387
16959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16960 || TARGET_MIX_SSE_I387)
16961 && flag_unsafe_math_optimizations"
16963 rtx op0 = gen_reg_rtx (XFmode);
16965 rtx op2 = gen_reg_rtx (<MODE>mode);
16966 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16968 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16969 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16973 (define_expand "asinxf2"
16974 [(set (match_dup 2)
16975 (mult:XF (match_operand:XF 1 "register_operand" "")
16977 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16978 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16979 (parallel [(set (match_operand:XF 0 "register_operand" "")
16980 (unspec:XF [(match_dup 5) (match_dup 1)]
16982 (clobber (match_scratch:XF 6 ""))])]
16983 "TARGET_USE_FANCY_MATH_387
16984 && flag_unsafe_math_optimizations && !optimize_size"
16988 for (i = 2; i < 6; i++)
16989 operands[i] = gen_reg_rtx (XFmode);
16991 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16994 (define_expand "asin<mode>2"
16995 [(use (match_operand:MODEF 0 "register_operand" ""))
16996 (use (match_operand:MODEF 1 "general_operand" ""))]
16997 "TARGET_USE_FANCY_MATH_387
16998 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16999 || TARGET_MIX_SSE_I387)
17000 && flag_unsafe_math_optimizations && !optimize_size"
17002 rtx op0 = gen_reg_rtx (XFmode);
17003 rtx op1 = gen_reg_rtx (XFmode);
17005 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17006 emit_insn (gen_asinxf2 (op0, op1));
17007 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17011 (define_expand "acosxf2"
17012 [(set (match_dup 2)
17013 (mult:XF (match_operand:XF 1 "register_operand" "")
17015 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17016 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17017 (parallel [(set (match_operand:XF 0 "register_operand" "")
17018 (unspec:XF [(match_dup 1) (match_dup 5)]
17020 (clobber (match_scratch:XF 6 ""))])]
17021 "TARGET_USE_FANCY_MATH_387
17022 && flag_unsafe_math_optimizations && !optimize_size"
17026 for (i = 2; i < 6; i++)
17027 operands[i] = gen_reg_rtx (XFmode);
17029 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17032 (define_expand "acos<mode>2"
17033 [(use (match_operand:MODEF 0 "register_operand" ""))
17034 (use (match_operand:MODEF 1 "general_operand" ""))]
17035 "TARGET_USE_FANCY_MATH_387
17036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17037 || TARGET_MIX_SSE_I387)
17038 && flag_unsafe_math_optimizations && !optimize_size"
17040 rtx op0 = gen_reg_rtx (XFmode);
17041 rtx op1 = gen_reg_rtx (XFmode);
17043 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17044 emit_insn (gen_acosxf2 (op0, op1));
17045 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17049 (define_insn "fyl2xxf3_i387"
17050 [(set (match_operand:XF 0 "register_operand" "=f")
17051 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17052 (match_operand:XF 2 "register_operand" "u")]
17054 (clobber (match_scratch:XF 3 "=2"))]
17055 "TARGET_USE_FANCY_MATH_387
17056 && flag_unsafe_math_optimizations"
17058 [(set_attr "type" "fpspc")
17059 (set_attr "mode" "XF")])
17061 (define_insn "fyl2x_extend<mode>xf3_i387"
17062 [(set (match_operand:XF 0 "register_operand" "=f")
17063 (unspec:XF [(float_extend:XF
17064 (match_operand:MODEF 1 "register_operand" "0"))
17065 (match_operand:XF 2 "register_operand" "u")]
17067 (clobber (match_scratch:XF 3 "=2"))]
17068 "TARGET_USE_FANCY_MATH_387
17069 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17070 || TARGET_MIX_SSE_I387)
17071 && flag_unsafe_math_optimizations"
17073 [(set_attr "type" "fpspc")
17074 (set_attr "mode" "XF")])
17076 (define_expand "logxf2"
17077 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17078 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17079 (match_dup 2)] UNSPEC_FYL2X))
17080 (clobber (match_scratch:XF 3 ""))])]
17081 "TARGET_USE_FANCY_MATH_387
17082 && flag_unsafe_math_optimizations"
17084 operands[2] = gen_reg_rtx (XFmode);
17085 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17088 (define_expand "log<mode>2"
17089 [(use (match_operand:MODEF 0 "register_operand" ""))
17090 (use (match_operand:MODEF 1 "register_operand" ""))]
17091 "TARGET_USE_FANCY_MATH_387
17092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17093 || TARGET_MIX_SSE_I387)
17094 && flag_unsafe_math_optimizations"
17096 rtx op0 = gen_reg_rtx (XFmode);
17098 rtx op2 = gen_reg_rtx (XFmode);
17099 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17101 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17102 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17106 (define_expand "log10xf2"
17107 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17108 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17109 (match_dup 2)] UNSPEC_FYL2X))
17110 (clobber (match_scratch:XF 3 ""))])]
17111 "TARGET_USE_FANCY_MATH_387
17112 && flag_unsafe_math_optimizations"
17114 operands[2] = gen_reg_rtx (XFmode);
17115 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17118 (define_expand "log10<mode>2"
17119 [(use (match_operand:MODEF 0 "register_operand" ""))
17120 (use (match_operand:MODEF 1 "register_operand" ""))]
17121 "TARGET_USE_FANCY_MATH_387
17122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17123 || TARGET_MIX_SSE_I387)
17124 && flag_unsafe_math_optimizations"
17126 rtx op0 = gen_reg_rtx (XFmode);
17128 rtx op2 = gen_reg_rtx (XFmode);
17129 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17131 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17132 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17136 (define_expand "log2xf2"
17137 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17138 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17139 (match_dup 2)] UNSPEC_FYL2X))
17140 (clobber (match_scratch:XF 3 ""))])]
17141 "TARGET_USE_FANCY_MATH_387
17142 && flag_unsafe_math_optimizations"
17144 operands[2] = gen_reg_rtx (XFmode);
17145 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17148 (define_expand "log2<mode>2"
17149 [(use (match_operand:MODEF 0 "register_operand" ""))
17150 (use (match_operand:MODEF 1 "register_operand" ""))]
17151 "TARGET_USE_FANCY_MATH_387
17152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17153 || TARGET_MIX_SSE_I387)
17154 && flag_unsafe_math_optimizations"
17156 rtx op0 = gen_reg_rtx (XFmode);
17158 rtx op2 = gen_reg_rtx (XFmode);
17159 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17161 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17162 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17166 (define_insn "fyl2xp1xf3_i387"
17167 [(set (match_operand:XF 0 "register_operand" "=f")
17168 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17169 (match_operand:XF 2 "register_operand" "u")]
17171 (clobber (match_scratch:XF 3 "=2"))]
17172 "TARGET_USE_FANCY_MATH_387
17173 && flag_unsafe_math_optimizations"
17175 [(set_attr "type" "fpspc")
17176 (set_attr "mode" "XF")])
17178 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17179 [(set (match_operand:XF 0 "register_operand" "=f")
17180 (unspec:XF [(float_extend:XF
17181 (match_operand:MODEF 1 "register_operand" "0"))
17182 (match_operand:XF 2 "register_operand" "u")]
17184 (clobber (match_scratch:XF 3 "=2"))]
17185 "TARGET_USE_FANCY_MATH_387
17186 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17187 || TARGET_MIX_SSE_I387)
17188 && flag_unsafe_math_optimizations"
17190 [(set_attr "type" "fpspc")
17191 (set_attr "mode" "XF")])
17193 (define_expand "log1pxf2"
17194 [(use (match_operand:XF 0 "register_operand" ""))
17195 (use (match_operand:XF 1 "register_operand" ""))]
17196 "TARGET_USE_FANCY_MATH_387
17197 && flag_unsafe_math_optimizations && !optimize_size"
17199 ix86_emit_i387_log1p (operands[0], operands[1]);
17203 (define_expand "log1p<mode>2"
17204 [(use (match_operand:MODEF 0 "register_operand" ""))
17205 (use (match_operand:MODEF 1 "register_operand" ""))]
17206 "TARGET_USE_FANCY_MATH_387
17207 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17208 || TARGET_MIX_SSE_I387)
17209 && flag_unsafe_math_optimizations && !optimize_size"
17211 rtx op0 = gen_reg_rtx (XFmode);
17213 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17215 ix86_emit_i387_log1p (op0, operands[1]);
17216 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17220 (define_insn "fxtractxf3_i387"
17221 [(set (match_operand:XF 0 "register_operand" "=f")
17222 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17223 UNSPEC_XTRACT_FRACT))
17224 (set (match_operand:XF 1 "register_operand" "=u")
17225 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17226 "TARGET_USE_FANCY_MATH_387
17227 && flag_unsafe_math_optimizations"
17229 [(set_attr "type" "fpspc")
17230 (set_attr "mode" "XF")])
17232 (define_insn "fxtract_extend<mode>xf3_i387"
17233 [(set (match_operand:XF 0 "register_operand" "=f")
17234 (unspec:XF [(float_extend:XF
17235 (match_operand:MODEF 2 "register_operand" "0"))]
17236 UNSPEC_XTRACT_FRACT))
17237 (set (match_operand:XF 1 "register_operand" "=u")
17238 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17239 "TARGET_USE_FANCY_MATH_387
17240 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17241 || TARGET_MIX_SSE_I387)
17242 && flag_unsafe_math_optimizations"
17244 [(set_attr "type" "fpspc")
17245 (set_attr "mode" "XF")])
17247 (define_expand "logbxf2"
17248 [(parallel [(set (match_dup 2)
17249 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17250 UNSPEC_XTRACT_FRACT))
17251 (set (match_operand:XF 0 "register_operand" "")
17252 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17253 "TARGET_USE_FANCY_MATH_387
17254 && flag_unsafe_math_optimizations"
17256 operands[2] = gen_reg_rtx (XFmode);
17259 (define_expand "logb<mode>2"
17260 [(use (match_operand:MODEF 0 "register_operand" ""))
17261 (use (match_operand:MODEF 1 "register_operand" ""))]
17262 "TARGET_USE_FANCY_MATH_387
17263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17264 || TARGET_MIX_SSE_I387)
17265 && flag_unsafe_math_optimizations"
17267 rtx op0 = gen_reg_rtx (XFmode);
17268 rtx op1 = gen_reg_rtx (XFmode);
17270 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17271 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17275 (define_expand "ilogbxf2"
17276 [(use (match_operand:SI 0 "register_operand" ""))
17277 (use (match_operand:XF 1 "register_operand" ""))]
17278 "TARGET_USE_FANCY_MATH_387
17279 && flag_unsafe_math_optimizations && !optimize_size"
17281 rtx op0 = gen_reg_rtx (XFmode);
17282 rtx op1 = gen_reg_rtx (XFmode);
17284 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17285 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17289 (define_expand "ilogb<mode>2"
17290 [(use (match_operand:SI 0 "register_operand" ""))
17291 (use (match_operand:MODEF 1 "register_operand" ""))]
17292 "TARGET_USE_FANCY_MATH_387
17293 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17294 || TARGET_MIX_SSE_I387)
17295 && flag_unsafe_math_optimizations && !optimize_size"
17297 rtx op0 = gen_reg_rtx (XFmode);
17298 rtx op1 = gen_reg_rtx (XFmode);
17300 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17301 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17305 (define_insn "*f2xm1xf2_i387"
17306 [(set (match_operand:XF 0 "register_operand" "=f")
17307 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17309 "TARGET_USE_FANCY_MATH_387
17310 && flag_unsafe_math_optimizations"
17312 [(set_attr "type" "fpspc")
17313 (set_attr "mode" "XF")])
17315 (define_insn "*fscalexf4_i387"
17316 [(set (match_operand:XF 0 "register_operand" "=f")
17317 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17318 (match_operand:XF 3 "register_operand" "1")]
17319 UNSPEC_FSCALE_FRACT))
17320 (set (match_operand:XF 1 "register_operand" "=u")
17321 (unspec:XF [(match_dup 2) (match_dup 3)]
17322 UNSPEC_FSCALE_EXP))]
17323 "TARGET_USE_FANCY_MATH_387
17324 && flag_unsafe_math_optimizations"
17326 [(set_attr "type" "fpspc")
17327 (set_attr "mode" "XF")])
17329 (define_expand "expNcorexf3"
17330 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17331 (match_operand:XF 2 "register_operand" "")))
17332 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17333 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17334 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17335 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17336 (parallel [(set (match_operand:XF 0 "register_operand" "")
17337 (unspec:XF [(match_dup 8) (match_dup 4)]
17338 UNSPEC_FSCALE_FRACT))
17340 (unspec:XF [(match_dup 8) (match_dup 4)]
17341 UNSPEC_FSCALE_EXP))])]
17342 "TARGET_USE_FANCY_MATH_387
17343 && flag_unsafe_math_optimizations && !optimize_size"
17347 for (i = 3; i < 10; i++)
17348 operands[i] = gen_reg_rtx (XFmode);
17350 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17353 (define_expand "expxf2"
17354 [(use (match_operand:XF 0 "register_operand" ""))
17355 (use (match_operand:XF 1 "register_operand" ""))]
17356 "TARGET_USE_FANCY_MATH_387
17357 && flag_unsafe_math_optimizations && !optimize_size"
17359 rtx op2 = gen_reg_rtx (XFmode);
17360 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17362 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17366 (define_expand "exp<mode>2"
17367 [(use (match_operand:MODEF 0 "register_operand" ""))
17368 (use (match_operand:MODEF 1 "general_operand" ""))]
17369 "TARGET_USE_FANCY_MATH_387
17370 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17371 || TARGET_MIX_SSE_I387)
17372 && flag_unsafe_math_optimizations && !optimize_size"
17374 rtx op0 = gen_reg_rtx (XFmode);
17375 rtx op1 = gen_reg_rtx (XFmode);
17377 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17378 emit_insn (gen_expxf2 (op0, op1));
17379 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17383 (define_expand "exp10xf2"
17384 [(use (match_operand:XF 0 "register_operand" ""))
17385 (use (match_operand:XF 1 "register_operand" ""))]
17386 "TARGET_USE_FANCY_MATH_387
17387 && flag_unsafe_math_optimizations && !optimize_size"
17389 rtx op2 = gen_reg_rtx (XFmode);
17390 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17392 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17396 (define_expand "exp10<mode>2"
17397 [(use (match_operand:MODEF 0 "register_operand" ""))
17398 (use (match_operand:MODEF 1 "general_operand" ""))]
17399 "TARGET_USE_FANCY_MATH_387
17400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17401 || TARGET_MIX_SSE_I387)
17402 && flag_unsafe_math_optimizations && !optimize_size"
17404 rtx op0 = gen_reg_rtx (XFmode);
17405 rtx op1 = gen_reg_rtx (XFmode);
17407 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17408 emit_insn (gen_exp10xf2 (op0, op1));
17409 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17413 (define_expand "exp2xf2"
17414 [(use (match_operand:XF 0 "register_operand" ""))
17415 (use (match_operand:XF 1 "register_operand" ""))]
17416 "TARGET_USE_FANCY_MATH_387
17417 && flag_unsafe_math_optimizations && !optimize_size"
17419 rtx op2 = gen_reg_rtx (XFmode);
17420 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17422 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17426 (define_expand "exp2<mode>2"
17427 [(use (match_operand:MODEF 0 "register_operand" ""))
17428 (use (match_operand:MODEF 1 "general_operand" ""))]
17429 "TARGET_USE_FANCY_MATH_387
17430 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17431 || TARGET_MIX_SSE_I387)
17432 && flag_unsafe_math_optimizations && !optimize_size"
17434 rtx op0 = gen_reg_rtx (XFmode);
17435 rtx op1 = gen_reg_rtx (XFmode);
17437 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17438 emit_insn (gen_exp2xf2 (op0, op1));
17439 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17443 (define_expand "expm1xf2"
17444 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17446 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17447 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17448 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17449 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17450 (parallel [(set (match_dup 7)
17451 (unspec:XF [(match_dup 6) (match_dup 4)]
17452 UNSPEC_FSCALE_FRACT))
17454 (unspec:XF [(match_dup 6) (match_dup 4)]
17455 UNSPEC_FSCALE_EXP))])
17456 (parallel [(set (match_dup 10)
17457 (unspec:XF [(match_dup 9) (match_dup 8)]
17458 UNSPEC_FSCALE_FRACT))
17459 (set (match_dup 11)
17460 (unspec:XF [(match_dup 9) (match_dup 8)]
17461 UNSPEC_FSCALE_EXP))])
17462 (set (match_dup 12) (minus:XF (match_dup 10)
17463 (float_extend:XF (match_dup 13))))
17464 (set (match_operand:XF 0 "register_operand" "")
17465 (plus:XF (match_dup 12) (match_dup 7)))]
17466 "TARGET_USE_FANCY_MATH_387
17467 && flag_unsafe_math_optimizations && !optimize_size"
17471 for (i = 2; i < 13; i++)
17472 operands[i] = gen_reg_rtx (XFmode);
17475 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17477 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17480 (define_expand "expm1<mode>2"
17481 [(use (match_operand:MODEF 0 "register_operand" ""))
17482 (use (match_operand:MODEF 1 "general_operand" ""))]
17483 "TARGET_USE_FANCY_MATH_387
17484 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17485 || TARGET_MIX_SSE_I387)
17486 && flag_unsafe_math_optimizations && !optimize_size"
17488 rtx op0 = gen_reg_rtx (XFmode);
17489 rtx op1 = gen_reg_rtx (XFmode);
17491 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17492 emit_insn (gen_expm1xf2 (op0, op1));
17493 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17497 (define_expand "ldexpxf3"
17498 [(set (match_dup 3)
17499 (float:XF (match_operand:SI 2 "register_operand" "")))
17500 (parallel [(set (match_operand:XF 0 " register_operand" "")
17501 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17503 UNSPEC_FSCALE_FRACT))
17505 (unspec:XF [(match_dup 1) (match_dup 3)]
17506 UNSPEC_FSCALE_EXP))])]
17507 "TARGET_USE_FANCY_MATH_387
17508 && flag_unsafe_math_optimizations && !optimize_size"
17510 operands[3] = gen_reg_rtx (XFmode);
17511 operands[4] = gen_reg_rtx (XFmode);
17514 (define_expand "ldexp<mode>3"
17515 [(use (match_operand:MODEF 0 "register_operand" ""))
17516 (use (match_operand:MODEF 1 "general_operand" ""))
17517 (use (match_operand:SI 2 "register_operand" ""))]
17518 "TARGET_USE_FANCY_MATH_387
17519 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17520 || TARGET_MIX_SSE_I387)
17521 && flag_unsafe_math_optimizations && !optimize_size"
17523 rtx op0 = gen_reg_rtx (XFmode);
17524 rtx op1 = gen_reg_rtx (XFmode);
17526 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17527 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17528 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17532 (define_expand "scalbxf3"
17533 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17534 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17535 (match_operand:XF 2 "register_operand" "")]
17536 UNSPEC_FSCALE_FRACT))
17538 (unspec:XF [(match_dup 1) (match_dup 2)]
17539 UNSPEC_FSCALE_EXP))])]
17540 "TARGET_USE_FANCY_MATH_387
17541 && flag_unsafe_math_optimizations && !optimize_size"
17543 operands[3] = gen_reg_rtx (XFmode);
17546 (define_expand "scalb<mode>3"
17547 [(use (match_operand:MODEF 0 "register_operand" ""))
17548 (use (match_operand:MODEF 1 "general_operand" ""))
17549 (use (match_operand:MODEF 2 "register_operand" ""))]
17550 "TARGET_USE_FANCY_MATH_387
17551 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17552 || TARGET_MIX_SSE_I387)
17553 && flag_unsafe_math_optimizations && !optimize_size"
17555 rtx op0 = gen_reg_rtx (XFmode);
17556 rtx op1 = gen_reg_rtx (XFmode);
17557 rtx op2 = gen_reg_rtx (XFmode);
17559 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17560 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17561 emit_insn (gen_scalbxf3 (op0, op1, op2));
17562 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17567 (define_insn "sse4_1_round<mode>2"
17568 [(set (match_operand:MODEF 0 "register_operand" "=x")
17569 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17570 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17573 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17574 [(set_attr "type" "ssecvt")
17575 (set_attr "prefix_extra" "1")
17576 (set_attr "mode" "<MODE>")])
17578 (define_insn "rintxf2"
17579 [(set (match_operand:XF 0 "register_operand" "=f")
17580 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17582 "TARGET_USE_FANCY_MATH_387
17583 && flag_unsafe_math_optimizations"
17585 [(set_attr "type" "fpspc")
17586 (set_attr "mode" "XF")])
17588 (define_expand "rint<mode>2"
17589 [(use (match_operand:MODEF 0 "register_operand" ""))
17590 (use (match_operand:MODEF 1 "register_operand" ""))]
17591 "(TARGET_USE_FANCY_MATH_387
17592 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17593 || TARGET_MIX_SSE_I387)
17594 && flag_unsafe_math_optimizations)
17595 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17596 && !flag_trapping_math
17597 && (TARGET_ROUND || !optimize_size))"
17599 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17600 && !flag_trapping_math
17601 && (TARGET_ROUND || !optimize_size))
17604 emit_insn (gen_sse4_1_round<mode>2
17605 (operands[0], operands[1], GEN_INT (0x04)));
17607 ix86_expand_rint (operand0, operand1);
17611 rtx op0 = gen_reg_rtx (XFmode);
17612 rtx op1 = gen_reg_rtx (XFmode);
17614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17615 emit_insn (gen_rintxf2 (op0, op1));
17617 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17622 (define_expand "round<mode>2"
17623 [(match_operand:MODEF 0 "register_operand" "")
17624 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17625 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17626 && !flag_trapping_math && !flag_rounding_math
17629 if (TARGET_64BIT || (<MODE>mode != DFmode))
17630 ix86_expand_round (operand0, operand1);
17632 ix86_expand_rounddf_32 (operand0, operand1);
17636 (define_insn_and_split "*fistdi2_1"
17637 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17638 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17640 "TARGET_USE_FANCY_MATH_387
17641 && !(reload_completed || reload_in_progress)"
17646 if (memory_operand (operands[0], VOIDmode))
17647 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17650 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17651 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17656 [(set_attr "type" "fpspc")
17657 (set_attr "mode" "DI")])
17659 (define_insn "fistdi2"
17660 [(set (match_operand:DI 0 "memory_operand" "=m")
17661 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17663 (clobber (match_scratch:XF 2 "=&1f"))]
17664 "TARGET_USE_FANCY_MATH_387"
17665 "* return output_fix_trunc (insn, operands, 0);"
17666 [(set_attr "type" "fpspc")
17667 (set_attr "mode" "DI")])
17669 (define_insn "fistdi2_with_temp"
17670 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17671 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17673 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17674 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17675 "TARGET_USE_FANCY_MATH_387"
17677 [(set_attr "type" "fpspc")
17678 (set_attr "mode" "DI")])
17681 [(set (match_operand:DI 0 "register_operand" "")
17682 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17684 (clobber (match_operand:DI 2 "memory_operand" ""))
17685 (clobber (match_scratch 3 ""))]
17687 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17688 (clobber (match_dup 3))])
17689 (set (match_dup 0) (match_dup 2))]
17693 [(set (match_operand:DI 0 "memory_operand" "")
17694 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17696 (clobber (match_operand:DI 2 "memory_operand" ""))
17697 (clobber (match_scratch 3 ""))]
17699 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17700 (clobber (match_dup 3))])]
17703 (define_insn_and_split "*fist<mode>2_1"
17704 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17705 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17707 "TARGET_USE_FANCY_MATH_387
17708 && !(reload_completed || reload_in_progress)"
17713 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17714 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17718 [(set_attr "type" "fpspc")
17719 (set_attr "mode" "<MODE>")])
17721 (define_insn "fist<mode>2"
17722 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17723 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17725 "TARGET_USE_FANCY_MATH_387"
17726 "* return output_fix_trunc (insn, operands, 0);"
17727 [(set_attr "type" "fpspc")
17728 (set_attr "mode" "<MODE>")])
17730 (define_insn "fist<mode>2_with_temp"
17731 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17732 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17734 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17735 "TARGET_USE_FANCY_MATH_387"
17737 [(set_attr "type" "fpspc")
17738 (set_attr "mode" "<MODE>")])
17741 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17742 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17744 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17746 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17747 (set (match_dup 0) (match_dup 2))]
17751 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17752 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17754 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17756 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17759 (define_expand "lrintxf<mode>2"
17760 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17761 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17763 "TARGET_USE_FANCY_MATH_387"
17766 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17767 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17768 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17769 UNSPEC_FIX_NOTRUNC))]
17770 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17771 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17774 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17775 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17776 (match_operand:MODEF 1 "register_operand" "")]
17777 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17778 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17779 && !flag_trapping_math && !flag_rounding_math
17782 ix86_expand_lround (operand0, operand1);
17786 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17787 (define_insn_and_split "frndintxf2_floor"
17788 [(set (match_operand:XF 0 "register_operand" "")
17789 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17790 UNSPEC_FRNDINT_FLOOR))
17791 (clobber (reg:CC FLAGS_REG))]
17792 "TARGET_USE_FANCY_MATH_387
17793 && flag_unsafe_math_optimizations
17794 && !(reload_completed || reload_in_progress)"
17799 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17801 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17802 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17804 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17805 operands[2], operands[3]));
17808 [(set_attr "type" "frndint")
17809 (set_attr "i387_cw" "floor")
17810 (set_attr "mode" "XF")])
17812 (define_insn "frndintxf2_floor_i387"
17813 [(set (match_operand:XF 0 "register_operand" "=f")
17814 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17815 UNSPEC_FRNDINT_FLOOR))
17816 (use (match_operand:HI 2 "memory_operand" "m"))
17817 (use (match_operand:HI 3 "memory_operand" "m"))]
17818 "TARGET_USE_FANCY_MATH_387
17819 && flag_unsafe_math_optimizations"
17820 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17821 [(set_attr "type" "frndint")
17822 (set_attr "i387_cw" "floor")
17823 (set_attr "mode" "XF")])
17825 (define_expand "floorxf2"
17826 [(use (match_operand:XF 0 "register_operand" ""))
17827 (use (match_operand:XF 1 "register_operand" ""))]
17828 "TARGET_USE_FANCY_MATH_387
17829 && flag_unsafe_math_optimizations && !optimize_size"
17831 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17835 (define_expand "floor<mode>2"
17836 [(use (match_operand:MODEF 0 "register_operand" ""))
17837 (use (match_operand:MODEF 1 "register_operand" ""))]
17838 "(TARGET_USE_FANCY_MATH_387
17839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17840 || TARGET_MIX_SSE_I387)
17841 && flag_unsafe_math_optimizations && !optimize_size)
17842 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17843 && !flag_trapping_math
17844 && (TARGET_ROUND || !optimize_size))"
17846 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17847 && !flag_trapping_math
17848 && (TARGET_ROUND || !optimize_size))
17851 emit_insn (gen_sse4_1_round<mode>2
17852 (operands[0], operands[1], GEN_INT (0x01)));
17853 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17854 ix86_expand_floorceil (operand0, operand1, true);
17856 ix86_expand_floorceildf_32 (operand0, operand1, true);
17860 rtx op0 = gen_reg_rtx (XFmode);
17861 rtx op1 = gen_reg_rtx (XFmode);
17863 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17864 emit_insn (gen_frndintxf2_floor (op0, op1));
17866 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17871 (define_insn_and_split "*fist<mode>2_floor_1"
17872 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17873 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17874 UNSPEC_FIST_FLOOR))
17875 (clobber (reg:CC FLAGS_REG))]
17876 "TARGET_USE_FANCY_MATH_387
17877 && flag_unsafe_math_optimizations
17878 && !(reload_completed || reload_in_progress)"
17883 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17885 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17886 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17887 if (memory_operand (operands[0], VOIDmode))
17888 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17889 operands[2], operands[3]));
17892 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17893 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17894 operands[2], operands[3],
17899 [(set_attr "type" "fistp")
17900 (set_attr "i387_cw" "floor")
17901 (set_attr "mode" "<MODE>")])
17903 (define_insn "fistdi2_floor"
17904 [(set (match_operand:DI 0 "memory_operand" "=m")
17905 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17906 UNSPEC_FIST_FLOOR))
17907 (use (match_operand:HI 2 "memory_operand" "m"))
17908 (use (match_operand:HI 3 "memory_operand" "m"))
17909 (clobber (match_scratch:XF 4 "=&1f"))]
17910 "TARGET_USE_FANCY_MATH_387
17911 && flag_unsafe_math_optimizations"
17912 "* return output_fix_trunc (insn, operands, 0);"
17913 [(set_attr "type" "fistp")
17914 (set_attr "i387_cw" "floor")
17915 (set_attr "mode" "DI")])
17917 (define_insn "fistdi2_floor_with_temp"
17918 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17919 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17920 UNSPEC_FIST_FLOOR))
17921 (use (match_operand:HI 2 "memory_operand" "m,m"))
17922 (use (match_operand:HI 3 "memory_operand" "m,m"))
17923 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17924 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17925 "TARGET_USE_FANCY_MATH_387
17926 && flag_unsafe_math_optimizations"
17928 [(set_attr "type" "fistp")
17929 (set_attr "i387_cw" "floor")
17930 (set_attr "mode" "DI")])
17933 [(set (match_operand:DI 0 "register_operand" "")
17934 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17935 UNSPEC_FIST_FLOOR))
17936 (use (match_operand:HI 2 "memory_operand" ""))
17937 (use (match_operand:HI 3 "memory_operand" ""))
17938 (clobber (match_operand:DI 4 "memory_operand" ""))
17939 (clobber (match_scratch 5 ""))]
17941 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17942 (use (match_dup 2))
17943 (use (match_dup 3))
17944 (clobber (match_dup 5))])
17945 (set (match_dup 0) (match_dup 4))]
17949 [(set (match_operand:DI 0 "memory_operand" "")
17950 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17951 UNSPEC_FIST_FLOOR))
17952 (use (match_operand:HI 2 "memory_operand" ""))
17953 (use (match_operand:HI 3 "memory_operand" ""))
17954 (clobber (match_operand:DI 4 "memory_operand" ""))
17955 (clobber (match_scratch 5 ""))]
17957 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17958 (use (match_dup 2))
17959 (use (match_dup 3))
17960 (clobber (match_dup 5))])]
17963 (define_insn "fist<mode>2_floor"
17964 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17965 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17966 UNSPEC_FIST_FLOOR))
17967 (use (match_operand:HI 2 "memory_operand" "m"))
17968 (use (match_operand:HI 3 "memory_operand" "m"))]
17969 "TARGET_USE_FANCY_MATH_387
17970 && flag_unsafe_math_optimizations"
17971 "* return output_fix_trunc (insn, operands, 0);"
17972 [(set_attr "type" "fistp")
17973 (set_attr "i387_cw" "floor")
17974 (set_attr "mode" "<MODE>")])
17976 (define_insn "fist<mode>2_floor_with_temp"
17977 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17978 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17979 UNSPEC_FIST_FLOOR))
17980 (use (match_operand:HI 2 "memory_operand" "m,m"))
17981 (use (match_operand:HI 3 "memory_operand" "m,m"))
17982 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17983 "TARGET_USE_FANCY_MATH_387
17984 && flag_unsafe_math_optimizations"
17986 [(set_attr "type" "fistp")
17987 (set_attr "i387_cw" "floor")
17988 (set_attr "mode" "<MODE>")])
17991 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17992 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17993 UNSPEC_FIST_FLOOR))
17994 (use (match_operand:HI 2 "memory_operand" ""))
17995 (use (match_operand:HI 3 "memory_operand" ""))
17996 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17998 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17999 UNSPEC_FIST_FLOOR))
18000 (use (match_dup 2))
18001 (use (match_dup 3))])
18002 (set (match_dup 0) (match_dup 4))]
18006 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18007 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18008 UNSPEC_FIST_FLOOR))
18009 (use (match_operand:HI 2 "memory_operand" ""))
18010 (use (match_operand:HI 3 "memory_operand" ""))
18011 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18013 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18014 UNSPEC_FIST_FLOOR))
18015 (use (match_dup 2))
18016 (use (match_dup 3))])]
18019 (define_expand "lfloorxf<mode>2"
18020 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18021 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18022 UNSPEC_FIST_FLOOR))
18023 (clobber (reg:CC FLAGS_REG))])]
18024 "TARGET_USE_FANCY_MATH_387
18025 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18026 && flag_unsafe_math_optimizations"
18029 (define_expand "lfloor<mode>di2"
18030 [(match_operand:DI 0 "nonimmediate_operand" "")
18031 (match_operand:MODEF 1 "register_operand" "")]
18032 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18033 && !flag_trapping_math
18036 ix86_expand_lfloorceil (operand0, operand1, true);
18040 (define_expand "lfloor<mode>si2"
18041 [(match_operand:SI 0 "nonimmediate_operand" "")
18042 (match_operand:MODEF 1 "register_operand" "")]
18043 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18044 && !flag_trapping_math
18045 && (!optimize_size || !TARGET_64BIT)"
18047 ix86_expand_lfloorceil (operand0, operand1, true);
18051 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18052 (define_insn_and_split "frndintxf2_ceil"
18053 [(set (match_operand:XF 0 "register_operand" "")
18054 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18055 UNSPEC_FRNDINT_CEIL))
18056 (clobber (reg:CC FLAGS_REG))]
18057 "TARGET_USE_FANCY_MATH_387
18058 && flag_unsafe_math_optimizations
18059 && !(reload_completed || reload_in_progress)"
18064 ix86_optimize_mode_switching[I387_CEIL] = 1;
18066 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18067 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18069 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18070 operands[2], operands[3]));
18073 [(set_attr "type" "frndint")
18074 (set_attr "i387_cw" "ceil")
18075 (set_attr "mode" "XF")])
18077 (define_insn "frndintxf2_ceil_i387"
18078 [(set (match_operand:XF 0 "register_operand" "=f")
18079 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18080 UNSPEC_FRNDINT_CEIL))
18081 (use (match_operand:HI 2 "memory_operand" "m"))
18082 (use (match_operand:HI 3 "memory_operand" "m"))]
18083 "TARGET_USE_FANCY_MATH_387
18084 && flag_unsafe_math_optimizations"
18085 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18086 [(set_attr "type" "frndint")
18087 (set_attr "i387_cw" "ceil")
18088 (set_attr "mode" "XF")])
18090 (define_expand "ceilxf2"
18091 [(use (match_operand:XF 0 "register_operand" ""))
18092 (use (match_operand:XF 1 "register_operand" ""))]
18093 "TARGET_USE_FANCY_MATH_387
18094 && flag_unsafe_math_optimizations && !optimize_size"
18096 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18100 (define_expand "ceil<mode>2"
18101 [(use (match_operand:MODEF 0 "register_operand" ""))
18102 (use (match_operand:MODEF 1 "register_operand" ""))]
18103 "(TARGET_USE_FANCY_MATH_387
18104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18105 || TARGET_MIX_SSE_I387)
18106 && flag_unsafe_math_optimizations && !optimize_size)
18107 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18108 && !flag_trapping_math
18109 && (TARGET_ROUND || !optimize_size))"
18111 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18112 && !flag_trapping_math
18113 && (TARGET_ROUND || !optimize_size))
18116 emit_insn (gen_sse4_1_round<mode>2
18117 (operands[0], operands[1], GEN_INT (0x02)));
18118 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18119 ix86_expand_floorceil (operand0, operand1, false);
18121 ix86_expand_floorceildf_32 (operand0, operand1, false);
18125 rtx op0 = gen_reg_rtx (XFmode);
18126 rtx op1 = gen_reg_rtx (XFmode);
18128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18129 emit_insn (gen_frndintxf2_ceil (op0, op1));
18131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18136 (define_insn_and_split "*fist<mode>2_ceil_1"
18137 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18138 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18140 (clobber (reg:CC FLAGS_REG))]
18141 "TARGET_USE_FANCY_MATH_387
18142 && flag_unsafe_math_optimizations
18143 && !(reload_completed || reload_in_progress)"
18148 ix86_optimize_mode_switching[I387_CEIL] = 1;
18150 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18151 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18152 if (memory_operand (operands[0], VOIDmode))
18153 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18154 operands[2], operands[3]));
18157 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18158 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18159 operands[2], operands[3],
18164 [(set_attr "type" "fistp")
18165 (set_attr "i387_cw" "ceil")
18166 (set_attr "mode" "<MODE>")])
18168 (define_insn "fistdi2_ceil"
18169 [(set (match_operand:DI 0 "memory_operand" "=m")
18170 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18172 (use (match_operand:HI 2 "memory_operand" "m"))
18173 (use (match_operand:HI 3 "memory_operand" "m"))
18174 (clobber (match_scratch:XF 4 "=&1f"))]
18175 "TARGET_USE_FANCY_MATH_387
18176 && flag_unsafe_math_optimizations"
18177 "* return output_fix_trunc (insn, operands, 0);"
18178 [(set_attr "type" "fistp")
18179 (set_attr "i387_cw" "ceil")
18180 (set_attr "mode" "DI")])
18182 (define_insn "fistdi2_ceil_with_temp"
18183 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18184 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18186 (use (match_operand:HI 2 "memory_operand" "m,m"))
18187 (use (match_operand:HI 3 "memory_operand" "m,m"))
18188 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18189 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18190 "TARGET_USE_FANCY_MATH_387
18191 && flag_unsafe_math_optimizations"
18193 [(set_attr "type" "fistp")
18194 (set_attr "i387_cw" "ceil")
18195 (set_attr "mode" "DI")])
18198 [(set (match_operand:DI 0 "register_operand" "")
18199 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18201 (use (match_operand:HI 2 "memory_operand" ""))
18202 (use (match_operand:HI 3 "memory_operand" ""))
18203 (clobber (match_operand:DI 4 "memory_operand" ""))
18204 (clobber (match_scratch 5 ""))]
18206 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18207 (use (match_dup 2))
18208 (use (match_dup 3))
18209 (clobber (match_dup 5))])
18210 (set (match_dup 0) (match_dup 4))]
18214 [(set (match_operand:DI 0 "memory_operand" "")
18215 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18217 (use (match_operand:HI 2 "memory_operand" ""))
18218 (use (match_operand:HI 3 "memory_operand" ""))
18219 (clobber (match_operand:DI 4 "memory_operand" ""))
18220 (clobber (match_scratch 5 ""))]
18222 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18223 (use (match_dup 2))
18224 (use (match_dup 3))
18225 (clobber (match_dup 5))])]
18228 (define_insn "fist<mode>2_ceil"
18229 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18230 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18232 (use (match_operand:HI 2 "memory_operand" "m"))
18233 (use (match_operand:HI 3 "memory_operand" "m"))]
18234 "TARGET_USE_FANCY_MATH_387
18235 && flag_unsafe_math_optimizations"
18236 "* return output_fix_trunc (insn, operands, 0);"
18237 [(set_attr "type" "fistp")
18238 (set_attr "i387_cw" "ceil")
18239 (set_attr "mode" "<MODE>")])
18241 (define_insn "fist<mode>2_ceil_with_temp"
18242 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18243 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18245 (use (match_operand:HI 2 "memory_operand" "m,m"))
18246 (use (match_operand:HI 3 "memory_operand" "m,m"))
18247 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18248 "TARGET_USE_FANCY_MATH_387
18249 && flag_unsafe_math_optimizations"
18251 [(set_attr "type" "fistp")
18252 (set_attr "i387_cw" "ceil")
18253 (set_attr "mode" "<MODE>")])
18256 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18257 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18259 (use (match_operand:HI 2 "memory_operand" ""))
18260 (use (match_operand:HI 3 "memory_operand" ""))
18261 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18263 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18265 (use (match_dup 2))
18266 (use (match_dup 3))])
18267 (set (match_dup 0) (match_dup 4))]
18271 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18272 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18274 (use (match_operand:HI 2 "memory_operand" ""))
18275 (use (match_operand:HI 3 "memory_operand" ""))
18276 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18278 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18280 (use (match_dup 2))
18281 (use (match_dup 3))])]
18284 (define_expand "lceilxf<mode>2"
18285 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18286 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18288 (clobber (reg:CC FLAGS_REG))])]
18289 "TARGET_USE_FANCY_MATH_387
18290 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18291 && flag_unsafe_math_optimizations"
18294 (define_expand "lceil<mode>di2"
18295 [(match_operand:DI 0 "nonimmediate_operand" "")
18296 (match_operand:MODEF 1 "register_operand" "")]
18297 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18298 && !flag_trapping_math"
18300 ix86_expand_lfloorceil (operand0, operand1, false);
18304 (define_expand "lceil<mode>si2"
18305 [(match_operand:SI 0 "nonimmediate_operand" "")
18306 (match_operand:MODEF 1 "register_operand" "")]
18307 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18308 && !flag_trapping_math"
18310 ix86_expand_lfloorceil (operand0, operand1, false);
18314 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18315 (define_insn_and_split "frndintxf2_trunc"
18316 [(set (match_operand:XF 0 "register_operand" "")
18317 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18318 UNSPEC_FRNDINT_TRUNC))
18319 (clobber (reg:CC FLAGS_REG))]
18320 "TARGET_USE_FANCY_MATH_387
18321 && flag_unsafe_math_optimizations
18322 && !(reload_completed || reload_in_progress)"
18327 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18329 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18330 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18332 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18333 operands[2], operands[3]));
18336 [(set_attr "type" "frndint")
18337 (set_attr "i387_cw" "trunc")
18338 (set_attr "mode" "XF")])
18340 (define_insn "frndintxf2_trunc_i387"
18341 [(set (match_operand:XF 0 "register_operand" "=f")
18342 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18343 UNSPEC_FRNDINT_TRUNC))
18344 (use (match_operand:HI 2 "memory_operand" "m"))
18345 (use (match_operand:HI 3 "memory_operand" "m"))]
18346 "TARGET_USE_FANCY_MATH_387
18347 && flag_unsafe_math_optimizations"
18348 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18349 [(set_attr "type" "frndint")
18350 (set_attr "i387_cw" "trunc")
18351 (set_attr "mode" "XF")])
18353 (define_expand "btruncxf2"
18354 [(use (match_operand:XF 0 "register_operand" ""))
18355 (use (match_operand:XF 1 "register_operand" ""))]
18356 "TARGET_USE_FANCY_MATH_387
18357 && flag_unsafe_math_optimizations && !optimize_size"
18359 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18363 (define_expand "btrunc<mode>2"
18364 [(use (match_operand:MODEF 0 "register_operand" ""))
18365 (use (match_operand:MODEF 1 "register_operand" ""))]
18366 "(TARGET_USE_FANCY_MATH_387
18367 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18368 || TARGET_MIX_SSE_I387)
18369 && flag_unsafe_math_optimizations && !optimize_size)
18370 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18371 && !flag_trapping_math
18372 && (TARGET_ROUND || !optimize_size))"
18374 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18375 && !flag_trapping_math
18376 && (TARGET_ROUND || !optimize_size))
18379 emit_insn (gen_sse4_1_round<mode>2
18380 (operands[0], operands[1], GEN_INT (0x03)));
18381 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18382 ix86_expand_trunc (operand0, operand1);
18384 ix86_expand_truncdf_32 (operand0, operand1);
18388 rtx op0 = gen_reg_rtx (XFmode);
18389 rtx op1 = gen_reg_rtx (XFmode);
18391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18392 emit_insn (gen_frndintxf2_trunc (op0, op1));
18394 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18399 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18400 (define_insn_and_split "frndintxf2_mask_pm"
18401 [(set (match_operand:XF 0 "register_operand" "")
18402 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18403 UNSPEC_FRNDINT_MASK_PM))
18404 (clobber (reg:CC FLAGS_REG))]
18405 "TARGET_USE_FANCY_MATH_387
18406 && flag_unsafe_math_optimizations
18407 && !(reload_completed || reload_in_progress)"
18412 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18414 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18415 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18417 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18418 operands[2], operands[3]));
18421 [(set_attr "type" "frndint")
18422 (set_attr "i387_cw" "mask_pm")
18423 (set_attr "mode" "XF")])
18425 (define_insn "frndintxf2_mask_pm_i387"
18426 [(set (match_operand:XF 0 "register_operand" "=f")
18427 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18428 UNSPEC_FRNDINT_MASK_PM))
18429 (use (match_operand:HI 2 "memory_operand" "m"))
18430 (use (match_operand:HI 3 "memory_operand" "m"))]
18431 "TARGET_USE_FANCY_MATH_387
18432 && flag_unsafe_math_optimizations"
18433 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18434 [(set_attr "type" "frndint")
18435 (set_attr "i387_cw" "mask_pm")
18436 (set_attr "mode" "XF")])
18438 (define_expand "nearbyintxf2"
18439 [(use (match_operand:XF 0 "register_operand" ""))
18440 (use (match_operand:XF 1 "register_operand" ""))]
18441 "TARGET_USE_FANCY_MATH_387
18442 && flag_unsafe_math_optimizations"
18444 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18449 (define_expand "nearbyint<mode>2"
18450 [(use (match_operand:MODEF 0 "register_operand" ""))
18451 (use (match_operand:MODEF 1 "register_operand" ""))]
18452 "TARGET_USE_FANCY_MATH_387
18453 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18454 || TARGET_MIX_SSE_I387)
18455 && flag_unsafe_math_optimizations"
18457 rtx op0 = gen_reg_rtx (XFmode);
18458 rtx op1 = gen_reg_rtx (XFmode);
18460 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18461 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18463 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18467 (define_insn "fxam<mode>2_i387"
18468 [(set (match_operand:HI 0 "register_operand" "=a")
18470 [(match_operand:X87MODEF 1 "register_operand" "f")]
18472 "TARGET_USE_FANCY_MATH_387"
18473 "fxam\n\tfnstsw\t%0"
18474 [(set_attr "type" "multi")
18475 (set_attr "unit" "i387")
18476 (set_attr "mode" "<MODE>")])
18478 (define_expand "isinf<mode>2"
18479 [(use (match_operand:SI 0 "register_operand" ""))
18480 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18481 "TARGET_USE_FANCY_MATH_387
18482 && TARGET_C99_FUNCTIONS
18483 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18485 rtx mask = GEN_INT (0x45);
18486 rtx val = GEN_INT (0x05);
18490 rtx scratch = gen_reg_rtx (HImode);
18491 rtx res = gen_reg_rtx (QImode);
18493 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18494 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18495 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18496 cond = gen_rtx_fmt_ee (EQ, QImode,
18497 gen_rtx_REG (CCmode, FLAGS_REG),
18499 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18500 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18504 (define_expand "signbit<mode>2"
18505 [(use (match_operand:SI 0 "register_operand" ""))
18506 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18507 "TARGET_USE_FANCY_MATH_387
18508 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18510 rtx mask = GEN_INT (0x0200);
18512 rtx scratch = gen_reg_rtx (HImode);
18514 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18515 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18519 ;; Block operation instructions
18521 (define_expand "movmemsi"
18522 [(use (match_operand:BLK 0 "memory_operand" ""))
18523 (use (match_operand:BLK 1 "memory_operand" ""))
18524 (use (match_operand:SI 2 "nonmemory_operand" ""))
18525 (use (match_operand:SI 3 "const_int_operand" ""))
18526 (use (match_operand:SI 4 "const_int_operand" ""))
18527 (use (match_operand:SI 5 "const_int_operand" ""))]
18530 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18531 operands[4], operands[5]))
18537 (define_expand "movmemdi"
18538 [(use (match_operand:BLK 0 "memory_operand" ""))
18539 (use (match_operand:BLK 1 "memory_operand" ""))
18540 (use (match_operand:DI 2 "nonmemory_operand" ""))
18541 (use (match_operand:DI 3 "const_int_operand" ""))
18542 (use (match_operand:SI 4 "const_int_operand" ""))
18543 (use (match_operand:SI 5 "const_int_operand" ""))]
18546 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18547 operands[4], operands[5]))
18553 ;; Most CPUs don't like single string operations
18554 ;; Handle this case here to simplify previous expander.
18556 (define_expand "strmov"
18557 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18558 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18559 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18560 (clobber (reg:CC FLAGS_REG))])
18561 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18562 (clobber (reg:CC FLAGS_REG))])]
18565 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18567 /* If .md ever supports :P for Pmode, these can be directly
18568 in the pattern above. */
18569 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18570 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18572 /* Can't use this if the user has appropriated esi or edi. */
18573 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18574 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18576 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18577 operands[2], operands[3],
18578 operands[5], operands[6]));
18582 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18585 (define_expand "strmov_singleop"
18586 [(parallel [(set (match_operand 1 "memory_operand" "")
18587 (match_operand 3 "memory_operand" ""))
18588 (set (match_operand 0 "register_operand" "")
18589 (match_operand 4 "" ""))
18590 (set (match_operand 2 "register_operand" "")
18591 (match_operand 5 "" ""))])]
18592 "TARGET_SINGLE_STRINGOP || optimize_size"
18595 (define_insn "*strmovdi_rex_1"
18596 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18597 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18598 (set (match_operand:DI 0 "register_operand" "=D")
18599 (plus:DI (match_dup 2)
18601 (set (match_operand:DI 1 "register_operand" "=S")
18602 (plus:DI (match_dup 3)
18604 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18606 [(set_attr "type" "str")
18607 (set_attr "mode" "DI")
18608 (set_attr "memory" "both")])
18610 (define_insn "*strmovsi_1"
18611 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18612 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18613 (set (match_operand:SI 0 "register_operand" "=D")
18614 (plus:SI (match_dup 2)
18616 (set (match_operand:SI 1 "register_operand" "=S")
18617 (plus:SI (match_dup 3)
18619 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18621 [(set_attr "type" "str")
18622 (set_attr "mode" "SI")
18623 (set_attr "memory" "both")])
18625 (define_insn "*strmovsi_rex_1"
18626 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18627 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18628 (set (match_operand:DI 0 "register_operand" "=D")
18629 (plus:DI (match_dup 2)
18631 (set (match_operand:DI 1 "register_operand" "=S")
18632 (plus:DI (match_dup 3)
18634 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18636 [(set_attr "type" "str")
18637 (set_attr "mode" "SI")
18638 (set_attr "memory" "both")])
18640 (define_insn "*strmovhi_1"
18641 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18642 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18643 (set (match_operand:SI 0 "register_operand" "=D")
18644 (plus:SI (match_dup 2)
18646 (set (match_operand:SI 1 "register_operand" "=S")
18647 (plus:SI (match_dup 3)
18649 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18651 [(set_attr "type" "str")
18652 (set_attr "memory" "both")
18653 (set_attr "mode" "HI")])
18655 (define_insn "*strmovhi_rex_1"
18656 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18657 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18658 (set (match_operand:DI 0 "register_operand" "=D")
18659 (plus:DI (match_dup 2)
18661 (set (match_operand:DI 1 "register_operand" "=S")
18662 (plus:DI (match_dup 3)
18664 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18666 [(set_attr "type" "str")
18667 (set_attr "memory" "both")
18668 (set_attr "mode" "HI")])
18670 (define_insn "*strmovqi_1"
18671 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18672 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18673 (set (match_operand:SI 0 "register_operand" "=D")
18674 (plus:SI (match_dup 2)
18676 (set (match_operand:SI 1 "register_operand" "=S")
18677 (plus:SI (match_dup 3)
18679 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18681 [(set_attr "type" "str")
18682 (set_attr "memory" "both")
18683 (set_attr "mode" "QI")])
18685 (define_insn "*strmovqi_rex_1"
18686 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18687 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18688 (set (match_operand:DI 0 "register_operand" "=D")
18689 (plus:DI (match_dup 2)
18691 (set (match_operand:DI 1 "register_operand" "=S")
18692 (plus:DI (match_dup 3)
18694 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18696 [(set_attr "type" "str")
18697 (set_attr "memory" "both")
18698 (set_attr "mode" "QI")])
18700 (define_expand "rep_mov"
18701 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18702 (set (match_operand 0 "register_operand" "")
18703 (match_operand 5 "" ""))
18704 (set (match_operand 2 "register_operand" "")
18705 (match_operand 6 "" ""))
18706 (set (match_operand 1 "memory_operand" "")
18707 (match_operand 3 "memory_operand" ""))
18708 (use (match_dup 4))])]
18712 (define_insn "*rep_movdi_rex64"
18713 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18714 (set (match_operand:DI 0 "register_operand" "=D")
18715 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18717 (match_operand:DI 3 "register_operand" "0")))
18718 (set (match_operand:DI 1 "register_operand" "=S")
18719 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18720 (match_operand:DI 4 "register_operand" "1")))
18721 (set (mem:BLK (match_dup 3))
18722 (mem:BLK (match_dup 4)))
18723 (use (match_dup 5))]
18726 [(set_attr "type" "str")
18727 (set_attr "prefix_rep" "1")
18728 (set_attr "memory" "both")
18729 (set_attr "mode" "DI")])
18731 (define_insn "*rep_movsi"
18732 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18733 (set (match_operand:SI 0 "register_operand" "=D")
18734 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18736 (match_operand:SI 3 "register_operand" "0")))
18737 (set (match_operand:SI 1 "register_operand" "=S")
18738 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18739 (match_operand:SI 4 "register_operand" "1")))
18740 (set (mem:BLK (match_dup 3))
18741 (mem:BLK (match_dup 4)))
18742 (use (match_dup 5))]
18745 [(set_attr "type" "str")
18746 (set_attr "prefix_rep" "1")
18747 (set_attr "memory" "both")
18748 (set_attr "mode" "SI")])
18750 (define_insn "*rep_movsi_rex64"
18751 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18752 (set (match_operand:DI 0 "register_operand" "=D")
18753 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18755 (match_operand:DI 3 "register_operand" "0")))
18756 (set (match_operand:DI 1 "register_operand" "=S")
18757 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18758 (match_operand:DI 4 "register_operand" "1")))
18759 (set (mem:BLK (match_dup 3))
18760 (mem:BLK (match_dup 4)))
18761 (use (match_dup 5))]
18764 [(set_attr "type" "str")
18765 (set_attr "prefix_rep" "1")
18766 (set_attr "memory" "both")
18767 (set_attr "mode" "SI")])
18769 (define_insn "*rep_movqi"
18770 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18771 (set (match_operand:SI 0 "register_operand" "=D")
18772 (plus:SI (match_operand:SI 3 "register_operand" "0")
18773 (match_operand:SI 5 "register_operand" "2")))
18774 (set (match_operand:SI 1 "register_operand" "=S")
18775 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18776 (set (mem:BLK (match_dup 3))
18777 (mem:BLK (match_dup 4)))
18778 (use (match_dup 5))]
18781 [(set_attr "type" "str")
18782 (set_attr "prefix_rep" "1")
18783 (set_attr "memory" "both")
18784 (set_attr "mode" "SI")])
18786 (define_insn "*rep_movqi_rex64"
18787 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18788 (set (match_operand:DI 0 "register_operand" "=D")
18789 (plus:DI (match_operand:DI 3 "register_operand" "0")
18790 (match_operand:DI 5 "register_operand" "2")))
18791 (set (match_operand:DI 1 "register_operand" "=S")
18792 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18793 (set (mem:BLK (match_dup 3))
18794 (mem:BLK (match_dup 4)))
18795 (use (match_dup 5))]
18798 [(set_attr "type" "str")
18799 (set_attr "prefix_rep" "1")
18800 (set_attr "memory" "both")
18801 (set_attr "mode" "SI")])
18803 (define_expand "setmemsi"
18804 [(use (match_operand:BLK 0 "memory_operand" ""))
18805 (use (match_operand:SI 1 "nonmemory_operand" ""))
18806 (use (match_operand 2 "const_int_operand" ""))
18807 (use (match_operand 3 "const_int_operand" ""))
18808 (use (match_operand:SI 4 "const_int_operand" ""))
18809 (use (match_operand:SI 5 "const_int_operand" ""))]
18812 if (ix86_expand_setmem (operands[0], operands[1],
18813 operands[2], operands[3],
18814 operands[4], operands[5]))
18820 (define_expand "setmemdi"
18821 [(use (match_operand:BLK 0 "memory_operand" ""))
18822 (use (match_operand:DI 1 "nonmemory_operand" ""))
18823 (use (match_operand 2 "const_int_operand" ""))
18824 (use (match_operand 3 "const_int_operand" ""))
18825 (use (match_operand 4 "const_int_operand" ""))
18826 (use (match_operand 5 "const_int_operand" ""))]
18829 if (ix86_expand_setmem (operands[0], operands[1],
18830 operands[2], operands[3],
18831 operands[4], operands[5]))
18837 ;; Most CPUs don't like single string operations
18838 ;; Handle this case here to simplify previous expander.
18840 (define_expand "strset"
18841 [(set (match_operand 1 "memory_operand" "")
18842 (match_operand 2 "register_operand" ""))
18843 (parallel [(set (match_operand 0 "register_operand" "")
18845 (clobber (reg:CC FLAGS_REG))])]
18848 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18849 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18851 /* If .md ever supports :P for Pmode, this can be directly
18852 in the pattern above. */
18853 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18854 GEN_INT (GET_MODE_SIZE (GET_MODE
18856 if (TARGET_SINGLE_STRINGOP || optimize_size)
18858 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18864 (define_expand "strset_singleop"
18865 [(parallel [(set (match_operand 1 "memory_operand" "")
18866 (match_operand 2 "register_operand" ""))
18867 (set (match_operand 0 "register_operand" "")
18868 (match_operand 3 "" ""))])]
18869 "TARGET_SINGLE_STRINGOP || optimize_size"
18872 (define_insn "*strsetdi_rex_1"
18873 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18874 (match_operand:DI 2 "register_operand" "a"))
18875 (set (match_operand:DI 0 "register_operand" "=D")
18876 (plus:DI (match_dup 1)
18878 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18880 [(set_attr "type" "str")
18881 (set_attr "memory" "store")
18882 (set_attr "mode" "DI")])
18884 (define_insn "*strsetsi_1"
18885 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18886 (match_operand:SI 2 "register_operand" "a"))
18887 (set (match_operand:SI 0 "register_operand" "=D")
18888 (plus:SI (match_dup 1)
18890 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18892 [(set_attr "type" "str")
18893 (set_attr "memory" "store")
18894 (set_attr "mode" "SI")])
18896 (define_insn "*strsetsi_rex_1"
18897 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18898 (match_operand:SI 2 "register_operand" "a"))
18899 (set (match_operand:DI 0 "register_operand" "=D")
18900 (plus:DI (match_dup 1)
18902 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18904 [(set_attr "type" "str")
18905 (set_attr "memory" "store")
18906 (set_attr "mode" "SI")])
18908 (define_insn "*strsethi_1"
18909 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18910 (match_operand:HI 2 "register_operand" "a"))
18911 (set (match_operand:SI 0 "register_operand" "=D")
18912 (plus:SI (match_dup 1)
18914 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18916 [(set_attr "type" "str")
18917 (set_attr "memory" "store")
18918 (set_attr "mode" "HI")])
18920 (define_insn "*strsethi_rex_1"
18921 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18922 (match_operand:HI 2 "register_operand" "a"))
18923 (set (match_operand:DI 0 "register_operand" "=D")
18924 (plus:DI (match_dup 1)
18926 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18928 [(set_attr "type" "str")
18929 (set_attr "memory" "store")
18930 (set_attr "mode" "HI")])
18932 (define_insn "*strsetqi_1"
18933 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18934 (match_operand:QI 2 "register_operand" "a"))
18935 (set (match_operand:SI 0 "register_operand" "=D")
18936 (plus:SI (match_dup 1)
18938 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18940 [(set_attr "type" "str")
18941 (set_attr "memory" "store")
18942 (set_attr "mode" "QI")])
18944 (define_insn "*strsetqi_rex_1"
18945 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18946 (match_operand:QI 2 "register_operand" "a"))
18947 (set (match_operand:DI 0 "register_operand" "=D")
18948 (plus:DI (match_dup 1)
18950 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18952 [(set_attr "type" "str")
18953 (set_attr "memory" "store")
18954 (set_attr "mode" "QI")])
18956 (define_expand "rep_stos"
18957 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18958 (set (match_operand 0 "register_operand" "")
18959 (match_operand 4 "" ""))
18960 (set (match_operand 2 "memory_operand" "") (const_int 0))
18961 (use (match_operand 3 "register_operand" ""))
18962 (use (match_dup 1))])]
18966 (define_insn "*rep_stosdi_rex64"
18967 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18968 (set (match_operand:DI 0 "register_operand" "=D")
18969 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18971 (match_operand:DI 3 "register_operand" "0")))
18972 (set (mem:BLK (match_dup 3))
18974 (use (match_operand:DI 2 "register_operand" "a"))
18975 (use (match_dup 4))]
18978 [(set_attr "type" "str")
18979 (set_attr "prefix_rep" "1")
18980 (set_attr "memory" "store")
18981 (set_attr "mode" "DI")])
18983 (define_insn "*rep_stossi"
18984 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18985 (set (match_operand:SI 0 "register_operand" "=D")
18986 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18988 (match_operand:SI 3 "register_operand" "0")))
18989 (set (mem:BLK (match_dup 3))
18991 (use (match_operand:SI 2 "register_operand" "a"))
18992 (use (match_dup 4))]
18995 [(set_attr "type" "str")
18996 (set_attr "prefix_rep" "1")
18997 (set_attr "memory" "store")
18998 (set_attr "mode" "SI")])
19000 (define_insn "*rep_stossi_rex64"
19001 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19002 (set (match_operand:DI 0 "register_operand" "=D")
19003 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19005 (match_operand:DI 3 "register_operand" "0")))
19006 (set (mem:BLK (match_dup 3))
19008 (use (match_operand:SI 2 "register_operand" "a"))
19009 (use (match_dup 4))]
19012 [(set_attr "type" "str")
19013 (set_attr "prefix_rep" "1")
19014 (set_attr "memory" "store")
19015 (set_attr "mode" "SI")])
19017 (define_insn "*rep_stosqi"
19018 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19019 (set (match_operand:SI 0 "register_operand" "=D")
19020 (plus:SI (match_operand:SI 3 "register_operand" "0")
19021 (match_operand:SI 4 "register_operand" "1")))
19022 (set (mem:BLK (match_dup 3))
19024 (use (match_operand:QI 2 "register_operand" "a"))
19025 (use (match_dup 4))]
19028 [(set_attr "type" "str")
19029 (set_attr "prefix_rep" "1")
19030 (set_attr "memory" "store")
19031 (set_attr "mode" "QI")])
19033 (define_insn "*rep_stosqi_rex64"
19034 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19035 (set (match_operand:DI 0 "register_operand" "=D")
19036 (plus:DI (match_operand:DI 3 "register_operand" "0")
19037 (match_operand:DI 4 "register_operand" "1")))
19038 (set (mem:BLK (match_dup 3))
19040 (use (match_operand:QI 2 "register_operand" "a"))
19041 (use (match_dup 4))]
19044 [(set_attr "type" "str")
19045 (set_attr "prefix_rep" "1")
19046 (set_attr "memory" "store")
19047 (set_attr "mode" "QI")])
19049 (define_expand "cmpstrnsi"
19050 [(set (match_operand:SI 0 "register_operand" "")
19051 (compare:SI (match_operand:BLK 1 "general_operand" "")
19052 (match_operand:BLK 2 "general_operand" "")))
19053 (use (match_operand 3 "general_operand" ""))
19054 (use (match_operand 4 "immediate_operand" ""))]
19055 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19057 rtx addr1, addr2, out, outlow, count, countreg, align;
19059 /* Can't use this if the user has appropriated esi or edi. */
19060 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19065 out = gen_reg_rtx (SImode);
19067 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19068 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19069 if (addr1 != XEXP (operands[1], 0))
19070 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19071 if (addr2 != XEXP (operands[2], 0))
19072 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19074 count = operands[3];
19075 countreg = ix86_zero_extend_to_Pmode (count);
19077 /* %%% Iff we are testing strict equality, we can use known alignment
19078 to good advantage. This may be possible with combine, particularly
19079 once cc0 is dead. */
19080 align = operands[4];
19082 if (CONST_INT_P (count))
19084 if (INTVAL (count) == 0)
19086 emit_move_insn (operands[0], const0_rtx);
19089 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19090 operands[1], operands[2]));
19095 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19097 emit_insn (gen_cmpsi_1 (countreg, countreg));
19098 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19099 operands[1], operands[2]));
19102 outlow = gen_lowpart (QImode, out);
19103 emit_insn (gen_cmpintqi (outlow));
19104 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19106 if (operands[0] != out)
19107 emit_move_insn (operands[0], out);
19112 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19114 (define_expand "cmpintqi"
19115 [(set (match_dup 1)
19116 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19118 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19119 (parallel [(set (match_operand:QI 0 "register_operand" "")
19120 (minus:QI (match_dup 1)
19122 (clobber (reg:CC FLAGS_REG))])]
19124 "operands[1] = gen_reg_rtx (QImode);
19125 operands[2] = gen_reg_rtx (QImode);")
19127 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19128 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19130 (define_expand "cmpstrnqi_nz_1"
19131 [(parallel [(set (reg:CC FLAGS_REG)
19132 (compare:CC (match_operand 4 "memory_operand" "")
19133 (match_operand 5 "memory_operand" "")))
19134 (use (match_operand 2 "register_operand" ""))
19135 (use (match_operand:SI 3 "immediate_operand" ""))
19136 (clobber (match_operand 0 "register_operand" ""))
19137 (clobber (match_operand 1 "register_operand" ""))
19138 (clobber (match_dup 2))])]
19142 (define_insn "*cmpstrnqi_nz_1"
19143 [(set (reg:CC FLAGS_REG)
19144 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19145 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19146 (use (match_operand:SI 6 "register_operand" "2"))
19147 (use (match_operand:SI 3 "immediate_operand" "i"))
19148 (clobber (match_operand:SI 0 "register_operand" "=S"))
19149 (clobber (match_operand:SI 1 "register_operand" "=D"))
19150 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19153 [(set_attr "type" "str")
19154 (set_attr "mode" "QI")
19155 (set_attr "prefix_rep" "1")])
19157 (define_insn "*cmpstrnqi_nz_rex_1"
19158 [(set (reg:CC FLAGS_REG)
19159 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19160 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19161 (use (match_operand:DI 6 "register_operand" "2"))
19162 (use (match_operand:SI 3 "immediate_operand" "i"))
19163 (clobber (match_operand:DI 0 "register_operand" "=S"))
19164 (clobber (match_operand:DI 1 "register_operand" "=D"))
19165 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19168 [(set_attr "type" "str")
19169 (set_attr "mode" "QI")
19170 (set_attr "prefix_rep" "1")])
19172 ;; The same, but the count is not known to not be zero.
19174 (define_expand "cmpstrnqi_1"
19175 [(parallel [(set (reg:CC FLAGS_REG)
19176 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19178 (compare:CC (match_operand 4 "memory_operand" "")
19179 (match_operand 5 "memory_operand" ""))
19181 (use (match_operand:SI 3 "immediate_operand" ""))
19182 (use (reg:CC FLAGS_REG))
19183 (clobber (match_operand 0 "register_operand" ""))
19184 (clobber (match_operand 1 "register_operand" ""))
19185 (clobber (match_dup 2))])]
19189 (define_insn "*cmpstrnqi_1"
19190 [(set (reg:CC FLAGS_REG)
19191 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19193 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19194 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19196 (use (match_operand:SI 3 "immediate_operand" "i"))
19197 (use (reg:CC FLAGS_REG))
19198 (clobber (match_operand:SI 0 "register_operand" "=S"))
19199 (clobber (match_operand:SI 1 "register_operand" "=D"))
19200 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19203 [(set_attr "type" "str")
19204 (set_attr "mode" "QI")
19205 (set_attr "prefix_rep" "1")])
19207 (define_insn "*cmpstrnqi_rex_1"
19208 [(set (reg:CC FLAGS_REG)
19209 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19211 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19212 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19214 (use (match_operand:SI 3 "immediate_operand" "i"))
19215 (use (reg:CC FLAGS_REG))
19216 (clobber (match_operand:DI 0 "register_operand" "=S"))
19217 (clobber (match_operand:DI 1 "register_operand" "=D"))
19218 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19221 [(set_attr "type" "str")
19222 (set_attr "mode" "QI")
19223 (set_attr "prefix_rep" "1")])
19225 (define_expand "strlensi"
19226 [(set (match_operand:SI 0 "register_operand" "")
19227 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19228 (match_operand:QI 2 "immediate_operand" "")
19229 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19232 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19238 (define_expand "strlendi"
19239 [(set (match_operand:DI 0 "register_operand" "")
19240 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19241 (match_operand:QI 2 "immediate_operand" "")
19242 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19245 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19251 (define_expand "strlenqi_1"
19252 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19253 (clobber (match_operand 1 "register_operand" ""))
19254 (clobber (reg:CC FLAGS_REG))])]
19258 (define_insn "*strlenqi_1"
19259 [(set (match_operand:SI 0 "register_operand" "=&c")
19260 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19261 (match_operand:QI 2 "register_operand" "a")
19262 (match_operand:SI 3 "immediate_operand" "i")
19263 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19264 (clobber (match_operand:SI 1 "register_operand" "=D"))
19265 (clobber (reg:CC FLAGS_REG))]
19268 [(set_attr "type" "str")
19269 (set_attr "mode" "QI")
19270 (set_attr "prefix_rep" "1")])
19272 (define_insn "*strlenqi_rex_1"
19273 [(set (match_operand:DI 0 "register_operand" "=&c")
19274 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19275 (match_operand:QI 2 "register_operand" "a")
19276 (match_operand:DI 3 "immediate_operand" "i")
19277 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19278 (clobber (match_operand:DI 1 "register_operand" "=D"))
19279 (clobber (reg:CC FLAGS_REG))]
19282 [(set_attr "type" "str")
19283 (set_attr "mode" "QI")
19284 (set_attr "prefix_rep" "1")])
19286 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19287 ;; handled in combine, but it is not currently up to the task.
19288 ;; When used for their truth value, the cmpstrn* expanders generate
19297 ;; The intermediate three instructions are unnecessary.
19299 ;; This one handles cmpstrn*_nz_1...
19302 (set (reg:CC FLAGS_REG)
19303 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19304 (mem:BLK (match_operand 5 "register_operand" ""))))
19305 (use (match_operand 6 "register_operand" ""))
19306 (use (match_operand:SI 3 "immediate_operand" ""))
19307 (clobber (match_operand 0 "register_operand" ""))
19308 (clobber (match_operand 1 "register_operand" ""))
19309 (clobber (match_operand 2 "register_operand" ""))])
19310 (set (match_operand:QI 7 "register_operand" "")
19311 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19312 (set (match_operand:QI 8 "register_operand" "")
19313 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19314 (set (reg FLAGS_REG)
19315 (compare (match_dup 7) (match_dup 8)))
19317 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19319 (set (reg:CC FLAGS_REG)
19320 (compare:CC (mem:BLK (match_dup 4))
19321 (mem:BLK (match_dup 5))))
19322 (use (match_dup 6))
19323 (use (match_dup 3))
19324 (clobber (match_dup 0))
19325 (clobber (match_dup 1))
19326 (clobber (match_dup 2))])]
19329 ;; ...and this one handles cmpstrn*_1.
19332 (set (reg:CC FLAGS_REG)
19333 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19335 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19336 (mem:BLK (match_operand 5 "register_operand" "")))
19338 (use (match_operand:SI 3 "immediate_operand" ""))
19339 (use (reg:CC FLAGS_REG))
19340 (clobber (match_operand 0 "register_operand" ""))
19341 (clobber (match_operand 1 "register_operand" ""))
19342 (clobber (match_operand 2 "register_operand" ""))])
19343 (set (match_operand:QI 7 "register_operand" "")
19344 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19345 (set (match_operand:QI 8 "register_operand" "")
19346 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19347 (set (reg FLAGS_REG)
19348 (compare (match_dup 7) (match_dup 8)))
19350 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19352 (set (reg:CC FLAGS_REG)
19353 (if_then_else:CC (ne (match_dup 6)
19355 (compare:CC (mem:BLK (match_dup 4))
19356 (mem:BLK (match_dup 5)))
19358 (use (match_dup 3))
19359 (use (reg:CC FLAGS_REG))
19360 (clobber (match_dup 0))
19361 (clobber (match_dup 1))
19362 (clobber (match_dup 2))])]
19367 ;; Conditional move instructions.
19369 (define_expand "movdicc"
19370 [(set (match_operand:DI 0 "register_operand" "")
19371 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19372 (match_operand:DI 2 "general_operand" "")
19373 (match_operand:DI 3 "general_operand" "")))]
19375 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19377 (define_insn "x86_movdicc_0_m1_rex64"
19378 [(set (match_operand:DI 0 "register_operand" "=r")
19379 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19382 (clobber (reg:CC FLAGS_REG))]
19385 ; Since we don't have the proper number of operands for an alu insn,
19386 ; fill in all the blanks.
19387 [(set_attr "type" "alu")
19388 (set_attr "pent_pair" "pu")
19389 (set_attr "memory" "none")
19390 (set_attr "imm_disp" "false")
19391 (set_attr "mode" "DI")
19392 (set_attr "length_immediate" "0")])
19394 (define_insn "*x86_movdicc_0_m1_se"
19395 [(set (match_operand:DI 0 "register_operand" "=r")
19396 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19399 (clobber (reg:CC FLAGS_REG))]
19402 [(set_attr "type" "alu")
19403 (set_attr "pent_pair" "pu")
19404 (set_attr "memory" "none")
19405 (set_attr "imm_disp" "false")
19406 (set_attr "mode" "DI")
19407 (set_attr "length_immediate" "0")])
19409 (define_insn "*movdicc_c_rex64"
19410 [(set (match_operand:DI 0 "register_operand" "=r,r")
19411 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19412 [(reg FLAGS_REG) (const_int 0)])
19413 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19414 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19415 "TARGET_64BIT && TARGET_CMOVE
19416 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19418 cmov%O2%C1\t{%2, %0|%0, %2}
19419 cmov%O2%c1\t{%3, %0|%0, %3}"
19420 [(set_attr "type" "icmov")
19421 (set_attr "mode" "DI")])
19423 (define_expand "movsicc"
19424 [(set (match_operand:SI 0 "register_operand" "")
19425 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19426 (match_operand:SI 2 "general_operand" "")
19427 (match_operand:SI 3 "general_operand" "")))]
19429 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19431 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19432 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19433 ;; So just document what we're doing explicitly.
19435 (define_insn "x86_movsicc_0_m1"
19436 [(set (match_operand:SI 0 "register_operand" "=r")
19437 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19440 (clobber (reg:CC FLAGS_REG))]
19443 ; Since we don't have the proper number of operands for an alu insn,
19444 ; fill in all the blanks.
19445 [(set_attr "type" "alu")
19446 (set_attr "pent_pair" "pu")
19447 (set_attr "memory" "none")
19448 (set_attr "imm_disp" "false")
19449 (set_attr "mode" "SI")
19450 (set_attr "length_immediate" "0")])
19452 (define_insn "*x86_movsicc_0_m1_se"
19453 [(set (match_operand:SI 0 "register_operand" "=r")
19454 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19457 (clobber (reg:CC FLAGS_REG))]
19460 [(set_attr "type" "alu")
19461 (set_attr "pent_pair" "pu")
19462 (set_attr "memory" "none")
19463 (set_attr "imm_disp" "false")
19464 (set_attr "mode" "SI")
19465 (set_attr "length_immediate" "0")])
19467 (define_insn "*movsicc_noc"
19468 [(set (match_operand:SI 0 "register_operand" "=r,r")
19469 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19470 [(reg FLAGS_REG) (const_int 0)])
19471 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19472 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19474 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19476 cmov%O2%C1\t{%2, %0|%0, %2}
19477 cmov%O2%c1\t{%3, %0|%0, %3}"
19478 [(set_attr "type" "icmov")
19479 (set_attr "mode" "SI")])
19481 (define_expand "movhicc"
19482 [(set (match_operand:HI 0 "register_operand" "")
19483 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19484 (match_operand:HI 2 "general_operand" "")
19485 (match_operand:HI 3 "general_operand" "")))]
19486 "TARGET_HIMODE_MATH"
19487 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19489 (define_insn "*movhicc_noc"
19490 [(set (match_operand:HI 0 "register_operand" "=r,r")
19491 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19492 [(reg FLAGS_REG) (const_int 0)])
19493 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19494 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19496 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19498 cmov%O2%C1\t{%2, %0|%0, %2}
19499 cmov%O2%c1\t{%3, %0|%0, %3}"
19500 [(set_attr "type" "icmov")
19501 (set_attr "mode" "HI")])
19503 (define_expand "movqicc"
19504 [(set (match_operand:QI 0 "register_operand" "")
19505 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19506 (match_operand:QI 2 "general_operand" "")
19507 (match_operand:QI 3 "general_operand" "")))]
19508 "TARGET_QIMODE_MATH"
19509 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19511 (define_insn_and_split "*movqicc_noc"
19512 [(set (match_operand:QI 0 "register_operand" "=r,r")
19513 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19514 [(match_operand 4 "flags_reg_operand" "")
19516 (match_operand:QI 2 "register_operand" "r,0")
19517 (match_operand:QI 3 "register_operand" "0,r")))]
19518 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19520 "&& reload_completed"
19521 [(set (match_dup 0)
19522 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19525 "operands[0] = gen_lowpart (SImode, operands[0]);
19526 operands[2] = gen_lowpart (SImode, operands[2]);
19527 operands[3] = gen_lowpart (SImode, operands[3]);"
19528 [(set_attr "type" "icmov")
19529 (set_attr "mode" "SI")])
19531 (define_expand "mov<mode>cc"
19532 [(set (match_operand:X87MODEF 0 "register_operand" "")
19533 (if_then_else:X87MODEF
19534 (match_operand 1 "comparison_operator" "")
19535 (match_operand:X87MODEF 2 "register_operand" "")
19536 (match_operand:X87MODEF 3 "register_operand" "")))]
19537 "(TARGET_80387 && TARGET_CMOVE)
19538 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19539 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19541 (define_insn "*movsfcc_1_387"
19542 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19543 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19544 [(reg FLAGS_REG) (const_int 0)])
19545 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19546 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19547 "TARGET_80387 && TARGET_CMOVE
19548 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19550 fcmov%F1\t{%2, %0|%0, %2}
19551 fcmov%f1\t{%3, %0|%0, %3}
19552 cmov%O2%C1\t{%2, %0|%0, %2}
19553 cmov%O2%c1\t{%3, %0|%0, %3}"
19554 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19555 (set_attr "mode" "SF,SF,SI,SI")])
19557 (define_insn "*movdfcc_1"
19558 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19559 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19560 [(reg FLAGS_REG) (const_int 0)])
19561 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19562 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19563 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19564 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19566 fcmov%F1\t{%2, %0|%0, %2}
19567 fcmov%f1\t{%3, %0|%0, %3}
19570 [(set_attr "type" "fcmov,fcmov,multi,multi")
19571 (set_attr "mode" "DF")])
19573 (define_insn "*movdfcc_1_rex64"
19574 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19575 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19576 [(reg FLAGS_REG) (const_int 0)])
19577 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19578 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19579 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19580 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19582 fcmov%F1\t{%2, %0|%0, %2}
19583 fcmov%f1\t{%3, %0|%0, %3}
19584 cmov%O2%C1\t{%2, %0|%0, %2}
19585 cmov%O2%c1\t{%3, %0|%0, %3}"
19586 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19587 (set_attr "mode" "DF")])
19590 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19591 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19592 [(match_operand 4 "flags_reg_operand" "")
19594 (match_operand:DF 2 "nonimmediate_operand" "")
19595 (match_operand:DF 3 "nonimmediate_operand" "")))]
19596 "!TARGET_64BIT && reload_completed"
19597 [(set (match_dup 2)
19598 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19602 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19605 "split_di (operands+2, 1, operands+5, operands+6);
19606 split_di (operands+3, 1, operands+7, operands+8);
19607 split_di (operands, 1, operands+2, operands+3);")
19609 (define_insn "*movxfcc_1"
19610 [(set (match_operand:XF 0 "register_operand" "=f,f")
19611 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19612 [(reg FLAGS_REG) (const_int 0)])
19613 (match_operand:XF 2 "register_operand" "f,0")
19614 (match_operand:XF 3 "register_operand" "0,f")))]
19615 "TARGET_80387 && TARGET_CMOVE"
19617 fcmov%F1\t{%2, %0|%0, %2}
19618 fcmov%f1\t{%3, %0|%0, %3}"
19619 [(set_attr "type" "fcmov")
19620 (set_attr "mode" "XF")])
19622 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19623 ;; the scalar versions to have only XMM registers as operands.
19625 ;; SSE5 conditional move
19626 (define_insn "*sse5_pcmov_<mode>"
19627 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19628 (if_then_else:MODEF
19629 (match_operand:MODEF 1 "register_operand" "x,0")
19630 (match_operand:MODEF 2 "register_operand" "0,x")
19631 (match_operand:MODEF 3 "register_operand" "x,x")))]
19632 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19633 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19634 [(set_attr "type" "sse4arg")])
19636 ;; These versions of the min/max patterns are intentionally ignorant of
19637 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19638 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19639 ;; are undefined in this condition, we're certain this is correct.
19641 (define_insn "smin<mode>3"
19642 [(set (match_operand:MODEF 0 "register_operand" "=x")
19644 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19645 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19646 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19647 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19648 [(set_attr "type" "sseadd")
19649 (set_attr "mode" "<MODE>")])
19651 (define_insn "smax<mode>3"
19652 [(set (match_operand:MODEF 0 "register_operand" "=x")
19654 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19655 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19656 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19657 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19658 [(set_attr "type" "sseadd")
19659 (set_attr "mode" "<MODE>")])
19661 ;; These versions of the min/max patterns implement exactly the operations
19662 ;; min = (op1 < op2 ? op1 : op2)
19663 ;; max = (!(op1 < op2) ? op1 : op2)
19664 ;; Their operands are not commutative, and thus they may be used in the
19665 ;; presence of -0.0 and NaN.
19667 (define_insn "*ieee_smin<mode>3"
19668 [(set (match_operand:MODEF 0 "register_operand" "=x")
19670 [(match_operand:MODEF 1 "register_operand" "0")
19671 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19673 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19674 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19675 [(set_attr "type" "sseadd")
19676 (set_attr "mode" "<MODE>")])
19678 (define_insn "*ieee_smax<mode>3"
19679 [(set (match_operand:MODEF 0 "register_operand" "=x")
19681 [(match_operand:MODEF 1 "register_operand" "0")
19682 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19684 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19685 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19686 [(set_attr "type" "sseadd")
19687 (set_attr "mode" "<MODE>")])
19689 ;; Make two stack loads independent:
19691 ;; fld %st(0) -> fld bb
19692 ;; fmul bb fmul %st(1), %st
19694 ;; Actually we only match the last two instructions for simplicity.
19696 [(set (match_operand 0 "fp_register_operand" "")
19697 (match_operand 1 "fp_register_operand" ""))
19699 (match_operator 2 "binary_fp_operator"
19701 (match_operand 3 "memory_operand" "")]))]
19702 "REGNO (operands[0]) != REGNO (operands[1])"
19703 [(set (match_dup 0) (match_dup 3))
19704 (set (match_dup 0) (match_dup 4))]
19706 ;; The % modifier is not operational anymore in peephole2's, so we have to
19707 ;; swap the operands manually in the case of addition and multiplication.
19708 "if (COMMUTATIVE_ARITH_P (operands[2]))
19709 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19710 operands[0], operands[1]);
19712 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19713 operands[1], operands[0]);")
19715 ;; Conditional addition patterns
19716 (define_expand "addqicc"
19717 [(match_operand:QI 0 "register_operand" "")
19718 (match_operand 1 "comparison_operator" "")
19719 (match_operand:QI 2 "register_operand" "")
19720 (match_operand:QI 3 "const_int_operand" "")]
19722 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19724 (define_expand "addhicc"
19725 [(match_operand:HI 0 "register_operand" "")
19726 (match_operand 1 "comparison_operator" "")
19727 (match_operand:HI 2 "register_operand" "")
19728 (match_operand:HI 3 "const_int_operand" "")]
19730 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19732 (define_expand "addsicc"
19733 [(match_operand:SI 0 "register_operand" "")
19734 (match_operand 1 "comparison_operator" "")
19735 (match_operand:SI 2 "register_operand" "")
19736 (match_operand:SI 3 "const_int_operand" "")]
19738 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19740 (define_expand "adddicc"
19741 [(match_operand:DI 0 "register_operand" "")
19742 (match_operand 1 "comparison_operator" "")
19743 (match_operand:DI 2 "register_operand" "")
19744 (match_operand:DI 3 "const_int_operand" "")]
19746 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19749 ;; Misc patterns (?)
19751 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19752 ;; Otherwise there will be nothing to keep
19754 ;; [(set (reg ebp) (reg esp))]
19755 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19756 ;; (clobber (eflags)]
19757 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19759 ;; in proper program order.
19760 (define_insn "pro_epilogue_adjust_stack_1"
19761 [(set (match_operand:SI 0 "register_operand" "=r,r")
19762 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19763 (match_operand:SI 2 "immediate_operand" "i,i")))
19764 (clobber (reg:CC FLAGS_REG))
19765 (clobber (mem:BLK (scratch)))]
19768 switch (get_attr_type (insn))
19771 return "mov{l}\t{%1, %0|%0, %1}";
19774 if (CONST_INT_P (operands[2])
19775 && (INTVAL (operands[2]) == 128
19776 || (INTVAL (operands[2]) < 0
19777 && INTVAL (operands[2]) != -128)))
19779 operands[2] = GEN_INT (-INTVAL (operands[2]));
19780 return "sub{l}\t{%2, %0|%0, %2}";
19782 return "add{l}\t{%2, %0|%0, %2}";
19785 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19786 return "lea{l}\t{%a2, %0|%0, %a2}";
19789 gcc_unreachable ();
19792 [(set (attr "type")
19793 (cond [(eq_attr "alternative" "0")
19794 (const_string "alu")
19795 (match_operand:SI 2 "const0_operand" "")
19796 (const_string "imov")
19798 (const_string "lea")))
19799 (set_attr "mode" "SI")])
19801 (define_insn "pro_epilogue_adjust_stack_rex64"
19802 [(set (match_operand:DI 0 "register_operand" "=r,r")
19803 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19804 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19805 (clobber (reg:CC FLAGS_REG))
19806 (clobber (mem:BLK (scratch)))]
19809 switch (get_attr_type (insn))
19812 return "mov{q}\t{%1, %0|%0, %1}";
19815 if (CONST_INT_P (operands[2])
19816 /* Avoid overflows. */
19817 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19818 && (INTVAL (operands[2]) == 128
19819 || (INTVAL (operands[2]) < 0
19820 && INTVAL (operands[2]) != -128)))
19822 operands[2] = GEN_INT (-INTVAL (operands[2]));
19823 return "sub{q}\t{%2, %0|%0, %2}";
19825 return "add{q}\t{%2, %0|%0, %2}";
19828 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19829 return "lea{q}\t{%a2, %0|%0, %a2}";
19832 gcc_unreachable ();
19835 [(set (attr "type")
19836 (cond [(eq_attr "alternative" "0")
19837 (const_string "alu")
19838 (match_operand:DI 2 "const0_operand" "")
19839 (const_string "imov")
19841 (const_string "lea")))
19842 (set_attr "mode" "DI")])
19844 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19845 [(set (match_operand:DI 0 "register_operand" "=r,r")
19846 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19847 (match_operand:DI 3 "immediate_operand" "i,i")))
19848 (use (match_operand:DI 2 "register_operand" "r,r"))
19849 (clobber (reg:CC FLAGS_REG))
19850 (clobber (mem:BLK (scratch)))]
19853 switch (get_attr_type (insn))
19856 return "add{q}\t{%2, %0|%0, %2}";
19859 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19860 return "lea{q}\t{%a2, %0|%0, %a2}";
19863 gcc_unreachable ();
19866 [(set_attr "type" "alu,lea")
19867 (set_attr "mode" "DI")])
19869 (define_insn "allocate_stack_worker_32"
19870 [(set (match_operand:SI 0 "register_operand" "+a")
19871 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19872 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19873 (clobber (reg:CC FLAGS_REG))]
19874 "!TARGET_64BIT && TARGET_STACK_PROBE"
19876 [(set_attr "type" "multi")
19877 (set_attr "length" "5")])
19879 (define_insn "allocate_stack_worker_64"
19880 [(set (match_operand:DI 0 "register_operand" "=a")
19881 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19882 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19883 (clobber (reg:DI R10_REG))
19884 (clobber (reg:DI R11_REG))
19885 (clobber (reg:CC FLAGS_REG))]
19886 "TARGET_64BIT && TARGET_STACK_PROBE"
19888 [(set_attr "type" "multi")
19889 (set_attr "length" "5")])
19891 (define_expand "allocate_stack"
19892 [(match_operand 0 "register_operand" "")
19893 (match_operand 1 "general_operand" "")]
19894 "TARGET_STACK_PROBE"
19898 #ifndef CHECK_STACK_LIMIT
19899 #define CHECK_STACK_LIMIT 0
19902 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19903 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19905 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19906 stack_pointer_rtx, 0, OPTAB_DIRECT);
19907 if (x != stack_pointer_rtx)
19908 emit_move_insn (stack_pointer_rtx, x);
19912 x = copy_to_mode_reg (Pmode, operands[1]);
19914 x = gen_allocate_stack_worker_64 (x);
19916 x = gen_allocate_stack_worker_32 (x);
19920 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19924 (define_expand "builtin_setjmp_receiver"
19925 [(label_ref (match_operand 0 "" ""))]
19926 "!TARGET_64BIT && flag_pic"
19931 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19932 rtx label_rtx = gen_label_rtx ();
19933 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19934 xops[0] = xops[1] = picreg;
19935 xops[2] = gen_rtx_CONST (SImode,
19936 gen_rtx_MINUS (SImode,
19937 gen_rtx_LABEL_REF (SImode, label_rtx),
19938 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19939 ix86_expand_binary_operator (MINUS, SImode, xops);
19942 emit_insn (gen_set_got (pic_offset_table_rtx));
19946 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19949 [(set (match_operand 0 "register_operand" "")
19950 (match_operator 3 "promotable_binary_operator"
19951 [(match_operand 1 "register_operand" "")
19952 (match_operand 2 "aligned_operand" "")]))
19953 (clobber (reg:CC FLAGS_REG))]
19954 "! TARGET_PARTIAL_REG_STALL && reload_completed
19955 && ((GET_MODE (operands[0]) == HImode
19956 && ((!optimize_size && !TARGET_FAST_PREFIX)
19957 /* ??? next two lines just !satisfies_constraint_K (...) */
19958 || !CONST_INT_P (operands[2])
19959 || satisfies_constraint_K (operands[2])))
19960 || (GET_MODE (operands[0]) == QImode
19961 && (TARGET_PROMOTE_QImode || optimize_size)))"
19962 [(parallel [(set (match_dup 0)
19963 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19964 (clobber (reg:CC FLAGS_REG))])]
19965 "operands[0] = gen_lowpart (SImode, operands[0]);
19966 operands[1] = gen_lowpart (SImode, operands[1]);
19967 if (GET_CODE (operands[3]) != ASHIFT)
19968 operands[2] = gen_lowpart (SImode, operands[2]);
19969 PUT_MODE (operands[3], SImode);")
19971 ; Promote the QImode tests, as i386 has encoding of the AND
19972 ; instruction with 32-bit sign-extended immediate and thus the
19973 ; instruction size is unchanged, except in the %eax case for
19974 ; which it is increased by one byte, hence the ! optimize_size.
19976 [(set (match_operand 0 "flags_reg_operand" "")
19977 (match_operator 2 "compare_operator"
19978 [(and (match_operand 3 "aligned_operand" "")
19979 (match_operand 4 "const_int_operand" ""))
19981 (set (match_operand 1 "register_operand" "")
19982 (and (match_dup 3) (match_dup 4)))]
19983 "! TARGET_PARTIAL_REG_STALL && reload_completed
19985 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19986 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19987 /* Ensure that the operand will remain sign-extended immediate. */
19988 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19989 [(parallel [(set (match_dup 0)
19990 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19993 (and:SI (match_dup 3) (match_dup 4)))])]
19996 = gen_int_mode (INTVAL (operands[4])
19997 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19998 operands[1] = gen_lowpart (SImode, operands[1]);
19999 operands[3] = gen_lowpart (SImode, operands[3]);
20002 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20003 ; the TEST instruction with 32-bit sign-extended immediate and thus
20004 ; the instruction size would at least double, which is not what we
20005 ; want even with ! optimize_size.
20007 [(set (match_operand 0 "flags_reg_operand" "")
20008 (match_operator 1 "compare_operator"
20009 [(and (match_operand:HI 2 "aligned_operand" "")
20010 (match_operand:HI 3 "const_int_operand" ""))
20012 "! TARGET_PARTIAL_REG_STALL && reload_completed
20013 && ! TARGET_FAST_PREFIX
20015 /* Ensure that the operand will remain sign-extended immediate. */
20016 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20017 [(set (match_dup 0)
20018 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20022 = gen_int_mode (INTVAL (operands[3])
20023 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20024 operands[2] = gen_lowpart (SImode, operands[2]);
20028 [(set (match_operand 0 "register_operand" "")
20029 (neg (match_operand 1 "register_operand" "")))
20030 (clobber (reg:CC FLAGS_REG))]
20031 "! TARGET_PARTIAL_REG_STALL && reload_completed
20032 && (GET_MODE (operands[0]) == HImode
20033 || (GET_MODE (operands[0]) == QImode
20034 && (TARGET_PROMOTE_QImode || optimize_size)))"
20035 [(parallel [(set (match_dup 0)
20036 (neg:SI (match_dup 1)))
20037 (clobber (reg:CC FLAGS_REG))])]
20038 "operands[0] = gen_lowpart (SImode, operands[0]);
20039 operands[1] = gen_lowpart (SImode, operands[1]);")
20042 [(set (match_operand 0 "register_operand" "")
20043 (not (match_operand 1 "register_operand" "")))]
20044 "! TARGET_PARTIAL_REG_STALL && reload_completed
20045 && (GET_MODE (operands[0]) == HImode
20046 || (GET_MODE (operands[0]) == QImode
20047 && (TARGET_PROMOTE_QImode || optimize_size)))"
20048 [(set (match_dup 0)
20049 (not:SI (match_dup 1)))]
20050 "operands[0] = gen_lowpart (SImode, operands[0]);
20051 operands[1] = gen_lowpart (SImode, operands[1]);")
20054 [(set (match_operand 0 "register_operand" "")
20055 (if_then_else (match_operator 1 "comparison_operator"
20056 [(reg FLAGS_REG) (const_int 0)])
20057 (match_operand 2 "register_operand" "")
20058 (match_operand 3 "register_operand" "")))]
20059 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20060 && (GET_MODE (operands[0]) == HImode
20061 || (GET_MODE (operands[0]) == QImode
20062 && (TARGET_PROMOTE_QImode || optimize_size)))"
20063 [(set (match_dup 0)
20064 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20065 "operands[0] = gen_lowpart (SImode, operands[0]);
20066 operands[2] = gen_lowpart (SImode, operands[2]);
20067 operands[3] = gen_lowpart (SImode, operands[3]);")
20070 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20071 ;; transform a complex memory operation into two memory to register operations.
20073 ;; Don't push memory operands
20075 [(set (match_operand:SI 0 "push_operand" "")
20076 (match_operand:SI 1 "memory_operand" ""))
20077 (match_scratch:SI 2 "r")]
20078 "!optimize_size && !TARGET_PUSH_MEMORY
20079 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20080 [(set (match_dup 2) (match_dup 1))
20081 (set (match_dup 0) (match_dup 2))]
20085 [(set (match_operand:DI 0 "push_operand" "")
20086 (match_operand:DI 1 "memory_operand" ""))
20087 (match_scratch:DI 2 "r")]
20088 "!optimize_size && !TARGET_PUSH_MEMORY
20089 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20090 [(set (match_dup 2) (match_dup 1))
20091 (set (match_dup 0) (match_dup 2))]
20094 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20097 [(set (match_operand:SF 0 "push_operand" "")
20098 (match_operand:SF 1 "memory_operand" ""))
20099 (match_scratch:SF 2 "r")]
20100 "!optimize_size && !TARGET_PUSH_MEMORY
20101 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20102 [(set (match_dup 2) (match_dup 1))
20103 (set (match_dup 0) (match_dup 2))]
20107 [(set (match_operand:HI 0 "push_operand" "")
20108 (match_operand:HI 1 "memory_operand" ""))
20109 (match_scratch:HI 2 "r")]
20110 "!optimize_size && !TARGET_PUSH_MEMORY
20111 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20112 [(set (match_dup 2) (match_dup 1))
20113 (set (match_dup 0) (match_dup 2))]
20117 [(set (match_operand:QI 0 "push_operand" "")
20118 (match_operand:QI 1 "memory_operand" ""))
20119 (match_scratch:QI 2 "q")]
20120 "!optimize_size && !TARGET_PUSH_MEMORY
20121 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20122 [(set (match_dup 2) (match_dup 1))
20123 (set (match_dup 0) (match_dup 2))]
20126 ;; Don't move an immediate directly to memory when the instruction
20129 [(match_scratch:SI 1 "r")
20130 (set (match_operand:SI 0 "memory_operand" "")
20133 && ! TARGET_USE_MOV0
20134 && TARGET_SPLIT_LONG_MOVES
20135 && get_attr_length (insn) >= ix86_cost->large_insn
20136 && peep2_regno_dead_p (0, FLAGS_REG)"
20137 [(parallel [(set (match_dup 1) (const_int 0))
20138 (clobber (reg:CC FLAGS_REG))])
20139 (set (match_dup 0) (match_dup 1))]
20143 [(match_scratch:HI 1 "r")
20144 (set (match_operand:HI 0 "memory_operand" "")
20147 && ! TARGET_USE_MOV0
20148 && TARGET_SPLIT_LONG_MOVES
20149 && get_attr_length (insn) >= ix86_cost->large_insn
20150 && peep2_regno_dead_p (0, FLAGS_REG)"
20151 [(parallel [(set (match_dup 2) (const_int 0))
20152 (clobber (reg:CC FLAGS_REG))])
20153 (set (match_dup 0) (match_dup 1))]
20154 "operands[2] = gen_lowpart (SImode, operands[1]);")
20157 [(match_scratch:QI 1 "q")
20158 (set (match_operand:QI 0 "memory_operand" "")
20161 && ! TARGET_USE_MOV0
20162 && TARGET_SPLIT_LONG_MOVES
20163 && get_attr_length (insn) >= ix86_cost->large_insn
20164 && peep2_regno_dead_p (0, FLAGS_REG)"
20165 [(parallel [(set (match_dup 2) (const_int 0))
20166 (clobber (reg:CC FLAGS_REG))])
20167 (set (match_dup 0) (match_dup 1))]
20168 "operands[2] = gen_lowpart (SImode, operands[1]);")
20171 [(match_scratch:SI 2 "r")
20172 (set (match_operand:SI 0 "memory_operand" "")
20173 (match_operand:SI 1 "immediate_operand" ""))]
20175 && TARGET_SPLIT_LONG_MOVES
20176 && get_attr_length (insn) >= ix86_cost->large_insn"
20177 [(set (match_dup 2) (match_dup 1))
20178 (set (match_dup 0) (match_dup 2))]
20182 [(match_scratch:HI 2 "r")
20183 (set (match_operand:HI 0 "memory_operand" "")
20184 (match_operand:HI 1 "immediate_operand" ""))]
20186 && TARGET_SPLIT_LONG_MOVES
20187 && get_attr_length (insn) >= ix86_cost->large_insn"
20188 [(set (match_dup 2) (match_dup 1))
20189 (set (match_dup 0) (match_dup 2))]
20193 [(match_scratch:QI 2 "q")
20194 (set (match_operand:QI 0 "memory_operand" "")
20195 (match_operand:QI 1 "immediate_operand" ""))]
20197 && TARGET_SPLIT_LONG_MOVES
20198 && get_attr_length (insn) >= ix86_cost->large_insn"
20199 [(set (match_dup 2) (match_dup 1))
20200 (set (match_dup 0) (match_dup 2))]
20203 ;; Don't compare memory with zero, load and use a test instead.
20205 [(set (match_operand 0 "flags_reg_operand" "")
20206 (match_operator 1 "compare_operator"
20207 [(match_operand:SI 2 "memory_operand" "")
20209 (match_scratch:SI 3 "r")]
20210 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20211 [(set (match_dup 3) (match_dup 2))
20212 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20215 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20216 ;; Don't split NOTs with a displacement operand, because resulting XOR
20217 ;; will not be pairable anyway.
20219 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20220 ;; represented using a modRM byte. The XOR replacement is long decoded,
20221 ;; so this split helps here as well.
20223 ;; Note: Can't do this as a regular split because we can't get proper
20224 ;; lifetime information then.
20227 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20228 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20230 && ((TARGET_NOT_UNPAIRABLE
20231 && (!MEM_P (operands[0])
20232 || !memory_displacement_operand (operands[0], SImode)))
20233 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20234 && peep2_regno_dead_p (0, FLAGS_REG)"
20235 [(parallel [(set (match_dup 0)
20236 (xor:SI (match_dup 1) (const_int -1)))
20237 (clobber (reg:CC FLAGS_REG))])]
20241 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20242 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20244 && ((TARGET_NOT_UNPAIRABLE
20245 && (!MEM_P (operands[0])
20246 || !memory_displacement_operand (operands[0], HImode)))
20247 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20248 && peep2_regno_dead_p (0, FLAGS_REG)"
20249 [(parallel [(set (match_dup 0)
20250 (xor:HI (match_dup 1) (const_int -1)))
20251 (clobber (reg:CC FLAGS_REG))])]
20255 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20256 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20258 && ((TARGET_NOT_UNPAIRABLE
20259 && (!MEM_P (operands[0])
20260 || !memory_displacement_operand (operands[0], QImode)))
20261 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20262 && peep2_regno_dead_p (0, FLAGS_REG)"
20263 [(parallel [(set (match_dup 0)
20264 (xor:QI (match_dup 1) (const_int -1)))
20265 (clobber (reg:CC FLAGS_REG))])]
20268 ;; Non pairable "test imm, reg" instructions can be translated to
20269 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20270 ;; byte opcode instead of two, have a short form for byte operands),
20271 ;; so do it for other CPUs as well. Given that the value was dead,
20272 ;; this should not create any new dependencies. Pass on the sub-word
20273 ;; versions if we're concerned about partial register stalls.
20276 [(set (match_operand 0 "flags_reg_operand" "")
20277 (match_operator 1 "compare_operator"
20278 [(and:SI (match_operand:SI 2 "register_operand" "")
20279 (match_operand:SI 3 "immediate_operand" ""))
20281 "ix86_match_ccmode (insn, CCNOmode)
20282 && (true_regnum (operands[2]) != AX_REG
20283 || satisfies_constraint_K (operands[3]))
20284 && peep2_reg_dead_p (1, operands[2])"
20286 [(set (match_dup 0)
20287 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20290 (and:SI (match_dup 2) (match_dup 3)))])]
20293 ;; We don't need to handle HImode case, because it will be promoted to SImode
20294 ;; on ! TARGET_PARTIAL_REG_STALL
20297 [(set (match_operand 0 "flags_reg_operand" "")
20298 (match_operator 1 "compare_operator"
20299 [(and:QI (match_operand:QI 2 "register_operand" "")
20300 (match_operand:QI 3 "immediate_operand" ""))
20302 "! TARGET_PARTIAL_REG_STALL
20303 && ix86_match_ccmode (insn, CCNOmode)
20304 && true_regnum (operands[2]) != AX_REG
20305 && peep2_reg_dead_p (1, operands[2])"
20307 [(set (match_dup 0)
20308 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20311 (and:QI (match_dup 2) (match_dup 3)))])]
20315 [(set (match_operand 0 "flags_reg_operand" "")
20316 (match_operator 1 "compare_operator"
20319 (match_operand 2 "ext_register_operand" "")
20322 (match_operand 3 "const_int_operand" ""))
20324 "! TARGET_PARTIAL_REG_STALL
20325 && ix86_match_ccmode (insn, CCNOmode)
20326 && true_regnum (operands[2]) != AX_REG
20327 && peep2_reg_dead_p (1, operands[2])"
20328 [(parallel [(set (match_dup 0)
20337 (set (zero_extract:SI (match_dup 2)
20348 ;; Don't do logical operations with memory inputs.
20350 [(match_scratch:SI 2 "r")
20351 (parallel [(set (match_operand:SI 0 "register_operand" "")
20352 (match_operator:SI 3 "arith_or_logical_operator"
20354 (match_operand:SI 1 "memory_operand" "")]))
20355 (clobber (reg:CC FLAGS_REG))])]
20356 "! optimize_size && ! TARGET_READ_MODIFY"
20357 [(set (match_dup 2) (match_dup 1))
20358 (parallel [(set (match_dup 0)
20359 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20360 (clobber (reg:CC FLAGS_REG))])]
20364 [(match_scratch:SI 2 "r")
20365 (parallel [(set (match_operand:SI 0 "register_operand" "")
20366 (match_operator:SI 3 "arith_or_logical_operator"
20367 [(match_operand:SI 1 "memory_operand" "")
20369 (clobber (reg:CC FLAGS_REG))])]
20370 "! optimize_size && ! TARGET_READ_MODIFY"
20371 [(set (match_dup 2) (match_dup 1))
20372 (parallel [(set (match_dup 0)
20373 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20374 (clobber (reg:CC FLAGS_REG))])]
20377 ; Don't do logical operations with memory outputs
20379 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20380 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20381 ; the same decoder scheduling characteristics as the original.
20384 [(match_scratch:SI 2 "r")
20385 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20386 (match_operator:SI 3 "arith_or_logical_operator"
20388 (match_operand:SI 1 "nonmemory_operand" "")]))
20389 (clobber (reg:CC FLAGS_REG))])]
20390 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20391 [(set (match_dup 2) (match_dup 0))
20392 (parallel [(set (match_dup 2)
20393 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20394 (clobber (reg:CC FLAGS_REG))])
20395 (set (match_dup 0) (match_dup 2))]
20399 [(match_scratch:SI 2 "r")
20400 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20401 (match_operator:SI 3 "arith_or_logical_operator"
20402 [(match_operand:SI 1 "nonmemory_operand" "")
20404 (clobber (reg:CC FLAGS_REG))])]
20405 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20406 [(set (match_dup 2) (match_dup 0))
20407 (parallel [(set (match_dup 2)
20408 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20409 (clobber (reg:CC FLAGS_REG))])
20410 (set (match_dup 0) (match_dup 2))]
20413 ;; Attempt to always use XOR for zeroing registers.
20415 [(set (match_operand 0 "register_operand" "")
20416 (match_operand 1 "const0_operand" ""))]
20417 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20418 && (! TARGET_USE_MOV0 || optimize_size)
20419 && GENERAL_REG_P (operands[0])
20420 && peep2_regno_dead_p (0, FLAGS_REG)"
20421 [(parallel [(set (match_dup 0) (const_int 0))
20422 (clobber (reg:CC FLAGS_REG))])]
20424 operands[0] = gen_lowpart (word_mode, operands[0]);
20428 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20430 "(GET_MODE (operands[0]) == QImode
20431 || GET_MODE (operands[0]) == HImode)
20432 && (! TARGET_USE_MOV0 || optimize_size)
20433 && peep2_regno_dead_p (0, FLAGS_REG)"
20434 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20435 (clobber (reg:CC FLAGS_REG))])])
20437 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20439 [(set (match_operand 0 "register_operand" "")
20441 "(GET_MODE (operands[0]) == HImode
20442 || GET_MODE (operands[0]) == SImode
20443 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20444 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20445 && peep2_regno_dead_p (0, FLAGS_REG)"
20446 [(parallel [(set (match_dup 0) (const_int -1))
20447 (clobber (reg:CC FLAGS_REG))])]
20448 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20451 ;; Attempt to convert simple leas to adds. These can be created by
20454 [(set (match_operand:SI 0 "register_operand" "")
20455 (plus:SI (match_dup 0)
20456 (match_operand:SI 1 "nonmemory_operand" "")))]
20457 "peep2_regno_dead_p (0, FLAGS_REG)"
20458 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20459 (clobber (reg:CC FLAGS_REG))])]
20463 [(set (match_operand:SI 0 "register_operand" "")
20464 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20465 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20466 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20467 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20468 (clobber (reg:CC FLAGS_REG))])]
20469 "operands[2] = gen_lowpart (SImode, operands[2]);")
20472 [(set (match_operand:DI 0 "register_operand" "")
20473 (plus:DI (match_dup 0)
20474 (match_operand:DI 1 "x86_64_general_operand" "")))]
20475 "peep2_regno_dead_p (0, FLAGS_REG)"
20476 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20477 (clobber (reg:CC FLAGS_REG))])]
20481 [(set (match_operand:SI 0 "register_operand" "")
20482 (mult:SI (match_dup 0)
20483 (match_operand:SI 1 "const_int_operand" "")))]
20484 "exact_log2 (INTVAL (operands[1])) >= 0
20485 && peep2_regno_dead_p (0, FLAGS_REG)"
20486 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20487 (clobber (reg:CC FLAGS_REG))])]
20488 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20491 [(set (match_operand:DI 0 "register_operand" "")
20492 (mult:DI (match_dup 0)
20493 (match_operand:DI 1 "const_int_operand" "")))]
20494 "exact_log2 (INTVAL (operands[1])) >= 0
20495 && peep2_regno_dead_p (0, FLAGS_REG)"
20496 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20497 (clobber (reg:CC FLAGS_REG))])]
20498 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20501 [(set (match_operand:SI 0 "register_operand" "")
20502 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20503 (match_operand:DI 2 "const_int_operand" "")) 0))]
20504 "exact_log2 (INTVAL (operands[2])) >= 0
20505 && REGNO (operands[0]) == REGNO (operands[1])
20506 && peep2_regno_dead_p (0, FLAGS_REG)"
20507 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20508 (clobber (reg:CC FLAGS_REG))])]
20509 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20511 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20512 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20513 ;; many CPUs it is also faster, since special hardware to avoid esp
20514 ;; dependencies is present.
20516 ;; While some of these conversions may be done using splitters, we use peepholes
20517 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20519 ;; Convert prologue esp subtractions to push.
20520 ;; We need register to push. In order to keep verify_flow_info happy we have
20522 ;; - use scratch and clobber it in order to avoid dependencies
20523 ;; - use already live register
20524 ;; We can't use the second way right now, since there is no reliable way how to
20525 ;; verify that given register is live. First choice will also most likely in
20526 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20527 ;; call clobbered registers are dead. We may want to use base pointer as an
20528 ;; alternative when no register is available later.
20531 [(match_scratch:SI 0 "r")
20532 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20533 (clobber (reg:CC FLAGS_REG))
20534 (clobber (mem:BLK (scratch)))])]
20535 "optimize_size || !TARGET_SUB_ESP_4"
20536 [(clobber (match_dup 0))
20537 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20538 (clobber (mem:BLK (scratch)))])])
20541 [(match_scratch:SI 0 "r")
20542 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20543 (clobber (reg:CC FLAGS_REG))
20544 (clobber (mem:BLK (scratch)))])]
20545 "optimize_size || !TARGET_SUB_ESP_8"
20546 [(clobber (match_dup 0))
20547 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20548 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20549 (clobber (mem:BLK (scratch)))])])
20551 ;; Convert esp subtractions to push.
20553 [(match_scratch:SI 0 "r")
20554 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20555 (clobber (reg:CC FLAGS_REG))])]
20556 "optimize_size || !TARGET_SUB_ESP_4"
20557 [(clobber (match_dup 0))
20558 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20561 [(match_scratch:SI 0 "r")
20562 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20563 (clobber (reg:CC FLAGS_REG))])]
20564 "optimize_size || !TARGET_SUB_ESP_8"
20565 [(clobber (match_dup 0))
20566 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20567 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20569 ;; Convert epilogue deallocator to pop.
20571 [(match_scratch:SI 0 "r")
20572 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20573 (clobber (reg:CC FLAGS_REG))
20574 (clobber (mem:BLK (scratch)))])]
20575 "optimize_size || !TARGET_ADD_ESP_4"
20576 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20577 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20578 (clobber (mem:BLK (scratch)))])]
20581 ;; Two pops case is tricky, since pop causes dependency on destination register.
20582 ;; We use two registers if available.
20584 [(match_scratch:SI 0 "r")
20585 (match_scratch:SI 1 "r")
20586 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20587 (clobber (reg:CC FLAGS_REG))
20588 (clobber (mem:BLK (scratch)))])]
20589 "optimize_size || !TARGET_ADD_ESP_8"
20590 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20591 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20592 (clobber (mem:BLK (scratch)))])
20593 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20594 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20598 [(match_scratch:SI 0 "r")
20599 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20600 (clobber (reg:CC FLAGS_REG))
20601 (clobber (mem:BLK (scratch)))])]
20603 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20604 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20605 (clobber (mem:BLK (scratch)))])
20606 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20607 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20610 ;; Convert esp additions to pop.
20612 [(match_scratch:SI 0 "r")
20613 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20614 (clobber (reg:CC FLAGS_REG))])]
20616 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20617 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20620 ;; Two pops case is tricky, since pop causes dependency on destination register.
20621 ;; We use two registers if available.
20623 [(match_scratch:SI 0 "r")
20624 (match_scratch:SI 1 "r")
20625 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20626 (clobber (reg:CC FLAGS_REG))])]
20628 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20629 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20630 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20631 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20635 [(match_scratch:SI 0 "r")
20636 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20637 (clobber (reg:CC FLAGS_REG))])]
20639 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20640 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20641 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20642 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20645 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20646 ;; required and register dies. Similarly for 128 to plus -128.
20648 [(set (match_operand 0 "flags_reg_operand" "")
20649 (match_operator 1 "compare_operator"
20650 [(match_operand 2 "register_operand" "")
20651 (match_operand 3 "const_int_operand" "")]))]
20652 "(INTVAL (operands[3]) == -1
20653 || INTVAL (operands[3]) == 1
20654 || INTVAL (operands[3]) == 128)
20655 && ix86_match_ccmode (insn, CCGCmode)
20656 && peep2_reg_dead_p (1, operands[2])"
20657 [(parallel [(set (match_dup 0)
20658 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20659 (clobber (match_dup 2))])]
20663 [(match_scratch:DI 0 "r")
20664 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20665 (clobber (reg:CC FLAGS_REG))
20666 (clobber (mem:BLK (scratch)))])]
20667 "optimize_size || !TARGET_SUB_ESP_4"
20668 [(clobber (match_dup 0))
20669 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20670 (clobber (mem:BLK (scratch)))])])
20673 [(match_scratch:DI 0 "r")
20674 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20675 (clobber (reg:CC FLAGS_REG))
20676 (clobber (mem:BLK (scratch)))])]
20677 "optimize_size || !TARGET_SUB_ESP_8"
20678 [(clobber (match_dup 0))
20679 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20680 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20681 (clobber (mem:BLK (scratch)))])])
20683 ;; Convert esp subtractions to push.
20685 [(match_scratch:DI 0 "r")
20686 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20687 (clobber (reg:CC FLAGS_REG))])]
20688 "optimize_size || !TARGET_SUB_ESP_4"
20689 [(clobber (match_dup 0))
20690 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20693 [(match_scratch:DI 0 "r")
20694 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20695 (clobber (reg:CC FLAGS_REG))])]
20696 "optimize_size || !TARGET_SUB_ESP_8"
20697 [(clobber (match_dup 0))
20698 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20699 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20701 ;; Convert epilogue deallocator to pop.
20703 [(match_scratch:DI 0 "r")
20704 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20705 (clobber (reg:CC FLAGS_REG))
20706 (clobber (mem:BLK (scratch)))])]
20707 "optimize_size || !TARGET_ADD_ESP_4"
20708 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20709 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20710 (clobber (mem:BLK (scratch)))])]
20713 ;; Two pops case is tricky, since pop causes dependency on destination register.
20714 ;; We use two registers if available.
20716 [(match_scratch:DI 0 "r")
20717 (match_scratch:DI 1 "r")
20718 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20719 (clobber (reg:CC FLAGS_REG))
20720 (clobber (mem:BLK (scratch)))])]
20721 "optimize_size || !TARGET_ADD_ESP_8"
20722 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20723 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20724 (clobber (mem:BLK (scratch)))])
20725 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20726 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20730 [(match_scratch:DI 0 "r")
20731 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20732 (clobber (reg:CC FLAGS_REG))
20733 (clobber (mem:BLK (scratch)))])]
20735 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20736 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20737 (clobber (mem:BLK (scratch)))])
20738 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20739 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20742 ;; Convert esp additions to pop.
20744 [(match_scratch:DI 0 "r")
20745 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20746 (clobber (reg:CC FLAGS_REG))])]
20748 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20749 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20752 ;; Two pops case is tricky, since pop causes dependency on destination register.
20753 ;; We use two registers if available.
20755 [(match_scratch:DI 0 "r")
20756 (match_scratch:DI 1 "r")
20757 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20758 (clobber (reg:CC FLAGS_REG))])]
20760 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20761 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20762 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20763 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20767 [(match_scratch:DI 0 "r")
20768 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20769 (clobber (reg:CC FLAGS_REG))])]
20771 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20772 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20773 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20774 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20777 ;; Convert imul by three, five and nine into lea
20780 [(set (match_operand:SI 0 "register_operand" "")
20781 (mult:SI (match_operand:SI 1 "register_operand" "")
20782 (match_operand:SI 2 "const_int_operand" "")))
20783 (clobber (reg:CC FLAGS_REG))])]
20784 "INTVAL (operands[2]) == 3
20785 || INTVAL (operands[2]) == 5
20786 || INTVAL (operands[2]) == 9"
20787 [(set (match_dup 0)
20788 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20790 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20794 [(set (match_operand:SI 0 "register_operand" "")
20795 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20796 (match_operand:SI 2 "const_int_operand" "")))
20797 (clobber (reg:CC FLAGS_REG))])]
20799 && (INTVAL (operands[2]) == 3
20800 || INTVAL (operands[2]) == 5
20801 || INTVAL (operands[2]) == 9)"
20802 [(set (match_dup 0) (match_dup 1))
20804 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20806 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20810 [(set (match_operand:DI 0 "register_operand" "")
20811 (mult:DI (match_operand:DI 1 "register_operand" "")
20812 (match_operand:DI 2 "const_int_operand" "")))
20813 (clobber (reg:CC FLAGS_REG))])]
20815 && (INTVAL (operands[2]) == 3
20816 || INTVAL (operands[2]) == 5
20817 || INTVAL (operands[2]) == 9)"
20818 [(set (match_dup 0)
20819 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20821 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20825 [(set (match_operand:DI 0 "register_operand" "")
20826 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20827 (match_operand:DI 2 "const_int_operand" "")))
20828 (clobber (reg:CC FLAGS_REG))])]
20831 && (INTVAL (operands[2]) == 3
20832 || INTVAL (operands[2]) == 5
20833 || INTVAL (operands[2]) == 9)"
20834 [(set (match_dup 0) (match_dup 1))
20836 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20838 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20840 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20841 ;; imul $32bit_imm, reg, reg is direct decoded.
20843 [(match_scratch:DI 3 "r")
20844 (parallel [(set (match_operand:DI 0 "register_operand" "")
20845 (mult:DI (match_operand:DI 1 "memory_operand" "")
20846 (match_operand:DI 2 "immediate_operand" "")))
20847 (clobber (reg:CC FLAGS_REG))])]
20848 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20849 && !satisfies_constraint_K (operands[2])"
20850 [(set (match_dup 3) (match_dup 1))
20851 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20852 (clobber (reg:CC FLAGS_REG))])]
20856 [(match_scratch:SI 3 "r")
20857 (parallel [(set (match_operand:SI 0 "register_operand" "")
20858 (mult:SI (match_operand:SI 1 "memory_operand" "")
20859 (match_operand:SI 2 "immediate_operand" "")))
20860 (clobber (reg:CC FLAGS_REG))])]
20861 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20862 && !satisfies_constraint_K (operands[2])"
20863 [(set (match_dup 3) (match_dup 1))
20864 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20865 (clobber (reg:CC FLAGS_REG))])]
20869 [(match_scratch:SI 3 "r")
20870 (parallel [(set (match_operand:DI 0 "register_operand" "")
20872 (mult:SI (match_operand:SI 1 "memory_operand" "")
20873 (match_operand:SI 2 "immediate_operand" ""))))
20874 (clobber (reg:CC FLAGS_REG))])]
20875 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20876 && !satisfies_constraint_K (operands[2])"
20877 [(set (match_dup 3) (match_dup 1))
20878 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20879 (clobber (reg:CC FLAGS_REG))])]
20882 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20883 ;; Convert it into imul reg, reg
20884 ;; It would be better to force assembler to encode instruction using long
20885 ;; immediate, but there is apparently no way to do so.
20887 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20888 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20889 (match_operand:DI 2 "const_int_operand" "")))
20890 (clobber (reg:CC FLAGS_REG))])
20891 (match_scratch:DI 3 "r")]
20892 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20893 && satisfies_constraint_K (operands[2])"
20894 [(set (match_dup 3) (match_dup 2))
20895 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20896 (clobber (reg:CC FLAGS_REG))])]
20898 if (!rtx_equal_p (operands[0], operands[1]))
20899 emit_move_insn (operands[0], operands[1]);
20903 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20904 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20905 (match_operand:SI 2 "const_int_operand" "")))
20906 (clobber (reg:CC FLAGS_REG))])
20907 (match_scratch:SI 3 "r")]
20908 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20909 && satisfies_constraint_K (operands[2])"
20910 [(set (match_dup 3) (match_dup 2))
20911 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20912 (clobber (reg:CC FLAGS_REG))])]
20914 if (!rtx_equal_p (operands[0], operands[1]))
20915 emit_move_insn (operands[0], operands[1]);
20919 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20920 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20921 (match_operand:HI 2 "immediate_operand" "")))
20922 (clobber (reg:CC FLAGS_REG))])
20923 (match_scratch:HI 3 "r")]
20924 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20925 [(set (match_dup 3) (match_dup 2))
20926 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20927 (clobber (reg:CC FLAGS_REG))])]
20929 if (!rtx_equal_p (operands[0], operands[1]))
20930 emit_move_insn (operands[0], operands[1]);
20933 ;; After splitting up read-modify operations, array accesses with memory
20934 ;; operands might end up in form:
20936 ;; movl 4(%esp), %edx
20938 ;; instead of pre-splitting:
20940 ;; addl 4(%esp), %eax
20942 ;; movl 4(%esp), %edx
20943 ;; leal (%edx,%eax,4), %eax
20946 [(parallel [(set (match_operand 0 "register_operand" "")
20947 (ashift (match_operand 1 "register_operand" "")
20948 (match_operand 2 "const_int_operand" "")))
20949 (clobber (reg:CC FLAGS_REG))])
20950 (set (match_operand 3 "register_operand")
20951 (match_operand 4 "x86_64_general_operand" ""))
20952 (parallel [(set (match_operand 5 "register_operand" "")
20953 (plus (match_operand 6 "register_operand" "")
20954 (match_operand 7 "register_operand" "")))
20955 (clobber (reg:CC FLAGS_REG))])]
20956 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20957 /* Validate MODE for lea. */
20958 && ((!TARGET_PARTIAL_REG_STALL
20959 && (GET_MODE (operands[0]) == QImode
20960 || GET_MODE (operands[0]) == HImode))
20961 || GET_MODE (operands[0]) == SImode
20962 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20963 /* We reorder load and the shift. */
20964 && !rtx_equal_p (operands[1], operands[3])
20965 && !reg_overlap_mentioned_p (operands[0], operands[4])
20966 /* Last PLUS must consist of operand 0 and 3. */
20967 && !rtx_equal_p (operands[0], operands[3])
20968 && (rtx_equal_p (operands[3], operands[6])
20969 || rtx_equal_p (operands[3], operands[7]))
20970 && (rtx_equal_p (operands[0], operands[6])
20971 || rtx_equal_p (operands[0], operands[7]))
20972 /* The intermediate operand 0 must die or be same as output. */
20973 && (rtx_equal_p (operands[0], operands[5])
20974 || peep2_reg_dead_p (3, operands[0]))"
20975 [(set (match_dup 3) (match_dup 4))
20976 (set (match_dup 0) (match_dup 1))]
20978 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20979 int scale = 1 << INTVAL (operands[2]);
20980 rtx index = gen_lowpart (Pmode, operands[1]);
20981 rtx base = gen_lowpart (Pmode, operands[3]);
20982 rtx dest = gen_lowpart (mode, operands[5]);
20984 operands[1] = gen_rtx_PLUS (Pmode, base,
20985 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20987 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20988 operands[0] = dest;
20991 ;; Call-value patterns last so that the wildcard operand does not
20992 ;; disrupt insn-recog's switch tables.
20994 (define_insn "*call_value_pop_0"
20995 [(set (match_operand 0 "" "")
20996 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20997 (match_operand:SI 2 "" "")))
20998 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20999 (match_operand:SI 3 "immediate_operand" "")))]
21002 if (SIBLING_CALL_P (insn))
21005 return "call\t%P1";
21007 [(set_attr "type" "callv")])
21009 (define_insn "*call_value_pop_1"
21010 [(set (match_operand 0 "" "")
21011 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21012 (match_operand:SI 2 "" "")))
21013 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21014 (match_operand:SI 3 "immediate_operand" "i")))]
21017 if (constant_call_address_operand (operands[1], Pmode))
21019 if (SIBLING_CALL_P (insn))
21022 return "call\t%P1";
21024 if (SIBLING_CALL_P (insn))
21027 return "call\t%A1";
21029 [(set_attr "type" "callv")])
21031 (define_insn "*call_value_0"
21032 [(set (match_operand 0 "" "")
21033 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21034 (match_operand:SI 2 "" "")))]
21037 if (SIBLING_CALL_P (insn))
21040 return "call\t%P1";
21042 [(set_attr "type" "callv")])
21044 (define_insn "*call_value_0_rex64"
21045 [(set (match_operand 0 "" "")
21046 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21047 (match_operand:DI 2 "const_int_operand" "")))]
21050 if (SIBLING_CALL_P (insn))
21053 return "call\t%P1";
21055 [(set_attr "type" "callv")])
21057 (define_insn "*call_value_1"
21058 [(set (match_operand 0 "" "")
21059 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21060 (match_operand:SI 2 "" "")))]
21061 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21063 if (constant_call_address_operand (operands[1], Pmode))
21064 return "call\t%P1";
21065 return "call\t%A1";
21067 [(set_attr "type" "callv")])
21069 (define_insn "*sibcall_value_1"
21070 [(set (match_operand 0 "" "")
21071 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21072 (match_operand:SI 2 "" "")))]
21073 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21075 if (constant_call_address_operand (operands[1], Pmode))
21079 [(set_attr "type" "callv")])
21081 (define_insn "*call_value_1_rex64"
21082 [(set (match_operand 0 "" "")
21083 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21084 (match_operand:DI 2 "" "")))]
21085 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21086 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21088 if (constant_call_address_operand (operands[1], Pmode))
21089 return "call\t%P1";
21090 return "call\t%A1";
21092 [(set_attr "type" "callv")])
21094 (define_insn "*call_value_1_rex64_large"
21095 [(set (match_operand 0 "" "")
21096 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21097 (match_operand:DI 2 "" "")))]
21098 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21100 [(set_attr "type" "callv")])
21102 (define_insn "*sibcall_value_1_rex64"
21103 [(set (match_operand 0 "" "")
21104 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21105 (match_operand:DI 2 "" "")))]
21106 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21108 [(set_attr "type" "callv")])
21110 (define_insn "*sibcall_value_1_rex64_v"
21111 [(set (match_operand 0 "" "")
21112 (call (mem:QI (reg:DI R11_REG))
21113 (match_operand:DI 1 "" "")))]
21114 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21116 [(set_attr "type" "callv")])
21118 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21119 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21120 ;; caught for use by garbage collectors and the like. Using an insn that
21121 ;; maps to SIGILL makes it more likely the program will rightfully die.
21122 ;; Keeping with tradition, "6" is in honor of #UD.
21123 (define_insn "trap"
21124 [(trap_if (const_int 1) (const_int 6))]
21126 { return ASM_SHORT "0x0b0f"; }
21127 [(set_attr "length" "2")])
21129 (define_expand "sse_prologue_save"
21130 [(parallel [(set (match_operand:BLK 0 "" "")
21131 (unspec:BLK [(reg:DI 21)
21138 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21139 (use (match_operand:DI 1 "register_operand" ""))
21140 (use (match_operand:DI 2 "immediate_operand" ""))
21141 (use (label_ref:DI (match_operand 3 "" "")))])]
21145 (define_insn "*sse_prologue_save_insn"
21146 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21147 (match_operand:DI 4 "const_int_operand" "n")))
21148 (unspec:BLK [(reg:DI 21)
21155 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21156 (use (match_operand:DI 1 "register_operand" "r"))
21157 (use (match_operand:DI 2 "const_int_operand" "i"))
21158 (use (label_ref:DI (match_operand 3 "" "X")))]
21160 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21161 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21165 operands[0] = gen_rtx_MEM (Pmode,
21166 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21167 output_asm_insn (\"jmp\\t%A1\", operands);
21168 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21170 operands[4] = adjust_address (operands[0], DImode, i*16);
21171 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21172 PUT_MODE (operands[4], TImode);
21173 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21174 output_asm_insn (\"rex\", operands);
21175 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21177 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21178 CODE_LABEL_NUMBER (operands[3]));
21182 [(set_attr "type" "other")
21183 (set_attr "length_immediate" "0")
21184 (set_attr "length_address" "0")
21185 (set_attr "length" "135")
21186 (set_attr "memory" "store")
21187 (set_attr "modrm" "0")
21188 (set_attr "mode" "DI")])
21190 (define_expand "prefetch"
21191 [(prefetch (match_operand 0 "address_operand" "")
21192 (match_operand:SI 1 "const_int_operand" "")
21193 (match_operand:SI 2 "const_int_operand" ""))]
21194 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21196 int rw = INTVAL (operands[1]);
21197 int locality = INTVAL (operands[2]);
21199 gcc_assert (rw == 0 || rw == 1);
21200 gcc_assert (locality >= 0 && locality <= 3);
21201 gcc_assert (GET_MODE (operands[0]) == Pmode
21202 || GET_MODE (operands[0]) == VOIDmode);
21204 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21205 supported by SSE counterpart or the SSE prefetch is not available
21206 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21208 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21209 operands[2] = GEN_INT (3);
21211 operands[1] = const0_rtx;
21214 (define_insn "*prefetch_sse"
21215 [(prefetch (match_operand:SI 0 "address_operand" "p")
21217 (match_operand:SI 1 "const_int_operand" ""))]
21218 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21220 static const char * const patterns[4] = {
21221 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21224 int locality = INTVAL (operands[1]);
21225 gcc_assert (locality >= 0 && locality <= 3);
21227 return patterns[locality];
21229 [(set_attr "type" "sse")
21230 (set_attr "memory" "none")])
21232 (define_insn "*prefetch_sse_rex"
21233 [(prefetch (match_operand:DI 0 "address_operand" "p")
21235 (match_operand:SI 1 "const_int_operand" ""))]
21236 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21238 static const char * const patterns[4] = {
21239 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21242 int locality = INTVAL (operands[1]);
21243 gcc_assert (locality >= 0 && locality <= 3);
21245 return patterns[locality];
21247 [(set_attr "type" "sse")
21248 (set_attr "memory" "none")])
21250 (define_insn "*prefetch_3dnow"
21251 [(prefetch (match_operand:SI 0 "address_operand" "p")
21252 (match_operand:SI 1 "const_int_operand" "n")
21254 "TARGET_3DNOW && !TARGET_64BIT"
21256 if (INTVAL (operands[1]) == 0)
21257 return "prefetch\t%a0";
21259 return "prefetchw\t%a0";
21261 [(set_attr "type" "mmx")
21262 (set_attr "memory" "none")])
21264 (define_insn "*prefetch_3dnow_rex"
21265 [(prefetch (match_operand:DI 0 "address_operand" "p")
21266 (match_operand:SI 1 "const_int_operand" "n")
21268 "TARGET_3DNOW && TARGET_64BIT"
21270 if (INTVAL (operands[1]) == 0)
21271 return "prefetch\t%a0";
21273 return "prefetchw\t%a0";
21275 [(set_attr "type" "mmx")
21276 (set_attr "memory" "none")])
21278 (define_expand "stack_protect_set"
21279 [(match_operand 0 "memory_operand" "")
21280 (match_operand 1 "memory_operand" "")]
21283 #ifdef TARGET_THREAD_SSP_OFFSET
21285 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21286 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21288 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21289 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21292 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21294 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21299 (define_insn "stack_protect_set_si"
21300 [(set (match_operand:SI 0 "memory_operand" "=m")
21301 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21302 (set (match_scratch:SI 2 "=&r") (const_int 0))
21303 (clobber (reg:CC FLAGS_REG))]
21305 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21306 [(set_attr "type" "multi")])
21308 (define_insn "stack_protect_set_di"
21309 [(set (match_operand:DI 0 "memory_operand" "=m")
21310 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21311 (set (match_scratch:DI 2 "=&r") (const_int 0))
21312 (clobber (reg:CC FLAGS_REG))]
21314 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21315 [(set_attr "type" "multi")])
21317 (define_insn "stack_tls_protect_set_si"
21318 [(set (match_operand:SI 0 "memory_operand" "=m")
21319 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21320 (set (match_scratch:SI 2 "=&r") (const_int 0))
21321 (clobber (reg:CC FLAGS_REG))]
21323 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21324 [(set_attr "type" "multi")])
21326 (define_insn "stack_tls_protect_set_di"
21327 [(set (match_operand:DI 0 "memory_operand" "=m")
21328 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21329 (set (match_scratch:DI 2 "=&r") (const_int 0))
21330 (clobber (reg:CC FLAGS_REG))]
21333 /* The kernel uses a different segment register for performance reasons; a
21334 system call would not have to trash the userspace segment register,
21335 which would be expensive */
21336 if (ix86_cmodel != CM_KERNEL)
21337 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21339 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21341 [(set_attr "type" "multi")])
21343 (define_expand "stack_protect_test"
21344 [(match_operand 0 "memory_operand" "")
21345 (match_operand 1 "memory_operand" "")
21346 (match_operand 2 "" "")]
21349 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21350 ix86_compare_op0 = operands[0];
21351 ix86_compare_op1 = operands[1];
21352 ix86_compare_emitted = flags;
21354 #ifdef TARGET_THREAD_SSP_OFFSET
21356 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21357 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21359 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21360 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21363 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21365 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21367 emit_jump_insn (gen_beq (operands[2]));
21371 (define_insn "stack_protect_test_si"
21372 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21373 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21374 (match_operand:SI 2 "memory_operand" "m")]
21376 (clobber (match_scratch:SI 3 "=&r"))]
21378 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21379 [(set_attr "type" "multi")])
21381 (define_insn "stack_protect_test_di"
21382 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21383 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21384 (match_operand:DI 2 "memory_operand" "m")]
21386 (clobber (match_scratch:DI 3 "=&r"))]
21388 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21389 [(set_attr "type" "multi")])
21391 (define_insn "stack_tls_protect_test_si"
21392 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21393 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21394 (match_operand:SI 2 "const_int_operand" "i")]
21395 UNSPEC_SP_TLS_TEST))
21396 (clobber (match_scratch:SI 3 "=r"))]
21398 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21399 [(set_attr "type" "multi")])
21401 (define_insn "stack_tls_protect_test_di"
21402 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21403 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21404 (match_operand:DI 2 "const_int_operand" "i")]
21405 UNSPEC_SP_TLS_TEST))
21406 (clobber (match_scratch:DI 3 "=r"))]
21409 /* The kernel uses a different segment register for performance reasons; a
21410 system call would not have to trash the userspace segment register,
21411 which would be expensive */
21412 if (ix86_cmodel != CM_KERNEL)
21413 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21415 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21417 [(set_attr "type" "multi")])
21419 (define_mode_iterator CRC32MODE [QI HI SI])
21420 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21421 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21423 (define_insn "sse4_2_crc32<mode>"
21424 [(set (match_operand:SI 0 "register_operand" "=r")
21426 [(match_operand:SI 1 "register_operand" "0")
21427 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21430 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21431 [(set_attr "type" "sselog1")
21432 (set_attr "prefix_rep" "1")
21433 (set_attr "prefix_extra" "1")
21434 (set_attr "mode" "SI")])
21436 (define_insn "sse4_2_crc32di"
21437 [(set (match_operand:DI 0 "register_operand" "=r")
21439 [(match_operand:DI 1 "register_operand" "0")
21440 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21442 "TARGET_SSE4_2 && TARGET_64BIT"
21443 "crc32q\t{%2, %0|%0, %2}"
21444 [(set_attr "type" "sselog1")
21445 (set_attr "prefix_rep" "1")
21446 (set_attr "prefix_extra" "1")
21447 (set_attr "mode" "DI")])
21451 (include "sync.md")